C# Unity Character jumps really weird - c#

Hello guys!
I have a problem with my UNITY 5 code.
My character can jump but he jumps instantly and too fast.
It looks really weird.
I would greatly appreciate your feedback on my code!
using UnityEngine;
using System.Collections;
public class Gravity : MonoBehaviour {
private float inputDirection;
private float VerticalSpeed;
private float gravity = -2f;
private float speedmultiplier = 5f;
private bool jump;
private Vector3 moveVector;
private CharacterController controller;
// Use this for initialization
void Start () {
controller = GetComponent<CharacterController> ();
}
// Update is called once per frame
void Update () {
inputDirection = Input.GetAxis ("Horizontal");
moveVector = new Vector3 (inputDirection, VerticalSpeed, 0) * speedmultiplier;
controller.Move (moveVector * Time.deltaTime);
if (controller.isGrounded) {
VerticalSpeed = 0.0f;
jump = true;
} else {
VerticalSpeed = gravity;
jump = false;
}
if (Input.GetKey(KeyCode.X)) {
if(jump == true) {
VerticalSpeed += 25f;
}
}
}
}

You can try changing the vertical speed in your else to reflect a change over time.
Perhaps something like:
VerticalSpeed += gravity * Time.deltaTime
Instead of just setting it to gravity. You may need to play with your initial jump speed to get it to feel better, but this should start your jump fast-ish, slow down as you reach the top of the jump, and speed back up as you fall.

Related

How to prevent speeding of rigidbodies used to control characters

I have a player in unity with the movement controlled by a rigidbody. The movement on the Z axis is kept contstant by the game to keep the player moving forward. However, this means that the rigidbody keeps speeding up so its speed at the start of the game is much slower than the speed at the end of the game. Here is my script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
public class Controller : MonoBehaviour
{
[Tooltip("Rigidbody component attached to the player")]
public Rigidbody rb;
public float forwardMax;
public float slowBy;
private float movementX;
private float movementY;
private float gravity = -9.81f;
private bool isJumping = false;
private bool isSlowing = false;
private bool isSpeeding = false;
private float speedX = 100;
private float speedY = 150000;
private float speedZ = 60;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
// if(!controller.isGrounded)
// {
// Vector3 gravityVector = new Vector3(0.0f, gravity, 0.0f);
// rb.AddForce(gravityVector * Time.deltaTime);
// }
}
void OnCollisionEnter(Collision collision)
{
// SceneManager.LoadScene(1);
}
// Update is called once per frame
void OnMove(InputValue movementValue)
{
Vector2 movementVector = movementValue.Get<Vector2>();
movementX = movementVector.x;
movementY = movementVector.y;
}
void OnJump()
{
isJumping = true;
}
void CalculateMovement()
{
if(rb.velocity.z > 20)
{
rb.drag = 20;
}
else
{
rb.drag = 0;
}
Vector3 movement = new Vector3(movementX * speedX, 0.0f, speedZ);
if(isJumping)
{
movement.y += Mathf.Sqrt(speedY * -3.0f * gravity);
isJumping = false;
}
rb.AddForce(movement);
Debug.Log("Speed is " + rb.velocity.z);
}
void FixedUpdate()
{
CalculateMovement();
}
}
Is there a way to keep the forward velocity constant? The problem is worse when the player jumps.
First I tried clamping the forward (z-axis) vector but that had no effect. Then, I tried adding a backward vector onto the total when the forward velocity was above a certain number but this led to it speeding up and slowing down all the time. Then I tried the same thing with the drag on the rigidbody but that had the same effect.
You can use rigidbody.velocity and set it to constant value or whatever you want instead of adding force. By adding force, your character's speed increases.
Also you can use AddForce but you have to tune the force value dynamically according to the current velocity.
rigidbody velocity
How about directly setting the z value you want at the end of FixedUpdate() ?
......
void FixedUpdate()
{
CalculateMovementWithoutZMovement();
rb.velocity = new Vector3 (rb.velocity.x, rb.velocity.y, ConstantZValue);
}

Unity 2D Character Vibrates When Touching Wall

