[Unity]摄像机盒子:CamraBox

2020/03 23 23:03
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraCalc : MonoBehaviour
{
    static private Plane XZPlane = new Plane( Vector3.up, Vector3.zero );

    public Transform TargetObject;

    void OnDrawGizmos()
    {

        var camera = GetComponent<Camera>();

        var viewRect = new Rect(0.0f, 0.0f, 1.0f, 1.0f);

        Vector3[] frustumCorners = new Vector3[4];
        camera.CalculateFrustumCorners(viewRect, camera.farClipPlane, Camera.MonoOrStereoscopicEye.Mono, frustumCorners);
        for (int i = 0; i < 4; i++)
        {
            var p = camera.transform.TransformVector(frustumCorners[i]);            
            Ray ray = new Ray( camera.transform.position, (p- camera.transform.position).normalized );
            float f;
            if (XZPlane.Raycast(ray, out f))
            {
                frustumCorners[i] = ray.GetPoint(f);
            }
        }

        if (TargetObject == null)
        {
            return;
        }

        Vector2[] p2d = new Vector2[4];
        for(int i=0; i<4; ++i)
        {
            p2d[i] = new Vector2( frustumCorners[i].x, frustumCorners[i].z);
        }

        var checkPoint3 = TargetObject.transform.position;
        Vector2 checkPoint = new Vector2(checkPoint3.x, checkPoint3.z);

        Vector2[] c2cd= new Vector2[4];

        bool cross0 = getCross(p2d[0], p2d[1], checkPoint, checkPoint + new Vector2(1024, checkPoint.y),  out c2cd[0]);
        if (cross0)
        {
            Gizmos.DrawSphere( new Vector3(c2cd[0].x, 0, c2cd[0].y), 1);
        }

        bool cross1 = getCross(p2d[2], p2d[3], checkPoint, checkPoint - new Vector2(1024, checkPoint.y),  out c2cd[2]);
        if (cross1)
        {
            Gizmos.DrawSphere( new Vector3(c2cd[2].x, 0, c2cd[2].y), 1);
        }

        bool cross2 = getCross(p2d[1], p2d[2], checkPoint, checkPoint - new Vector2(checkPoint.x, 1024),  out c2cd[1]);
        if (cross2)
        {
            Gizmos.DrawSphere( new Vector3(c2cd[1].x, 0, c2cd[1].y), 1);
        }

        bool cross3 = getCross(p2d[3], p2d[0], checkPoint, checkPoint + new Vector2(checkPoint.x, 1024),  out c2cd[3]);
        if (cross3)
        {
            Gizmos.DrawSphere( new Vector3(c2cd[3].x, 0, c2cd[3].y), 1);
        }

        Gizmos.color = Color.yellow;
        Gizmos.DrawLine(frustumCorners[0], frustumCorners[1]);
        Gizmos.DrawLine(frustumCorners[1], frustumCorners[2]);
        Gizmos.DrawLine(frustumCorners[2], frustumCorners[3]);
        Gizmos.DrawLine(frustumCorners[3], frustumCorners[0]);
    }

    public static bool linecut(Vector2 a, Vector2 b, Vector2 c, Vector2 d, out float output) 
    {
        Vector2 cd = d - c;
        Vector2 n = new Vector2(cd.y, -cd.x);
        float div = Vector2.Dot(b - a, n);
        if (Mathf.Approximately(div, 0.0f))
        {
            output = 0;
            return false;
        }
        output = Vector2.Dot(c - a, n) / div;
        return true;
    }

    public static bool getCross(Vector2 a, Vector2 b, Vector2 c, Vector2 d, out Vector2 cross) 
    {
        float t1, t2;
        if (linecut(a, b, c, d, out t1) && linecut(c, d, a, b, out t2))
        {
            cross = (b - a) * t1 + a;
            return t1 >= 0f && t1 <= 1f && t2 >= 0f && t2 <= 1f;
        }
        cross = Vector2.zero;
        return false;
    }


}