wip: OctoPlayerDriver & New Triggers for OctoWorldEvent & Critical Path V1

This commit is contained in:
Alexandre Coirier
2026-05-19 23:40:16 +02:00
parent 578b94f1dc
commit 1cff87b60b
37 changed files with 6172 additions and 885 deletions
@@ -1,8 +1,7 @@
using OctoCore.Inputs;
using System.Linq;
using System.Globalization;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UIElements;
namespace OctoCore.Components
{
@@ -21,13 +20,7 @@ namespace OctoCore.Components
public bool IsRunning;
public float Yaw;
public float Pitch;
[Space(10)]
public bool IsDriven;
[Range(0, 1)] public float DriventIntensity;
public Transform DriveTarget;
public Transform DriveLookAt;
public OctoPlayerDriver Driver;
}
[System.Serializable]
@@ -68,7 +61,7 @@ namespace OctoCore.Components
}
[System.Serializable]
private class FirstPerson
public class FirstPerson
{
[Header("References")]
@@ -110,6 +103,7 @@ namespace OctoCore.Components
public bool IsPaused => State.IsPaused;
public float Radius => _references.Controller ? _references.Controller.radius : 0;
public FirstPerson _FirstPerson => _firstPerson;
void OnEnable()
{
@@ -143,6 +137,17 @@ namespace OctoCore.Components
HandleMovement();
}
public void Teleport(string positionAndYaw)
{
string[] s = positionAndYaw.Replace(" ", string.Empty).Split(',');
float x = float.Parse(s[0], CultureInfo.InvariantCulture.NumberFormat);
float y = float.Parse(s[1], CultureInfo.InvariantCulture.NumberFormat);
float z = float.Parse(s[2], CultureInfo.InvariantCulture.NumberFormat);
float a = float.Parse(s[3], CultureInfo.InvariantCulture.NumberFormat);
Teleport(new Vector3(x, y, z), Quaternion.Euler(0, a, 0));
}
public void Teleport(Vector3 position, Quaternion rotation)
{
State.IsPaused = _jumpInput = _jumpping = _runInput = false;
@@ -169,20 +174,9 @@ namespace OctoCore.Components
if (OctoCore.Instance)
OctoCore.Instance.UI.SetCursor();
}
public void Drive(Transform target, Transform lookAt)
{
State.DriveTarget = target;
State.DriveLookAt = lookAt;
State.IsDriven = true;
}
public void ReleaseDrive()
{
State.IsDriven = false;
State.DriveTarget = null;
State.DriveLookAt = null;
}
public void Drive(OctoPlayerDriver driver) { State.Driver = driver; }
public void ReleaseDrive() { State.Driver = null; }
public void SetYaw(float yaw) { State.Yaw = yaw; }
public void SetPitch(float pitch) { State.Yaw = pitch; }
@@ -259,21 +253,8 @@ namespace OctoCore.Components
move = camRight * move.x + camForward * move.z;
}
if (State.IsDriven)
{
State.DriventIntensity = Mathf.Clamp01(State.DriventIntensity + move.magnitude * t * 1);
Vector3 driveDir = State.DriveTarget.position - transform.position;
float driveAtten = 1 - Mathf.Clamp01(driveDir.magnitude);
Vector3 driveMove = driveDir;
driveMove.y = 0;
driveMove = driveMove.normalized * move.magnitude;
driveMove = Vector3.Lerp(driveMove, Vector3.zero, driveAtten);
move = Vector3.Lerp(move, driveMove, State.DriventIntensity);
}
if (State.Driver)
State.Driver.ApplyMoveInfluence(move, move.magnitude * t, out move);
float deltaSmooth = t * (accelerating ? 30 : 15);
_moveDirection = Vector3.Lerp(_moveDirection, move, deltaSmooth * 1.5f);
@@ -349,25 +330,8 @@ namespace OctoCore.Components
State.Yaw += mouseX;
State.Pitch = Mathf.Clamp(State.Pitch + mouseY, _firstPerson.MinPitch, _firstPerson.MaxPitch);
if (State.IsDriven)
{
Vector3 lookAt = State.DriveLookAt.position - _firstPerson.Camera.transform.position;
lookAt = lookAt.normalized;
Vector3 playerPos2D = transform.position;
Vector3 targetPos2D = State.DriveTarget.position;
playerPos2D.y = targetPos2D.y = 0;
float yaw = Mathf.Atan2(lookAt.x, lookAt.z) * Mathf.Rad2Deg;
float pitch = Mathf.Asin(-lookAt.y) * Mathf.Rad2Deg;
float lerp = 1 - Mathf.Clamp01(Vector3.Distance(playerPos2D, targetPos2D) / 2);
float yawRange = Mathf.Lerp(180, 0, lerp);
float pitchRange = Mathf.Lerp(90, 0, lerp);
State.Yaw = yaw + Mathf.Clamp(Mathf.DeltaAngle(yaw, State.Yaw), -yawRange, yawRange);
State.Pitch = pitch + Mathf.Clamp(Mathf.DeltaAngle(pitch, State.Pitch), -pitchRange, pitchRange);
}
if (State.Driver)
State.Driver.ApplyLookInfluence(State.Yaw, State.Pitch, Time.deltaTime, out State.Yaw, out State.Pitch);
Quaternion YawRot = Quaternion.Euler(0, State.Yaw, 0);
Quaternion PitchRot = Quaternion.Euler(State.Pitch, 0, 0);
@@ -1,9 +1,19 @@
using UnityEngine;
using UnityEngine.Events;
namespace OctoCore.Components
{
public class OctoPlayerDriver : MonoBehaviour
{
[System.Serializable]
public class State
{
[Range(0, 1)] public float MoveInfluence;
[Range(0, 1)] public float LookInfluence;
[Range(0, 180)] public float YawRange = 180;
[Range(0, 90)] public float PitchRange = 90;
}
[System.Serializable]
public class References
{
@@ -11,21 +21,145 @@ namespace OctoCore.Components
public Transform LookAt;
}
[System.Serializable]
public class Settings
{
[Min(.1f)] public float DriveStrength = 1;
[Range(0, 1)] public float LookAtStrength = 1;
[Range(.1f, 3)] public float LookAtSmooth = 1;
[Range(0, 1)] public float LookAtPoint = .5f;
public AnimationCurve DriveCurve = AnimationCurve.EaseInOut(0, 0, 1 , 1);
}
[System.Serializable]
public class Events
{
public UnityEvent OnDrive;
public UnityEvent OnFullInfluence;
public UnityEvent OnRelease;
}
[SerializeField, OctoReadOnly] private State _state;
[SerializeField] private References _references;
[SerializeField] private Settings _settings;
[SerializeField] private Events _events;
public References _References => _references;
public State _State => _state;
private bool _fullInfluenceReached;
void OnDrawGizmos()
{
UnityEditor.Handles.color = Color.cyan;
const float size = .3f;
if (_references.Target)
{
UnityEditor.Handles.matrix = _references.Target.localToWorldMatrix;
UnityEditor.Handles.DrawLine(Vector3.forward * size, Vector3.back * size);
UnityEditor.Handles.DrawLine(Vector3.left * size, Vector3.right * size);
}
if (_references.LookAt)
{
UnityEditor.Handles.matrix = _references.LookAt.localToWorldMatrix;
UnityEditor.Handles.DrawWireCube(Vector3.zero, Vector3.one * size * .75f);
}
}
void Start()
{
}
void Update()
{
}
public void DrivePlayer()
{
OctoPlayer.Instance.Drive(_references.Target, _references.LookAt);
_fullInfluenceReached = false;
_state.YawRange = 180;
_state.PitchRange = 90;
OctoPlayer.Instance.Drive(this);
_events.OnDrive?.Invoke();
}
public void ReleasePlayer()
{
OctoPlayer.Instance.ReleaseDrive();
_state.YawRange = 180;
_state.PitchRange = 90;
_events.OnRelease?.Invoke();
}
public void ApplyMoveInfluence(Vector3 inMove, float delta, out Vector3 outMove)
{
if (!OctoPlayer.Instance || !OctoPlayer.Instance._FirstPerson.Camera)
{
outMove = inMove;
return;
}
_state.MoveInfluence = Mathf.Clamp01(_state.MoveInfluence + delta * _settings.DriveStrength);
float moveInfluence = _settings.DriveCurve.Evaluate(_state.MoveInfluence);
if (!_fullInfluenceReached && _state.MoveInfluence >= 1)
{
_events.OnFullInfluence?.Invoke();
_fullInfluenceReached = true;
}
Vector3 offset = _references.Target.position - OctoPlayer.Instance.transform.position;
Vector3 offset2D = offset;
offset2D.y = 0;
float driveAtten = Mathf.InverseLerp(1, .1f, offset2D.magnitude);
Vector3 driveMove = offset;
driveMove.y = 0;
driveMove = driveMove.normalized * inMove.magnitude;
driveMove = Vector3.Lerp(driveMove, Vector3.zero, driveAtten);
outMove = Vector3.Lerp(inMove, driveMove, moveInfluence);
}
public void ApplyLookInfluence(float inYaw, float inPitch, float deltaTime, out float outYaw, out float outPitch)
{
if (!OctoPlayer.Instance || !OctoPlayer.Instance._FirstPerson.Camera)
{
outYaw = inYaw;
outPitch = inPitch;
return;
}
Vector3 lookAt = _references.LookAt.position - OctoPlayer.Instance._FirstPerson.Camera.transform.position;
lookAt = lookAt.normalized;
Vector3 offset = _references.Target.position - OctoPlayer.Instance.transform.position;
Vector3 offset2D = offset;
offset2D.y = 0;
float lookAtYaw = Mathf.Atan2(lookAt.x, lookAt.z) * Mathf.Rad2Deg;
float lookAtPitch = Mathf.Asin(-lookAt.y) * Mathf.Rad2Deg;
_state.LookInfluence = Mathf.InverseLerp(_settings.LookAtPoint, 1, _state.MoveInfluence) * _settings.LookAtStrength;
float lookInfluence = _settings.DriveCurve.Evaluate(_state.LookInfluence);
float t = deltaTime * _settings.LookAtSmooth;
_state.YawRange = Mathf.Lerp(_state.YawRange, Mathf.Lerp(180, 0, lookInfluence), t);
_state.PitchRange = Mathf.Lerp(_state.PitchRange, Mathf.Lerp(90, 0, lookInfluence), t);
outYaw = lookAtYaw + Mathf.Clamp(Mathf.DeltaAngle(lookAtYaw, inYaw), -_state.YawRange, _state.YawRange);
outPitch = lookAtPitch + Mathf.Clamp(Mathf.DeltaAngle(lookAtPitch, inPitch), -_state.PitchRange, _state.PitchRange);
}
}
}
@@ -0,0 +1,261 @@
using UnityEngine;
namespace OctoCore.Components
{
/// <summary>
/// Procedural animation supporting translation, rotation, and scaling.
/// Supports multiple animation types (Constant, PingPong, Loop, Single) with easing.
/// </summary>
[DefaultExecutionOrder(0)]
public class OctoProceduralAnimator : MonoBehaviour
{
public enum AnimationSpace
{
Local,
World
}
public enum AnimationType
{
Constant, // Continuous movement without return
PingPong, // Back and forth (A → B → A)
Loop, // Loop with teleport (A → B, teleport to A)
Single // Play once then stop
}
public enum AnimationBalance
{
Centered,
Forward,
Backward
}
[System.Serializable]
public class Settings
{
[Tooltip("Animation space")]
public AnimationSpace Space = AnimationSpace.Local;
[Tooltip("Type of animation loop")]
public AnimationType Type = AnimationType.PingPong;
[Tooltip("TCenter of animation")]
public AnimationBalance Balance = AnimationBalance.Centered;
[Tooltip("Custom animation curve")]
public AnimationCurve Curve = AnimationCurve.EaseInOut(0, 0, 1, 1);
[Tooltip("Play on Awake")]
public bool PlayOnAwake = true;
[Tooltip("Animation speed multiplier")]
public float Duration = 4;
[Tooltip("Time offset to desynchronize multiple animations")]
public float TimeOffset = 0;
[Tooltip("Translation amount in local space (meters)")]
public Vector3 Translation = Vector3.zero;
[Tooltip("Rotation amount in degrees")]
public Vector3 Rotation = Vector3.zero;
[Tooltip("Scale amount relative to initial scale")]
public Vector3 Scale = Vector3.zero;
}
[System.Serializable]
public class State
{
[Tooltip("Current animation time")]
public float CurrentTime;
[Tooltip("Is animation finished? (Single only)")]
public bool IsFinished;
[HideInInspector] public Vector3 InitialPosition;
[HideInInspector] public Quaternion InitialRotation;
[HideInInspector] public Vector3 InitialScale;
}
[SerializeField] private Settings _settings;
[SerializeField] private State _state;
private bool _started;
private float _timeOffset;
void OnDrawGizmosSelected()
{
}
void OnEnable()
{
_timeOffset = Time.timeSinceLevelLoad;
_started = _settings.PlayOnAwake;
}
void Start()
{
_state.InitialPosition = transform.localPosition;
_state.InitialRotation = transform.localRotation;
_state.InitialScale = transform.localScale;
_state.CurrentTime = _settings.TimeOffset;
_state.IsFinished = false;
}
void Update()
{
if (_state.IsFinished || !_started)
return;
_state.CurrentTime = Time.timeSinceLevelLoad + _settings.TimeOffset * _settings.Duration - _timeOffset;
float normalizedTime = GetNormalizedTime(_state.CurrentTime);
float easedTime = ApplyEasing(normalizedTime);
float balanceTime = ApplyBalance(easedTime);
ApplyTranslation(balanceTime);
ApplyRotation(balanceTime);
ApplyScale(balanceTime);
}
/// <summary>
/// Play animation from initial state.
/// </summary>
[ContextMenu("PlayAnimation")]
public void PlayAnimation()
{
ResetAnimation();
_timeOffset = Time.timeSinceLevelLoad;
_started = true;
}
/// <summary>
/// Resets animation to initial state.
/// </summary>
public void ResetAnimation()
{
_state.CurrentTime = _settings.TimeOffset;
_state.IsFinished = false;
transform.localPosition = _state.InitialPosition;
transform.localRotation = _state.InitialRotation;
transform.localScale = _state.InitialScale;
}
/// <summary>
/// Pauses or resumes animation.
/// </summary>
public void SetPaused(bool paused)
{
enabled = !paused;
}
/// <summary>
/// Gets normalized time [0,1] based on animation type.
/// </summary>
private float GetNormalizedTime(float time)
{
if (_settings.Duration == 0)
return 0;
switch (_settings.Type)
{
case AnimationType.Constant:
return time / _settings.Duration;
case AnimationType.PingPong:
return Mathf.PingPong(time / _settings.Duration, 1);
case AnimationType.Loop:
return Mathf.Repeat(time / _settings.Duration, 1f);
case AnimationType.Single:
if (time >= _settings.Duration)
{
_state.IsFinished = true;
return 1;
}
return time / _settings.Duration;
default:
return 0f;
}
}
private float ApplyBalance(float time)
{
switch (_settings.Balance)
{
case AnimationBalance.Centered:
return time - .5f;
case AnimationBalance.Backward:
return -time;
default:
return time;
}
}
/// <summary>
/// Applies easing function to normalized time.
/// </summary>
private float ApplyEasing(float time)
{
switch (_settings.Type)
{
default:
return _settings.Curve.Evaluate(time); ;
case AnimationType.Constant:
return time;
}
}
/// <summary>
/// Applies translation based on eased time.
/// </summary>
private void ApplyTranslation(float time)
{
if (_settings.Translation == Vector3.zero)
return;
Vector3 offset = _settings.Translation * time;
if (_settings.Space == AnimationSpace.Local)
offset = _state.InitialRotation * offset;
transform.localPosition = _state.InitialPosition + offset;
}
/// <summary>
/// Applies rotation based on eased time.
/// </summary>
private void ApplyRotation(float time)
{
if (_settings.Rotation == Vector3.zero)
return;
Vector3 rotation = _settings.Rotation * time;
Quaternion rotationOffset = Quaternion.Euler(rotation);
if (_settings.Space == AnimationSpace.Local)
rotationOffset = _state.InitialRotation * rotationOffset;
else
rotationOffset = rotationOffset * _state.InitialRotation;
transform.localRotation = rotationOffset;
}
/// <summary>
/// Applies scale based on eased time.
/// </summary>
private void ApplyScale(float t)
{
if (_settings.Scale == Vector3.zero)
return;
Vector3 scale = Vector3.one + _settings.Scale * t;
transform.localScale = Vector3.Scale(_state.InitialScale, scale);
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0097589062bdfad4a96fa20e8effbe2f
@@ -1,32 +1,51 @@
using OctoCore.Inputs;
using OctoCore.Utilities;
using System;
using System.Collections;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
namespace OctoCore.Components
{
[DefaultExecutionOrder(100)]
public class OctoWorldEvent : MonoBehaviour
{
public enum Conditions { None, Player, Tags, Targets }
//[SerializeField] private InputActionAsset _actionAsset;
//[SerializeField] private InputActionReference _actionReference;
//[Space(10)]
public enum ExecutionModes
{
Immediate,
Delayed,
ImmediateAndDelayed
}
[SerializeField] private Utilities.OctoEvents _trigger;
[SerializeField] private OctoActions _action;
[SerializeField] private Conditions _condition;
[SerializeField] private string[] _tags;
[SerializeField] private GameObject[] _targets;
[Range(0f, 1f)]
[SerializeField] private float _tolerance = .5f;
[SerializeField] private float _duration = 1f;
[SerializeField] private ExecutionModes _execution;
[SerializeField, Min(0f)] private float _delay = 1f;
[SerializeField] private UnityEvent _onTrigger;
[SerializeField] private UnityEvent _onTriggerDelayed;
private bool _playerInside;
private bool[] _tagsInside;
private bool[] _targetsInside;
private float _lookAtTimer;
private bool _lookAtTriggered;
private Coroutine _delayedCoroutine;
private const string PlayerTag = "Player";
void Awake()
@@ -37,11 +56,11 @@ namespace OctoCore.Components
switch (_trigger)
{
case Utilities.OctoEvents.Awake:
SetTrigger();
ExecuteTrigger();
break;
case Utilities.OctoEvents.Action:
OctoCore.Instance.Inputs.SubscribeAction(_action, SetTrigger);
OctoCore.Instance.Inputs.SubscribeAction(_action, ExecuteTrigger);
break;
}
}
@@ -49,40 +68,42 @@ namespace OctoCore.Components
void OnEnable()
{
if (_trigger == Utilities.OctoEvents.OnEnable)
SetTrigger();
ExecuteTrigger();
}
void Start()
{
if (_trigger == Utilities.OctoEvents.Start)
SetTrigger();
ExecuteTrigger();
}
void Update()
{
if (_trigger == Utilities.OctoEvents.Update)
SetTrigger();
ExecuteTrigger();
if (_trigger == Utilities.OctoEvents.OnPlayerLookAt)
UpdatePlayerLookAt();
}
void LateUpdate()
{
if (_trigger == Utilities.OctoEvents.LateUpdate)
SetTrigger();
ExecuteTrigger();
}
void FixedUpdate()
{
if (_trigger == Utilities.OctoEvents.FixedUpdate)
SetTrigger();
ExecuteTrigger();
}
void OnDisable()
{
if (_trigger == Utilities.OctoEvents.OnDisable)
SetTrigger();
ExecuteTrigger();
_playerInside = false;
_tagsInside = new bool[_tags.Length];
_targetsInside = new bool[_targets.Length];
ResetState();
}
void OnDestroy()
@@ -90,49 +111,53 @@ namespace OctoCore.Components
switch (_trigger)
{
case Utilities.OctoEvents.OnDestroy:
SetTrigger();
ExecuteTrigger();
break;
case Utilities.OctoEvents.Action:
OctoCore.Instance?.Inputs.UnsubscribeAction(_action, SetTrigger);
OctoCore.Instance?.Inputs.UnsubscribeAction(_action, ExecuteTrigger);
break;
}
}
void OnTriggerEnter(Collider col)
{
if (_trigger == Utilities.OctoEvents.OnTriggerEnter)
{
EvaluateTrigger(col);
SetTrigger();
}
if (_trigger != Utilities.OctoEvents.OnTriggerEnter)
return;
EvaluateTrigger(col);
TriggerWithCondition();
}
void OnTriggerStay(Collider col)
{
if (_trigger != Utilities.OctoEvents.OnTriggerStay)
return;
EvaluateTrigger(col);
if (_trigger == Utilities.OctoEvents.OnTriggerStay)
SetTrigger();
TriggerWithCondition();
}
void OnTriggerExit(Collider col)
{
if (_trigger == Utilities.OctoEvents.OnTriggerExit)
SetTrigger();
if (_trigger != Utilities.OctoEvents.OnTriggerExit)
return;
TriggerWithCondition();
EvaluateTrigger(col, false);
}
public void SetTrigger()
void TriggerWithCondition()
{
switch (_condition)
{
case Conditions.None:
_onTrigger?.Invoke();
ExecuteTrigger();
break;
case Conditions.Player:
if (_playerInside)
_onTrigger?.Invoke();
ExecuteTrigger();
break;
case Conditions.Tags:
@@ -140,7 +165,7 @@ namespace OctoCore.Components
{
if (_tagsInside[i])
{
_onTrigger?.Invoke();
ExecuteTrigger();
break;
}
}
@@ -151,7 +176,7 @@ namespace OctoCore.Components
{
if (_targetsInside[i])
{
_onTrigger?.Invoke();
ExecuteTrigger();
break;
}
}
@@ -159,43 +184,122 @@ namespace OctoCore.Components
}
}
void ExecuteTrigger()
{
switch (_execution)
{
case ExecutionModes.Immediate:
_onTrigger?.Invoke();
break;
case ExecutionModes.Delayed:
StartDelayedTrigger();
break;
case ExecutionModes.ImmediateAndDelayed:
_onTrigger?.Invoke();
StartDelayedTrigger();
break;
}
}
void StartDelayedTrigger()
{
if (_delayedCoroutine != null)
StopCoroutine(_delayedCoroutine);
_delayedCoroutine = StartCoroutine(DelayedTrigger());
}
IEnumerator DelayedTrigger()
{
yield return new WaitForSeconds(_delay);
_onTriggerDelayed?.Invoke();
_delayedCoroutine = null;
}
void UpdatePlayerLookAt()
{
Camera cam = Camera.main;
if (cam == null)
return;
Vector3 viewportPosition = cam.WorldToViewportPoint(transform.position);
bool isInFront = viewportPosition.z > 0f;
Vector2 screenPosition = new Vector2(
viewportPosition.x * Screen.width,
viewportPosition.y * Screen.height
);
Vector2 screenCenter = new Vector2(
Screen.width * .5f,
Screen.height * .5f
);
float radius = Mathf.Min(Screen.width, Screen.height) * _tolerance * .5f;
bool isInsideCircle = Vector2.Distance(screenPosition, screenCenter) <= radius;
if (isInFront && isInsideCircle)
{
_lookAtTimer += Time.deltaTime;
if (!_lookAtTriggered && _lookAtTimer >= _duration)
{
_lookAtTriggered = true;
ExecuteTrigger();
}
}
else
{
_lookAtTimer = 0f;
_lookAtTriggered = false;
}
}
void EvaluateTrigger(Collider col, bool inside = true)
{
switch (_condition)
{
case Conditions.Player:
if (col.tag == PlayerTag)
if (col.CompareTag(PlayerTag))
_playerInside = inside;
break;
case Conditions.Tags:
if (_tags.Contains(col.tag))
for (int i = 0; i < _tags.Length; i++)
{
for (int i = 0; i < _tags.Length; i++)
{
bool tagMatch = col.tag == _tags[i];
if (tagMatch)
{
_tagsInside[i] = inside ? tagMatch : !tagMatch;
}
}
if (col.CompareTag(_tags[i]))
_tagsInside[i] = inside;
}
break;
case Conditions.Targets:
if (_targets.Contains(col.gameObject))
for (int i = 0; i < _targets.Length; i++)
{
for (int i = 0; i < _targets.Length; i++)
{
bool targetMatch = col.gameObject == _targets[i];
if (targetMatch)
{
_targetsInside[i] = inside ? targetMatch : !targetMatch;
}
}
if (col.gameObject == _targets[i])
_targetsInside[i] = inside;
}
break;
}
}
void ResetState()
{
_playerInside = false;
_tagsInside = new bool[_tags.Length];
_targetsInside = new bool[_targets.Length];
_lookAtTimer = 0f;
_lookAtTriggered = false;
if (_delayedCoroutine != null)
{
StopCoroutine(_delayedCoroutine);
_delayedCoroutine = null;
}
}
}
}
@@ -0,0 +1,101 @@
using OctoCore.Utilities;
using UnityEditor;
namespace OctoCore.Components.Editor
{
[CustomEditor(typeof(OctoWorldEvent))]
public class OctoWorldEventEditor : UnityEditor.Editor
{
SerializedProperty _trigger;
SerializedProperty _action;
SerializedProperty _condition;
SerializedProperty _tags;
SerializedProperty _targets;
SerializedProperty _tolerance;
SerializedProperty _duration;
SerializedProperty _execution;
SerializedProperty _delay;
SerializedProperty _onTrigger;
SerializedProperty _onTriggerDelayed;
void OnEnable()
{
_trigger = serializedObject.FindProperty("_trigger");
_action = serializedObject.FindProperty("_action");
_condition = serializedObject.FindProperty("_condition");
_tags = serializedObject.FindProperty("_tags");
_targets = serializedObject.FindProperty("_targets");
_tolerance = serializedObject.FindProperty("_tolerance");
_duration = serializedObject.FindProperty("_duration");
_execution = serializedObject.FindProperty("_execution");
_delay = serializedObject.FindProperty("_delay");
_onTrigger = serializedObject.FindProperty("_onTrigger");
_onTriggerDelayed = serializedObject.FindProperty("_onTriggerDelayed");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(_trigger);
var trigger = (Utilities.OctoEvents)_trigger.enumValueIndex;
if (trigger == Utilities.OctoEvents.Action)
EditorGUILayout.PropertyField(_action);
if (trigger == Utilities.OctoEvents.OnPlayerLookAt)
{
EditorGUILayout.Space(5);
EditorGUILayout.PropertyField(_tolerance);
EditorGUILayout.PropertyField(_duration);
}
if (UsesTriggerCondition(trigger))
{
EditorGUILayout.Space(5);
EditorGUILayout.PropertyField(_condition);
var condition = (OctoWorldEvent.Conditions)_condition.enumValueIndex;
if (condition == OctoWorldEvent.Conditions.Tags)
EditorGUILayout.PropertyField(_tags, true);
if (condition == OctoWorldEvent.Conditions.Targets)
EditorGUILayout.PropertyField(_targets, true);
}
DrawExecutionEvents();
serializedObject.ApplyModifiedProperties();
}
void DrawExecutionEvents()
{
EditorGUILayout.Space(10);
EditorGUILayout.PropertyField(_execution);
var execution = (OctoWorldEvent.ExecutionModes)_execution.enumValueIndex;
if (execution == OctoWorldEvent.ExecutionModes.Immediate ||
execution == OctoWorldEvent.ExecutionModes.ImmediateAndDelayed)
{
EditorGUILayout.PropertyField(_onTrigger);
}
if (execution == OctoWorldEvent.ExecutionModes.Delayed ||
execution == OctoWorldEvent.ExecutionModes.ImmediateAndDelayed)
{
EditorGUILayout.PropertyField(_delay);
EditorGUILayout.PropertyField(_onTriggerDelayed);
}
}
bool UsesTriggerCondition(Utilities.OctoEvents trigger)
{
return trigger == Utilities.OctoEvents.OnTriggerEnter ||
trigger == Utilities.OctoEvents.OnTriggerStay ||
trigger == Utilities.OctoEvents.OnTriggerExit;
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: fe9cee260bac87a4b80f9bbb38b71211