make rigidbody jump and maintain velocity
I know people have previously asked this but i just cant find an answer that works for me. I want my character to be able to be moving and have a smooth up and down jump how would i script this??
Answer by oStaiko · Oct 26, 2016 at 02:05 AM
Is this a 2d platformer kind of sense or a 3d platformer? Either way it's kind of the same. Just have gravity turned on and it'll do the work for you.
Transform trans;
float jumpVelocity;
void Jump ()
{
trans.velocity += new Vector3(0.0f, jumpVelocity, 0.0f);
}
Now, if you have gravity turned off... you're gonna have a harder time. We'll have to apply a downwards acceleration, however depending on what type of game you are making, that'll vary a lot in how we do it. If my above example doesn't work for you, just tell me why, and a bit mopre information on the layout of the game (2d/3d, physics/no physics, planar movements/platformer, etc)
using UnityEngine;
[RequireComponent(typeof(Player$$anonymous$$otor))]
public class PlayerController : $$anonymous$$onoBehaviour {
[SerializeField]
private float speed = 5f;
[SerializeField]
private float lookSensitivity = 3f;
private Player$$anonymous$$otor motor;
void Start ()
{
motor = GetComponent<Player$$anonymous$$otor>();
}
void Update ()
{
//calculate movement velocity as 3d vector
float x$$anonymous$$ov = Input.GetAxisRaw("Horizontal");
float z$$anonymous$$ov = Input.GetAxisRaw ("Vertical");
Vector3 moveHorizontal = transform.right * x$$anonymous$$ov;
Vector3 moveVertical = transform.forward * z$$anonymous$$ov;
Vector3 _velocity = (moveHorizontal + moveVertical).normalized * speed;
motor.$$anonymous$$ove(_velocity);
float rotY = Input.GetAxisRaw ("$$anonymous$$ouse X");
Vector3 _rotation = new Vector3 (0f, rotY, 0f) * lookSensitivity;
motor.Rotate (_rotation);
float rotX = Input.GetAxisRaw ("$$anonymous$$ouse Y");
Vector3 _cameraRotation = new Vector3 (rotX, 0f, 0f) * lookSensitivity;
motor.RotateCamera (_cameraRotation);
}
}
//this is my player controller
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class Player$$anonymous$$otor : $$anonymous$$onoBehaviour {
[SerializeField]
private Camera cam;
private Vector3 velocity = Vector3.zero;
private Vector3 rotation = Vector3.zero;
private Vector3 cameraRotation = Vector3.zero;
//private Vector3 thrusterforce = Vector3.zero;
private Rigidbody rb;
void Start ()
{
rb = GetComponent<Rigidbody>();
}
public void $$anonymous$$ove (Vector3 _velocity)
{
velocity = _velocity;
}
public void Rotate (Vector3 _rotation)
{
rotation = _rotation;
}
public void RotateCamera (Vector3 _cameraRotation)
{
cameraRotation = _cameraRotation;
}
//public void ApplyThruster (Vector3 _thrusterforce)
//{
// thrusterforce = _thrusterforce;
//}
void FixedUpdate ()
{
Perform$$anonymous$$ovement();
PerformRotation ();
}
void Perform$$anonymous$$ovement()
{
if (velocity != Vector3.zero) {
rb.$$anonymous$$ovePosition (rb.position + velocity * Time.fixedDeltaTime);
}
//if (thrusterforce != Vector3.zero) {
//rb.AddForce (thrusterforce * Time.fixedDeltaTime, Force$$anonymous$$ode.Acceleration);
//}
}
void PerformRotation ()
{
rb.$$anonymous$$oveRotation (rb.rotation * Quaternion.Euler (rotation));
if (cam != null) {
cam.transform.Rotate (-cameraRotation);
}
}
}
//this is my player motor
//where would i add the code?
Alright, I'm going to assume this is a 3d game, and currently you're moving your character by arrow keys to change the relative velocities to walk forwards/left/right and all that, and then using the mouse to look around. If those assumptions are right, here's what you'll want to do. In Update(), add something like this:
if (Input.GetAxisRaw("NameOfAxis" > 0 && isGrounded)
{
Jump();
}
This tests for two things, if the player is pressing a jump key which you'll set later, and if the player is grounded. Now, testing if a player is grounded will work by adding in two nbew collision functions, which require your player to have a collision box if they don't already. These go on PlayerController:
void OnCollisionEnter(myCollision : Collision){
if (myCollision.gameObject.name == "ground")
{
isGrounded = true;
}
}
void OnCollisionExit(myCollision : Collision){
if (myCollision.gameObject.name == "ground")
{
isGrounded = false;
}
}
Now this works by replacing the "ground" with the name of your floor, or you can just tag all of your floors and replace the name with the tag ins$$anonymous$$d, really that part depends on how your current floor system works. When you stop touching the floor, isGrounded is set to false, and prevents additional jumping. Next we write our Jump() function in Player$$anonymous$$otor:
float jumpForce;
public void Jump()
{
rb.AddForce(transform.up * jumpForce);
}
You will probably need a large force, since the time it'll be applied over will be very small. $$anonymous$$aybe throw a deltatime in there too, just test it and see how it goes ya know? That should all work, but I didn't test it myself, so if it doesn't we'll take it from there.
Your answer
Follow this Question
Related Questions
How i make a ball jump where i point with my mouse?[3D] 0 Answers
How can I make Jumps smooth? 0 Answers
Jumping to platform of different depth in 3D game 0 Answers
Double jump. Jumping after falling off a platform 1 Answer
Rigidbody Stop and jump 0 Answers