1. ActorAttribute v1
一开始我是想做一个可以使用泛型 ScriptableObject 的角色属性
1.1 ScriptableGenericVariable v1
泛型 ScriptableObject
Assets/MeowFramework/Core/Scriptable/ScriptableVariable/ScriptableGenericVariable.cs
using Sirenix.OdinInspector;
using UnityEngine;
namespace MeowFramework.Core.Scriptable
{
[InlineEditor]
public class ScriptableGenericVariable<T> : SerializedScriptableObject
{
[TextArea]
[Tooltip("开发者注释")]
public string DeveloperDescription = "";
[Tooltip("可资产化变量的值")]
public T Value;
}
}
1.2 ScriptableFloatVariable v1
泛型 ScriptableObject 不能生成,需要进行一步继承
Assets/MeowFramework/Core/Scriptable/ScriptableVariable/ScriptableFloatVariable.cs
using Sirenix.OdinInspector;
using UnityEngine;
namespace MeowFramework.Core.Scriptable
{
[InlineEditor]
[CreateAssetMenu(menuName = "MeowFramework/Scriptable Variable/Create Scriptable Float Variable")]
public class ScriptableFloatVariable : ScriptableGenericVariable<float>
{
}
}
同时这个继承泛型 ScriptableObject 的类需要放在单独的文件中
1.3 ActorAttribute v1
这就是真正使用 泛型 ScriptableObject 的角色属性类
Assets/MeowFramework/Core/Entity/Actor/ActorAttribute.cs
using System;
using MeowFramework.Core.Scriptable;
using Sirenix.OdinInspector;
using UnityEngine;
namespace MeowFramework.Core.Entity
{
public class ActorAttribute<T>
{
[Tooltip("是否使用字面值")]
public bool IsLiteral = true;
[ShowIf("@IsLiteral")]
[Tooltip("值")]
private T value;
[ShowIf("@!IsLiteral")]
[ShowInInspector]
[Tooltip("可资产化值")]
private ScriptableGenericVariable<T> scriptableValue;
public T Value
{
get => value;
set
{
AfterSetValue(this.value, value);
this.value = value;
}
}
[HideInInspector]
public Action<T,T> AfterSetValue;
}
}
但是用了之后,发现这个泛型 ScriptableObject 变量赋完了之后,运行游戏之后,监视器上还会恢复 null
太草了,这样我完美的泛型想法直接崩溃了
那么为了能在监视器中配置 ScriptableObject,还是要看看是哪错了
首先要排除泛型的影响,于是我写成
1.4 ScriptableFloatVariable v2
Assets/MeowFramework/Core/Scriptable/ScriptableVariable/ScriptableFloatVariable.cs
using Sirenix.OdinInspector;
using UnityEngine;
namespace MeowFramework.Core.Scriptable
{
[InlineEditor]
[CreateAssetMenu(menuName = "MeowFramework/Scriptable Variable/Create Scriptable Float Variable")]
public class ScriptableFloatVariable : SerializedScriptableObject
{
[Tooltip("值")]
public float Value;
}
}
1.5 ActorFloatAttribute v2
Assets/MeowFramework/Core/Scriptable/ActorAttribute/ActorFloatAttribute.cs
using System;
using MeowFramework.Core.Scriptable;
using Sirenix.OdinInspector;
using UnityEngine;
namespace MeowFramework.Core.ActorAttribute
{
public class ActorFloatAttribute
{
[Tooltip("是否使用字面值")]
public bool IsLiteral = true;
[ShowIf("@IsLiteral")]
[Tooltip("值")]
private float value;
[ShowIf("@!IsLiteral")]
[ShowInInspector]
[Tooltip("可资产化值")]
private ScriptableFloatVariable scriptableValue;
public float Value
{
get => value;
set
{
AfterSetValue(this.value, value);
this.value = value;
}
}
[HideInInspector]
public Action<float,float> AfterSetValue;
}
}
发现还是不行
这样的话就是,A 脚本中的 B 类对象成员中的 ScriptableObject 成员不能配置了
经过实验,直接在监视器里面配置 A 脚本中的 ScriptableObject 成员是可以的
那么还要实验的就是单独一个A 脚本中的继承 泛型 ScriptableObject 的成员是否可行
1.6 TestVariable v3
Assets/MeowFramework/Core/Scriptable/ScriptableVariable/TestVariable.cs
using Sirenix.OdinInspector;
using UnityEngine;
namespace MeowFramework.Core.Scriptable
{
[InlineEditor]
[CreateAssetMenu(menuName = "MeowFramework/Scriptable Variable/Create Test Variable")]
public class TestVariable : ScriptableGenericVariable<float>
{
}
}
public TestVariable testVariable; 这样写是可以的 public ScriptableGenericVariable<float> testVariable; 也是可以的
懂了,总之 A 脚本中的 B 类对象成员中的 ScriptableObject 成员 就是不行的
2. ScriptableVariable v3
2.1 ScriptableFloatVariable v3
Assets/MeowFramework/Core/Scriptable/ScriptableVariable/ScriptableFloatVariable.cs
using System;
using Sirenix.OdinInspector;
using UnityEngine;
namespace MeowFramework.Core.Scriptable
{
[InlineEditor]
[CreateAssetMenu(menuName = "MeowFramework/Scriptable Variable/Create Scriptable Float Variable")]
public class ScriptableFloatVariable : SerializedScriptableObject
{
[ShowInInspector]
private float value;
public float Value
{
get => value;
set
{
AfterSetValue?.Invoke(this.value, value);
this.value = value;
}
}
[HideInInspector]
public Action<float,float> AfterSetValue;
}
}
这时,就不需要一个 ActorAttribute 了,应该直接把 ActorAttribute 的内容写在 ActorBase 里
|