首页 > 解决方案 > 通过移动其 X 和 Z 位置,使沿 Y 轴移动的对象在某个点上保持静止

问题描述

我需要相机在 Y 轴上移动后在初始位置看到一个物体。我用一些图片来更好地解释自己。这是对象的初始位置。主摄像头不会改变位置。在坐标 (0, 0, 0) 处,我使用另一个相机作为背景图像。从同一点开始,我绘制 Gizmo 线。

在此处输入图像描述

现在通过我的编辑器,我将 Y 轴上的平面从 0 移动到 -2。我的对象的 Y 与平面的 Y 相关联,因此它也下降了 2 个单位。

在此处输入图像描述

现在是我想要自动化的部分。我想沿 X 轴和 Z 轴移动对象,以便它的脚出现在相机上,就好像它们处于相同的初始位置一样。通过在 X 轴和 Z 轴上的场景视图中手动移动它,我将脚放在一个看起来与以前相同的位置,当然它更小,因为它离相机更远。

在此处输入图像描述

如何通过代码计算要分配给我的对象在 Y 轴上给定点的位置的 X 和 Z 坐标,以便一个点保持在屏幕空间中的相同位置?

标签: c#unity3d

解决方案


您可以使用射线和平面来计算这一点。

在对象移动之前,创建一个Ray从相机到您需要保持在同一位置的对象上的点:

// Where the "feet" are relative to the object's origin
public Vector3 cameraKeepOffset = new Vector3(0f,-1f,0f); 

public Ray perspectiveRay;

...

Vector3 positionToKeep = transform.position + cameraKeepOffset;
Vector3 cameraPosition = Camera.main.transform.position;

perspectiveRay = new Ray(cameraPosition, positionToKeep - cameraPosition);

这个想法是,每当物体移动时,找到可以沿着该射线放置的位置。如果我们在 y 位置放置一个水平平面,那么射线与该平面相交的地方就是应该放置对象的位置。

因此,当对象移动时,创建Plane偏移量所在的位置,找到perspectiveRay与它相交的位置,然后移动对象以使其偏移量位于该点:

Plane yPlane = new Plane(Vector3.up, cameraKeepOffset + transform.position);
float distanceFromCam;
if ( !Raycast(perspectiveRay, out distanceFromCam)) {
    Debug.log("Camera is not pointing at plane");

    // Handle bugs here, return if necessary, etc.
} else {
    Vector3 intersectionPoint = Ray.GetPoint(distanceFromCam);
    transform.position = intersectionPoint - cameraKeepOffset;
}

推荐阅读