Like the title says when i walk into a wall i start to vibrate. It doesn't affect gameplay just graphics i believe. The game is a 2D platformer using rigidbody 2D. I am new to game dev so what you fixed could you please tell me how you fix it. Thank you.
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float MovementSpeed = 1;
public float JumpForce = 1;
private Rigidbody2D _rigidbody;
private float coyoteTime = 0.2f;
private float coyoteTimeCounter;
private float jumpBufferTime = 0.05f;
private float jumpBufferCounter;
[SerializeField] private Rigidbody2D rigidbody2D;
[SerializeField] private Transform groundCheck;
[SerializeField] private LayerMask groundLayer;
private bool isGrounded()
{
return Physics2D.OverlapCircle(groundCheck.position, 0.2f, groundLayer);
}
private void Start()
{
_rigidbody = GetComponent<Rigidbody2D>();
}
private void Update()
{
if (isGrounded())
{
coyoteTimeCounter = coyoteTime;
}
else
{
coyoteTimeCounter -= Time.deltaTime;
}
if (Input.GetButtonDown("Jump"))
{
jumpBufferCounter = jumpBufferTime;
}
else
{
jumpBufferCounter -= Time.deltaTime;
}
var movement = Input.GetAxis("Horizontal");
transform.position += new Vector3(movement, 0, 0) * Time.deltaTime * MovementSpeed;
if (coyoteTimeCounter > 0f && jumpBufferCounter > 0f)
{
_rigidbody.velocity = new Vector2(_rigidbody.velocity.x, JumpForce);
jumpBufferCounter = 0f;
}
if (Input.GetButtonUp("Jump") && _rigidbody.velocity.y > 0f)
{
_rigidbody.velocity = new Vector2(_rigidbody.velocity.x, _rigidbody.velocity.y * 0.5f);
coyoteTimeCounter = 0f;
}
}
}
Sorry if the code is sort of sloppy. I am using multiple tutorials to make the movement perfect for me.
Ah! I have had this problem before.
The reason the vibration is happening, is because you are adding a force manually through rigidbody.velocity. The better (And more efficient) way to do it is through rigidbody.AddForce(). This should allow for the rigidbody to calculate physics much smoother.
The only issue that may arise is if you plan for the player to have a constant speed. If you AddForce(1000) with no other arguments, the character will start accelerating, instead of moving at a constant speed.
If you need the player to move at a constant speed, you can append a ForceMode to! I am not sure what one you would use, but that my idea. One example would be rigidbody.AddForce(1000, ForceMode.VelocityChange),

Diagonal movements are faster than normal movements

FIRST : SORRY FOR MY ENGLISH !!!
Hello everyone, i'm very new into Unity (5 days).
Today i've make a script for the basics movements with a rigid-bodie, BUT the diagonal movements are faster than the normal movements.. I search on Internet but I don't find a post that i can understand.
So here my script.
Also if you know how to not move when we jump, or when we jump into a direction, it follow this direction, tell me. (I know my english is terrible.) Also, i'm new into this website.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovements : MonoBehaviour
{
[SerializeField] private float walkingSpeed;
[SerializeField] private float runningSpeed;
[SerializeField] private float jumpForce;
[SerializeField] private float jumpRaycastDistance;
private Rigidbody rb;
float speed;
Vector3 movement;
/////////////////////////////////////////////////////
void Start()
{
rb = GetComponent<Rigidbody>();
}
/////////////////////////////////////////////////////
void Update()
{
Jumping();
}
/////////////////////////////////////////////////////
private void FixedUpdate()
{
Movements();
}
/////////////////////////////////////////////////////
private void Movements()
{
float hAxis = Input.GetAxisRaw("Horizontal");
float vAxis = Input.GetAxisRaw("Vertical");
if(Input.GetButton("Run"))
{
Vector3 movement = new Vector3(hAxis, 0, vAxis) * runningSpeed * Time.deltaTime;
Vector3 newPosition = rb.position + rb.transform.TransformDirection(movement);
rb.MovePosition(newPosition);
}
else
{
Vector3 movement = new Vector3(hAxis, 0, vAxis) * walkingSpeed * Time.deltaTime;
Vector3 newPosition = rb.position + rb.transform.TransformDirection(movement);
rb.MovePosition(newPosition);
}
}
/////////////////////////////////////////////////////
private void Jumping()
{
if(Input.GetButtonDown("Jump"))
{
if (isGrounded())
{
rb.AddForce(0, jumpForce, 0, ForceMode.Impulse);
}
}
}
/////////////////////////////////////////////////////
private bool isGrounded()
{
return Physics.Raycast(transform.position, Vector3.down, jumpRaycastDistance);
}
}
You need to clamp your velocity in order to keep it same. Look into Vector3.ClampMagnitude()
velocity = Vector3.ClampMagnitude(velocity, _movementSpeed);
velocity.y = playerVelocity.Y; // keeping your Y velocity same since you have jumping.
playerVelocity = velocity;
EDIT: in your case it should be something like this.
_maxSpeed is the speed limit.
private void FixedUpdate()
{
Movements();
var clampedVelocity = Vector3.ClampMagnitude(rb.velocity, _maxSpeed);
clampedVelocity.y = rb.velocity.y;
rb.velocity = clampedVelocity;
}
Try normalizing the vector. (more info is on unity docs, but normalize() will make sure that the sum of all the vector's values isnt above 1.

Delay before jump

I'm learning Unity, and I'm doing a character move, but the animation of the jump has a delay for the character to literally jump, a 0.30s until it picks up, how do I add this delay in the code?
Like, I thought of doing somehow that when you hit "Space" release the animation, count 0.20s and make the jump. it's viable? How can I do this?
In short, the character jumps before the animation.
Animation Video:
https://imgur.com/a/LgzkSKi
public class PlayerController : MonoBehaviour {
public float moveSpeed;
public float jumpForce;
public CharacterController controller;
private Vector3 moveDirection;
public float gravityScale;
public Animator animator;
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;
jump();
controller.Move(moveDirection * Time.deltaTime);
animator.SetFloat("Speed", (Mathf.Abs(Input.GetAxis("Vertical"))));
}
void jump() {
if (controller.isGrounded) {
moveDirection.y = 0f;
if (Input.GetButtonDown("Jump")) {
moveDirection.y = jumpForce;
Debug.Log("jump");
}
}
moveDirection.y = moveDirection.y + (Physics.gravity.y * gravityScale * Time.deltaTime);
animator.SetBool("isGrounded", controller.isGrounded);
}
}
In your jump() function don't apply the jump force. Instead, set the next time the character is supposed to jump.
float nextJumpTime;
bool todoJump;
void jump() {
if (!todoJump && Input.GetButtonDown("Jump")) {
// Remember we have to jump and when
nextJumpTime = Time.time + 0.2f;
todoJump = true;
}
// Execute the jump
if (todoJump && Time.time >= nextJumpTime) {
todoJump = false;
moveDirection.y = jumpForce;
}
}
Either that or read on coroutines. Start a coroutine on input, yield return new WaitForSecond(0.2f); in the coroutine and then execute the jump.
To what One Man Mokey Squad suggest I think you should also consider to get a new jump animation or trim the current animation.
I think it's not a great idea to create a custom code for that broken jump animation because you will not be able to reuse your script.

