So I made my own character controller using a rigid body and it works pretty much perfectly. One of the main reasons I made it was so the player could change their speed while in mid air as being air born is a common thing in my game. When the player jumps, they gain all the velocity from their own WASD movement and then that is added up with their current WASD movement / 2. Problem is that when I do Vector3 /= Vector3.magnitude to make sure jumping isn’t used to move faster, the direction the player is moving seems to be pulled slightly to the Z or -Z axis and it gets really annoying. This doesn’t happen when they move directly in the X or Z axis as that uses Mathf.Min instead of /= Vector3.magnitude. That leads me to believe that it is /= Vector3.magnitude causing the issue but after hours and hours of trying, I am still unable to fix it and am unsure of why the issue is happening in the first place. The code looks fine.
Here’s the commented jumping function of my script:
IEnumerator Jump (){
EnteredFreeFall = false;
//If they stay in mid air too long, this becomes try and they begin to lose the velocity gained from when the
//first jumped (Pretty much drag)
LeftGround = false;
//Used to make sure the script wont cancel the second it starts because the player is on the ground
WasSprinting = IsSprinting;
//Used to continue stop jumping being used to get free sprinting
StoredMovement = MoveDirection;
//The WASD direction is stored in MoveDirection
//Sets the max speed the player can reach.
if (IsSprinting)
{
StoredMovement *= SprintSpeed*SpeedModifier;
Cap.z = Mathf.Max (Mathf.Abs(StoredMovement.z), SprintSpeed);
Cap.x = Mathf.Max (Mathf.Abs(StoredMovement.x), MovementSpeed);
}
else
{
StoredMovement *= MovementSpeed*SpeedModifier;
Cap.z = Mathf.Max (Mathf.Abs(StoredMovement.z), MovementSpeed);
Cap.x = Mathf.Max (Mathf.Abs(StoredMovement.x), MovementSpeed);
}
//for loop using yield
for(float A = 100.0f; A >= 0; A--)
{
//ChangeStoredMovement lets me edit StoredMovement while keeping a copy of it pretty much
ChangeStoredMovement = StoredMovement;
//Stop the jump function if the player lands, but only if they left the ground first.
if (!Grounded)
{
LeftGround = true;
}
if (Grounded && LeftGround)
{
IsJumping = false;
break;
}
//Drain energy if the player got velocity from sprinting and let go of the sprint button
if (WasSprinting && !IsSprinting)
{
if (EnteredFreeFall)
{
Energy -= ((SprintCost+EnergyRecharge)*A/100);
}
else
{
Energy -= (SprintCost+EnergyRecharge);
}
}
//Apply drag if the player has been in the air too long
if (EnteredFreeFall)
{
ChangeStoredMovement.x *= A/100;
ChangeStoredMovement.z *= A/100;
}
//Gets the current WASD movement with half your base speed and adds it to the velocity you got when you first jumped
FloatDirection = MoveDirection;
FloatDirection *= MovementSpeed*SpeedModifier*0.5f;
FloatDirection += ChangeStoredMovement;
//Caps the velocity to make sure the playe can't go faster in air than they could on the ground.
//This cap is used for if they are moving directly in the X or Z axis.
if (FloatDirection.z >= 0)
{
FloatDirection.z = Mathf.Min (FloatDirection.z, Cap.z);
}
else
{
FloatDirection.z = Mathf.Max (FloatDirection.z, -Cap.z);
}
if (FloatDirection.x >= 0)
{
FloatDirection.x = Mathf.Min (FloatDirection.x, Cap.x);
}
else
{
FloatDirection.x = Mathf.Max (FloatDirection.x, -Cap.x);
}
//Same as above but this is for if they are moving say Vector3 (7,0,7) rather than (1,0,0)
if (FloatDirection.magnitude > Mathf.Max (Cap.z, Cap.x))
{
FloatDirection /= FloatDirection.magnitude;
if (Mathf.Abs(FloatDirection.z) >= Mathf.Abs(FloatDirection.x))
{
FloatDirection.z *= Cap.z;
FloatDirection.x *= Cap.z;
}
else
{
FloatDirection.z *= Cap.x;
FloatDirection.x *= Cap.x;
}
}
//Cancel the jump if you jump directly into a wall
if (Physics.Raycast (VarTransform.position, FloatDirection/FloatDirection.magnitude/2, 0.4f, SlopeLayerMask)||
Physics.Raycast (VarTransform.position, Vector3.up, 1.35f, SlopeLayerMask))
{
IsJumping = false;
break;
}
//Add the upward force from the jump
if (!EnteredFreeFall)
{
FloatDirection.y = JumpHeight*(A/100.0f);
}
//Apply the force and wait for the next fixed update (so the for loop doesn't happen instantly;
rigidbody.AddForce(FloatDirection, ForceMode.Impulse);
yield return new WaitForFixedUpdate();
if (A == 0)
{
//Cancel the jump once you have been in mid air for 4 seconds (200 fixed updates)
if (EnteredFreeFall)
{
IsJumping = false;
break;
}
//After 2 seconds (100 fixed updates), EnteredFreeFall is set true witch slows eases out of the jump
//function via drag
else
{
A = 100.0f;
EnteredFreeFall = true;
}
}
}
}
Anyone know what the problem is, or how to work around it?