2D - Aim Object Rotates WIth Character Movement; Why Does Idle Default to One Direction?

I’m a beginner programmer learning C#. I have been using tutorials to create a beginner 2D top down game, and have gotten to the point where I can move the Player using Input Action with animations.

I began to try having a ranged attack the player could perform, and started by adding a game object titled that would rotate with the player’s movements that would be how the player aims. I added code to the player’s movement to simulate this. This is the code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    [SerializeField] private float _moveSpeed = 5f;
    private float attackTime = .25f;
    private float attackCounter = .25f;
    private bool isAttacking;

    private Vector2 _movement;

    private Rigidbody2D _rb;
    private Animator _animator;
    public Transform Aim;
    bool isWalking = false;
    private const string _horizontal = "Horizontal";
    private const string _vertical = "Vertical";
    private const string _lastHorizontal = "LastHorizontal";
    private const string _lastVertical = "LastVertical";

    // Start is called before the first frame update
    private void Awake()
    {
        _rb = GetComponent<Rigidbody2D>();
        _animator = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        _movement.Set(InputManager.Movement.x, InputManager.Movement.y);

        _rb.velocity = _movement * _moveSpeed;

        _animator.SetFloat(_horizontal, _movement.x);
        _animator.SetFloat(_vertical, _movement.y);

        if (isWalking)
        {
            Vector3 vector3 = Vector3.left * InputManager.Movement.x + Vector3.down * InputManager.Movement.y;
            Aim.rotation = Quaternion.LookRotation(Vector3.forward, vector3);
        }

        if (_movement != Vector2.zero)
        {
            _animator.SetFloat(_lastHorizontal, _movement.x);
            _animator.SetFloat(_lastVertical, _movement.y);

            isWalking = false;
            Vector3 vector3 = (Vector3.left * _movement.x + Vector3.down * _movement.y);
            Aim.rotation = Quaternion.LookRotation(Vector3.forward, vector3);
        }
        else
        {
            isWalking = true;
        }


        if (isAttacking)
        {
            attackCounter -= Time.deltaTime;
            if (attackCounter <= 0)
            {
                _animator.SetBool("isAttacking", false);
                isAttacking = false;
            }

        }

        if (Input.GetKeyDown(KeyCode.F))
        {
            attackCounter = attackTime;
            _animator.SetBool("isAttacking", true);
            isAttacking = true;
        }
    }
}

With this code, the player movements work with animations, and the object rotates with the player while the player is moving. But in idle the aim object always defaults to the down position of the player sprite, meaning it doesn’t end in the players last moving direction. I don’t think it’s a problem with the animator, and it has to be something wrong with the code. Everything else works except this. What could be the problem?

Couple of questions

  1. Why do you need a seperate object to find the direction your aiming?

  2. Is this object a child of your player character?

  1. I need a separate object because my player’s transform isn’t actually rotating, it’s simulating rotation through animations. The object is supposed to actually rotate.

  2. Yes it is a child of my player character.

Don’t execute line 53 above if the vector3 variable is below a certain magnitude, something like:

if (vector3.magnitude > 0.1f)
{
  // do line 53 here
}

You should also take a moment to name your variables better. The name vector3, while completely legal, is bad in two ways:

  • it conveys absolutely NOTHING about the variable
  • it is extremely similar to the type Vector3 causing more confusion

A better candidate might be movement or moveVector or something like that.

Naming is hard… name things WELL to reduce your own confusion and wasted time.