我尝试在点击光标位置时示例化我的 * ballPrefab *。我知道Input.mousePosition
只接受x和y坐标。但是,我的摄像头看的是x(全局)(as you can see here)的方向。所以我将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
,我无法应用变换。
最后,我读到了光线投射,但我并不真正理解它们。
1条答案
按热度按时间hpcdzsge1#
要理解这个问题,最好先了解
ScreenToWorldPoint
是如何工作的。闭上一只眼睛,直视前方,不要移动眼睛(就像一个2D相机)。然后伸出你的一只手臂,把你的食指放在你视野范围内的某个东西上(就像鼠标指针一样),但不要移动眼睛或直视它。ScreenToWorldPoint
函数的工作原理是记录手指在眼睛视图的X轴和Y轴上的位置,但它也需要知道你在Z轴(深度)上伸出手臂和手指有多远,才能让你的手指与你所指的东西对齐。问题是
Input.mousePosition
将返回Vector3,其中Z轴(深度)为0,也就是说你传给ScreenToWorldPoint
的时候,它基本上不知道你的胳膊和手指伸了多远,就像把你的手指直接放在你的眼球上,但是添加很少的X或Y,这样手指仍然指向你的物体。你会得到非常小的X和Y值,而Z值将在你的眼球(相机)所在的任何地方。另一个问题是,你手动将结果X值设置为0,所以X值将始终为0,Z值将始终位于相机的Z位置,Y值将非常小,这一切都是因为没有向
ScreenToWorldPoint
函数传递深度值,这将导致ballPrefab
在世界上的最终位置始终大致相同。所以试着给予它一个像这样的深度参考:
似乎您希望球始终位于世界的X轴上,因此另一种解决方案是使用摄影机X位置的绝对值(基本上是摄影机与X轴的距离)作为深度值。
这将允许您在无需调整任何
distanceFromCamera
变量的情况下移入和移出相机(在您的情况下是沿着X轴)。