In my prototype, the player can run jump at/over buildings in 3D space. However, if the player jumps close to the building’s edge, rather than just sliding off to the side, they continue to travel at the same velocity. This is not what I want, they should just slide off the side.
Here’s what I mean (top view):
What is happening
What I want to happen
Any solutions?
Code(C#):
public class PlayerMovement : MonoBehaviour
{
public float sensitivityX = 15F;
public float forwardSpeed = 12.5f;
public float sprintSpeed = 25f;
public float strafeSpeed = 8f;
public float backwardSpeed = 8f;
[Range(0, 1)]
public float gravity = 1f;
public float maxFallSpeed = 100f;
public float jumpHeight = 10f;
public float maxChargeTime = 1f;
public bool disableInput;
Vector3 velocityVector;
CharacterController controller;
float v;
float h;
float fSpeed;
float hSpeed;
float vSpeed;
bool jump;
float jumpTimer;
bool jumping;
void Awake()
{
// Make the rigid body not change rotation
if (GetComponent<Rigidbody>())
GetComponent<Rigidbody>().freezeRotation = true;
velocityVector = Vector3.zero;
controller = GetComponent<CharacterController>();
v = 0;
h = 0;
fSpeed = 0;
hSpeed = 0;
vSpeed = 0;
jumpTimer = 0;
hang = false;
jumping = false;
disableInput = false;
}
void Update()
{
transform.Rotate(0, Input.GetAxis("Mouse X") * sensitivityX, 0);
if (jumping && controller.isGrounded) //right when we hit the ground
{
jumping = false;
}
}
void FixedUpdate()
{
GetInput();
if (!controller.isGrounded)
{
vSpeed -= gravity * Time.deltaTime;
}
else
{
fSpeed = 0;
hSpeed = 0;
vSpeed = 0;
if (v > 0)
fSpeed = v * forwardSpeed * Time.deltaTime;
else if (v < 0)
fSpeed = v * backwardSpeed * Time.deltaTime;
if (h != 0)
hSpeed = h * strafeSpeed * Time.deltaTime;
if (jumpTimer > 0f && jump) //ground jump
{
if (jumpTimer <= 0.125f)
{
vSpeed = jumpHeight * Time.deltaTime;
}
else if (jumpTimer > 0.125f)
{
if (jumpTimer > maxChargeTime)
jumpTimer = maxChargeTime;
vSpeed = (jumpHeight + (jumpHeight * jumpTimer)) * Time.deltaTime;
}
}
}
if (vSpeed <= -maxFallSpeed)
vSpeed = maxFallSpeed;
Vector3 vector = new Vector3(hSpeed, vSpeed, fSpeed); //movement vector
vector = transform.TransformDirection(vector); //convert to world coordinates
velocityVector = vector;
controller.Move(velocityVector);
if (jump && !controller.isGrounded) //if off the ground and jumped, reset jump timer
ResetJumpTimer();
}
void GetInput()
{
if (!disableInput)
{
v = Input.GetAxis("Vertical");
h = Input.GetAxis("Horizontal");
//jump charge
if (Input.GetButton("Jump"))
{
jumpTimer += Time.deltaTime;
}
//jump release
if (Input.GetButtonUp("Jump"))
{
jump = true;
}
}
}
void ResetJumpTimer()
{
jumpTimer = 0;
jump = false;
jumping = true;
}
}