0
点赞
收藏
分享

微信扫一扫

20220329-代码日记-小地图区域显示

香小蕉 2022-03-30 阅读 67
c#unity

今日学习: 小地图区域显示

前几天学习了小地图,画符,今天又是小地图。不过这次的小地图跟上次不一样,是在小地图上显示摄像机照到地形的范围。

回顾一下,在上一个小地图中,用到了比例,在画符中,用到了GL,这次的这个小地图,结合了比例和GL,把摄像机照到的范围大小,映射到了摄像机上。

在场景中:
在这里插入图片描述
位置随意,将Image的轴心点改成(0,0)。

创建两个脚本:
CameraView(挂到MainCamera上)和MapView(挂到Image上)。

直接上代码:
以下是完整代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraView : MonoBehaviour
{
    public Vector3[] rayPoints;
    public Terrain terrain;
    private void Start()
    {
        rayPoints = new Vector3[4];
        for (int i = 0; i < 4; i++)
        {
            rayPoints[i] = Vector3.zero;
        }
    }
    private void Update()
    {
        Ray tmpZeroRay = Camera.main.ViewportPointToRay(Vector3.zero);
        //在Scene面板上画出射线轨迹
        Debug.DrawRay(tmpZeroRay.origin, tmpZeroRay.direction, Color.red);
        Ray oneToZeroRay = Camera.main.ViewportPointToRay(Vector3.right);
        Debug.DrawRay(oneToZeroRay.origin, oneToZeroRay.direction, Color.blue);
        Ray oneToOneRay = Camera.main.ViewportPointToRay(Vector3.one);
        Debug.DrawRay(oneToOneRay.origin, oneToOneRay.direction, Color.green);
        Ray zeroToOneRay = Camera.main.ViewportPointToRay(Vector3.up);
        Debug.DrawRay(zeroToOneRay.origin, zeroToOneRay.direction, Color.yellow);

        RaycastHit hitOut;
        if(Physics.Raycast(tmpZeroRay ,out hitOut, 1000))
        {
            //射向的点的世界坐标
            rayPoints[0] = hitOut.point;
        }
        if (Physics.Raycast(oneToZeroRay, out hitOut, 1000))
        {
            //射向的点的世界坐标
            rayPoints[1] = hitOut.point;
        }
        if (Physics.Raycast(oneToOneRay, out hitOut, 1000))
        {
            //射向的点的世界坐标
            rayPoints[2] = hitOut.point;
        }
        if (Physics.Raycast(zeroToOneRay, out hitOut, 1000))
        {
            //射向的点的世界坐标
            rayPoints[3] = hitOut.point;
        }
    }

    public Vector2 GetRate(int index)
    {
        Vector2 result = Vector2.zero;
        //防止越界
        index = index % rayPoints.Length;
        Vector3 localToTerrain = rayPoints[index] - terrain.transform.position;
        result.x = localToTerrain.x / terrain.terrainData.size.x;
        result.y = localToTerrain.z / terrain.terrainData.size.z;
        
        return result;
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MapView : MonoBehaviour
{
    CameraView cameraView;
    RectTransform rectTransform;
    private void Start()
    {
        cameraView = Camera.main.GetComponent<CameraView>();
        rectTransform = transform.GetComponent<RectTransform>();
    }

    /// <summary>
    /// 计算位置
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    public Vector2 CaculatePos(int index)
    {
        Vector2 result = Vector2.zero;
        Vector2 tmpRate = cameraView.GetRate(index);
        result.x = rectTransform.sizeDelta.x * tmpRate.x;
        result.y = rectTransform.sizeDelta.y * tmpRate.y;
        return result;
    }


    static Material lineMaterial;
    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();
        lineMaterial.SetPass(0);

        GL.PushMatrix();
        GL.MultMatrix(transform.localToWorldMatrix);

        //GL.LoadOrtho();
        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();
    }
}

如果想在运行过程中操纵摄像机的移动,可以再写一个摄像机移动的脚本挂载到摄像机上。


今日,懒,不想动

举报

相关推荐

0 条评论