相机角度与物体向量相交

3
我正在尝试确定相机前向矢量与物体矢量相交的角度。抱歉,根据我的知识,这不是很容易解释,请参考附图:相机可能没有直接对准物体(OBJ),我想知道相机前向矢量(红色V1)与物体矢量(红色V2)相交的角度(图中的“?”),例如A点、B点、C点等,具体取决于相机的x旋转角度。

diagram

我尝试计算红线的归一化向量v1和v2。然后计算两个向量之间的角度https://onlinemschool.com/math/library/vector/angl/,但在测试时结果与预期值不符。
//v1
Vector3 hypoth = Camera.main.transform.forward.normalized;
//v2
Vector3 adjacent = (new Vector3(obj.transform.position.x, obj.transform.position.y, Camera.main.transform.position.z) 
                        -obj.transform.position).normalized;

float dotProd = Vector3.Dot(adjacent, hypoth);
float cosOfAngle = dotProd / (Vector3.Magnitude(adjacent) * Vector3.Magnitude(hypoth));
double radAngle = Math.Acos(cosOfAngle);
float angle = (float)((180 / Math.PI) * radAngle);

1
除非你执行 (obj.transform.position - new Vector3(obj.transform.position.x, obj.transform.position.y, Camera.main.transform.position.z)).normalized;,否则 adjacent 点不会 远离 obj - Ruzihm
1
如果您解释一下为什么需要角度,可能会有所帮助 - 是否需要有符号的角度?如果是这样,负角度表示什么?根据您对角度的意图,您甚至可能根本不需要计算角度。 - Ruzihm
1
如果您已经知道一个90度的角度,那么您能不能简单地使用180f - 90f - Vector3.Angle(camera.forward, (obj.position - camera.position).normalized) 来计算呢? - derHugo
1
嗨@ruzihm,抱歉回复晚了,我出门旅行了,没法测试。你提出的解决方案可行,但我的物体高度不同,因此我的图表不准确,导致不一致。最终,我对相机前面的物体进行了射线投射,作为足够好的解决方案-这些物体足够大。非常感谢你的帮助 :) - Sergio Solorzano
2个回答

3

找到v1v2之间的夹角,这个角度与你在图表中标记的不一样:

what your code is calculating

相反,解出向量v1与垂直于向量v2的平面之间的夹角:

diagram explaining why this works

我们可以在Unity中使用Vector3.ProjectOnPlane将v1投影到垂直于v2的平面上,然后使用Vector3.Angle找到该投影与v1之间的角度:
Vector3 projection = Vector3.ProjectOnPlane(hypoth, adjacent); 
float angle = Vector3.Angle(projection, hypoth);

0

我有一个类似的情况,我想把地形单位的碰撞器设置在玩家喷气机的同一高度,并且必须在相机的视线上,否则当你射击地形单位时,子弹会看起来像是穿过地面上的敌人单位移动,这只适用于透视相机,对于正交相机,您可能根本不需要这样做,只需将对象设置在与相机相同的高度即可对齐所有内容。

这是我的代码

 void SetColliderLocation()
{
    // Object on the ground
    A = TerrainUnit.transform.position;
    // Camera location
    B = cam.transform.position;
    // Enemy jet height 
    height = mainPlayerTransform.position.y;
    // Unit Vector normalized between A and B
    AB_Normalized = (A - B).normalized;
    // The unit vector required to move the collider to maintain its hieght and line of sight with the camera
    unitVector = (height - A.y) / AB_Normalized.y;
    // Setting the location of the collidar .
    collidarGameObject.transform.position = (AB_Normalized * unitVector) + A;
}

我希望这与您所寻找的内容有些相似。

编辑:

如果您应用了此脚本,而不是碰撞器,您将看到盒子位置始终位于天空中的相机和地面上的物体之间,无论相机或地面上的物体是否移动。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接