233 lines
7.4 KiB
C#
233 lines
7.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Drawing;
|
|
using Sirenix.OdinInspector;
|
|
using Sirenix.Serialization;
|
|
using Unity.Mathematics;
|
|
|
|
[Serializable]
|
|
public class EnvironmentObserver{
|
|
// TODO: Clean this ugly shit up. Custom inspector with Odin plz.
|
|
public string label;
|
|
public bool drawLabel;
|
|
|
|
enum LabelDrawingLocation{
|
|
PlayerOffset,
|
|
HitLocation,
|
|
IntersectingLength,
|
|
}
|
|
|
|
enum CastType{
|
|
Ray,
|
|
Box,
|
|
Sphere,
|
|
BoxCast,
|
|
SphereCast
|
|
}
|
|
|
|
[ShowInInspector, SerializeField]
|
|
CastType castType;
|
|
|
|
[SerializeReference]
|
|
public List<EnvironmentObserver> children;
|
|
|
|
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;
|
|
|
|
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.
|
|
|
|
switch (castType) {
|
|
case CastType.Ray:
|
|
Physics.Raycast(relativeStart, player.transform.rotation * direction, out hit, length, ignoreMask);
|
|
break;
|
|
case CastType.Box:
|
|
if (Physics.OverlapBox(startOffsetFromRotation, size / 2f, player.transform.rotation * Quaternion.Euler(rotation), ignoreMask).Length > 0) {
|
|
return true;
|
|
};
|
|
break;
|
|
case CastType.Sphere:
|
|
break;
|
|
case CastType.BoxCast:
|
|
break;
|
|
case CastType.SphereCast:
|
|
break;
|
|
}
|
|
|
|
if (hit.transform != null) {
|
|
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) ;
|
|
|
|
Color gizmoColor = Evaluate(player) ? Color.green : Color.red;
|
|
gizmoColor = active ? gizmoColor : Color.gray;
|
|
|
|
using (Draw.ingame.WithColor(gizmoColor)){
|
|
Vector3 labelStartPos = Vector3.zero;
|
|
switch (labelLocation) {
|
|
case LabelDrawingLocation.PlayerOffset:
|
|
labelStartPos = player.transform.position + labelLocationOffset;
|
|
break;
|
|
case LabelDrawingLocation.IntersectingLength:
|
|
labelStartPos = (relativeStart + (player.transform.rotation * direction * length) / 2f ) + labelLocationOffset;
|
|
break;
|
|
case LabelDrawingLocation.HitLocation:{
|
|
if (hit.transform != null) {
|
|
labelStartPos = hit.point + labelLocationOffset;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (castType) {
|
|
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);
|
|
break;
|
|
case CastType.Sphere:
|
|
break;
|
|
case CastType.BoxCast:
|
|
break;
|
|
default:
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
|
|
Draw.ingame.Label3D(
|
|
labelStartPos,
|
|
player.transform.rotation * Quaternion.Euler(labelRotationOffset),
|
|
hit.collider == null ? "" : hit.collider.name,
|
|
.5f,
|
|
LabelAlignment.Center,
|
|
Color.black
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
public class PlayerEnvironmentManager : MonoBehaviour{
|
|
[OdinSerialize]
|
|
public List<EnvironmentObserver> observers;
|
|
|
|
void Start(){
|
|
CheckDuplicateLabels(observers);
|
|
}
|
|
|
|
// TODO: Not working.
|
|
void CheckDuplicateLabels(List<EnvironmentObserver> sourceList){
|
|
foreach (EnvironmentObserver sourceObserver in observers) {
|
|
foreach (EnvironmentObserver observer in sourceList) {
|
|
if (sourceObserver == observer) {
|
|
continue;
|
|
}
|
|
|
|
if (sourceObserver.label == observer.label) {
|
|
Debug.LogError($"Duplicate label found in observer: {observer.label} is in use multiple times");
|
|
}
|
|
|
|
if (observer.children != null && observer.children.Count > 0) {
|
|
CheckDuplicateLabels(observer.children);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool EvaluateFromString(string searchLabel, List<EnvironmentObserver> observerList = null){
|
|
List<EnvironmentObserver> listToUse = observers;
|
|
|
|
if (observerList != null) {
|
|
listToUse = observerList;
|
|
}
|
|
|
|
foreach (EnvironmentObserver observer in listToUse) {
|
|
if (observer.label == searchLabel) {
|
|
return observer.Evaluate(gameObject);
|
|
}
|
|
|
|
if (observer.children != null && observer.children.Count > 0) {
|
|
foreach (EnvironmentObserver childObserver in observer.children) {
|
|
EvaluateFromString(searchLabel, childObserver.children);
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public EnvironmentObserver FindObserverFromString(string searchLabel, List<EnvironmentObserver> observerList = null){
|
|
List<EnvironmentObserver> listToUse = observers;
|
|
|
|
if (observerList != null) {
|
|
listToUse = observerList;
|
|
}
|
|
|
|
foreach (EnvironmentObserver observer in listToUse) {
|
|
if (observer.label == searchLabel) {
|
|
return observer;
|
|
}
|
|
|
|
if (observer.children != null && observer.children.Count > 0) {
|
|
foreach (EnvironmentObserver childObserver in observer.children) {
|
|
FindObserverFromString(searchLabel, childObserver.children);
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
void Update(){
|
|
Debug.Log(EvaluateFromString("gamedev"));
|
|
}
|
|
|
|
void LateUpdate(){
|
|
foreach (EnvironmentObserver observer in observers) {
|
|
observer.DrawObserverGizmo(gameObject);
|
|
|
|
if (observer.children != null && observer.children.Count > 0) {
|
|
foreach (EnvironmentObserver childObserver in observer.children) {
|
|
childObserver.DrawObserverGizmo(gameObject);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|