这是一个非常奇怪的错误。我创建了以下脚本,旨在通过围绕圆形路径移动并面向鼠标来计算在我的游戏中发射弹丸的位置:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ProjectileFire : MonoBehaviour
{
[System.Serializable]
public class ButtonDirectionSet {
public string button;
public float direction;
public bool degrees = true;
}
public GameObject projectile;
public Vector2 centerPoint;
public float radius = 1.0f;
public string fireButton = "Fire1";
public bool followMouse = false;
public bool followKeyboard = true;
public List<ButtonDirectionSet> buttonDirectionMap = new List<ButtonDirectionSet>();
public bool degrees = true;
public float direction;
private readonly float maxDirection = 360 * Mathf.Deg2Rad;
// Start is called before the first frame update
void Start()
{
foreach (ButtonDirectionSet set in buttonDirectionMap) {
if (set.degrees) {
set.direction *= Mathf.Deg2Rad;
}
}
if (degrees) {
direction *= Mathf.Deg2Rad;
}
}
void Update()
{
foreach (ButtonDirectionSet set in buttonDirectionMap) {
if (Input.GetButtonDown(set.button)) {
direction = set.direction;
}
}
if ((followKeyboard && followMouse && Input.GetMouseButton(0)) || !followKeyboard) {
Vector3 mouse = Input.mousePosition;
mouse.z = transform.position.z - Camera.main.transform.position.z;
Vector3 mousePosition = transform.InverseTransformPoint(Camera.main.ScreenToWorldPoint(mouse));
float xPos = mousePosition.x - centerPoint.x;
if (Mathf.Abs(xPos) < 0.1f)
{
xPos = 0.1f * Mathf.Sign(xPos);
}
float yPos = mousePosition.y - centerPoint.y;
if (Mathf.Abs(yPos) < 0.1f)
{
yPos = 0.1f * Mathf.Sign(yPos);
}
direction = Mathf.Atan2(yPos, xPos);
}
if (direction < 0) direction += maxDirection;
transform.localPosition = centerPoint + (new Vector2(Mathf.Cos(direction), Mathf.Sin(direction)) * radius);
}
}
如果您将“跟随键盘”和“跟随鼠标”都设置为 true,则当您按住左键单击按钮时,对象应该朝向鼠标定位。在大多数情况下,这是有效的,但由于某种原因,即使我根本不移动鼠标,对象也会在两个不同位置之间快速变化一段时间,从而产生抖动。此外,即使我根本不移动鼠标,“方向”值也会以相同的速率自行切换。这种情况不会一直发生,但在看似随机的情况下确实经常发生。
我能做些什么来减轻或消除这种行为?
答案 0 :(得分:1)
因为方向也会抖动,所以你计算方向的方式有问题。
方向抖动的原因是 transform.InverseTransformPoint
。由于对象的位置发生了变化,鼠标相对于对象的位置也随着每一次移动而发生变化,因此方向也发生了变化。
这里有两种方法:
1:
Vector2 direction;
if ((followKeyboard && followMouse && Input.GetMouseButton(0)) || !followKeyboard)
{
Vector3 mouseOnScreen = Camera.main.ScreenToWorldPoint(Input.mousePosition) - new Vector3(centerPoint.x, centerPoint.y, 0);
direction = new Vector2(mouseOnScreen.x, mouseOnScreen.y);
}
transform.localPosition = centerPoint + (direction.normalized * radius);
这是一种不使用角度的简单方法。它获取鼠标在世界空间中屏幕上的位置。然后它使它成为一个向量 2 所以 z 值不会影响它。然后,它将新位置设置为中心加上鼠标的方向,半径为大小
2:
if ((followKeyboard && followMouse && Input.GetMouseButton(0)) || !followKeyboard)
{
Vector3 mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition) - new Vector3(centerPoint.x, centerPoint.y, 0);
direction = Mathf.Atan2(mousePosition.y, mousePosition.x);
}
transform.localPosition = centerPoint + (new Vector2(Mathf.Cos(direction), Mathf.Sin(direction)) * radius);
这和你做的方式一样,但稍微清理了一下。这种方式不使用 transform.InverseTransformPoint
,而是减去 centerPoint。这将向量从 centerPoint 返回到鼠标,将 centerPoint 设置为原点。这也是第一个解决方案。