changed: more detail to observers. gizmos fixed and editor layout cleaned up
This commit is contained in:
@@ -5,12 +5,12 @@ using Drawing;
|
||||
using Sirenix.OdinInspector;
|
||||
using Sirenix.Serialization;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
[Serializable]
|
||||
public class EnvironmentObserver{
|
||||
// TODO: Clean this ugly shit up. Custom inspector with Odin plz.
|
||||
public string label;
|
||||
public bool drawLabel;
|
||||
|
||||
enum LabelDrawingLocation{
|
||||
PlayerOffset,
|
||||
@@ -18,66 +18,96 @@ public class EnvironmentObserver{
|
||||
IntersectingLength,
|
||||
}
|
||||
|
||||
enum CastType{
|
||||
public enum CastType{
|
||||
Ray,
|
||||
Box,
|
||||
Sphere,
|
||||
BoxOverlap,
|
||||
SphereOverlap,
|
||||
BoxCast,
|
||||
SphereCast
|
||||
}
|
||||
|
||||
// [BoxGroup("Settings")]
|
||||
[ShowInInspector, SerializeField] public CastType castType;
|
||||
|
||||
[Button(ButtonSizes.Large), GUIColor("@GetObserverStatusColorStatic(active, hit)")]
|
||||
public void Active(){
|
||||
active = !active;
|
||||
}
|
||||
|
||||
[ShowInInspector, SerializeField]
|
||||
CastType castType;
|
||||
[HideInInspector]
|
||||
public bool active;
|
||||
|
||||
// Parameters for Cast cast types
|
||||
[BoxGroup("Settings")]
|
||||
public float length;
|
||||
[BoxGroup("Settings")]
|
||||
public Vector3 direction;
|
||||
[BoxGroup("Settings")]
|
||||
public Vector3 offset;
|
||||
|
||||
[ShowIfGroup("Settings/Casts3D", VisibleIf = "@castType == CastType.Ray || castType == CastType.BoxCast || castType == CastType.SphereCast")]
|
||||
[BoxGroup("Settings/Casts3D")]
|
||||
public float width;
|
||||
|
||||
|
||||
// Parameters for Overlap cast types
|
||||
[BoxGroup("Settings/Overlaps")]
|
||||
public Vector3 size;
|
||||
|
||||
[PropertyTooltip(
|
||||
"Only use rotation when an observers direction alone can't (for whatever reason) fully be expressed without specifying a rotation.")]
|
||||
[ShowIfGroup("Settings/Casts3D")]
|
||||
[BoxGroup("Settings/Casts3D")]
|
||||
public Vector3 rotation;
|
||||
|
||||
[BoxGroup("Settings")]
|
||||
public LayerMask ignoreLayers = ~0;
|
||||
|
||||
public RaycastHit hit;
|
||||
|
||||
[SerializeReference]
|
||||
public List<EnvironmentObserver> children;
|
||||
|
||||
[HideInInspector]
|
||||
public Collider[] overlapHits;
|
||||
|
||||
public bool drawLabel;
|
||||
public Vector3 labelLocationOffset;
|
||||
public Vector3 labelRotationOffset;
|
||||
|
||||
|
||||
[ShowInInspector, SerializeField]
|
||||
LabelDrawingLocation labelLocation;
|
||||
|
||||
public bool active;
|
||||
|
||||
// Parameters
|
||||
public float length;
|
||||
public float width;
|
||||
|
||||
public Vector3 size;
|
||||
public Vector3 rotation;
|
||||
|
||||
public Vector3 start;
|
||||
public Vector3 direction;
|
||||
|
||||
public bool useLayerMask;
|
||||
public LayerMask ignoreMask;
|
||||
|
||||
public RaycastHit hit;
|
||||
private Collider[] overlapHits;
|
||||
|
||||
// NOTE: I had a ref for a RaycastHit here that would correspond to hit but idk if it's needed.
|
||||
public bool Evaluate(GameObject player){
|
||||
if (active) {
|
||||
ignoreMask -= player.layer;
|
||||
|
||||
Vector3 relativeStart = player.transform.position + start;
|
||||
Vector3 startOffsetFromRotation = player.transform.position + player.transform.rotation * (start) ;
|
||||
float halfExtents = width / 2f;
|
||||
|
||||
// NOTE: I had a ref for a RaycastHit here that would correspond to hit but idk if it's needed.
|
||||
// Remove player's layer from LayerMask.
|
||||
ignoreLayers -= player.layer;
|
||||
|
||||
// Set some of the variables used later during casting
|
||||
Vector3 relativeStart = player.transform.position + offset;
|
||||
Vector3 relativeStartWithRotation = player.transform.position + player.transform.rotation * (offset) ;
|
||||
|
||||
switch (castType) {
|
||||
case CastType.Ray:
|
||||
Physics.Raycast(relativeStart, player.transform.rotation * direction, out hit, length, ignoreMask);
|
||||
Physics.Raycast(relativeStart, player.transform.rotation * direction, out hit, length, ignoreLayers);
|
||||
break;
|
||||
case CastType.Box:
|
||||
if (Physics.OverlapBox(startOffsetFromRotation, size / 2f, player.transform.rotation * Quaternion.Euler(rotation), ignoreMask).Length > 0) {
|
||||
case CastType.BoxOverlap:
|
||||
overlapHits = Physics.OverlapBox(relativeStartWithRotation, size / 2f,
|
||||
player.transform.rotation * Quaternion.Euler(rotation), ignoreLayers);
|
||||
|
||||
if (overlapHits.Length > 0) {
|
||||
return true;
|
||||
};
|
||||
|
||||
break;
|
||||
case CastType.Sphere:
|
||||
case CastType.SphereOverlap:
|
||||
break;
|
||||
case CastType.BoxCast:
|
||||
// TODO: Make this not an if statement. Check that it works with NodeCanvas first
|
||||
if (Physics.BoxCast(relativeStartWithRotation, Vector3.one * (width / 2f), (player.transform.rotation * Quaternion.Euler(rotation) * direction),
|
||||
out hit, Quaternion.LookRotation(direction) * Quaternion.Euler(rotation), length, ignoreLayers)
|
||||
);
|
||||
break;
|
||||
case CastType.SphereCast:
|
||||
break;
|
||||
@@ -87,13 +117,12 @@ public class EnvironmentObserver{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
hit = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void DrawObserverGizmo(GameObject player){
|
||||
Vector3 relativeStart = player.transform.position + start;
|
||||
Vector3 startOffsetFromRotation = player.transform.position + player.transform.rotation * (start) ;
|
||||
Vector3 relativeStart = player.transform.position + offset;
|
||||
Vector3 relativeStartWithRotation = player.transform.position + player.transform.rotation * (offset) ;
|
||||
|
||||
Color gizmoColor = Evaluate(player) ? Color.green : Color.red;
|
||||
gizmoColor = active ? gizmoColor : Color.gray;
|
||||
@@ -120,12 +149,22 @@ public class EnvironmentObserver{
|
||||
case CastType.Ray:
|
||||
Draw.ingame.Line(relativeStart, relativeStart + (player.transform.rotation * direction.normalized) * length);
|
||||
break;
|
||||
case CastType.Box:
|
||||
Draw.ingame.WireBox(startOffsetFromRotation, player.transform.rotation * Quaternion.Euler(rotation), size);
|
||||
case CastType.BoxOverlap:
|
||||
Draw.ingame.WireBox(relativeStartWithRotation, player.transform.rotation * Quaternion.Euler(rotation), size);
|
||||
break;
|
||||
case CastType.Sphere:
|
||||
case CastType.SphereOverlap:
|
||||
break;
|
||||
case CastType.BoxCast:
|
||||
// Create an offset start point for the center of the wirebox, since gizmos are drawn with their pivot in the center.
|
||||
Vector3 offsetWithRotationAndLength = (Quaternion.LookRotation(direction) * Quaternion.Euler(rotation)) * (Vector3.forward * length / 2f);
|
||||
Vector3 offsetFromCenter = relativeStartWithRotation + player.transform.rotation * offsetWithRotationAndLength;
|
||||
|
||||
// Also create a rotation for use with the gizmos. Mainly just to shorten the lines
|
||||
Quaternion gizmosRotation = player.transform.rotation * Quaternion.LookRotation(direction) * Quaternion.Euler(rotation);
|
||||
|
||||
// Draw the gizmos for the boxcast
|
||||
Draw.ingame.WireBox(relativeStartWithRotation, gizmosRotation, Vector3.one * width);
|
||||
Draw.ingame.WireBox(offsetFromCenter, gizmosRotation, new float3(width, width, length + width));
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
@@ -139,14 +178,28 @@ public class EnvironmentObserver{
|
||||
LabelAlignment.Center,
|
||||
Color.black
|
||||
);
|
||||
|
||||
Sirenix.Utilities.Editor.GUIHelper.RequestRepaint();
|
||||
}
|
||||
}
|
||||
|
||||
static Color GetObserverStatusColorStatic(bool active, RaycastHit hit){
|
||||
if (active) {
|
||||
if (hit.Equals(default(RaycastHit))) {
|
||||
return Color.green;
|
||||
}
|
||||
|
||||
return Color.red;
|
||||
}
|
||||
|
||||
return Color.gray;
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerEnvironmentManager : MonoBehaviour{
|
||||
[OdinSerialize]
|
||||
public List<EnvironmentObserver> observers;
|
||||
|
||||
|
||||
void Start(){
|
||||
CheckDuplicateLabels(observers);
|
||||
}
|
||||
@@ -219,6 +272,7 @@ public class PlayerEnvironmentManager : MonoBehaviour{
|
||||
}
|
||||
|
||||
void LateUpdate(){
|
||||
// Draw Gizmos
|
||||
foreach (EnvironmentObserver observer in observers) {
|
||||
observer.DrawObserverGizmo(gameObject);
|
||||
|
||||
@@ -228,5 +282,16 @@ public class PlayerEnvironmentManager : MonoBehaviour{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear hit
|
||||
foreach (EnvironmentObserver observer in observers) {
|
||||
observer.hit = default;
|
||||
|
||||
if (observer.children != null && observer.children.Count > 0) {
|
||||
foreach (EnvironmentObserver childObserver in observer.children) {
|
||||
childObserver.hit = default;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user