- Home /
Flip 2D player in x-axis to face movement direction
Hi!
I'm new to unity and the game world, but I have always wonder how it would be to build a game so I have started out with a 2D game :)
So, I have a player gameobject that use collider and rigidbody2d to move around (yes, no really control over the player object). He bounces around and I would like him to turn/flip into the direction he is moving on the x-axis. This is the code I have so far. It works when he moves right, but when he moves left he flips back and forth between facing left&right.
I have attached this script to my player:
void Start ()
{
direction = 1;
_posX = transform.position.x;
Debug.Log ("Position X: " + _posX);
}
void Update()
{
if (transform.position.x < _posX)
{
Debug.Log("Moving left - " + transform.position.x);
if (direction == 1)
{
transform.localScale = new Vector2(-1, transform.localScale.y);
direction = -1;
}
}
else
{
Debug.Log("Moving right - " + transform.position.x);
if (direction == -1)
{
transform.localScale = new Vector2(1, transform.localScale.y);
direction = 1;
}
}
_posX = transform.position.x;
}
Hope someone can help me to figure out what is wrong :)
Regards Stellan
Answer by koray1396 · Mar 20, 2014 at 06:59 PM
in your if statement, when velocity.x < 0, you flip your character every frame by, so it flips back and forth.
transform.localScale = new Vector2(-transform.localScale.x, transform.localScale.y);
a simple way to fix it is;
float someScale;
void Start(){
someScale = transform.localScale.x; // assuming this is facing right
}
// replace transform.localScale = new Vector2(transform.localScale.x, transform.localScale.y); by
transform.localScale = new Vector2(someScale, transform.localScale.y);
// and... transform.localScale = new Vector2(-transform.localScale.x, transform.localScale.y); by
transform.localScale = new Vector2(-someScale, transform.localScale.y);
Thanks alot! Works perfectly!
How come that I have to set the someSmale in the start event? Why can't transform.localScale.x be called in the Update event directly?
I been trying to flip my player so many Codes from tutorial on youtube. The only Answer that work was yours. Thank You!! Thank You !!
Answer by swag_swag · Mar 20, 2014 at 05:18 PM
,Simply try changing the (direction = -1) for "Moving left - " to a -1. Or perhaps direction = 1` void Start () { direction = -1; _posX = transform.position.x;
Debug.Log ("Position X: " + _posX);
}
void Update()
{
if (transform.position.x < _posX)
{
Debug.Log("Moving left - " + transform.position.x);
if (direction == -1)
{
transform.localScale = new Vector2(-1, transform.localScale.y);
direction = -1;
}
}
else
{
Debug.Log("Moving right - " + transform.position.x);
if (direction == -1)
{
transform.localScale = new Vector2(1, transform.localScale.y);
direction = 1;
}
}
_posX = transform.position.x;
}`
Answer by deamo · Mar 20, 2014 at 06:50 PM
I have updated the code a bit. More correct way to determine what way he is moving on the x-axis, but he still starts to flip back and forth as soon as he moves left :(
Can it have something to do with my collider?
void Start ()
{
Debug.Log (rigidbody2D.velocity.x);
}
void Update()
{
if (rigidbody2D.velocity.x >= 0)
{
Debug.Log("Moving right " + rigidbody2D.velocity.x);
transform.localScale = new Vector2(transform.localScale.x, transform.localScale.y);
}
else
{
Debug.Log("Moving left " + rigidbody2D.velocity.x);
transform.localScale = new Vector2(-transform.localScale.x, transform.localScale.y);
}
}
the following code runs on every update.
transform.localScale = new Vector2(-transform.localScale.x, transform.localScale.y);
this is continuously flipping the gameobject. -transform.localScale.x in this line means the reverse of CURRENT localScale.x NOT the reverse of starting value of localScale.x.
Simply, it looks at the gameobject and says "well this is now 1, it should be -1". In the next frame, "now this is -1, and i am making it 1".
Apologies for putting it like this, I couldn't figure out any other way to describe it. But you should understand the difference;
void Start(){
someValue = transform.position;
}
void Update(){
someValue2 = transform.position;
}
someValue will give you the starting position and will not change unless you put another line. someValue2 will give you the current position, and this will run on every update, means, this value will be updated in regards to the object.
I hope this is explaining for you and the issue is clarified.
Nice days!
Answer by Fubiou · Sep 07, 2015 at 07:32 AM
Hey, I found a simple way to flip the 2d character with a simple line:
transform.localEulerAngles = transform.eulerAngles + Vector3(0,180,-2*transform.eulerAngles.z);
Answer by kakubeiUK · Feb 02, 2019 at 03:38 PM
What's wrong with flipX = true;
?
I think it's because the flipX only works for the sprite and not for the colliders, so the scale is changed to maintain the relationships. But in the platform game I use the FlipX and it worked perfectly, besides the code is very clean Example: if (inputHorizontal > 0) sprite.flipX = false; else if (inputHorizontal < 0) sprite.flipX = true;
Just wanted to add that flipX won't work if you have any child game objects as well :)