123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- 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;
- }
- }
- }
|