在 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 states,flipX
只影响渲染,而不影响其他组件(例如碰撞器和动画器)。
翻转精灵最简单的方法是使用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;
}
我已经花了几个小时来尝试解决这个问题,我尝试了很多方法,但 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 states,flipX
只影响渲染,而不影响其他组件(例如碰撞器和动画器)。
翻转精灵最简单的方法是使用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;
}