Character Rotation Snapping Back to Original Postiton

Hi, everyone. Been going thru these forums for a while. Still Struggling on my first game. I’ve been stuck here for about 4 days so any help would be greatly appreciated. I’ve seen alot of problems like mine but can’t find a response that quite fixes my problem. Probably something really simple. Well here’s the code

using UnityEngine;
using System.Collections;



    public class NoHat : MonoBehaviour
    {
        Collider2D coll;
        Transform trans;
        Rigidbody2D rb2d;
        Animator anim;
        public float xVelAdj;
        public float yVelAdj;
        public float moveForce;
        public bool grounded;
        public bool swimming;
        private bool facingRight;
        public LayerMask whatIsGround;
        public LayerMask whatIsWater;

        void Start()
        {
            coll = GetComponent<Collider2D>();
            trans = this.GetComponent<Transform>();
            rb2d = this.GetComponent<Rigidbody2D>();
            anim = GetComponent<Animator>();
        }

        void Update()
        {
            xVelAdj = Input.GetAxis("Horizontal");
            yVelAdj = Input.GetAxis("Vertical");
            rb2d.gravityScale = 0;
            rb2d.drag = 1.5f;
            rb2d.angularDrag = 2;
            grounded = Physics2D.IsTouchingLayers(coll, whatIsGround);
            swimming = Physics2D.IsTouchingLayers(coll, whatIsWater);
            //rb2d.freezeRotation = false;
        }

        void FixedUpdate()
        {
        Vector2 moveVec = new Vector2(xVelAdj, yVelAdj) * moveForce;
        Vector3 lookVec = new Vector3(xVelAdj, yVelAdj, 4096);
        trans.rotation = Quaternion.LookRotation(lookVec, Vector3.back);
        rb2d.AddForce(moveVec);      
        //for flipping player
        float horizontal = xVelAdj;
            Flip(horizontal);
    }
        //to Flip player facing left or right
        private void Flip(float Horizontal)
        {
            if (Horizontal < 0 && !facingRight || Horizontal > 0 && facingRight)
            {
                facingRight = !facingRight;

                Vector3 theScale = transform.localScale;

                theScale.x *= -1;

                transform.localScale = theScale;
            }
        }
    }

Good job posting the code, with correct formatting! Now, don’t forget to also post (a) what you’re trying to do, (b) what actually happens, and if it’s still not abundantly clear, (c) how (b) differs from (a).

1 Like

Ok thanks for input. So I want my character to rotate in the same direction that I’m moving. Which it does fine. But when I stop moving he snaps back to 0. Now I know that this is bc if there’s no input then that’s the position it would go back into bc I’m technically not looking in any direction based on the code I have. I just don’t know how to tell it to keep looking in the direction that I was when I was moving.

What about updating the way you’re rotated only if the input isn’t zero?

2 Likes

Yes, I think @methos5k is (as usual) right — just throw an “if (xVelAdj != 0 || yVelAdj != 0)” block around your rotation update code in FixedUpdate.

1 Like

Like this?

using UnityEngine;
using System.Collections;



    public class NoHat : MonoBehaviour
    {
        Collider2D coll;
        Transform trans;
        Rigidbody2D rb2d;
        Animator anim;
    private Vector3 inputRot;
        public float xVelAdj;
        public float yVelAdj;
        public float moveForce;
        public bool grounded;
        public bool swimming;
        private bool facingRight;
        public LayerMask whatIsGround;
        public LayerMask whatIsWater;

        void Start()
        {
            coll = GetComponent<Collider2D>();
            trans = this.GetComponent<Transform>();
            rb2d = this.GetComponent<Rigidbody2D>();
            anim = GetComponent<Animator>();
        }

        void Update()
        {
            xVelAdj = Input.GetAxis("Horizontal");
            yVelAdj = Input.GetAxis("Vertical");
            rb2d.gravityScale = 0;
            rb2d.drag = 1.5f;
            rb2d.angularDrag = 2;
            grounded = Physics2D.IsTouchingLayers(coll, whatIsGround);
            swimming = Physics2D.IsTouchingLayers(coll, whatIsWater);
            //rb2d.freezeRotation = false;
        }

        void FixedUpdate()
        {
        Vector2 moveVec = new Vector2(xVelAdj, yVelAdj) * moveForce;
        Vector3 lookVec = new Vector3(xVelAdj, yVelAdj, 4096);
        if (xVelAdj != 0 || yVelAdj != 0)
        { trans.rotation = Quaternion.LookRotation(lookVec, Vector3.back); }
        rb2d.AddForce(moveVec);       
        //for flipping player
        float horizontal = xVelAdj;
           Flip(horizontal);
    }
        //to Flip player facing left or right
        private void Flip(float Horizontal)
        {
            if (Horizontal < 0 && !facingRight || Horizontal > 0 && facingRight)
            {
                facingRight = !facingRight;

                Vector3 theScale = transform.localScale;

                theScale.x *= -1;

                transform.localScale = theScale;
            }
        }
    }

