the only problem that i face that the player only jump when they build momentum and i dont want that i want player jump by pressing space while standing or moving i tried velocity.y=jumphight which doesnt work too
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovment : MonoBehaviour
{
public CharacterController controller;
public float speed = 12f;
public float gravity = -9.81f;
Vector3 velocity;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
bool isGrounded;
public float JumpHight = 3f;
void Update()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if(isGrounded && velocity.y<0)
{
controller.slopeLimit = 45.0f;
velocity.y = -2f;//when player is grounded it just put some gravity to him all the time
}
float x = Input.GetAxis("Horizontal");//moves left and right
float z = Input.GetAxis("Vertical");//moves up and down
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move*speed*Time.deltaTime);
if(Input.GetButtonDown("Jump") && controller.isGrounded)
{
velocity.y = Mathf.Sqrt(JumpHight * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
}
you could use an addforce on the rigidbody with a ForceMode force , and if you don't want your physic depending on the fps use FixedUpdate instead of update
GetComponent<Rigidbody>().AddForce(Vector3.up,ForceMode.Force);
Vector3 velocity;
public float gravity = -9.82f;
public float JumpHeight = 3f;
if(Input.GetButtonDown("Jump")
{
velocity.y = Matf.Sqrt(JumpHeight * -2f * gravity);
}
You could also do what the other person said, the reason this person's line of code might not have worked it due to how weak it is. Here is an updated version of said code.
GetComponent<Rigidbody>().AddForce(Vector3.up * 10f ,ForceMode.Impulse);
The reason I am using the * is to increase the "up" variable since it means Vector3(0f, 1f, 0f); and using the ForceMode.Impulse to make it more volatile and stronger.
Hope this code helps you in your game making,
Kind Regards. SB
Related
When I try to run this code on unity,everything works expect the jumping.Anyone know why?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;
public float speed = 12f;
public float gravity = -9.81f;
public float jumpHeight;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
Vector3 velocity;
bool isGrounded;
// Update is called once per frame
void Update()
{
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if(isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
if(Input.GetButtonDown("Jump") && isGrounded);
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity *Time.deltaTime);
}
}
For jumping in unity you can just add a Vector3 to the object you want to make jump, if it is in movement unity calculate automatic the trajectory of the object.
Your problem is with this line here
velocity.y += gravity * Time.deltaTime;
Don't try add gravity yourself, unity will be handing this for you if you have a character controller
As suggested in the comment, First make the isGrounded a little more stable.
Use the character's RigidBody and AddForce(Vector3 force, ForceMode mode = ForceMode.Force); to implement jumps, as a Jump is an impulsive force applied on the character in the up direction. Directly using Move is not the best way of implementing a jump force.
Documentation for RigidBody.AddForce
using System.Collections;
using System.Collections.Generic; // <-- Since these are not utilized and not necessary for this code, defined by being grey in their Colour.
// Consider Removing them, To stop using unnecessary Data / Library calls in your code
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
/* THINGS TO KNOW */
// Private - only members of this class have access.
// Public -can be accessed outside of the script.
// Public Static - can be accessed in other scripts by using ( nameOfTheScript.VariableFromThatScript ) which are called Pointers.
// Protected - means it's only available in the class itself and any child-class.
// [SerializeField] private - Means that the variable is no longer publicly accessible, but can still be accessed inside the Editor (Inspector) of Unity
// Giving you the chance to drag / drop your character controller and modify values of other variables (while not overwriting your values outside of your other scripts)
// Always define if your variable is Public / Private or Protected, by default they will be Public.
[SerializeField] private CharacterController controller;
[SerializeField] private float speed = 12f;
[SerializeField] private float gravity = -9.81f;
[SerializeField] private float jumpHeight; // !! On Default this Element is going to be 0, if Not Defined Within the Inspector !!!
[SerializeField] private Transform groundCheck;
[SerializeField] private float groundRadius = 0.4f; // groundDistance -> groundRadius ( As it defines the size of the Sphere made from GroundCheck element)
[SerializeField] private LayerMask groundMask;
private Vector3 velocity;
[SerializeField] private bool isGrounded;
void Update() // Called once per frame.
{
// Defines if the character IsGrounded ( True or False )
// 1) Find object groundCheck (dragged in the inspector for the code)
// .position Getting its position where GroundCheck is at the current moment
//,2) Make a Sphere with a radius of ..
// 3) Define what LayerMask is going to be checked.
isGrounded = Physics.CheckSphere(groundCheck.position, groundRadius, groundMask);
if (isGrounded && velocity.y < 0) // !! Issue fixed " if (isGrounded && velocity.y < 0); " You cannot have " ; " - breaker before your method brackets.
{
velocity.y = -2f;
}
/* Move these function into their separate methods.*/
/* Makes it easier to read as well as Debug,
in order to find where the issue in your code is taking place*/
Move();
Jump();
controller.Move(velocity * Time.deltaTime);
}
private void Move()
{
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);
}
private void Jump()
{
// Y Axis
if (Input.GetButtonDown("Jump") && isGrounded)
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime; // Applies gravity with (times) * Last updated frame to next update frame.
}
}
Make sure that you add : LayerMask to your object as well from which you are trying to jump from and check if you can jump. Found on this Picture ->
LayerMask Applied to The Floor Or Ground Object
On Player GameObject, Make sure that you have defined all variable values, as well as other GameObjects : such as " groundCheck " found on this Picture ->
Player Game Object Information In Inspector
Last put not least make sure you have defined JumpHeight in your Inspector of the Player
Though there are a lot of improvements still to make, this is what I would suggest, having provided you with commenting for Each Change or Explanation of a function.
I am trying to make a FPS game but when I press w for a bit and then release it slides a bit further than wanted. I am pretty new to Unity and think it has something to do with the updates.
Code:
public float moveSpeed = 5f;
public float jumpForce = 5f;
public CharacterController controller;
private Vector3 moveDirection;
public float gravityScale;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
float yStore = moveDirection.y;
moveDirection = (transform.forward * Input.GetAxis("Vertical")) + (transform.right * Input.GetAxis("Horizontal"));
moveDirection = moveDirection.normalized * moveSpeed;
moveDirection.y = yStore;
if (controller.isGrounded)
{
moveDirection.y = 0f;
if (Input.GetButtonDown("Jump"))
{
moveDirection.y = jumpForce;
}
}
moveDirection.y = moveDirection.y + (Physics.gravity.y * gravityScale);
controller.Move(moveDirection * Time.deltaTime);
}
add a physics material to your ground and set the dynamic friction to 1. Next, set the static friction from 0.5 to 1. And last but not least, set the bounciness to 0.
Play around with these values a bit until you find something that is satisfactory.
here is the link to the documentation:
https://docs.unity3d.com/Manual/class-PhysicMaterial.html
it basically explains what each property does.
If you dont collide with something you can fly! its really strange, please help me if you can.
i dont know how to fix it cause i am new in it.
Here is a script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player_Movement : MonoBehaviour
{
public float speed = 4.0f;
public float gravity = -9.8f;
private CharacterController _charCont;
// Use this for initialization
void Start()
{
_charCont = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
float deltaX = Input.GetAxis("Horizontal") * speed;
float deltaZ = Input.GetAxis("Vertical") * speed;
Vector3 movement = new Vector3(deltaX, 0, deltaZ);
movement = Vector3.ClampMagnitude(movement, speed); //Limits the max speed of the player
// movement.y = gravity;
movement *= Time.deltaTime; //Ensures the speed the player moves does not change based on frame rate
movement = transform.TransformDirection(movement);
_charCont.Move(movement);
}
}
I don't know that CharacterController but it sounds like it takes the global movement vector.
After
movement = transform.TransformDirection(movement);
you should erase the Y component
movement.y = 0;
This is weird.
I've been learning more in depth about Rigidbody, and I can't for the life of me, make it jump. I'm copying exactly what I see on youtube tutorials, and it works for the youtubers, but not for me.
In more C# english - I was trying to .AddForce(ForceMode.TriedEverything) on the y axis, via user Input. It won't work consistently. sometimes it's higher, sometimes lower, most times nothing at all. this is weird. and I didn't even put isGrounded or any other limitation. Simply "addforce if user input". This is case no 1
Case 2 is much simpler, and NEVER works: it's based on setting the velocity to a new vector with only the y axis manipulated. I'll sharethe code. the “jumpForce” is set to 12, but i've tried 500 too. no difference. This case does have a “grounded” condition, but it didn't work without it as well. Anyway, both print statements get executed.
Both cases were tested in Update and in FixedUpdate, no differences.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMotor : MonoBehaviour
{
public LayerMask layerMask = default;
public bool grounded;
[SerializeField] float moveSpeed = 7f;
[SerializeField] float jumpForce = 12f;
Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
float x = Input.GetAxisRaw("Horizontal") * moveSpeed;
float y = Input.GetAxisRaw("Vertical") * moveSpeed;
Vector3 movePosition = transform.right * x + transform.forward * y;
Vector3 newPosition = new Vector3(movePosition.x, rb.velocity.y, movePosition.z);
grounded = Physics.CheckSphere(new Vector3(transform.position.x, transform.position.y - 1, transform.position.z), 0.4f, layerMask);
if (Input.GetKeyDown(KeyCode.Space)&& grounded)
{
print("reached if statement");
rb.velocity = new Vector3(rb.velocity.x, jumpForce, rb.velocity.z);
print("jumpingjumping");
}
rb.velocity = newPosition;
}
void FixedUpdate()
{
}
}
Thanks folks.
The problem is the order of your code. You are setting the newPosition variable before the jump statement so the y velocity is 0, then you are setting the y velocity to the jump velocity but after that you set the velocity to the newPosition which still has a velocity of 0 because it was set before the jump statement. Here is the working code:
public LayerMask layerMask = default;
public bool grounded;
[SerializeField] float moveSpeed = 7f;
[SerializeField] float jumpForce = 12f;
Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
float x = Input.GetAxisRaw("Horizontal") * moveSpeed;
float y = Input.GetAxisRaw("Vertical") * moveSpeed;
Vector3 movePosition = transform.right * x + transform.forward * y;
grounded = Physics.CheckSphere(new Vector3(transform.position.x, transform.position.y - 1, transform.position.z), 0.4f, layerMask);
if (Input.GetKeyDown(KeyCode.Space) && grounded)
{
print("reached if statement");
rb.velocity = new Vector3(rb.velocity.x, jumpForce, rb.velocity.z);
print("jumpingjumping");
}
Vector3 newPosition = new Vector3(movePosition.x, rb.velocity.y, movePosition.z);
rb.velocity = newPosition;
}
void FixedUpdate()
{
}
Hope this helped you!
Soo, I'm trying to code a simple Platformer as a work for class, and I'm having problems with the jumping, the character actually jumps but it seems as a teleport since it instantly reaches the peak of the jump and then gradually falls, I'd like to make it smoother.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class playerMovement : MonoBehaviour {
public float speed;
public float jumpForce;
public bool grounded;
public Transform groundCheck;
private Rigidbody2D rb2d;
// Use this for initialization
void Start () {
rb2d = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update () {
}
private void FixedUpdate()
{
float moveVertical = 0;
float moveHorizontal = Input.GetAxis("Horizontal") * speed;
moveHorizontal *= Time.deltaTime;
grounded = Physics2D.Linecast(transform.position, groundCheck.position, 1 << LayerMask.NameToLayer("Ground"));
if (grounded && Input.GetKeyDown("space"))
{
moveVertical = Input.GetAxis("Jump") * jumpForce;
moveVertical *= Time.deltaTime;
}
Vector2 move = new Vector2(moveHorizontal, moveVertical);
transform.Translate(move);
}
}
The answer to the question is below, however, for future questions related to Unity ask on the Unity forum. You will get a better answer quicker as more people are focused on Unity itself.
To fix your jump, rather split your vertical and horizontal movement in two parts and use your rigidbody you assigned in in your Start() function to handle jumping. Use ForceMode.Impulse to get an instant burst of speed/acceleration.
private void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal") * speed;
moveHorizontal *= Time.deltaTime;
grounded = Physics2D.Linecast(transform.position, groundCheck.position, 1 << LayerMask.NameToLayer("Ground"));
if (grounded && Input.GetKeyDown("space"))
{
rb2d.AddForce(transform.up * jumpForce, ForceMode.Impulse);
}
Vector2 move = new Vector2(moveHorizontal, 0);
transform.Translate(move);
}
Instead of setting the position when you jump, add a vertical impulse to the character's rigidbody with:
if (grounded && Input.GetKeyDown("space"))
{
moveVertical = Input.GetAxis("Jump") * jumpForce;
moveVertical *= Time.fixedDeltaTime;
rb2d.AddForce(moveVertical, ForceMode.Impulse);
}
Vector2 move = new Vector2(moveHorizontal, 0f);
This will let Rigidbody2D handle the work of altering the vertical velocity on each frame.
Also, since you are doing all of these calculations in FixedUpdate, instead of Update, there is no sense in using Time.deltaTime. You should be using Time.fixedDeltaTime instead.