void Start() { m_moveInput = new MoveInputs(); PickNewDestination(); m_run = Random.Range(0.0f, 1.0f) < 0.35f; }
public static MoveInputs GetPlayerInputs(Transform player) { MoveInputs inputs = new MoveInputs(); float x = Controls.AverageValue(GameAxis.MoveX); float y = Controls.AverageValue(GameAxis.MoveY); Vector3 raw = Vector3.ClampMagnitude(new Vector3(x, 0, y), 1); if (raw.magnitude > 0) { inputs.Turn = Utils.GetBearing(player.forward, Camera.main.transform.rotation * raw, Vector3.up); inputs.Forward = 1; } m_walk = Controls.JustDown(GameButton.WalkToggle) ? !m_walk : m_walk; inputs.Run = raw.magnitude > 0.75f && m_walk == Controls.IsDown(GameButton.Walk); inputs.Jump = Controls.JustDown(GameButton.Jump); return inputs; }
public MoveInputs GetInputs() { MoveInputs moveInput = new MoveInputs(); Quaternion rot = Quaternion.LookRotation(Vector3.ProjectOnPlane(transform.forward, Vector3.up), Vector3.up); Vector3 disp = Quaternion.Inverse(rot) * (m_destination - transform.position); float bearing = 0; if (disp.sqrMagnitude > 0.001f) { bearing = Mathf.DeltaAngle(Quaternion.LookRotation(disp).eulerAngles.y, 0); } Debug.DrawLine(transform.position, m_destination); moveInput.Forward = disp.magnitude > 0.2f ? 1 : 0; moveInput.Turn = -bearing; moveInput.Run = m_run; moveInput.Jump = false; return moveInput; }
/* * Moves the character based on the provided input */ private void ExecuteMovement(MoveInputs inputs) { m_forwardVelocity = Mathf.MoveTowards(m_forwardVelocity, inputs.forward * (inputs.run ? runSpeed : walkSpeed), acceleration * Time.deltaTime); Vector3 desiredMove = transform.forward * m_forwardVelocity * Time.deltaTime; m_angularVelocity = rotSpeed * inputs.turn; m_move = new Vector3(desiredMove.x, m_move.y, desiredMove.z); if (m_controller.isGrounded) { // align the character to the ground being stood on Vector3 normal = GetGroundNormal(normalSamples, groundSmoothRadius); Quaternion targetRot = Quaternion.LookRotation(Vector3.Cross(transform.right, normal), normal); transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, Time.deltaTime * groundAlignSpeed); // keeps the character on the ground by applying a small downwards velocity proportional to the slope the character is standing on float slopeFactor = (1 - Mathf.Clamp01(Vector3.Dot(normal, Vector3.up))); m_move.y = -0.2f * slopeFactor + (1 - slopeFactor) * -0.01f; // jumping if (inputs.jump) { m_move.y = jumpSpeed; } } else { // slowly orient the character up in the air Vector3 normal = Vector3.up; Quaternion targetRot = Quaternion.LookRotation(Vector3.Cross(transform.right, normal), normal); transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, Time.deltaTime * airAlignSpeed); // gravity when character is in the air m_move += Physics.gravity * gravityFraction * Time.deltaTime; } m_CollisionFlags = m_controller.Move(m_move); transform.Rotate(0, m_angularVelocity * Time.deltaTime, 0, Space.Self); }
/* * Moves the character based on the provided input */ public void ExecuteMovementAA(MoveInputs inputs) { bool isStaggered = Utils.InDuration(m_staggerTime, staggerDuration); m_isRunning = inputs.Run; float targetSpeed = inputs.Forward * (isStaggered ? staggerMoveSpeed : (inputs.Run ? runSpeed : walkSpeed)); m_attemptedSpeed = Mathf.MoveTowards(m_attemptedSpeed, targetSpeed, acceleration * Time.deltaTime); Vector3 moveVelocity = transform.forward * m_attemptedSpeed; moveVelocity.y = m_actualVelocity.y; Vector3 lowerSphereCenter = transform.TransformPoint(m_controller.center) + Vector3.down * (m_controller.height * 0.5f - (m_controller.radius + 0.01f)); RaycastHit[] hits = Physics.SphereCastAll(lowerSphereCenter, m_controller.radius, Vector3.down, 0.02f + m_controller.skinWidth, m_groundSpherecast, QueryTriggerInteraction.Ignore); m_isGrounded = hits != null && hits.Length > 0; // if there is only one hit, Unity doesn't always return the correct normal, using Vector3.Up instead with SphereCastAll. SphereCast works however... if (hits != null && hits.Length == 1) { RaycastHit hit; m_isGrounded = Physics.SphereCast(lowerSphereCenter, m_controller.radius, Vector3.down, out hit, 0.02f + m_controller.skinWidth, m_groundSpherecast, QueryTriggerInteraction.Ignore); hits[0] = hit; } Vector3 alignNormal; if (m_isGrounded) { RaycastHit bestHit = hits.OrderBy(h => h.point.y).First(); NormalInfo normalInfo = GetGroundNormal(normalSamples, groundSmoothRadius, m_controller.slopeLimit, 90); alignNormal = normalInfo.limitedNormal ?? (normalInfo.normal ?? Vector3.up); bool slipping = Vector3.Dot(bestHit.normal, Vector3.up) < Mathf.Cos(m_controller.slopeLimit / 2 * Mathf.Deg2Rad) && moveVelocity.y <= 0; if (slipping || (Time.time - m_slipTime) < 1.0f) { if (slipping) { m_slipTime = Time.deltaTime; } moveVelocity = m_actualVelocity + Vector3.ProjectOnPlane(Physics.gravity * Time.deltaTime, bestHit.normal); } else if (inputs.Jump) { moveVelocity.y = jumpSpeed; } else if (bestHit.transform.gameObject.layer == LayerMask.NameToLayer("Ground")) { float slopeFactor = (1 - Mathf.Clamp(Vector3.Dot(bestHit.normal, Vector3.up), 0, 0.5f)); moveVelocity.y = (-0.05f * slopeFactor + (1 - slopeFactor) * -0.01f) / Time.deltaTime; } } else { alignNormal = Vector3.up; } Quaternion targetRot = Quaternion.LookRotation(Vector3.Cross(transform.right, alignNormal), alignNormal); if (Quaternion.Angle(transform.rotation, targetRot) > 2.0f) { transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, (m_isGrounded ? groundAlignSpeed : airAlignSpeed) * Time.deltaTime); } moveVelocity += gravityFraction * Physics.gravity * Time.deltaTime; Vector3 oldPosition = transform.position; m_controller.Move(moveVelocity * Time.deltaTime); m_actualVelocity = (transform.position - oldPosition) / Time.deltaTime; m_actualVelocity.y = m_actualVelocity.y > 0 ? Mathf.Min(m_actualVelocity.y, moveVelocity.y) : Mathf.Max(m_actualVelocity.y, moveVelocity.y); float maxTurnSpeed = isStaggered ? staggerRotateSpeed : (m_isGrounded ? rotSpeed : airRotSpeed); float targetAngVelocity = forwardAngVelocity * Mathf.Sign(inputs.Turn) + (oppositeAngVelocity - forwardAngVelocity) * (inputs.Turn / 180); m_angVelocity = Mathf.Clamp(Mathf.MoveTowards(m_angVelocity, targetAngVelocity, maxTorque * Time.deltaTime), -maxTurnSpeed, maxTurnSpeed); float deltaRotation = m_angVelocity * Time.deltaTime; if (Mathf.Abs(inputs.Turn) < Mathf.Abs(deltaRotation)) { deltaRotation = inputs.Turn; m_angVelocity = 0; } transform.Rotate(0, deltaRotation, 0, Space.Self); }
/* * Moves the character based on the provided input */ public void ExecuteMovement(MoveInputs inputs) { bool isStaggered = Utils.InDuration(m_staggerTime, staggerDuration); m_isRunning = inputs.Run; float targetSpeed = inputs.Forward * (isStaggered ? staggerMoveSpeed : (inputs.Run ? runSpeed : walkSpeed)); GetComponent<Rigidbody>().AddForce(targetSpeed * transform.forward); //m_attemptedSpeed = Mathf.MoveTowards(m_attemptedSpeed, targetSpeed, acceleration * Time.deltaTime); //Vector3 moveVelocity = transform.forward * m_attemptedSpeed; Vector3 lowerSphereCenter = transform.TransformPoint(m_controller.center) + Vector3.down * (m_controller.height * 0.5f - (m_controller.radius + 0.01f)); RaycastHit[] hits = Physics.SphereCastAll(lowerSphereCenter, m_controller.radius, Vector3.down, 0.02f + m_controller.skinWidth, m_groundSpherecast, QueryTriggerInteraction.Ignore); m_isGrounded = hits != null && hits.Length > 0; // if there is only one hit, Unity doesn't always return the correct normal, using Vector3.Up instead with SphereCastAll. SphereCast works however... if (hits != null && hits.Length == 1) { RaycastHit hit; m_isGrounded = Physics.SphereCast(lowerSphereCenter, m_controller.radius, Vector3.down, out hit, 0.02f + m_controller.skinWidth, m_groundSpherecast, QueryTriggerInteraction.Ignore); hits[0] = hit; } float maxTurnSpeed = isStaggered ? staggerRotateSpeed : (m_isGrounded ? rotSpeed : airRotSpeed); float targetAngVelocity = forwardAngVelocity * Mathf.Sign(inputs.Turn) + (oppositeAngVelocity - forwardAngVelocity) * (inputs.Turn / 180); m_angVelocity = Mathf.Clamp(Mathf.MoveTowards(m_angVelocity, targetAngVelocity, maxTorque * Time.deltaTime), -maxTurnSpeed, maxTurnSpeed); float deltaRotation = m_angVelocity * Time.deltaTime; if (Mathf.Abs(inputs.Turn) < Mathf.Abs(deltaRotation)) { deltaRotation = inputs.Turn; m_angVelocity = 0; } transform.Rotate(0, deltaRotation, 0, Space.Self); }
public void CheckForInput() { if (mCurInput == MoveInputs.Centering) { return; } //Use Buffered if (mCurInput == MoveInputs.None && mBufferedInput != MoveInputs.None) { mCurInput = mBufferedInput; mBufferedInput = MoveInputs.None; } //Set Current Or Buffer if (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A) && mCurInput == MoveInputs.None) { mCurInput = MoveInputs.Left; } else if (Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D) && mCurInput == MoveInputs.None) { mCurInput = MoveInputs.Right; } else if (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.A)) { mBufferedInput = MoveInputs.Left; } else if (Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.D)) { mBufferedInput = MoveInputs.Right; } if (!Player.ChangingLanes) { if (mCurInput == MoveInputs.Left) { if (mRiderType == RiderType.WildRider) { Player.ChangeToLane(Player.CurLane - 2 % (Player.MaxLaneAvailable - Player.MinLaneAvailable)); } else if (mRiderType == RiderType.ZooLander) { mCurInput = MoveInputs.None; } else { Player.ChangeToLane(Player.CurLane - 1); } } else if (mCurInput == MoveInputs.Right) { if (mRiderType == RiderType.WildRider) { Player.ChangeToLane(Player.CurLane + 2 % (Player.MaxLaneAvailable - Player.MinLaneAvailable)); } else if (mRiderType == RiderType.ZooLander) { Player.ChangeToLane(Player.CurLane + 1 % (Player.MaxLaneAvailable - Player.MinLaneAvailable)); } else { Player.ChangeToLane(Player.CurLane + 1); } } } if (Reload >= ArrowReloadSpeed) { if (Input.GetKeyDown(KeyCode.Space)) { Shoot(); } } }
public void LaneChangeComplete() { mCurInput = MoveInputs.None; }
/* * Executes the player's or AI's commands */ void Update() { if (GetComponent<TSAI>()) { ExecuteMovement(GetComponent<TSAI>().GetMovement()); } else { MoveInputs inputs = new MoveInputs(); inputs.turn = Input.GetAxis("Horizontal"); inputs.forward = Input.GetAxis("Vertical"); inputs.run = Input.GetKey(KeyCode.LeftShift) && Input.GetAxis("Vertical") > 0; inputs.jump = Input.GetButtonDown("Jump"); ExecuteMovement(inputs); } }