Home > Enterprise >  I'm having difficulty finding a way to track if my character is stationary and what direction t
I'm having difficulty finding a way to track if my character is stationary and what direction t

Time:11-03

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);
  • Related