Unity jumping fails while going against a wall

Okay im trying to make my object (player) to jump everything is okay until i go against a wall and keep going against (still W is down) i cant jump wen im hitting a wall if i stop walking he will be enable to jump i tried making the walls on touch to make the player to have velocity = zero but it does not work,
i tried to add rigid body to the walls and freezing them in place, trying to make them kinematic does not work too .
I wish wen i go against walls and keep walking against them to be enable to jump.
If you know how i can do that please share thanks .
Here is the move script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveScript : MonoBehaviour {
private float speed;
private float jumpHight;
private float straffeSpeed;
private float fallMultiplier;
private Rigidbody rig;
private Collider coll;
// Use this for initialization
private void Awake()
{
rig = GetComponent<Rigidbody>();
coll = GetComponent<Collider>();
straffeSpeed = 1.5f;
fallMultiplier = 2.5f;
speed = 10f;
jumpHight = 4f;
}
void Start () {
GroundCheck();
}
// Update is called once per frame
void Update () {
Move();
GroundCheck();
BetterFall();
}
private void Move()
{
float hAxis = Input.GetAxis("Horizontal") * straffeSpeed;
float vAxis = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(hAxis, 0, vAxis) * speed * Time.deltaTime;
rig.MovePosition(transform.position + movement);
if (Input.GetKey(KeyCode.Space) && GroundCheck())
{
rig.velocity = Vector3.up * jumpHight;
}
}
private bool GroundCheck()
{
return Physics.Raycast(transform.position, -Vector3.up, coll.bounds.extents.y + 0.2f);
}
private void BetterFall()
{
if(rig.velocity.y < 0)
{
rig.velocity += Vector3.up * Physics.gravity.y * (fallMultiplier - 1) * Time.deltaTime;
}
}
if (Input.GetKeyDown(KeyCode.Space) && GroundCheck())
{
rig.velocity = Vector3.up * jumpHight;
}
I don't think you are doing this quite right. Try this:
if (Input.GetKeyDown(KeyCode.Space) && GroundCheck())
{
rig.AddForce(Vector3.up * jumpHight, ForceMode.Impulse);
}
:-)

Categories