在 Unity 中转身时翻转敌方精灵

Flipping an enemy sprite when he turns around in Unity

我已经花了几个小时来尝试解决这个问题,我尝试了很多方法,但 none 其中的方法有效...

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

这是我的一部分代码(很多代码都是关于 AI 的,所以我 post 只是其中的一部分)

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));   
}

假设,sr 是一个 SpriteRenderer 组件,sr.flipX 方法很好。但是,您对 Rigidbody 上的力量的评估是不正确的。 rb.AddForce 具有 void 的 return 类型,读取 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 > 0) 并且它正朝着左侧 (rb.velocity.x < 0).

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

翻转精灵最简单的方法是使用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;
}