78 lines
3.1 KiB
C#
78 lines
3.1 KiB
C#
using UnityEngine;
|
|
|
|
public struct vGroundPlaneCast
|
|
{
|
|
public Vector3 p1, p2, p3, p4;
|
|
public Vector3 planeNormal;
|
|
public Vector3 planeCenter;
|
|
public Vector3 centerNormal;
|
|
|
|
public float planeDistance;
|
|
public bool hasFloor;
|
|
public readonly int planeAngle
|
|
{
|
|
get
|
|
{
|
|
return (int)Vector3.Angle(Vector3.up, planeNormal);
|
|
}
|
|
}
|
|
RaycastHit hit;
|
|
|
|
public void CalculatePlane(Transform transform, Vector3 position, Vector3 down, float distance, LayerMask mask, float plane = 0.5f)
|
|
{
|
|
Vector3 basePosition = transform.position;
|
|
float size = plane * 0.5f;
|
|
planeNormal = -down;
|
|
/// p1 --- p2
|
|
/// | |
|
|
/// | |
|
|
/// p4 --- p3
|
|
p1 = position + transform.forward * size - transform.right * size;
|
|
p2 = position + transform.forward * size + transform.right * size;
|
|
p3 = position - transform.forward * size + transform.right * size;
|
|
p4 = position - transform.forward * size - transform.right * size;
|
|
//Debug.DrawRay(p1, Vector3.down * distance);
|
|
//Debug.DrawRay(p2, Vector3.down * distance);
|
|
//Debug.DrawRay(p3, Vector3.down * distance);
|
|
//Debug.DrawRay(p4, Vector3.down * distance);
|
|
|
|
bool _hasFloor1 = false;
|
|
bool _hasFloor2 = false;
|
|
bool _hasFloor3 = false;
|
|
bool _hasFloor4 = false;
|
|
if (Physics.Raycast(position, down, out hit, distance, mask))
|
|
{
|
|
centerNormal = hit.normal;
|
|
planeCenter = hit.point;
|
|
}
|
|
else planeCenter = transform.position + Vector3.down * distance;
|
|
if (Physics.Raycast(p1, down, out hit, distance, mask)) { p1 = hit.point; _hasFloor1 = true; }
|
|
else p1 = basePosition + Vector3.forward * size + Vector3.left * size;
|
|
if (Physics.Raycast(p2, down, out hit, distance, mask)) { p2 = hit.point; _hasFloor2 = true; }
|
|
else p2 = basePosition + Vector3.forward * size + Vector3.right * size;
|
|
if (Physics.Raycast(p3, down, out hit, distance, mask)) { p3 = hit.point; _hasFloor3 = true; }
|
|
else p3 = basePosition + Vector3.back * size + Vector3.right * size;
|
|
if (Physics.Raycast(p4, down, out hit, distance, mask)) { p4 = hit.point; _hasFloor4 = true; }
|
|
else p4 = basePosition + Vector3.back * size + Vector3.left * size;
|
|
var _planeCenter = (p1 + p2 + p3 + p4) / 4;
|
|
//if (_planeCenter.y > hit.point.y)
|
|
//{
|
|
planeCenter = _planeCenter;
|
|
//}
|
|
planeNormal = (-GetNormal(p1, p2, p3)) + (-GetNormal(p2, p1, p3)) + (-GetNormal(p3, p2, p4)) + (-GetNormal(p4, p3, p1));
|
|
|
|
planeDistance = (position - planeCenter).magnitude;
|
|
hasFloor = (_hasFloor1 || _hasFloor2 || _hasFloor3 || _hasFloor4);
|
|
|
|
}
|
|
|
|
readonly Vector3 GetNormal(Vector3 a, Vector3 b, Vector3 c)
|
|
{
|
|
// Find vectors corresponding to two of the sides of the triangle.
|
|
Vector3 side1 = b - a;
|
|
Vector3 side2 = c - a;
|
|
|
|
// Cross the vectors to get a perpendicular vector, then normalize it.
|
|
return Vector3.Cross(side1, side2).normalized;
|
|
}
|
|
} |