一、工程截图
FOVPlane.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[DisallowMultipleComponent]
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class FOVPlane : MonoBehaviour
{
[SerializeField]
private Camera m_Camera;
private Vector3 m_CameraPosition;
private MeshFilter m_MeshFilter;
private Vector3[] m_Corners;
private Transform m_Transform;
private bool m_Flip;//画面上下翻转
void Awake()
{
if (m_Camera == null)
m_Camera = Camera.main;
if (m_Camera != null)
m_CameraPosition = m_Camera.transform.position;
m_MeshFilter = this.GetComponent<MeshFilter>();
m_Transform = transform;
}
void Start()
{
MeshRectangle();
m_Transform.position = Vector3.zero;
m_Transform.rotation = Quaternion.identity;
m_Transform.localScale = Vector3.one;
}
// 创建一个矩形
void MeshRectangle()
{
float distance = transform.position.z - m_CameraPosition.z;
m_Corners = GetCameraFovPositionByDistance(m_Camera, distance);
//矩形的四个顶点坐标
Vector3[] vertices = new Vector3[4];
vertices[0] = m_Corners[0];
vertices[1] = m_Corners[1];
vertices[2] = m_Corners[2];
vertices[3] = m_Corners[3];
//三角形顶点索引
int[] triangles = new int[6] { 0, 1, 2, 1, 3, 2 };
//每个顶点的法线
Vector3[] normals = new Vector3[4];
normals[0] = Vector3.back;
normals[1] = Vector3.back;
normals[2] = Vector3.back;
normals[3] = Vector3.back;
//UV贴图坐标
Vector2[] uvs = new Vector2[4];
if (m_Flip)
{
uvs[0] = new Vector2(0, 1);
uvs[1] = new Vector2(1, 1);
uvs[2] = new Vector2(0, 0);
uvs[3] = new Vector2(1, 0);
}
else
{
uvs[0] = new Vector2(0, 0);
uvs[1] = new Vector2(1, 0);
uvs[2] = new Vector2(0, 1);
uvs[3] = new Vector2(1, 1);
}
//顶点颜色
Color32[] colors32 = new Color32[4];
colors32[0] = Color.white;
colors32[1] = Color.white;
colors32[2] = Color.white;
colors32[3] = Color.white;
Mesh mesh = new Mesh();
mesh.hideFlags = HideFlags.DontSave;
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.colors32 = colors32;
mesh.uv = uvs;
mesh.normals = normals;
m_MeshFilter.mesh = mesh;
}
/// <summary>
/// 转载 https://www.cnblogs.com/shanksyi/p/5634060.html
/// 获取指定距离下相机视口四个角的坐标
/// </summary>
/// <param name="cam"></param>
/// <param name="distance">相对于相机的距离</param>
/// <returns></returns>
public Vector3[] GetCameraFovPositionByDistance(Camera cam, float distance)
{
Vector3[] corners = new Vector3[4];
float halfFOV = (cam.fieldOfView * 0.5f) * Mathf.Deg2Rad;
float aspect = cam.aspect;
float height = distance * Mathf.Tan(halfFOV);
float width = height * aspect;
Transform tx = cam.transform;
// 左上角
corners[0] = tx.position - (tx.right * width);
corners[0] += tx.up * height;
corners[0] += tx.forward * distance;
// 右上角
corners[1] = tx.position + (tx.right * width);
corners[1] += tx.up * height;
corners[1] += tx.forward * distance;
// 左下角
corners[2] = tx.position - (tx.right * width);
corners[2] -= tx.up * height;
corners[2] += tx.forward * distance;
// 右下角
corners[3] = tx.position + (tx.right * width);
corners[3] -= tx.up * height;
corners[3] += tx.forward * distance;
return corners;
}
void Update()
{
if (m_Corners == null)
return;
for (int i = 0; i < m_Corners.Length; i++)
{
Debug.DrawLine(m_CameraPosition, m_Corners[i], Color.red);
}
}
}
二、运行测试