I tried that already. Doesn’t Work, am i putting it in the wrong place?

How exactly doesn’t it work? I would expect this code, as posted above, would not rotate the object when there is no movement input. It’ll still flip it, of course (because the Flip call on line 51 is not inside the if-block). Is that not what you want?

1 Like

Yeah it’s weird right? I had the exact same code written before (except I was using unity cross platform ) and it worked. All of a sudden it doesn’t. I wonder if something weird could be going on in the editor? Idk. But when I stop moving the rotation still goes back to zero. I’ll post screen shots lore something later when I get off of work. To see if that helps.

Ok, so i changed the 4096 in the z axis and made it a lower number (360) and it seems to work better but not quite still. It works on the joystick, but only works sometimes with the keyboard.

Also is there a way to make the movement smoother? He only moves in 8 directions.

I don’t understand what you’re trying to do there. It’s really strange code. Can you back up and explain what it is you’re trying to do? I’m guessing you just want him to face in the direction of the control input, but does “face” mean to rotate around Y (typical for a 3D game) or to rotate around Z (typical for a 2D game)?

If the latter, then what you really want is a 2D version of LookRotation, which I happen to have:

    /// This is a 2D version of Quaternion.LookAt; it returns a quaternion
    /// that makes the local +X axis point in the given forward direction.
    static Quaternion LookAt2D(Vector2 forward) {
        return Quaternion.Euler(0, 0, Mathf.Atan2(forward.y, forward.x) * Mathf.Rad2Deg);
    }

So, try just passing new Vector2(xVelAdj, yVelAdj) to this function, and stuffing the result into transform.rotation (assuming you really are working in 2D). Of course do this only when they are not both zero.

You mean that he currently moves in only 8 directions, but you’d like him to rotate to any arbitrary direction? That’ll happen naturally with the code above if you actually have analog inputs, like with an analog stick. If you’re using the keyboard, of course, then you have no easy way to indicate anything other than 8 directions. You’d have to go to some completely different control scheme if you want arbitrary directions with keyboard input.

1 Like

I’m not sure why it’s only working sometimes. I can say, though, that when you’re reading an axis like that, I think it’s acceptable to put it into FixedUpdate.

One way I can think of moving in more than 8 directions, is to let the horizontal axis rotate your character, and then you can move forward/backward based on the rotation. I suppose you can move side to side, also, but it would have to be with different keys (or possibly more awkwardly with a toggle).

1 Like

So by “face” I mean rotate in the direction of the control input around the “Z” axis for a 2D game. Sorry for my noobness but how would i pass the new Vector2(xVelAdj, yVelAdj) to that function. I can’t seem to change anything in it without an error.

Ok, nevermind got it. This seems to work perfectly.

if (xVelAdj != 0 || yVelAdj != 0)
        {
            float angle = Mathf.Atan2(-xVelAdj, yVelAdj) * Mathf.Rad2Deg;
            transform.rotation = Quaternion.AngleAxis(angle, Vector3.forward);
        }

thnx for all the help guys.

I also bookmarked that Luminary Apps:Blog page. Very helpful stuff there. Thanks again!

2 Likes

Cool, glad you got it working. :slight_smile: