翻转角色时,角色武器的旋转向后
When fliping the character the rotation of character's weapon goes backward
我在场景中有两个游戏对象,1.Character(Parent Object) 和 2.Weapon(Child Object)。问题是当角色向右移动时,武器的旋转很好,它朝向角色面向的方向并按预期旋转,正如您在下面的 Gif 图像中看到的那样。但是,当我向左翻转时,一切都出错了,武器向后移动,当我按下箭头时,旋转上升,当按下向上箭头时,旋转下降,请参见下面的 Gif 图像。请帮助如何修复它。
这是我的代码:
public float weaponRotationSpeed = 13f;
private Animator anim;
private float angle;
void Awake()
{
anim = GetComponent<Animator>();
}
void Update()
{
Vector2 hv = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
Vector3 changeParentScale = transform.localScale;
if (hv != Vector2.zero)
{
if (Input.GetAxis("Horizontal") < 0)
{
changeParentScale.x = -5f;
transform.localScale = changeParentScale;
}
else if (Input.GetAxis("Horizontal") > 0)
{
changeParentScale.x = 5f;
transform.localScale = changeParentScale;
}
angle = Mathf.Atan2(hv.y, hv.x) * Mathf.Rad2Deg;
transform.Find("Weapon").rotation = Quaternion.Lerp(transform.Find("Weapon").rotation,
Quaternion.Euler(0, 0, angle),
weaponRotationSpeed * Time.deltaTime);
anim.SetBool("isRunning", true);
}
else
{
anim.SetBool("isRunning", false);
}
那么你可能也想翻转旋转?例如。使用 Mathf.Sign
Quaternion.Euler(0,0, angle * Mathf.Sign(changeParentScale.x))
您的代码中还有其他一些小缺陷!
- 你不应该使用
Find
每一帧.. 而是存储它 一次 。
- 您正在重复使用
GetAxis
并且第一次也应该存储值.. 您不是已经在 hv
中有了它们吗?
Lerp
是一个很酷的工具,但你用错了 ;) 它使用给定的因子对每一帧进行插值。通常你想要一个固定的,例如0.5f
且未使用 Time.deltaTime
它可能更像是
// You will have to adjust this value again
// This needs to be a constant value between 0 and 1
// - 0: rotation isn't updated at all
// - 1: rotation immediately jumps to target
// - e.g. 0.5f: rotation is every frame set to the middle between current and target
[Range(0f, 1f)]
public float weaponRotationSpeed = 0.5f;
// already reference these via the Inspector
[SerializeField] private Animator anim;
[SerializeField] private Transform weapon;
private float angle;
// As Fallback get them ONCE on runtime
void Awake()
{
if(!anim) anim = GetComponent<Animator>();
if(!weapon) weapon = transform.Find("Weapon");
}
void Update()
{
Vector2 hv = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
Vector3 changeParentScale = transform.localScale;
if (hv != Vector2.zero)
{
// get direction of Horizontal
int sign = Mathf.Sign(hv.x);
if (!Mathf.Approximately(hv.x, 0))
{
changeParentScale.x = 5f * sign;
transform.localScale = changeParentScale;
}
angle = Mathf.Atan2(hv.y, hv.x) * Mathf.Rad2Deg;
weapon.rotation = Quaternion.Lerp(weapon.rotation, Quaternion.Euler(0, 0, angle * sign), weaponRotationSpeed);
anim.SetBool("isRunning", true);
}
else
{
anim.SetBool("isRunning", false);
}
}
或者你也可以通过不使用 rotation
而使用 localRotation
来旋转武器来解决它。
我在场景中有两个游戏对象,1.Character(Parent Object) 和 2.Weapon(Child Object)。问题是当角色向右移动时,武器的旋转很好,它朝向角色面向的方向并按预期旋转,正如您在下面的 Gif 图像中看到的那样。但是,当我向左翻转时,一切都出错了,武器向后移动,当我按下箭头时,旋转上升,当按下向上箭头时,旋转下降,请参见下面的 Gif 图像。请帮助如何修复它。
这是我的代码:
public float weaponRotationSpeed = 13f;
private Animator anim;
private float angle;
void Awake()
{
anim = GetComponent<Animator>();
}
void Update()
{
Vector2 hv = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
Vector3 changeParentScale = transform.localScale;
if (hv != Vector2.zero)
{
if (Input.GetAxis("Horizontal") < 0)
{
changeParentScale.x = -5f;
transform.localScale = changeParentScale;
}
else if (Input.GetAxis("Horizontal") > 0)
{
changeParentScale.x = 5f;
transform.localScale = changeParentScale;
}
angle = Mathf.Atan2(hv.y, hv.x) * Mathf.Rad2Deg;
transform.Find("Weapon").rotation = Quaternion.Lerp(transform.Find("Weapon").rotation,
Quaternion.Euler(0, 0, angle),
weaponRotationSpeed * Time.deltaTime);
anim.SetBool("isRunning", true);
}
else
{
anim.SetBool("isRunning", false);
}
那么你可能也想翻转旋转?例如。使用 Mathf.Sign
Quaternion.Euler(0,0, angle * Mathf.Sign(changeParentScale.x))
您的代码中还有其他一些小缺陷!
- 你不应该使用
Find
每一帧.. 而是存储它 一次 。 - 您正在重复使用
GetAxis
并且第一次也应该存储值.. 您不是已经在hv
中有了它们吗? Lerp
是一个很酷的工具,但你用错了 ;) 它使用给定的因子对每一帧进行插值。通常你想要一个固定的,例如0.5f
且未使用Time.deltaTime
它可能更像是
// You will have to adjust this value again
// This needs to be a constant value between 0 and 1
// - 0: rotation isn't updated at all
// - 1: rotation immediately jumps to target
// - e.g. 0.5f: rotation is every frame set to the middle between current and target
[Range(0f, 1f)]
public float weaponRotationSpeed = 0.5f;
// already reference these via the Inspector
[SerializeField] private Animator anim;
[SerializeField] private Transform weapon;
private float angle;
// As Fallback get them ONCE on runtime
void Awake()
{
if(!anim) anim = GetComponent<Animator>();
if(!weapon) weapon = transform.Find("Weapon");
}
void Update()
{
Vector2 hv = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));
Vector3 changeParentScale = transform.localScale;
if (hv != Vector2.zero)
{
// get direction of Horizontal
int sign = Mathf.Sign(hv.x);
if (!Mathf.Approximately(hv.x, 0))
{
changeParentScale.x = 5f * sign;
transform.localScale = changeParentScale;
}
angle = Mathf.Atan2(hv.y, hv.x) * Mathf.Rad2Deg;
weapon.rotation = Quaternion.Lerp(weapon.rotation, Quaternion.Euler(0, 0, angle * sign), weaponRotationSpeed);
anim.SetBool("isRunning", true);
}
else
{
anim.SetBool("isRunning", false);
}
}
或者你也可以通过不使用 rotation
而使用 localRotation
来旋转武器来解决它。