Untitled
unknown
csharp
a year ago
7.6 kB
13
Indexable
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);
}
}
Editor is loading...
Leave a Comment