Advertisement
JoshButner

Henchman - ScooterMoveController.cs

Mar 10th, 2022
13
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.17 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class ScooterMoveController : MonoBehaviour{
  6.  
  7.     [Tooltip("The actual physics object to move")]
  8.     public Rigidbody scooterRB;
  9.     [Tooltip("The component that controls throttle input")]
  10.     public ThrottleController throttle;
  11.     [Tooltip("The global forward direction of this object is the direction we'll move in.")]
  12.     public Transform steeringDir;
  13.     [Tooltip("If true, vertical rotation of the cycle is allowed, the rigidbody x constraint must also be disabled.")]
  14.     public bool doRotateVertical = false;
  15.     [Tooltip("The acceleration applied if the throttle is maxxed forward.")]
  16.     public float maxAcceleration = 5f;
  17.     [Tooltip("The acceleration applied if the throttle is maxxed in reverse.")]
  18.     public float reverseAcceleration = 5f;
  19.     [Tooltip("When true, acceleration is applied as force, when false it's added as velocity.")]
  20.     private bool accelerationIsForce = true;
  21.     [Tooltip("The speed at which the scooter tries to turn.")]
  22.     public float turnSpeed = 30f;
  23.     //[Tooltip("The speed at which the scooter tries to turn when close to a standstill.")]
  24.     //public float standstillTurnSpeed = 30f;
  25.     //[Tooltip("The speed at which the scooter tries to turn when close to full speed.")]
  26.     //public float topSpeedTurnSpeed = 15f;
  27.     [Tooltip("The rate at which the scooter's turning slows as it reaches top turning speed.")]
  28.     public float turnDrag = 10f;
  29.     [Tooltip("The factor by which velocity is moved from side-to-side motion to forward motion when turning (the rest of this velocity is lost).")]
  30.     public float velocityForwardConversionFactor = 0.3f;
  31.     [Tooltip("Non-vertical velocity is capped at this value.")]
  32.     public float maxSpeed = 30f;
  33.     // [Tooltip("How much the cycle leans when you turn, in degrees.")]
  34.     // public float leanFactor = 30f;
  35.  
  36.     void Update(){
  37.         if (doRotateVertical)
  38.             scooterRB.constraints |= RigidbodyConstraints.FreezeRotationX;
  39.     }
  40.  
  41.     void FixedUpdate(){
  42.         // Get the current forward direction of the scooter
  43.         Vector3 trueForwardDir = scooterRB.transform.forward;
  44.         // We don't care about vertical orientation
  45.         trueForwardDir.y = 0f;
  46.         // Calculate the magnitude of the velocity in the forward direction
  47.         Vector3 trueForward = Vector3.Project(scooterRB.velocity, trueForwardDir);
  48.  
  49.         // ### FORCE ###
  50.         // Add the force
  51.         if (accelerationIsForce)
  52.         {
  53.             scooterRB.AddForce(scooterRB.transform.forward * (maxAcceleration * throttle.ThrottleValue - reverseAcceleration * throttle.ReverseThrottleValue), ForceMode.Acceleration);
  54.         }
  55.         else
  56.         {
  57.             scooterRB.velocity = scooterRB.velocity + (scooterRB.transform.forward * (maxAcceleration * throttle.ThrottleValue - reverseAcceleration * throttle.ReverseThrottleValue) * Time.fixedDeltaTime);
  58.         }
  59.         // Debug.Log(scooterRB.transform.forward * maxAcceleration * highestFixedUpdateThrottleValue * Time.fixedDeltaTime);
  60.  
  61.         // This should only be done when we're finished with the highestFixedUpdateThrottleValue for this FixedUpdate cycle
  62.         throttle.ResetThrottle();
  63.  
  64.         // ### FORWARD FORCE CONVERSION ###
  65.         // We don't want to include vertical velocity in velocity calculations
  66.         Vector3 originalVel = scooterRB.velocity;
  67.         Vector3 flatVel = originalVel;
  68.         flatVel.y = 0;
  69.         // Convert sideways velocity into forward velocity at a reduced rate, remove sideways velocity proportionally
  70.         float sidewaysVelocity = flatVel.magnitude - trueForward.magnitude;
  71.         Vector3 convertedFlatVel = trueForward.normalized * (trueForward.magnitude + sidewaysVelocity * velocityForwardConversionFactor * Time.fixedDeltaTime) + flatVel.normalized * (sidewaysVelocity * (1 - velocityForwardConversionFactor * Time.fixedDeltaTime));
  72.         scooterRB.velocity = new Vector3(convertedFlatVel.x, originalVel.y, convertedFlatVel.z);
  73.  
  74.         // ### VELOCITY CAP ###
  75.         // We don't want to include vertical velocity in velocity calculations
  76.         originalVel = scooterRB.velocity;
  77.         flatVel = originalVel;
  78.         flatVel.y = 0;
  79.         // Cap the max speed
  80.         if(flatVel.magnitude > maxSpeed){
  81.             flatVel = flatVel.normalized * maxSpeed;
  82.             scooterRB.velocity = new Vector3(flatVel.x, originalVel.y, flatVel.z);
  83.         }
  84.  
  85.         // ### DIRECTION ###
  86.         Vector3 targetDir = steeringDir.forward;
  87.         if (!doRotateVertical)
  88.         {
  89.             // Throw away vertical orientation if we don't care about vertical rotation
  90.             targetDir.y = 0f;
  91.         }
  92.         // Get the target rotation
  93.         Quaternion targetRot = Quaternion.LookRotation(targetDir);
  94.  
  95.         // We need to know whether we're going forward or backwards, so we check whether the vector is the same or not
  96.         // Due to properties of dot product and projection, this should be 1 if the vectors are in the same direction and -1 otherwise
  97.         float signMult = Vector3.Dot(trueForward.normalized, trueForwardDir.normalized);
  98.         if (!Mathf.Approximately(signMult, 1) && !Mathf.Approximately(signMult, -1) && !Mathf.Approximately(signMult, 0))
  99.         {
  100.             throw new UnityException("We expect signMult to be either 0, 1, or -1, instead it was: " + signMult);
  101.         }
  102.         // The actual velocity is the magnitude times the signMult to determine the direction
  103.         float currentForwardVel = trueForward.magnitude * signMult;
  104.  
  105.         float targetTurnSpeed = turnSpeed; // Mathf.Lerp(standstillTurnSpeed, topSpeedTurnSpeed, Mathf.InverseLerp(0, currentForwardVel, topSpeedTurnSpeed));
  106.         // We want the turn to be more extreme the farther away from the center the handles are turned
  107.         float turnIntensity = Vector3.SignedAngle(trueForwardDir, targetDir, Vector3.up) / 180f;
  108.         float targetTurnAmount = targetTurnSpeed * Time.fixedDeltaTime * currentForwardVel * turnIntensity;
  109.         // The scooter rotates towards the orientation of the handlebars at a rate of the maxTurnSpeed multiplied by the forward speed multiplied by how far from the current forward the handlebars are turned
  110.         // The signMult from currentForwardVel means if we go backwards, the controls are inverted like expected
  111.         //scooterRB.MoveRotation(scooterRB.rotation * Quaternion.AngleAxis(targetTurnAmount, Vector3.up));
  112.  
  113.         float turnRemaining = targetTurnAmount - scooterRB.angularVelocity.y;
  114.         scooterRB.AddRelativeTorque(turnRemaining * Vector3.up, ForceMode.VelocityChange);
  115.  
  116.  
  117.         // This is a workaround to a bug with rigidbody constraints Unity refuses to fix
  118.         // This locks the x and z rotations
  119.         if(scooterRB.transform.rotation.eulerAngles.x != 0 || scooterRB.transform.rotation.eulerAngles.z != 0)
  120.         {
  121.             scooterRB.transform.rotation = Quaternion.AngleAxis(scooterRB.transform.eulerAngles.y, Vector3.up);
  122.         }
  123.  
  124.         // Rotate the cycle around the forward axis to emulate lean
  125.         // scooterRB.transform.localRotation = Quaternion.AngleAxis(-leanFactor * currentForwardVel * turnIntensity, Vector3.forward);
  126.     }
  127. }
  128.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement