如何在 C# 中的鼠标位置实例化 Unity 预制件?



我试图实例化我的ballPrefab点击光标的位置。我知道Input.mousePosition只取x和y坐标。然而,我的相机看起来在x(全局)的方向(正如你在这里看到的)。所以我把x变成0。问题在于,无论我在哪里左键点击,预制件每次都会在相同的y和z位置生成。

这是我的代码。

[SerializeField]
private GameObject ballPrefab;
void Update()
{
Vector3 mousePos = Input.mousePosition;
mousePos = Camera.main.ScreenToWorldPoint(mousePos);
mousePos.x = 0;
if (Input.GetButtonDown("Fire1"))
{
Instantiate(ballPrefab, mousePos, ballPrefab.transform.rotation);
}
}

我在网上搜了一个小时。

我遇到的是Cursor.Position,它似乎是旧的(?),因为System.Windows.Forms不存在。

我还尝试使鼠标位置为new Point,但随后我无法将其转换为Vector3。

我也想到了transform.localPosition,因为我的相机正对着"错误"。如果我使用Input.mousePosition,我就不能应用变换了。

最后,我读了关于光线投射的书,但我真的不理解它们。

要理解这个问题,最好了解ScreenToWorldPoint是如何工作的。闭上你的一只眼睛,直视前方,不要移动你的眼睛(就像一个2D相机)。然后伸出你的一只手臂,把你的食指放在你视线范围内的东西上(比如鼠标指针),但不要移动你的眼睛或直视它。ScreenToWorldPoint功能通过记录手指在视线的X轴和Y轴上的位置来工作,但它也需要知道你的手臂和手指在Z轴上伸出了多远(深度),以使你的手指与你所指向的东西对齐。就像从你的眼睛到你的手指画一条线。

问题是Input.mousePosition将返回Z轴(深度)为0的Vector3。这意味着当你将它传递给ScreenToWorldPoint时,它基本上不知道你将手臂和手指伸出了多远。这就像把你的手指直接放在你的眼球上,但增加了很少的X或Y,所以手指仍然指向你的物体。你将获得非常小的X和Y值,而Z值将出现在你的眼球(摄像机)所在的位置。

另一个问题是您手动将结果X值设置为0。所以X将始终为0,Z将始终位于相机的Z位置,Y值将非常小,这都是因为没有将深度值传递给ScreenToWorldPoint函数。这将导致ballPrefab总是在世界中大致相同的位置结束。

所以试着给它一个深度参考,像这样:

public float distanceFromCamera = 5f;
public GameObject ballPrefab;
void Update()
{      
if (Input.GetButtonDown("Fire1"))
{
Vector3 mousePos = Input.mousePosition;
mousePos = Camera.main.ScreenToWorldPoint(
new Vector3(mousePos.x, mousePos.y, distanceFromCamera));
Instantiate(ballPrefab, mousePos, ballPrefab.transform.rotation);
}     
}

似乎你希望球总是在世界的X轴上,所以另一个解决方案是使用相机的X位置的绝对值(即相机从X = 0的距离)作为深度值。

mousePos = Camera.main.ScreenToWorldPoint(
new Vector3(mousePos.x, mousePos.y,
Mathf.Abs(Camera.main.transform.position.x)));

这将允许您移动您的相机内外(在您的情况下沿X轴),而无需调整任何distanceFromCamera变量。

最新更新