Files
BABA_YAGA/Assets/Scripts/Player/Generic/Utils/vGroundPlaneCast.cs
2026-06-04 10:42:23 +07:00

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;
}
}