using System; using System.Collections.Generic; using UnityEngine; using Drawing; using Reset.Movement; using Sirenix.OdinInspector; public enum PlayerFacingDirection{ TowardsTarget = 0, MatchForward, MatchCamera, Static, Momentum } namespace Reset.Units{ // public interface IBuffSource{ - Unused good idea? // public Object sourceObject(); // public // } public class UnitMovementData{ // Movement Direction public float accelerationSmoothing = 5f; public float deaccelerationSmoothing = 5f; public AnimationCurve deaccelerationCurve; // Move Speed public float moveSpeedTarget = 15f; public float moveSpeedSoothing = 10f; // Jumping [ShowInInspector, ReadOnly] public float jumpPower; public float jumpPowerDecay; // Gravity [ShowInInspector, ReadOnly] public float gravityPower; public float gravityMax; public float gravityAcceleration; // Rotation public PlayerFacingDirection rotateFacing; public float rotationSpeedTarget = 5f; public float rotationSmoothing; // Smoothing public Quaternion targetRotation; public float currentRotSpeed; } public class UnitMovementHandler : MonoBehaviour{ // class MovementFloatModifier{ // // IBuffSource source // public float value; // } // Debug viewing // Smoothed Values [ShowInInspector, ReadOnly] private float outputSpeed; [ShowInInspector, ReadOnly] private Vector3 outputMoveDirection; [ShowInInspector, ReadOnly] private Quaternion outputRotation; [ShowInInspector, ReadOnly] private float outputRotationSpeed; private CharacterController controller; public PlayerControls controls; [SerializeReference, ShowInInspector] public UnitMovementData data = new UnitMovementData(); void Awake(){ controller = GetComponent(); } void Update(){ UpdateCurrentDirection(); UpdateCurrentSpeed(); UpdateCurrentGravity(); UpdateCurrentRotation(); DoMovement(); } private void UpdateCurrentDirection(){ // Get input value Vector3 inputMovement = new Vector3( controls. rawMoveInput.x, 0f, controls. rawMoveInput.y); // Construct move direction Vector3 targetDirection = inputMovement; if (inputMovement.magnitude < .1f) { targetDirection = Vector3.zero; } // Remove Y from variables Vector3 targetNoY = new Vector3(targetDirection.x, 0f, targetDirection.z); Vector3 currentNoY = new Vector3(outputMoveDirection.x, 0f, outputMoveDirection.z); // Smooth movement if (targetNoY.magnitude > currentNoY.magnitude) { currentNoY = Vector3.Slerp(currentNoY, targetNoY,data.accelerationSmoothing * Time.deltaTime); } else { float deaccelValue = data.deaccelerationCurve.Evaluate(inputMovement.magnitude); currentNoY = Vector3.Lerp(currentNoY, targetNoY, data.deaccelerationSmoothing * Time.deltaTime); } // Commit move direction outputMoveDirection = new Vector3(currentNoY.x, outputMoveDirection.y, currentNoY.z); } private void UpdateCurrentSpeed(){ outputSpeed = Mathf.Lerp(outputSpeed, data.moveSpeedTarget, data.moveSpeedSoothing * Time.deltaTime); } private void UpdateCurrentGravity(){ // Accelerate gravity data.gravityPower += data.gravityAcceleration * Time.deltaTime; data.gravityPower = Mathf.Min(data.gravityPower, data.gravityMax); // Apply a constant gravity if the player is grounded if (controller.isGrounded) { data.gravityPower = .1f; } // Create the final gravity value float gravityMoveDirection = data.jumpPower + Physics.gravity.y * data.gravityPower; // Commit gravity to move direction, ignoring XZ since those are done in UpdateMovementDirection outputMoveDirection = new Vector3(outputMoveDirection.x, gravityMoveDirection, outputMoveDirection.z); } private void UpdateCurrentRotation(){ // Calculate rotation speed outputRotationSpeed = Mathf.Lerp(outputRotationSpeed, data.rotationSpeedTarget, data.rotationSmoothing * Time.deltaTime); // Get input value Vector3 inputMovement = new Vector3(controls.rawMoveInput.x, 0f, controls.rawMoveInput.y); switch (data.rotateFacing) { // TODO: Recomment case PlayerFacingDirection.TowardsTarget: Debug.LogError("Not implemented..."); break; case PlayerFacingDirection.Momentum: if (inputMovement.magnitude > .03f){ outputRotation = Camera.main.transform.rotation * Quaternion.LookRotation(outputMoveDirection); } break; case PlayerFacingDirection.MatchForward: if (controls.rawMoveInput.magnitude < 0.01f) { break; } outputRotation = Camera.main.transform.rotation * Quaternion.LookRotation(inputMovement); break; case PlayerFacingDirection.MatchCamera: outputRotation = Quaternion.Euler(Camera.main.transform.rotation.eulerAngles.Flatten(0, null, 0)); break; case PlayerFacingDirection.Static: outputRotation = transform.rotation; break; } // Set final rotation transform.rotation = Quaternion.Lerp(transform.rotation, outputRotation, 10f * Time.deltaTime).Flatten(0, null, 0); } public void DoMovement(){ DoMovement(outputMoveDirection, outputSpeed); } public void DoMovement(Vector3 moveDir, float speed){ // Commit the move, with respect to the camera's rotation controller.Move((Camera.main.transform.rotation.Flatten(0, null, 0) * (moveDir * speed) * Time.deltaTime)); } public void LateUpdate(){ UpdateGravityLate(); } private void UpdateGravityLate(){ // Decay jump power } } }