I have a script to jump, but it jumps depending on the value of the JumpFactor constant. I would like the jump to happen using the JumpToPositionX (float target) method. I think I need to somehow calculate the JumpFactor depending on the value of the target in the JumpToPositionX method. I found an article on Wikipedia, but I don't even know where to start. I have not found examples of how to do this with the CharacterController.
public class ExampleClass : MonoBehaviour
{
const float Speed = 6f;
const float JumpFactor = 14f;
const float Gravity = 20f;
private Vector3 moveDirection = Vector3.zero;
CharacterController controller;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
if (controller.isGrounded)
{
moveDirection = new Vector3(1f, 0f, 0f); // Move X Direction
moveDirection *= Speed;
if (Input.GetButton("Jump"))
moveDirection.y = JumpFactor;
}
moveDirection.y -= Gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
}
// Method for jump, calling from other script.
void JumpToPositionX(float target)
{
}
}
Theory
I assume you want to use the ballistic physic.
Let's see what formula we can use
Where :
is known it's (0f,-9.81f)
or (0f, Gravity)
in your case.
is known too, it's your initial position before the jump.
is the end target position.
Resolution
You have to find the end time and the initial Velocity . So here's the position equation:
We can simplify the process by looking only for the x axis because there's no acceleration.
is simplified to :
Let's isolate the from the x position formula :
Now you have the total time of the jump . You just need to find the initial y velocity by using the y position formula :
Isolate the Vyo :
So now you have all informations for computing the jump : Initial and end position, Total time, Initial velocity and acceleration.
Implementation
Here's an example of the MonoBehaviour you can create :
public class JumpBehaviour : MonoBehaviour
{
public CharacterController CharacterController;
public Transform TargetPosition;
private bool jumpStarted = false;
private float totalTime = 0f;
private float t = 0f;
private Vector2 V0;
private Vector2 initialPosition;
private bool jumpKeyDown;
private const float xSpeed = 6f;
private const float gravity = -9.81f;
void Update()
{
jumpKeyDown = Input.GetKeyDown(KeyCode.Space);
}
void FixedUpdate()
{
if (jumpStarted)
{
UpdateJumpPosition(Time.fixedDeltaTime);
}
else if (jumpKeyDown )
{
StartJump();
}
}
private void UpdateJumpPosition(float deltaTime)
{
t += deltaTime;
if(t > totalTime)
{
//End of jump
transform.position = TargetPosition.position;
jumpStarted = false;
return;
}
Vector2 newPosition = new Vector2(0f, gravity) * t * t + V0 * t + initialPosition;
CharacterController.Move(newPosition);
}
private void StartJump()
{
jumpStarted = true;
initialPosition = transform.position;
// Absolute because xSpeed could be positive or negative. We dont want negative time
float delta = TargetPosition.position.x - transform.position.x;
totalTime = Mathf.Abs(delta / xSpeed);
t = 0f;
float yInitialSpeed = (TargetPosition.position.y - transform.position.y - gravity * totalTime * totalTime) / totalTime;
// Using Sign to set the direction of horizontal movement
V0 = new Vector2(xSpeed * Mathf.Sign(delta), yInitialSpeed);
}
}
And this is the result
Conclusion
This is just an quick example to figure out how to compute the initial value of the jump and movement in 2D.
As derHugo said on comment you should not use transform.position
direct attribution with Physic.
For 3D it's the same idea but you should compute the speed x,z from target direction and speed magnitude.
Vector3 delta = TargetPosition - transform.position;
delta.y = 0f;
float direction = delta.normalized;
Vector3 initialSpeed = direction * movementSpeed;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With