Files
LowPolyRPG/Assets/Plugins/RaycastPro/Core/Planers/Planar.cs
Caleb Sandford deQuincey 715fb68744 Initial commitment
2025-06-25 11:10:11 +01:00

211 lines
7.0 KiB
C#

namespace RaycastPro.Planers
{
using System;
using RaySensors;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
#if UNITY_EDITOR
using Editor;
using UnityEditor;
#endif
[Serializable]
public class RaySensorEvent : UnityEvent<RaySensor> { }
public abstract class Planar : BasePlanar
{
public RaySensor outerRay;
public override bool Performed { get; protected set; }
/// <summary>
///
/// </summary>
public RaySensorEvent onReceiveRay;
/// <summary>
///
/// </summary>
public RaySensorEvent onCloneRay;
/// <summary>
///
/// </summary>
public RaySensorEvent onBeginReceiveRay;
/// <summary>
///
/// </summary>
public RaySensorEvent onEndReceiveRay;
public abstract void GetForward(RaySensor raySensor, out Vector3 forward);
protected void ApplyLengthControl(RaySensor raySensor)
{
switch (lengthControl)
{
case LengthControl.Constant:
raySensor.cloneRaySensor.direction = raySensor.direction.normalized * length;
break;
case LengthControl.Sync:
raySensor.cloneRaySensor.direction = raySensor.direction * length;
break;
case LengthControl.Continues:
raySensor.cloneRaySensor.direction =
raySensor.direction.normalized * (raySensor.ContinuesDistance * length);
break;
}
}
/// <summary>
/// It will instantiate a ray Clone
/// </summary>
/// <param name="raySensor"></param>
private void CloneInstantiate(RaySensor raySensor)
{
if (!raySensor) return;
if (!InLayer(raySensor.gameObject) || raySensor.hit.transform != transform) return;
switch (outerType)
{
case OuterType.Auto:
if (raySensor is PathRay)
{
InstantiateClone(raySensor);
}
else
{
InstantiateReference(raySensor);
}
break;
case OuterType.Reference:
InstantiateReference(raySensor);
break;
case OuterType.Clone:
InstantiateClone(raySensor);
break;
}
OnReceiveRay(raySensor);
}
private void InstantiateReference(RaySensor raySensor)
{
// Double supported Clone Sensors
raySensor.cloneRaySensor = Instantiate(outerRay ? outerRay : raySensor, poolManager);
#if UNITY_EDITOR
RenameClone(raySensor.cloneRaySensor);
#endif
raySensor.cloneRaySensor.baseRaySensor = raySensor;
}
private GameObject _tObj;
protected CloneRay cloneRay;
private void InstantiateClone(RaySensor raySensor)
{
_tObj = new GameObject();
//Scene Debugging
SceneManager.MoveGameObjectToScene(_tObj, raySensor.gameObject.scene);
cloneRay = _tObj.AddComponent<CloneRay>();
cloneRay.transform.parent = poolManager;
#if UNITY_EDITOR
RenameClone(cloneRay);
#endif
cloneRay.CopyFrom(raySensor, this, (this is PortalPlanar planar) ? planar.outer : transform);
// Double supported Clone Sensors
cloneRay.baseRaySensor = raySensor;
raySensor.cloneRaySensor = cloneRay;
}
#if UNITY_EDITOR
private Collider validateCollideGizmo;
private void OnValidate()
{
if (transform.TryGetComponent(out Collider collider))
{
validateCollideGizmo = collider;
}
}
protected void DrawPlanar()
{
Gizmos.color = DefaultColor.Alpha(.5f);
if (validateCollideGizmo is MeshCollider _mc)
{
Gizmos.DrawWireMesh(_mc.sharedMesh, transform.position, transform.rotation, transform.lossyScale);
}
else if (validateCollideGizmo is SphereCollider _sc)
{
Gizmos.DrawSphere(_sc.center, _sc.radius);
}
else
{
Gizmos.matrix = transform.localToWorldMatrix;
Gizmos.DrawWireCube(Vector3.zero, Vector2.one);
}
}
internal override void OnGizmos()
{
var matrix = Gizmos.matrix;
Gizmos.DrawRay(transform.position, transform.forward * offset);
Gizmos.color = HelperColor;
Gizmos.matrix = transform.localToWorldMatrix;
Gizmos.DrawWireCube(Vector3.zero, Vector2.one);
Gizmos.matrix = matrix;
}
protected void GeneralField(SerializedObject _so, bool lengthControlField = true, bool outerField = true)
{
EditorGUILayout.PropertyField(_so.FindProperty(nameof(poolManager)), CPoolManager.ToContent(TPoolManager));
PlanarBaseField(_so);
DetectLayerField(_so);
BaseDirectionField(_so);
PropertyMaxField(_so.FindProperty(nameof(offset)), COffset.ToContent());
if (lengthControlField) LengthControlField(_so);
if (outerField) OuterField(_so.FindProperty(nameof(outerType)), _so.FindProperty(nameof(outerRay)));
BaseField(_so, hasInfluence: true, hasInteraction: false, hasUpdateMode: false);
}
protected void EventField(SerializedObject _so)
{
EventFoldout =
EditorGUILayout.BeginFoldoutHeaderGroup(EventFoldout, CEvents, RCProEditor.HeaderFoldout);
if (EventFoldout) RCProEditor.EventField(_so, new[] {nameof(onReceiveRay), nameof(onCloneRay), nameof(onBeginReceiveRay), nameof(onEndReceiveRay)});
}
#endif
internal abstract void OnReceiveRay(RaySensor sensor);
internal virtual void OnBeginReceiveRay(RaySensor sensor)
{
if (this is BlockPlanar) return;
CloneInstantiate(sensor);
sensor.cloneRaySensor?.transform.RemoveChildren();
OnCloneRay(sensor.cloneRaySensor);
}
/// <summary>
/// Call OnCloneRay Event
/// </summary>
/// <param name="sensor">Need Clone Ray Sensor</param>
internal void OnCloneRay(RaySensor sensor) => onCloneRay?.Invoke(sensor);
internal virtual bool OnEndReceiveRay(RaySensor sensor)
{
Destroy(sensor.cloneRaySensor.gameObject);
return true;
}
void CloneDestroy(RaySensor sensor)
{
if (sensor.cloneRaySensor)
{
CloneDestroy(sensor.cloneRaySensor);
}
Destroy(sensor.gameObject);
}
}
}