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

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;
}
}发射射线的效果如图所示

可视区域相对地形的位置 = 世界坐标 - 地形位置
可视区域相对地形的比例 = 相对地形的位置/地形的宽高
/// 获取第几个Point在地图上的比例
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
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点在小地图上的位置
同步到小地图的可视区域 = 小地图的宽高*可视区域相对地形的比例
/// <summary>
/// <summary>
/// 计算同步到小地图的位置
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
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中实现小地图上实时同步相机可视区域。通过从相机四个角发出射线并计算与地形的交点,获取可视区域的比例,然后根据比例确定小地图上对应的位置,最终在小地图上绘制可视区域。


3281

被折叠的 条评论
为什么被折叠?



