会议分享的代码 https://github.com/roboryantron/Unite2017
接下来主要研究这个代码
1.FloatVariable
第一个场景,核心是 FloatVariable
using UnityEngine;
namespace RoboRyanTron.Unite2017.Variables
{
[CreateAssetMenu]
public class FloatVariable : ScriptableObject
{
#if UNITY_EDITOR
[Multiline]
public string DeveloperDescription = "";
#endif
public float Value;
public void SetValue(float value)
{
Value = value;
}
public void SetValue(FloatVariable value)
{
Value = value.Value;
}
public void ApplyChange(float amount)
{
Value += amount;
}
public void ApplyChange(FloatVariable amount)
{
Value += amount.Value;
}
}
}
就是一个可以通过 float 数值或者同类型数值更改的变量 但是做成 ScriptableObject 说明他是在整个工程中共享的 看到“整个工程共享”我一般就是想到存档,要不然就是 Buff,我朋友说是想到背包系统 其实他完全可以作为逻辑中的一个数据,一个可以共享的数据 比如原来我有一个角色有一个血量,现在血条UI和心跳音源都要引用这个血量 那我就不得不让血条UI和心跳音源知道角色类是什么,然后使用 角色类实例.HP 获得血量 这就是 rigid reference 硬引用,就是我必须要知道一个不能改变的“路径”——文件路径或者引用路径 那么怎么用软引用呢,就是我所有需要用到某个变量的类,都只需要知道这个变量 ScriptableObject 就好了,就不需要从别人那里获得引用了
比如
主角处理受到的伤害需要用到 HP
![在这里插入图片描述](https://img-blog.csdnimg.cn/5ee5a3fc2a34472884b9d7d16e50c36a.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5buJ5Lu35Za1,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
UI 的填充数值需要用到 HP
![在这里插入图片描述](https://img-blog.csdnimg.cn/1cb336aef7784f758db36481c4ee77f4.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5buJ5Lu35Za1,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
音源的音量需要用到 HP
![在这里插入图片描述](https://img-blog.csdnimg.cn/3d42181e5dfe452b99f67ee9f6d0aaa3.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5buJ5Lu35Za1,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
由于他们用到的 HP 是相同的,所以都引用一个表示 HP 的 ScriptableObject UI,音源都不需要知道主角是谁,知道 HP 是谁就好了
这简直是最佳的解耦 还对策划友好,因为策划只需要在监视器中连接文件就好了 可调试性强,在编辑器进入调试时,你在编辑器中更改这个 ScriptableObject 的值可以影响到所有引用他的对象 解耦,策划友好,可调试,一个 ScriptableObject 做到了全部,牛啊
2.GameEvent
我之前也是把事件放在类里面,然后通过一个硬引用找到这个事件的 但是他还把事件做成了 ScriptableObject
using System.Collections.Generic;
using UnityEngine;
namespace RoboRyanTron.Unite2017.Events
{
[CreateAssetMenu]
public class GameEvent : ScriptableObject
{
private readonly List<GameEventListener> eventListeners =
new List<GameEventListener>();
public void Raise()
{
for(int i = eventListeners.Count -1; i >= 0; i--)
eventListeners[i].OnEventRaised();
}
public void RegisterListener(GameEventListener listener)
{
if (!eventListeners.Contains(listener))
eventListeners.Add(listener);
}
public void UnregisterListener(GameEventListener listener)
{
if (eventListeners.Contains(listener))
eventListeners.Remove(listener);
}
}
}
using UnityEngine;
using UnityEngine.Events;
namespace RoboRyanTron.Unite2017.Events
{
public class GameEventListener : MonoBehaviour
{
[Tooltip("Event to register with.")]
public GameEvent Event;
[Tooltip("Response to invoke when Event is raised.")]
public UnityEvent Response;
private void OnEnable()
{
Event.RegisterListener(this);
}
private void OnDisable()
{
Event.UnregisterListener(this);
}
public void OnEventRaised()
{
Response.Invoke();
}
}
}
看他是怎么用的 事件发出者只需要知道事件素材是哪个,然后调用 Raise 方法
![在这里插入图片描述](https://img-blog.csdnimg.cn/c4af0c3c6bfc4cb0a7329ad1e67b6a51.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5buJ5Lu35Za1,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
事件接收者只需要知道事件素材是哪个,然后定义回调
![在这里插入图片描述](https://img-blog.csdnimg.cn/1e15a359327d43ab9794edc9fbc0c1a6.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5buJ5Lu35Za1,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
太爽了……
3.Setting
用来做全局设置,跟 floatvariable 一样
4.枚举
枚举直接用一个 list 方便动态改……太强了
using System.Collections.Generic;
using UnityEngine;
namespace RoboRyanTron.Unite2017.Elements
{
[CreateAssetMenu]
public class AttackElement : ScriptableObject
{
[Tooltip("The elements that are defeated by this element.")]
public List<AttackElement> DefeatedElements = new List<AttackElement>();
}
}
好吧……我觉得我似乎领悟到了一切
|