- Home /
Distracting Sprite flip
I'm making a small, proof of concept game for myself but I am running in to an issue. The character can aim her gun depending on where the mouse is, so there are different sprites whether she is moving forward or backwards. I'll admit, I'm in the early stages, but right now, when I turn her around, there is a brief moment where the character faces the new direction before reorienting herself to face the mouse. I find this very distracting and would like to know if there is anything I can do to negate this, like delay the update so it waits until the next frame to flip the sprite.
Thanks for your help.
Hi there. Information you provided is not detail. Are you using animation Controller?
Do you rotate the character by script? If so, we probably need the code.
Answer by Juice-Tin · Jan 07, 2015 at 08:45 AM
If you're using transform.LookAt(), that's almost always a bad choice as your object will just blindly stare at the other object.
Instead you should manually look up how to properly rotate objects using their rotation property, so you have control over which axis' are being used.
(IE. They will rotate in X or Y axis, but not Z)
Answer by Peteman · Jan 07, 2015 at 04:28 PM
I'm using an animator component.
Here's what the code looks like:
using UnityEngine;
using System.Collections;
public class CharacterControllerScript : MonoBehaviour {
public float jumpForce = 7f;
public float maxSpeed = 8f;
public bool facingRight;
// Use this for initialization
Animator anim;
public bool grounded = false;
public bool doubleJumped = false;
public Transform groundCheck;
float groundRadius = 0.2f;
public LayerMask whatIsGround;
//checks what can the character land on.
Transform armGraphics;
Transform playerGraphics;
void Start () {
anim = GetComponent<Animator>();
playerGraphics = transform.FindChild("Graphics");
}
//test
// Update is called once per frame
void FixedUpdate ()
{
grounded = Physics2D.OverlapCircle (groundCheck.position, groundRadius, whatIsGround);
//checks if there is something underneath
if (grounded)
{
doubleJumped = false;
}
anim.SetBool ("Ground", grounded);
//tells the Ground variable in the animation controller that speed is this.
float move = Input.GetAxis ("Horizontal");
//gets the movement direction
anim.SetFloat ("Speed", Mathf.Abs (move));
//tells the Speed variable in the animation controller that speed is this.
anim.SetFloat ("vSpeed", rigidbody2D.velocity.y);
//tells the vertical speed variable in the animation controller that speed is this.
if (!grounded)
{
//return;
}
//rigidbody2D.velocity.y is the speed of up and down
rigidbody2D.velocity = new Vector2 (move * maxSpeed, rigidbody2D.velocity.y);
if (move > 0 && !facingRight)
{
Flip ();
}
else if (move < 0 && facingRight)
{
Flip ();
}
//this is to keep you from switching direction when you don't want to
}
void Update()
{
//TestFixedUpdate ();
//so we can get the jump value more accurately
if ((grounded || !doubleJumped) && Input.GetButtonDown("Jump"))
{
anim.SetBool("Ground", false);
//rigidbody2D.
rigidbody2D.AddForce(new Vector2(0, jumpForce));
if ((!doubleJumped))
{
rigidbody2D.velocity = new Vector2(0, 0);
doubleJumped = true;
}
}
}
void Flip()
{
facingRight = !facingRight;
Vector3 theScale = playerGraphics.localScale;
Vector3 theScaleArm = armGraphics.localScale;
//gets the local scale
theScale.x *= -1;
//turns around the scale
//theScaleArm.y *= -1;
playerGraphics.localScale = theScale;
//sets the new scale
armGraphics.localScale = theScaleArm;
Vector3 armTransform = armGraphics.localPosition;
armTransform.x *= -1;
armGraphics.localPosition = armTransform;
}
}
using UnityEngine;
using System.Collections;
public class ArmRotator : MonoBehaviour {
public int rotationOffset = 0;
Animator anim;
bool flippedArm;
bool faceRight;
void Start () {
anim = GetComponentInParent<Animator>();
}
// Update is called once per frame
void FixedUpdate () {
faceRight = GetComponentInParent<CharacterControllerScript> ().facingRight;
//subtracting the position of the player from the mouse position
Vector3 difference;
difference = Camera.main.ScreenToWorldPoint (Input.mousePosition) - transform.position;
difference.Normalize (); //normalizing the vector. the vector will be 1.
float rotZ = Mathf.Atan2 (difference.y, difference.x) * Mathf.Rad2Deg; //find the angle in degrees
transform.rotation = Quaternion.Euler (0f, 0f, rotZ + rotationOffset);
if (!flippedArm && ((rotZ >90) || (rotZ <-90)))
{
FlipArm();
}
else if ((rotZ <90) && flippedArm && (rotZ >-90) )
{
FlipArm();
}
if (!faceRight)
{
rotZ = Mathf.Abs(rotZ-180);
if (rotZ>180)
rotZ -= 360;
}
anim.SetFloat ("Angle_Arm", rotZ);
}
void FlipArm()
{
Vector3 theScale = transform.localScale;
flippedArm = !flippedArm;
theScale.y*= -1;
transform.localScale = theScale;
}
}
Your answer
Follow this Question
Related Questions
How to call sprite at run time 3 Answers
Same sprite animation on multiple objects 1 Answer
How to increase sprite animation speed 2 Answers
Sprite animation triggers OnCollisionEnter2D every frame (no root motion or animate physics) 0 Answers
Playing two sprite-based animations simultaneously (Not Legacy) 2 Answers