【问题标题】:Flipping an enemy sprite when he turns around in Unity在 Unity 中转身时翻转敌方精灵
【发布时间】:2017-10-15 03:49:17
【问题描述】:

我已经尝试了几个小时来解决这个问题,我尝试了很多方法,但都没有奏效......

所以我有一个敌人使用 AI 跟随玩家,我需要精灵在敌人左转或右转时翻转。

这是我的代码的一部分(很多代码都是关于人工智能的,所以我只发布其中的一部分)

Vector3 dir = ( path.vectorPath[currentWaypoint] - transform.position ).normalized;
dir *= speed * Time.fixedDeltaTime;

//Move the AI
rb.AddForce (dir, fMode);

void Update () {

    if (rb.AddForce > 0) {
        sr.flipX = false;
    } else if (rb.AddForce < 0)
        sr.flipX = true;

    animate.SetFloat ("pMove", Mathf.Abs(rb.AddForce));   
}

【问题讨论】:

  • rb.AddForce &gt; 0 ??首先AddForce是一个函数,也是一个void的返回类型。我真的鼓励你在继续之前理解basic C# stuff
  • 为所有方向预渲染精灵(除非您的游戏支持超过 8 个方向)比使用一些技巧更有效
  • @Programmer 嗯,我有点知道,但正如我所说,我尝试了很多方法,这种方法只是最后一种,我至少在检查,谁知道呢。

标签: c# unity3d 2d sprite flip


【解决方案1】:

翻转精灵最简单的方法是使用localScale.x *= -1; 而不是检查 AddForce 您应该检查刚体在 x 轴(或 y 轴,如果你翻转精灵取决于它是否跳跃或坠落)

基本上在Update() 中,您可以执行以下操作:vx = rigidbody.velocity.x; 将速度存储在精灵的 x 轴上。然后在LastUpdate() 中检查是否需要翻转精灵:

if (vx > 0) {
    facingRight = true;
} else if (vx < 0) { 
    facingRight = false;
}

if (((facingRight) && (localScale.x<0)) || ((!facingRight) && (localScale.x>0))) {
    localScale.x *= -1;
}

这里有一个完整的示例,其中精灵根据玩家的输入移动。您需要为您的 AI 添加它。

//store references to components on the gameObject
Transform transform;
Rigidbody2D rigidbody;

public float MoveSpeed = 3f;

// hold player motion in this timestep
float vx;
float vy;

Awake () {
    // get a reference to the components we are going to be changing and store a reference for efficiency purposes
    transform = GetComponent<Transform> ();
    rigidbody = GetComponent<Rigidbody2D> ();

}


void Update()
{
    // determine horizontal velocity change based on the horizontal input
    vx = Input.GetAxisRaw ("Horizontal");

    //Change in case you are jumping or falling
    vy = rigidbody.velocity.y;

    // Change the actual velocity on the rigidbody
    rigidbody.velocity = new Vector2(_vx * MoveSpeed, _vy);

}

// Checking to see if the sprite should be flipped
// this is done in LateUpdate since the Animator may override the localScale
// this code will flip the player even if the animator is controlling scale
void LateUpdate()
{
    // get the current scale
    Vector3 localScale = transform.localScale;

    if (vx > 0) // moving right so face right
    {
        facingRight = true;
    } else if (vx < 0) { // moving left so face left
        facingRight = false;
    }

    // check to see if scale x is right for the player
    // if not, multiple by -1 which is an easy way to flip a sprite
    if (((facingRight) && (localScale.x<0)) || ((!facingRight) && (localScale.x>0))) {
        localScale.x *= -1;
    }   

    // update the scale
    transform.localScale = localScale;
}

【讨论】:

  • 这是一种简洁的方法,就像将 Y 旋转设置为 180 度一样。但是,我想知道,在这种特殊情况下,修改RigidbodyTransform 是否会迫使物理学重新计算GameObject 的对撞机。当比例为 -1 时,X 方向的力会发生什么变化?我之所以问,是因为 Rigidbody 的 Unity 文档明确强调 "you shouldn’t manipulate the Rigidbody and the Transform of the same GameObject - only one or the other",因为 Rigidbody 上有扭矩和力。
  • 稍后我会读到这个链接,我会告诉你的。但到目前为止,我对这种方法没有任何问题。
  • 谢谢!我现在就试试这个,我在睡觉:p
  • 天哪,它成功了!非常感谢。现在我将学习更多知识以帮助其他人。
  • 如果你想让你的精灵一起批处理是个坏主意。负比例会破坏批处理。不推荐,使用 SpriteRenderer flipX 代替它是为此目的而制作的。
【解决方案2】:

假设,sr 是一个 SpriteRenderer 组件,sr.flipX 方法很好。但是,您对Rigidbody 的作用力的评估是不对的。 rb.AddForce 的返回类型为void,判断Rigidbody 是否对其施加了作用力的正确方法是阅读rb.velocity.magnitude。此外,rb.velocity 会以Vector3 为您提供游戏对象的速度方向。假设您正在 X 轴上工作,请将其放入您的 LateUpdate 方法中:

sr.flipX = rb.velocity.magnitude > 0 && rb.velocity.x < 0 ? true : false;

如果Rigidbody 正在移动(rb.velocity.magnitude &gt; 0)并且它正在向左侧移动(@987654337),而不是 Update 方法中的 if-else 块@)。

在您的问题中,您只要求翻转精灵:Unity documentation statesflipX 仅影响渲染,而不影响其他组件(例如碰撞器和动画师)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    • 2022-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多