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

C# 在Unity 2D中翻转2D精灵动画,c#,animation,unity3d,2d,sprite,C#,Animation,Unity3d,2d,Sprite,我有一个关于2D精灵动画的快速问题,我在任何地方都找不到明确的答案: 我有一个右边有行走动画的精灵。但是,当他向左走时,我显然想将动画向左翻转(2D侧滚动) 我可以使用transform.localscale.x轻松翻转精灵本身,但是,这只会翻转精灵。不是动画剪辑。(这不再在统一中发生) 因此,当精灵翻转时,动画剪辑开始播放的那一刻,它会向右翻转(因为我仅有的动画剪辑是针对右向精灵的) 这是在Photoshop中翻转精灵的唯一方法,还是有一种在Unity中翻转精灵的方法 谢谢 更新:使用unit

我有一个关于2D精灵动画的快速问题,我在任何地方都找不到明确的答案:

我有一个右边有行走动画的精灵。但是,当他向左走时,我显然想将动画向左翻转(2D侧滚动)

我可以使用
transform.localscale.x
轻松翻转精灵本身,但是,这只会翻转精灵。不是动画剪辑。(这不再在统一中发生)

因此,当精灵翻转时,动画剪辑开始播放的那一刻,它会向右翻转(因为我仅有的动画剪辑是针对右向精灵的)

这是在Photoshop中翻转精灵的唯一方法,还是有一种在Unity中翻转精灵的方法

谢谢


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

我最终通过这样做解决了这个问题:

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 Platformer示例

要使用
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"));

}
void Update()
{
//在X轴上:-1f为左,1f为右
//玩家移动。检查水平移动
如果(Input.GetAxisRaw(“水平”)>0.5f | | Input.GetAxisRaw(“水平”)<-0.5f)
{
transform.Translate(新矢量3(Input.GetAxisRaw(“水平”)*moveSpeed*Time.deltaTime,0f,0f));
如果(Input.GetAxisRaw(“水平”)>0.5f&&!facingRight)
{
//如果我们向右移动,但没有向右移动,请翻转精灵并将facingRight设置为true。
翻转();
facingRight=正确;
}else if(Input.GetAxisRaw(“水平”)<0.5f&&facingRight)
{
//如果我们向左移动,但不面向左,翻转精灵并将facingRight设置为false。
翻转();
facingRight=错误;
}
//如果我们不是水平移动,检查垂直移动。如果“else-If”停止对角线移动。更改为“If”以允许对角线移动。
}else if(Input.GetAxisRaw(“垂直”)>0.5f | | Input.GetAxisRaw(“垂直”)<-0.5f)
{
transform.Translate(新矢量3(0f,Input.GetAxisRaw(“垂直”)*moveSpeed*Time.deltaTime,0f));
}
//供动画师用作参数的变量
anim.SetFloat(“MoveX”,Input.GetAxisRaw(“水平”);
anim.SetFloat(“MoveY”,Input.GetAxisRaw(“垂直”);
}

您也可以在变换本身上执行此操作(无需使用animator)。但在这种情况下,旋转值可以被animator覆盖,这就是我所做的-与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");
    }      
}

如果您正在Unity中设置动画:

  • 复制要翻转的动画的所有帧(精灵)
  • 将这些帧粘贴到新动画中,并选择第一帧上的所有内容
  • 将第一帧的x比例从1更改为-1
  • 对动画的最后一帧执行相同的操作
  • 现在它应该朝着另一个方向玩

    这是我的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);
        }
    }
    
    publicstring-face=“right”;
    公共字符串优先;
    私人空间
    {
    前向=前向;
    }
    无效更新()
    {
    //存储来自控制器水平轴的移动
    向量2移动=向量2.0;
    move.x=Input.GetAxis(“水平”);
    //调用函数
    确定(移动);
    }
    //确定字符的方向
    无效确定(矢量2移动)
    {
    如果(移动.x<-0.01f)
    {
    “面向左”;
    }
    否则,如果(移动x>0.01f)
    {
    正面=“右”;
    }
    //如果方向发生变化
    如果(前向!=前向)
    {
    //更新方向
    前向=前向;
    //变换
    gameObject.transform.Rotate(0,180,0);
    }
    }
    
    建议的编辑(应该作为注释或alt-ans发布):“你也可以让一个动画向左走,并且有一个面向你的精灵的功能。根据
    isFscingRight==true
    ,x比例应该是1或-1”这也是一个很好的答案。这是在动画gui视图中执行此操作的另一种方法。不应该是否定的答案……我已经编辑了这个我已经实现的非常有用的答案的最新补充内容,就是在按下该键时进行检查,以确定是否需要翻转精灵。@Donglecow-更改太大了,您可能应该做另一个答案。@dbc我应该吗?我只是在Jestus的答案的基础上,提供了一些基本代码来说明如何实现该方法。如果你仍然这么说,那么我将恢复编辑并发布我自己的答案。@Donglecow-好吧,编辑得到了批准,所以这一点确实是你的选择。我认为语法是
    animator.transform.Rotate(新向量3(0,180,0))transform.Rotate支持方法覆盖。因此,您可以使用包含旋转的两个参数(float xAngle、float yAngle、float zAngle、Space relativeTo=Space.Self);并旋转(矢量3欧拉,空间相对论=Space.Self);检查
    
    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);
        }
    }