Reputation: 3
I am developing an endless runner platformer game for android devices and i have a problem. I am using BoxCast for ground detection and animations are not working correctly. Also sometimes at the first jump it jumps way higher then it should. I think the problem is the way i am stopping animations in GroundCheck function. Looks like it immediately stops animation. But i don't find any other places to stop animations.Can you guys please help with this problem. Also animator is attached to model and it is child of Player gameobject. (if you don't like code please say your opinion i am trying to get better at this)
using UnityEngine;
public class Player : MonoBehaviour
{
[Header("Move Settings")]
[SerializeField] float jumpSpeed = 5f;
[SerializeField] float normalSpeed = .2f;
[SerializeField] float slowSpeed = .01f;
[SerializeField] float slowAnimationSpeed = .02f;
[Header("CastBox Settings")]
public Vector3 boxsize;
public float maxDistance;
public LayerMask layerMask;
//Cached References
private Rigidbody playerRigidBody;
private Animator playerAnimator;
//Properties
private bool canDoubleJump = false;
private Vector3 jumpInput;
private float moveSpeed;
private void Awake()
{
playerRigidBody = GetComponent<Rigidbody>();
playerAnimator = GetComponentInChildren<Animator>();
}
private void Start()
{
moveSpeed = normalSpeed;
jumpInput = Vector3.up * jumpSpeed;
}
private void FixedUpdate()
{
GroundCheck();
Move();
}
private void OnJump()
{
if (GroundCheck())
{
Jump();
canDoubleJump = true;
playerAnimator.SetBool("Jump", true);
}
else if (!GroundCheck() && canDoubleJump)
{
Jump();
playerAnimator.SetBool("DoubleJump", true);
canDoubleJump = false;
}
}
private void Jump()
{
playerRigidBody.AddForce(jumpInput, ForceMode.Impulse);
}
private void Move()
{
if (Input.GetKeyDown(KeyCode.Space))
{
OnJump();
}
if (Input.GetKey(KeyCode.LeftShift) && GroundCheck())
{
SlowSpeed();
}
else
{
NormalSpeed();
}
transform.position += Vector3.right * moveSpeed;
}
private void SlowSpeed()
{
moveSpeed = slowSpeed;
playerAnimator.speed = slowAnimationSpeed;
}
private void NormalSpeed()
{
moveSpeed = normalSpeed;
playerAnimator.speed = 1;
}
bool GroundCheck()
{
if (Physics.BoxCast(transform.position, boxsize,
-transform.up, transform.rotation, maxDistance, layerMask))
{
playerAnimator.SetBool("Jump", false);
playerAnimator.SetBool("DoubleJump", false);
return true;
}
else
{
return false;
}
}
private void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawCube(transform.position - transform.up * maxDistance, boxsize);
}
}
I tried to use a didJumpStopped bool but it doesnt work or i used it wrong. I tried to set both animation bools to false at different places but it doesn't work too. At my first prototype i was stopping animations at "OncollisionEnter" function with "Ground" tag at road and it was working correctly. But i don't like using Tags at collision detection.
Upvotes: 0
Views: 85
Reputation: 20390
It looks like your input reader could be catching multiple jumps? Meaning in the Move()
function you might be reading multiple frames where the jump key is pressed, and applying multiple jump forces before the character actually gets off the ground and starts failing the ground check.
I think you're supposed to do input checks during Update()
, not FixedUpdate()
... so maybe that is what is causing the problem.
OnKeyPress should only happen once per Update frame, but again, you may be getting multiple of those per FixedUpdate call...
From https://docs.unity3d.com/ScriptReference/Input.GetKeyDown.html:
"Call this function from the Update function, since the state gets reset each frame. It will not return true until the user has released the key and pressed it again."
If that's not the issue, can you verify what you have maxDistance, jumpSpeed, and boxsize set to?
Upvotes: 0