在Unity 2D中翻转2D精灵动画

15

我有一个关于2D精灵动画的问题,我无法在特定的地方找到答案:

我有一个带有向右行走动画的精灵。然而,当他向左行走(2D横向滚动游戏),我想要翻转动画,使之朝左。

我可以轻松地翻转精灵本身,使用transform.localscale.x,但是,这只是翻转了精灵,而不是动画剪辑。(在Unity中已经不再发生这种情况)

因此,虽然精灵会翻转,但一旦动画开始播放,它就会回到向右的状态(因为我只有一个面向右的动画剪辑)。

是否唯一的方法是在Photoshop中翻转精灵,还是在Unity中有办法做到这一点?

谢谢!

更新:使用实际版本的Unity,如果通过将变换乘以-1来缩放变换,则动画帧也会被缩放。

6个回答

16

我最终通过这样做弄明白了:

void Flip()
{
    // Switch the way the player is labelled as facing
    facingRight = !facingRight;

    // Multiply the player's x local scale by -1
    Vector3 theScale = transform.localScale;
    theScale.x *= -1;
    transform.localScale = theScale;
}

这是从Unity的2D平台游戏示例中得到的。

为了实现某种检查,利用Flip方法,您可以执行类似于以下基本移动代码的操作。 facingRight被设置为类上的一个值,以便其他方法可以使用它,并且默认为false

void Update() 
{

    //On X axis: -1f is left, 1f is right

    //Player Movement. Check for horizontal movement
    if (Input.GetAxisRaw ("Horizontal") > 0.5f || Input.GetAxisRaw("Horizontal") < -0.5f) 
    {
        transform.Translate (new Vector3 (Input.GetAxisRaw ("Horizontal") * moveSpeed * Time.deltaTime, 0f, 0f));
        if (Input.GetAxisRaw ("Horizontal") > 0.5f && !facingRight) 
        {
            //If we're moving right but not facing right, flip the sprite and set     facingRight to true.
            Flip ();
            facingRight = true;
        } else if (Input.GetAxisRaw("Horizontal") < 0.5f && facingRight) 
        {
            //If we're moving left but not facing left, flip the sprite and set facingRight to false.
            Flip ();
            facingRight = false;
        }

    //If we're not moving horizontally, check for vertical movement. The "else if" stops diagonal movement. Change to "if" to allow diagonal movement.
    } else if (Input.GetAxisRaw ("Vertical") > 0.5f || Input.GetAxisRaw("Vertical") < -0.5f) 
    {
        transform.Translate (new Vector3 (0f, Input.GetAxisRaw ("Vertical") * moveSpeed * Time.deltaTime, 0f));
    }

    //Variables for the animator to use as params
    anim.SetFloat ("MoveX", Input.GetAxisRaw ("Horizontal"));
    anim.SetFloat ("MoveY", Input.GetAxisRaw ("Vertical"));

}

我在这个非常有帮助的答案中进行了最后的编辑,我已经实现了一个检查,以确定按键时是否需要翻转精灵。 - Donglecow
@Donglecow - 这个变化太大了,你最好另外写一个答案。 - dbc
@dbc 我应该吗?我只是在 Jestus 的答案基础上提供了一些基本代码来展示方法如何实现。如果你仍然这么说,那么我会撤销编辑并发布自己的答案。 - Donglecow
@Donglecow - 嗯,编辑已经通过了,所以现在选择权就在你手里了。 - dbc

3
void FlipHorizontal()
{
    animator.transform.Rotate(0, 180, 0);
}

您也可以在transform自身上进行操作(而不是使用动画器)。但在这种情况下,旋转值可能会被动画器覆盖。

我认为语法是 animator.transform.Rotate(new Vector3(0, 180, 0)); - JaredH
transform.Rotate支持方法重载。因此,您可以同时使用包含Rotate(float xAngle,float yAngle,float zAngle,Space relativeTo = Space.Self)和Rotate(Vector3 eulers,Space relativeTo = Space.Self)的参数。 请查看https://docs.unity3d.com/ScriptReference/Transform.Rotate.html。 - HyoJin KIM

0

这是我做的方式 - 几乎与Jestus使用Unity脚本的技术相同。

var facing : String = "right";

function updateFacing(curr : String){
    if(curr != facing){
        facing = curr;
        var theScale : Vector3 = gameObject.transform.localScale;
        theScale.x *= -1;
        gameObject.transform.localScale = theScale;
    }
}

//put to use
function controls(){
    if(Input.GetKey (KeyCode.LeftArrow)){
        updateFacing("left");
    } else if(Input.GetKey (KeyCode.RightArrow)){
        updateFacing("right");
    }      
}

0

如果你正在使用Unity进行动画制作:

  1. 复制你想要翻转的动画的所有帧(精灵)。
  2. 将这些帧粘贴到新的动画中,并选择第一帧上的所有内容。
  3. 将第一帧的x比例从1更改为-1。
  4. 对于你的动画的最后一帧,也做同样的事情。

现在它应该面向另一个方向播放了!


感谢EduLopez提供的建议(本应该作为评论或备选答案发布):“您还可以让一个动画向左走,并编写一个函数来面对您的精灵。根据isFacingRight == true,x比例尺将为1或-1。” - G42
这也是一个很好的答案。这是在动画GUI视图中完成此操作的另一种方式。不应该是负面答案... - Lovera

0
这是我的C#实现。它使用一个字符串作为方向面对,使得调试变得更加容易一些。
public string facing = "right";
public string previousFacing;

private void Awake()
{
    previousFacing = facing;
}

void Update()
{
    // store movement from horizontal axis of controller
    Vector2 move = Vector2.zero;
    move.x = Input.GetAxis("Horizontal");
    // call function
    DetermineFacing(move);
}
// determine direction of character
void DetermineFacing(Vector2 move)
{
    if (move.x < -0.01f)
    {
        facing = "left";
    }
    else if (move.x > 0.01f)
    {
        facing = "right";
    }
    // if there is a change in direction
    if (previousFacing != facing)
    {
        // update direction
        previousFacing = facing;
        // change transform
        gameObject.transform.Rotate(0, 180, 0);
    }
}

0
如果需要,更改水平 > 0
Animator anim;
SpriteRenderer sr;
bool lastFlip;

horizontal = Input.GetAxis("Horizontal");
anim.SetFloat("Move_X", horizontal);
if(horizontal==0){
    sr.flipX = lastFlip;
}else{
    sr.flipX = horizontal < 0;
    lastFlip = sr.flipX;
}

你的回答可以通过提供更多的支持性信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的回答是否正确。你可以在帮助中心找到关于如何撰写好回答的更多信息。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接