Repository URL to install this package:
Version:
1.0.0 ▾
|
using System.ComponentModel;
using Fluctio.FluctioSim.Common.Configuration;
using Fluctio.FluctioSim.Core.Components.MachineLearning.NumberProviders;
using UnityEngine;
#if UNITY_EDITOR
using Fluctio.FluctioSim.EditorUtils.Gui;
using UnityEditor;
#endif
namespace Fluctio.FluctioSim.Core.Components.MachineLearning.Triggers
{
[AddComponentMenu(Config.PrefixedName+"/Machine Learning/Triggers/Number Trigger", Config.ComponentMenuOrder + 70)]
public class NumberTrigger : Trigger
{
[field: SerializeField] public ConditionType ConditionType { get; private set; }
[field: SerializeField] public ComparisonType ComparisonType { get; private set; }
[field: SerializeField] public float ExactNumber { get; private set; }
[field: SerializeField] public float MinNumber { get; private set; }
[field: SerializeField] public float MaxNumber { get; private set; }
[field: SerializeField] public NumberProvider Number { get; private set; }
private bool _wasConditionSatisfiedPreviously = false;
private bool IsConditionSatisfied()
{
var number = Number.GetNumber();
return ComparisonType switch
{
ComparisonType.InRange or ComparisonType.Max or ComparisonType.Min
=> (number >= MinNumber) && (number <= MaxNumber),
// ReSharper disable once CompareOfFloatsByEqualityOperator
ComparisonType.Exact => (number == ExactNumber),
ComparisonType.ApproximateFloat => Mathf.Approximately(number, ExactNumber),
_ => throw new InvalidEnumArgumentException(
nameof(ComparisonType),
(int)ComparisonType,
ComparisonType.GetType())
};
}
private void OnValidate()
{
// ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
switch (ComparisonType)
{
case ComparisonType.Max:
MinNumber = -Mathf.Infinity;
break;
case ComparisonType.Min:
MaxNumber = Mathf.Infinity;
break;
}
}
private void FixedUpdate()
{
var isConditionSatisfied = IsConditionSatisfied();
switch (ConditionType)
{
case ConditionType.EachStepWhileSatisfied:
if (isConditionSatisfied)
{
ScheduleActions();
}
break;
case ConditionType.OnceWhenSatisfied:
if (isConditionSatisfied && !_wasConditionSatisfiedPreviously)
{
ScheduleActions();
}
break;
default:
throw new InvalidEnumArgumentException(
nameof(ConditionType),
(int)ConditionType,
ConditionType.GetType());
}
_wasConditionSatisfiedPreviously = isConditionSatisfied;
}
}
public enum ConditionType
{
[Tooltip("Trigger each step while condition is true")]
EachStepWhileSatisfied,
[Tooltip("Trigger once when condition becomes true")]
OnceWhenSatisfied,
}
public enum ComparisonType
{
[InspectorName("Trigger when smaller than")]
Max,
[InspectorName("Trigger when bigger than")]
Min,
[InspectorName("Trigger when in range")]
InRange,
[InspectorName("Trigger when exactly")]
Exact,
[InspectorName("Trigger when almost exactly (use Mathf.Approximately)")]
[Tooltip("Uses Mathf.Approximately() to avoid floating point inaccuracies")]
ApproximateFloat,
}
#if UNITY_EDITOR
[CustomEditor(typeof(NumberTrigger), true)]
public class DistanceTriggerEditor : Editor
{
// ReSharper disable once InconsistentNaming
private new NumberTrigger target => (NumberTrigger)base.target;
private void DrawDistanceProperties()
{
switch (target.ComparisonType)
{
case ComparisonType.Min:
serializedObject.DrawProperties(nameof(target.MinNumber));
break;
case ComparisonType.Max:
serializedObject.DrawProperties(nameof(target.MaxNumber));
break;
case ComparisonType.InRange:
serializedObject.DrawProperties(nameof(target.MinNumber), nameof(target.MaxNumber));
break;
case ComparisonType.ApproximateFloat:
case ComparisonType.Exact:
serializedObject.DrawProperties(nameof(target.ExactNumber));
break;
default:
throw new InvalidEnumArgumentException(
nameof(target.ComparisonType),
(int)target.ComparisonType,
target.ComparisonType.GetType());
}
}
public override void OnInspectorGUI()
{
serializedObject.Update();
serializedObject.DrawProperties("ConditionType", "Number", "ComparisonType");
DrawDistanceProperties();
serializedObject.ApplyModifiedProperties();
}
}
#endif
}