如何从渲染纹理中获取3D世界空间位置

Muh*_*han 8 c# camera unity-game-engine

我正在使用 渲染纹理制作侧面贴图,它工作正常,我通过这些步骤完成了它.

  1. 一个主摄像机渲染场景.
  2. NGUI相机渲染GUI.
  3. 该GUI包含渲染纹理(minimap),使用GUI Camera渲染纹理上的场景.

现在我想进一步改进地图并希望它变得棘手.我想从渲染纹理点击点看世界空间位置.有没有什么方法可以从渲染纹理的特定点击点获得世界空间位置?

如果我单击渲染纹理中的某个位置,那么如何在3D世界空间中获得该点.

例如:我在渲染纹理上单击了一个汽车对象.现在,我如何在3D世界空间中突出显示或获取它.如何将2D渲染纹理点击位置转换为世界空间位置!

yes*_*yes 4

这假设了一些事情。

首先,我使用 EventSystems 来获得鼠标点击。这不是必需的,它可以轻松更改(尽管由您^^)。要正确设置它,您EventSystem的场景中需要一个(如果您有 UI,您可能已经有一个)。

其次,您需要将一个PhysicsRaycaster组件连接到主摄像头(玩家可以看到的摄像头)。

最后,在包含渲染纹理渲染器的游戏对象(我使用了一个简单的四边形)上,您应用以下脚本并分配相应的相机。

using UnityEngine;
using UnityEngine.EventSystems;

//i chose box collider because its cheap
[RequireComponent(typeof(BoxCollider))]
public class RenderTextureRaycaster : MonoBehaviour, IPointerDownHandler {

    //assign in inspector
    public Camera portalExit;

    BoxCollider portal;
    Vector3 portalExitSize;

    void Start() {
        portal = GetComponent<BoxCollider>();
        //this is the target camera resolution, idk if there is another way to get it.
        portalExitSize = new Vector3(portalExit.targetTexture.width, portalExit.targetTexture.height, 0);
    }

    public void OnPointerDown(PointerEventData eventData) {
        //the click in world space
        Vector3 worldClick = eventData.pointerCurrentRaycast.worldPosition;
        //transformed into local space
        Vector3 localClick = transform.InverseTransformPoint(worldClick);
        //since the origin of the collider is in its center, we need to offset it by half its size to get it realtive to bottom left
        Vector3 textureClick = localClick + portal.size / 2;
        //now we scale it up by the actual texture size which equals to the "camera resoution"
        Vector3 rayOriginInCameraSpace = Vector3.Scale(textureClick, portalExitSize);

        //with this knowledge we can creata a ray.
        Ray portaledRay = portalExit.ScreenPointToRay(rayOriginInCameraSpace );
        RaycastHit raycastHit;

        //and cast it.
        if (Physics.Raycast(portaledRay, out raycastHit)) {
            Debug.DrawLine(portaledRay.origin, raycastHit.point, Color.blue, 4);
        }
        else {
            Debug.DrawRay(portaledRay.origin, portaledRay.direction * 100, Color.red, 4);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:上面可能有点冗长,如果您喜欢一个衬垫,您可以轻松减少它,它只是为了展示它是如何工作的。另外,请仅将此视为概念证明,其尚未经过彻底测试

  • 好吧,抱歉,我对 NGUI 毫无头绪。你为什么不使用 unity ui,因为 4.6(我认为)它非常棒。但它基本上应该遵循相同的逻辑。一旦您知道自己在纹理中相对于其左下点的位置,您就可以得出相机屏幕上的位置。渲染纹理的相机与其渲染到的渲染纹理具有相同的结果。 (2认同)