You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			212 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			212 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C#
		
	
using UnityEngine;
 | 
						|
using System.Collections;
 | 
						|
using Valve.VR.InteractionSystem;
 | 
						|
 | 
						|
namespace Valve.VR.InteractionSystem.Sample
 | 
						|
{
 | 
						|
    public class JoeJeff : MonoBehaviour
 | 
						|
    {
 | 
						|
        public float animationSpeed;
 | 
						|
 | 
						|
        public float jumpVelocity;
 | 
						|
 | 
						|
        [SerializeField]
 | 
						|
        private float m_MovingTurnSpeed = 360;
 | 
						|
        [SerializeField]
 | 
						|
        private float m_StationaryTurnSpeed = 180;
 | 
						|
 | 
						|
        public float airControl;
 | 
						|
 | 
						|
        [Tooltip("The time it takes after landing a jump to slow down")]
 | 
						|
        public float frictionTime = 0.2f;
 | 
						|
 | 
						|
        [SerializeField]
 | 
						|
        private float footHeight = 0.1f;
 | 
						|
        [SerializeField]
 | 
						|
        private float footRadius = 0.03f;
 | 
						|
 | 
						|
        private RaycastHit footHit;
 | 
						|
 | 
						|
        private bool isGrounded;
 | 
						|
 | 
						|
        private float turnAmount;
 | 
						|
        private float forwardAmount;
 | 
						|
 | 
						|
        private float groundedTime;
 | 
						|
 | 
						|
        private Animator animator;
 | 
						|
 | 
						|
        private Vector3 input;
 | 
						|
 | 
						|
        private bool held;
 | 
						|
 | 
						|
        private new Rigidbody rigidbody;
 | 
						|
        private Interactable interactable;
 | 
						|
 | 
						|
        public FireSource fire;
 | 
						|
 | 
						|
 | 
						|
        private void Start()
 | 
						|
        {
 | 
						|
            animator = GetComponent<Animator>();
 | 
						|
            rigidbody = GetComponent<Rigidbody>();
 | 
						|
            interactable = GetComponent<Interactable>();
 | 
						|
            animator.speed = animationSpeed;
 | 
						|
        }
 | 
						|
 | 
						|
        private void Update()
 | 
						|
        {
 | 
						|
            held = interactable.attachedToHand != null;
 | 
						|
 | 
						|
            jumpTimer -= Time.deltaTime;
 | 
						|
 | 
						|
            CheckGrounded();
 | 
						|
 | 
						|
            rigidbody.freezeRotation = !held;
 | 
						|
 | 
						|
            if (held == false)
 | 
						|
                FixRotation();
 | 
						|
        }
 | 
						|
 | 
						|
        private void FixRotation()
 | 
						|
        {
 | 
						|
            Vector3 eulers = transform.eulerAngles;
 | 
						|
            eulers.x = 0;
 | 
						|
            eulers.z = 0;
 | 
						|
            Quaternion targetRotation = Quaternion.Euler(eulers);
 | 
						|
 | 
						|
            transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.deltaTime * (isGrounded ? 20 : 3));
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        public void OnAnimatorMove()
 | 
						|
        {
 | 
						|
            // we implement this function to override the default root motion.
 | 
						|
            // this allows us to modify the positional speed before it's applied.
 | 
						|
            if (Time.deltaTime > 0)
 | 
						|
            {
 | 
						|
                Vector3 animationDelta = (animator.deltaPosition) / Time.deltaTime;
 | 
						|
 | 
						|
                animationDelta = Vector3.ProjectOnPlane(animationDelta, footHit.normal);
 | 
						|
 | 
						|
                if (isGrounded && jumpTimer < 0)
 | 
						|
                {
 | 
						|
                    if (groundedTime < frictionTime) //slow down when first hitting the floor after a jump
 | 
						|
                    {
 | 
						|
                        float moveFac = Mathf.InverseLerp(0, frictionTime, groundedTime);
 | 
						|
                        //print(moveFac);
 | 
						|
                        Vector3 lerpV = Vector3.Lerp(rigidbody.velocity, animationDelta, moveFac * Time.deltaTime * 30);
 | 
						|
                        animationDelta.x = lerpV.x;
 | 
						|
                        animationDelta.z = lerpV.z;
 | 
						|
                    }
 | 
						|
 | 
						|
                    // adding a little downward force to keep him on the floor
 | 
						|
                    animationDelta.y += -0.2f;// rb.velocity.y;
 | 
						|
                    rigidbody.velocity = animationDelta;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    rigidbody.velocity += input * Time.deltaTime * airControl;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        public void Move(Vector3 move, bool jump)
 | 
						|
        {
 | 
						|
            input = move;
 | 
						|
            if (move.magnitude > 1f)
 | 
						|
                move.Normalize();
 | 
						|
 | 
						|
            move = transform.InverseTransformDirection(move);
 | 
						|
 | 
						|
            turnAmount = Mathf.Atan2(move.x, move.z);
 | 
						|
            forwardAmount = move.z;
 | 
						|
 | 
						|
            ApplyExtraTurnRotation();
 | 
						|
 | 
						|
            // control and velocity handling is different when grounded and airborne:
 | 
						|
            if (isGrounded)
 | 
						|
            {
 | 
						|
                HandleGroundedMovement(jump);
 | 
						|
            }
 | 
						|
 | 
						|
 | 
						|
            // send input and other state parameters to the animator
 | 
						|
            UpdateAnimator(move);
 | 
						|
        }
 | 
						|
 | 
						|
        private void UpdateAnimator(Vector3 move)
 | 
						|
        {
 | 
						|
            animator.speed = fire.isBurning ? animationSpeed * 2 : animationSpeed;
 | 
						|
            // update the animator parameters
 | 
						|
            animator.SetFloat("Forward", fire.isBurning ? 2 : forwardAmount, 0.1f, Time.deltaTime);
 | 
						|
            animator.SetFloat("Turn", turnAmount, 0.1f, Time.deltaTime);
 | 
						|
            animator.SetBool("OnGround", isGrounded);
 | 
						|
            animator.SetBool("Holding", held);
 | 
						|
 | 
						|
            if (!isGrounded)
 | 
						|
            {
 | 
						|
                animator.SetFloat("FallSpeed", Mathf.Abs(rigidbody.velocity.y));
 | 
						|
                animator.SetFloat("Jump", rigidbody.velocity.y);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        private void ApplyExtraTurnRotation()
 | 
						|
        {
 | 
						|
            // help the character turn faster (this is in addition to root rotation in the animation)
 | 
						|
            float turnSpeed = Mathf.Lerp(m_StationaryTurnSpeed, m_MovingTurnSpeed, forwardAmount);
 | 
						|
            transform.Rotate(0, turnAmount * turnSpeed * Time.deltaTime, 0);
 | 
						|
        }
 | 
						|
 | 
						|
        private void CheckGrounded()
 | 
						|
        {
 | 
						|
            isGrounded = false;
 | 
						|
            if (jumpTimer < 0 & !held) // make sure we didn't just jump
 | 
						|
            {
 | 
						|
                isGrounded = (Physics.SphereCast(new Ray(transform.position + Vector3.up * footHeight, Vector3.down), footRadius, out footHit, footHeight - footRadius));
 | 
						|
                if (Vector2.Distance(new Vector2(transform.position.x, transform.position.z), new Vector2(footHit.point.x, footHit.point.z)) > footRadius / 2)
 | 
						|
                {
 | 
						|
                    isGrounded = false;
 | 
						|
                    //on slope, hit point is on edge of sphere cast
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        private void FixedUpdate()
 | 
						|
        {
 | 
						|
            groundedTime += Time.fixedDeltaTime;
 | 
						|
            if (!isGrounded) groundedTime = 0; // reset timer
 | 
						|
 | 
						|
            if (isGrounded & !held)
 | 
						|
            {
 | 
						|
                Debug.DrawLine(transform.position, footHit.point);
 | 
						|
 | 
						|
                rigidbody.position = new Vector3(rigidbody.position.x, footHit.point.y, rigidbody.position.z);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
        private void HandleGroundedMovement(bool jump)
 | 
						|
        {
 | 
						|
            // check whether conditions are right to allow a jump:
 | 
						|
            if (jump && isGrounded)
 | 
						|
            {
 | 
						|
                Jump();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        private float jumpTimer;
 | 
						|
        public void Jump()
 | 
						|
        {
 | 
						|
            isGrounded = false;
 | 
						|
            jumpTimer = 0.1f;
 | 
						|
            animator.applyRootMotion = false;
 | 
						|
            rigidbody.position += Vector3.up * 0.03f;
 | 
						|
            Vector3 velocity = rigidbody.velocity;
 | 
						|
            velocity.y = jumpVelocity;
 | 
						|
            rigidbody.velocity = velocity;
 | 
						|
        }
 | 
						|
    }
 | 
						|
} |