Unity3D 小地图(3) 实时同步相机可视区域

在小地图上同步摄像机的可视区域

基本可以分为这两个步骤

1,相机的可视区,找到相机四个角相应的世界位置
        从相机的四个角,发出四条射线,射向地面。
        建立一个数组存储射线与地面相交的四个点.
2,将相机可视区域同步到小地图中
        可视区域相对地形的位置 = 世界坐标 - 地形位置
        可视区域相对地形的比例 =  相对地形的位置/地形的宽高
        同步到小地图的可视区域 = 小地图的宽高*可视区域相对地形的比例

3,将比例得到的可视区域显示在小地图上面

从相机的四个角,发出四条射线,射向地面。

Unity3D 小地图(3) 实时同步相机可视区域_第1张图片

 Camera.main.ViewportPointToRay(Vector3.zero);

从摄像机的视图坐标发射一条射线,分别以 zero,up,one,right 来表示屏幕坐标系的(0,0),(1,0),(1,1),(0,1).

    RaycastHit hitOut;
    public Vector3[] rayPoint;
    public Terrain myTerrain;
	// Use this for initialization
	void Start () {
        //数组初始化赋值
        rayPoint = new Vector3[4];
        for (int i = 0; i < 4; i++)
        {
            rayPoint[i] = Vector3.zero;
        }
    }

    // Update is called once per frame
    void Update()
    {
        //从屏幕视图坐标向地面发射射线
        Ray zeroRay = Camera.main.ViewportPointToRay(Vector3.zero);
       
        Ray zeroToOneRay = Camera.main.ViewportPointToRay(Vector3.right);
        Ray oneToZeroRay = Camera.main.ViewportPointToRay(Vector3.up);
        Ray oneRay = Camera.main.ViewportPointToRay(Vector3.one);

        if (Physics.Raycast(zeroRay, out hitOut, 1000))
        {
            rayPoint[0] = hitOut.point;
        }

        if (Physics.Raycast(oneToZeroRay, out hitOut, 1000))
        {
            rayPoint[1] = hitOut.point;
        }

        if (Physics.Raycast(oneRay, out hitOut, 1000))
        {
            rayPoint[2] = hitOut.point;
        }

        if (Physics.Raycast(zeroToOneRay, out hitOut, 1000))
        {
            rayPoint[3] = hitOut.point;
        }
    }

发射射线的效果如图所示 

Unity3D 小地图(3) 实时同步相机可视区域_第2张图片

获取数组Point点再地图上的位置比例
        可视区域相对地形的位置 = 世界坐标 - 地形位置

        可视区域相对地形的比例 =  相对地形的位置/地形的宽高

    /// 获取第几个Point在地图上的比例
    /// 
    /// 
    /// 
    public Vector2 GetRate(int index)
    {
        //没有意义,给Result一个初始化值
        Vector2 result = Vector2.zero;
        //防止越界
        index = index % rayPoint.Length;
       // Debug.Log(index);
        //Point相对于地形的位置
        Vector3 localToTerrain = rayPoint[index] - myTerrain.transform.position;
        //获取点在地形上的位置的比例
        result.x = localToTerrain.x / myTerrain.terrainData.size.x;
        result.y = localToTerrain.z / myTerrain.terrainData.size.z;

        return result;
    }

按Point点在地形上的比例激素那Point点在小地图上的位置

  同步到小地图的可视区域 = 小地图的宽高*可视区域相对地形的比例

 /// 
/// 
    /// 计算同步到小地图的位置
    /// 
    /// 
    /// 
    public Vector2 CaculatePos(int index)
    {
        Vector2 result = Vector2.zero;
        Vector2 tmpRate = cameraView.GetRate(index);

        result.x = rectTrans.sizeDelta.x * tmpRate.x;
        result.y = rectTrans.sizeDelta.y * tmpRate.y;
        return result;
    }

在屏幕中画线,显示在小地图上方

 static void CreateLineMaterial()
    {
        if (!lineMaterial)
        {
            // Unity has a built-in shader that is useful for drawing
            // simple colored things.
            Shader shader = Shader.Find("Hidden/Internal-Colored");
            lineMaterial = new Material(shader);
            lineMaterial.hideFlags = HideFlags.HideAndDontSave;
            // Turn on alpha blending
            lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
            lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
            // Turn backface culling off
            lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
            // Turn off depth writes
            lineMaterial.SetInt("_ZWrite", 0);
        }
    }

    // Will be called after all regular rendering is done
    public void OnRenderObject()
    {
        CreateLineMaterial();
        // Apply the line material
        lineMaterial.SetPass(0);
        GL.PushMatrix();
        GL.MultMatrix(transform.localToWorldMatrix);
        // Draw lines
        GL.Begin(GL.LINES);
        GL.Color(Color.red);
        for (int i = 1; i < 5; i++)
        {
            Vector2 tmpFront = CaculatePos(i - 1);
            Vector2 tmpBack = CaculatePos(i);
            GL.Vertex3(tmpFront.x, tmpFront.y,0);
            GL.Vertex3(tmpBack.x, tmpBack.y, 0);
        }
        
        GL.End();
        GL.PopMatrix();
    }


你可能感兴趣的:(Unity3D 小地图(3) 实时同步相机可视区域)