I recently got my character movement working pretty nicely, and I'm now trying to tie it in nicely with the animations I have set up.
Is there a way to track if the character is stationary? I found a way to track this using:
ani.SetBool("Stationary", rb.IsSleeping());
However, this seems to update pretty slowly for what I need as the character X-Axis keeps updating for about half a second after the movement key is released. Is there a better way to check for a stationary character that will consider the character stationary before it stops fully?
Is there a way to track the direction a character is facing and keep them facing that way even if they stop moving?
Here is my full code for reference;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class KittenController2 : MonoBehaviour
{
Rigidbody2D rb;
Animator ani;
public float speed;
public float jumpForce;
private float direction = 0f;
void Start()
{
rb = GetComponent<Rigidbody2D>();
ani = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
direction = Input.GetAxis("Horizontal");
ani.SetBool("Stationary", rb.IsSleeping());
if (direction > 0f)
{
rb.velocity = new Vector2(direction * speed, rb.velocity.y);
ani.SetFloat("Move X", direction);
}
else if (direction < 0f)
{
rb.velocity = new Vector2(direction * speed, rb.velocity.y);
ani.SetFloat("Move X", direction);
}
else
{
rb.velocity = new Vector2(0, rb.velocity.y);
}
if (Input.GetKeyDown(KeyCode.Space))
{
Jump();
}
}
void FixedUpdate()
{
}
void Jump()
{
rb.AddForce(new Vector2(0f, jumpForce), ForceMode2D.Impulse);
ani.SetTrigger("Jump");
}
}
CodePudding user response:
This is for the direction check:
private bool facingRight; // serialize this at top
private void FacingRight() // call this in the update function
{
if ((facingRight == true) && ((Input.GetKey(KeyCode.LeftArrow))|| (Input.GetKey(KeyCode.A)))) // keys you are pressing to move towards left
{
transform.Rotate(0, 180, 0);
facingRight = false;
}
else if ((facingRight == false) && ((Input.GetKey(KeyCode.RightArrow) || (Input.GetKey(KeyCode.D))))) // again the keys you are pressing for the movement to right
{
transform.Rotate(0, 180, 0);
facingRight = true;
}
}
CodePudding user response:
The IsSleeping
is most probably a bad indicator. Afaik a rigidbody goes to sleeping state depending on your physics settings after it has been stationary for a certain delay.
What you rather could use is simply using
// In general it is more efficient to check the sqrMagnitude than the magnitude
// especially if you do it each frame
ani.SetBool("Stationary", Mathf.Approximately(rb.velocity.sqrMagnitude, 0));
This will simply directly check whether the rigidbody is currently moving.
If a certain movement threshold is precision enough you could also just use
[Tooltip ("Below this absolute movement speed the object is considered stationary")]
public float stationaryThreshold = 0.01f;
private float squaredStationaryThreshold;
void Awake()
{
squaredStationaryThreshold = stationaryThreshold * stationaryThreshold;
}
And then check
ani.SetBool("Stationary", rb.velocity.sqrMagnitude <= squaredStationaryThreshold);