I’ll start off by saying I’m very new to Unity and C# and I’m attempting my first project after following a series of youtube tutorials. I manually made physics for my player (for acceleration, airborne velocity and drag, gravity, etc), but when I jump moving forward (or any other direction for that matter), when I rotate my character (through my mouse movement) my airborne movement changes relative to my rotation rather than remaining constant (I guess since it’s moving in local space?). I’d like it so my airborne velocity gets influenced by my grounded velocity (that which is influenced by WASD), but doesn’t move relative to my rotation, and i keep my movement direction no matter where I look.
I’ve been pouring overt my code for a while but I can’t figure it out.
My player is called PlayerColliderParent, it has a Character Controller attached to it, along with my script PlayerColliderParentScript.cs (which handles all physics and movement for the player)
Any help is appreciated as I really want to fix this.
Here is a video of the problem occuring:
And here is PlayerColliderParentScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerColliderParentScript : MonoBehaviour
{
public Transform cameraRotation;
public Vector3 directionalInput;
public float accelerationAmount = 0.5f;
public float maxSpeed = 6f;
public float maxMoveSpeed =6f;
public Vector3 directionalSpeed;
public Vector3 airDirectionalSpeed;
public float terminalVelocity = 30f;
public float gravityStrength = 1f;
public float currentYvel;
public float airDrag;
public float maxAirSpeed;
public float jumpStrength = 1f;
Vector3 gravityController;
//Rigidbody playerBody = new Rigidbody();
CharacterController controller = new CharacterController();
//Rigidbody playerBody = new Rigidbody();
// Start is called before the first frame update
void Start()
{
//playerBody = GetComponent<Rigidbody>();
controller = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
//set acceleration factor
float accelerationFactor = (accelerationAmount * 200) * Time.deltaTime;
//rotate horizontally with camera
transform.localEulerAngles = new Vector3(0, cameraRotation.localEulerAngles.y, 0);
//JUMP or press against ground (.isGrounded doesn't work otherwise)
if (controller.isGrounded == true)
{
if (Input.GetKey(KeyCode.Space))
{
currentYvel = jumpStrength;
}
else
{
currentYvel = -2f /** Time.deltaTime * 500*/;
}
}
//accelerate while movement key is held
//z axis
if (Input.GetKey(KeyCode.W))
{
directionalInput.z = 1;
if (directionalSpeed.z < maxSpeed)
{
directionalSpeed.z += accelerationFactor;
}
}
else if (Input.GetKey(KeyCode.S))
{
directionalInput.z = -1;
if (directionalSpeed.z < maxSpeed)
{
directionalSpeed.z += accelerationFactor;
}
}
else if (directionalSpeed.z > 0)
{
if (controller.isGrounded == true)
{
directionalInput.z = 0;
directionalSpeed.z -= accelerationFactor;
}
else
{
directionalSpeed.z -= airDrag * Time.deltaTime * 100;
}
}
else if (directionalSpeed.z < 0)
{
if (controller.isGrounded == true)
{
directionalInput.z = 0;
directionalSpeed.z += accelerationFactor;
}
else
{
directionalSpeed.z += airDrag * Time.deltaTime * 100;
}
}
else
{
directionalInput.z = 0;
}
//x axis
if (Input.GetKey(KeyCode.D))
{
directionalInput.x = 1;
if (directionalSpeed.x < maxSpeed)
{
directionalSpeed.x += accelerationFactor;
}
}
else if (Input.GetKey(KeyCode.A))
{
directionalInput.x = -1;
if (directionalSpeed.x < maxSpeed)
{
directionalSpeed.x += accelerationFactor;
}
}
else if (directionalSpeed.x > 0)
{
if (controller.isGrounded == true)
{
directionalInput.x = 0;
directionalSpeed.x -= accelerationFactor;
}
else
{
directionalSpeed.x -= airDrag * Time.deltaTime * 100;
}
}
else if (directionalSpeed.x < 0)
{
if (controller.isGrounded == true)
{
directionalInput.x = 0;
directionalSpeed.x += accelerationFactor;
}
else
{
directionalSpeed.x += airDrag * Time.deltaTime * 100;
}
}
else
{
directionalInput.x = 0;
}
//accelerate downwards if not grounded
if (controller.isGrounded == false)
{
if (currentYvel > -terminalVelocity)
{
currentYvel -= gravityStrength * Time.deltaTime;
}
}
//Reset gravity vecctor
gravityController = Vector3.zero;
//calculate movement velocity
Vector3 direction = directionalInput.normalized;
float velocityX = direction.x * Mathf.Round(directionalSpeed.x);
float velocityY = (currentYvel / 2) * Time.deltaTime;
float velocityZ = direction.z * Mathf.Round(directionalSpeed.z);
Vector3 velocity = new Vector3(velocityX * Time.deltaTime, velocityY, velocityZ * Time.deltaTime);
//check for sprint key
if (Input.GetKey(KeyCode.LeftShift))
{
velocity *= 1.5f;
}
//move player according to velocity
controller.Move(transform.TransformDirection(velocity));
//set airspeed the same as character velocity
airDirectionalSpeed.x = velocityX * Time.deltaTime;
airDirectionalSpeed.y = 0;
airDirectionalSpeed.z = velocityZ * Time.deltaTime;
if (airDirectionalSpeed.x > 0)
{
airDirectionalSpeed.x -= airDrag * Time.deltaTime * 100;
}
if (airDirectionalSpeed.z > 0)
{
airDirectionalSpeed.z -= airDrag * Time.deltaTime * 100;
}
airDirectionalSpeed = transform.TransformDirection(airDirectionalSpeed);
Vector3 airVelocity = new Vector3(airDirectionalSpeed.x, 0, airDirectionalSpeed.z);
Vector3 airMoveAmountX = new Vector3((airVelocity.x / 3), 0, 0);
Vector3 airMoveAmountZ = new Vector3(0, 0, (airVelocity.z / 3));
//move player according to airspeed
if (controller.isGrounded == false)
{
if (airDirectionalSpeed.x < maxAirSpeed | airDirectionalSpeed.x > -maxAirSpeed)
{
controller.Move(airMoveAmountX);
}
if (airDirectionalSpeed.z < maxAirSpeed | airDirectionalSpeed.z > -maxAirSpeed)
{
controller.Move(airMoveAmountZ);
}
}
}
}