Untitled
unknown
csharp
11 days ago
7.6 kB
1
Indexable
Never
using System.Runtime.CompilerServices; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.Video; public class MoveAction : PlayerAction { // On Move Vector2 move; public void OnMove(InputAction.CallbackContext callbackContext) { // If control lock is active, ignore left/right input if (!controlLockActive) { move = callbackContext.ReadValue<Vector2>(); } else { // Prevent left and right input during the control lock period move.x = 0; // Only vertical movement allowed } } // On Enable void OnEnable() { playerPhysics.onPlayerPhysicsUpdate += Move; } // On Disable void OnDisable() { playerPhysics.onPlayerPhysicsUpdate -= Move; } // Movement Settings [SerializeField] Transform cameraTransform; [SerializeField] float acceleration; [SerializeField] float deceleration; [SerializeField] float maxSpeed; [SerializeField] float minTurnSpeed; [SerializeField] float maxTurnSpeed; [SerializeField, Range(0, 1)] float turnDeceleration; [SerializeField] float uphillDeceleration; [SerializeField] float downhillAcceleration; [SerializeField] bool controlLockActive; [SerializeField] float controlLockTimer; [SerializeField] float brakeSpeed; [SerializeField, Range(0, 1)] float softBrakeThreshold; [SerializeField] float brakeThreshold; [SerializeField] float brakeTime; [SerializeField] private Animator animator; [SerializeField] private ParticleSystem speedLines; [SerializeField] private float speedLineThreshold; [SerializeField] private Camera mainCamera; [SerializeField] private float targetFOV = 90f; [SerializeField] private float baseFOV = 60f; [SerializeField] private float fovChangeSpeed = 2f; private bool launched = false; private Vector3[] parabolicPoints; private int currentPointIndex; private float launchDuration; private float launchTime; bool braking; float brakeTimer; private void FixedUpdate() { if(controlLockActive) { controlLockTimer -= Time.deltaTime; if(controlLockTimer <= 0) { controlLockActive = false; } } if (launched) { FollowLaunchPath(); } } public void StartLaunch(Vector3[] pathPoints, float duration) { launched = true; parabolicPoints = pathPoints; currentPointIndex = 0; launchDuration = duration; launchTime = 0f; TriggerControlLock(duration); } private void FollowLaunchPath() { if (currentPointIndex < parabolicPoints.Length) { RB.position = Vector3.Lerp(RB.position, parabolicPoints[currentPointIndex], launchTime / launchDuration); currentPointIndex++; if (currentPointIndex >= parabolicPoints.Length) { EndLaunch(); } } } private void EndLaunch() { launched = false; controlLockActive = false; } public bool IsBraking() { return braking; } public Vector3 GetMoveVector() { return GetMoveVector(cameraTransform, groundInfo.normal, move); } //Control Lock Trigger public void TriggerControlLock(float duration) { controlLockActive = true; controlLockTimer = duration; } // Move function void Move() { Vector3 moveVector = GetMoveVector(cameraTransform, groundInfo.normal, move); if (launched) return; float currentSpeed = playerPhysics.speed; animator.SetFloat("Speed", currentSpeed); animator.speed = Mathf.Clamp(currentSpeed / maxSpeed, 0.5f, 2f); if (currentSpeed >= speedLineThreshold && !speedLines.isPlaying) { speedLines.Play(); } else if (currentSpeed < speedLineThreshold && speedLines.isPlaying) { speedLines.Stop(); } if (currentSpeed >= speedLineThreshold) { mainCamera.fieldOfView = Mathf.Lerp(mainCamera.fieldOfView, targetFOV, fovChangeSpeed * Time.deltaTime); } else { mainCamera.fieldOfView = Mathf.Lerp(mainCamera.fieldOfView, baseFOV, fovChangeSpeed * Time.deltaTime); } bool wasBraking = braking; braking = groundInfo.ground && playerPhysics.speed > RB.sleepThreshold && ((braking && brakeTimer > 0) || Vector3.Dot(moveVector.normalized, playerPhysics.horizontalVelocity) < -brakeThreshold); if (braking) { brakeTimer -= Time.deltaTime; } if (braking && !wasBraking) { brakeTimer = brakeTime; } if (braking) { animator.SetBool("IsBraking", true); Decelerate(brakeSpeed); } else { animator.SetBool("IsBraking", false); if (move.magnitude > 0) { if (Vector3.Dot(moveVector.normalized, playerPhysics.horizontalVelocity.normalized) >= (groundInfo.ground ? -softBrakeThreshold : 0)) { Accelerate(acceleration); } else { Decelerate(brakeSpeed); } } else { Decelerate(deceleration); } } // Acceleration function void Accelerate(float speed) { float maxRadDelta = Mathf.Lerp(minTurnSpeed, maxTurnSpeed, playerPhysics.speed / maxSpeed) * Mathf.PI * Time.deltaTime; float maxDistDelta = speed * Time.deltaTime; Vector3 velocity = Vector3.RotateTowards(playerPhysics.horizontalVelocity, moveVector * maxSpeed, maxRadDelta, maxDistDelta); velocity -= velocity * (Vector3.Angle(playerPhysics.horizontalVelocity, velocity) / 180 * turnDeceleration); float dot = Vector3.Dot(velocity.normalized, Vector3.up); float slopeFactor = dot > 0 ? -uphillDeceleration : -downhillAcceleration; velocity += velocity.normalized * dot * slopeFactor; RB.velocity = velocity + playerPhysics.verticalVelocity; } // Deceleration function void Decelerate(float speed) { RB.velocity = Vector3.MoveTowards(playerPhysics.horizontalVelocity, Vector3.zero, speed * Time.deltaTime) + playerPhysics.verticalVelocity; } } // Get Move Vector function Vector3 GetMoveVector(Transform relativeTo, Vector3 upNormal, Vector2 move) { Vector3 rightNormal = Vector3.Cross(upNormal, relativeTo.forward); Vector3 forwardNormal = Vector3.Cross(relativeTo.right, upNormal); Vector3.OrthoNormalize(ref upNormal, ref forwardNormal, ref rightNormal); Debug.DrawRay(RB.transform.position, rightNormal * 10, Color.red); Debug.DrawRay(RB.transform.position, forwardNormal * 10, Color.green); return (rightNormal * move.x) + (forwardNormal * move.y); } }
Leave a Comment