Files
VOIDRPG/Assets/90 - Scripts/Generic/MultiSourceWrapper.cs
T
2026-07-09 21:33:33 +02:00

75 lines
2.5 KiB
C#

using System;
using System.Linq;
using System.Reflection;
using Sirenix.OdinInspector;
using UnityEngine;
namespace VOID.Generic
{
[Serializable]
[HideReferenceObjectPicker]
public class MultiSourceWrapper<T> where T : class
{
/// <summary>
/// Returns value from given source:
/// - From inline object
/// - From selected ScriptableObject (that have field "value")
/// </summary>
public T value => _usageType switch
{
MultiSourceUsageType.None => null,
MultiSourceUsageType.Inline => _value,
MultiSourceUsageType.ScriptableObject => _valueFromScriptableObject,
_ => throw new ArgumentOutOfRangeException()
};
[SerializeField]
[EnumToggleButtons]
[OnValueChanged(nameof(OnUsageTypeChange))]
[HideLabel]
private MultiSourceUsageType _usageType;
[SerializeField]
[ShowIf(nameof(_usageType), MultiSourceUsageType.Inline)]
[HideLabel]
private T _value;
[SerializeField]
[ShowIf(nameof(_usageType), MultiSourceUsageType.ScriptableObject)]
[OnValueChanged(nameof(OnScriptableObjectSelected))]
[HideLabel]
private ScriptableObject _scriptableObject;
private T _valueFromScriptableObject;
private void OnScriptableObjectSelected()
{
var field = _scriptableObject.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.FirstOrDefault(field => field.Name == "value" && field.FieldType == typeof(T));
_valueFromScriptableObject = field == null ? default : field.GetValue(_scriptableObject) as T;
}
private void OnUsageTypeChange()
{
switch (_usageType)
{
case MultiSourceUsageType.None:
_value = null;
_scriptableObject = null;
_valueFromScriptableObject = null;
break;
case MultiSourceUsageType.Inline:
_scriptableObject = null;
_valueFromScriptableObject = null;
break;
case MultiSourceUsageType.ScriptableObject:
_value = null;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}