如题,本系统实现了一种触发器(可视为简单的脚本)系统,代码如下:
TriggerGroup.cs:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Script.Systems.TriggerSyatem;
using System;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
namespace Script.Systems.TriggerSystem
{
public class TriggerSet
{
public ITrigger triggers;
public string name;
public string description;
public TriggerSet(ITrigger triggers, string name, string description)
{
this.triggers = triggers;
this.name = name;
this.description = description;
}
public void Active()
{
triggers.Active();
}
public void Inactive()
{
triggers.Inactive();
}
// 序列化
public string Serialize()
{
return SerializationHelper.Serialize(this);
}
// 反序列化
public static TriggerSet Deserialize(string json)
{
return SerializationHelper.Deserialize<TriggerSet>(json);
}
}
public class TriggerGroup : MonoBehaviour, ITrigger
{
private List<ITrigger> triggers = new List<ITrigger>();
public void RegisterTrigger(ITrigger trigger)
{
triggers.Add(trigger);
}
public void UnregisterTrigger(ITrigger trigger)
{
triggers.Remove(trigger);
}
public List<ITrigger> GetTriggers()
{
return new List<ITrigger>(triggers);
}
ITrigger ITrigger.Copy()
{
var copy = new TriggerGroup();
foreach (var trigger in triggers)
{
copy.triggers.Add(trigger.Copy());
}
return copy;
}
public void Active()
{
foreach (var trigger in triggers)
{
trigger.Active();
}
}
public void Inactive()
{
foreach (var trigger in triggers)
{
trigger.Inactive();
}
}
// 序列化
public string Serialize()
{
return SerializationHelper.Serialize(this);
}
// 反序列化
public static TriggerGroup Deserialize(string json)
{
return SerializationHelper.Deserialize<TriggerGroup>(json);
}
}
public class Trigger : ITrigger
{
public string triggerName;
public List<Event> events = new List<Event>();
public List<BaseCondition> conditions = new List<BaseCondition>();
public List<BaseAction> actions = new List<BaseAction>();
public void CheckTrigger(JObject arguments)
{
bool allConditionsMet = true;
foreach (var condition in conditions)
{
var actualArguments = new JObject(arguments);
actualArguments.AddRange(condition.addonArguments);
if (!condition.CheckCondition(condition.parameters.MatchParameters(arguments)))
{
allConditionsMet = false;
break;
}
}
if (allConditionsMet)
{
foreach (var action in actions)
{
action.Execute(action.Parameters.MatchParameters(arguments));
}
}
}
public ITrigger Copy()
{
var newTrigger = new Trigger
{
triggerName = this.triggerName
};
foreach (var @event in this.events)
{
newTrigger.events.Add(@event);
}
foreach (var condition in this.conditions)
{
newTrigger.conditions.Add(condition);
}
foreach (var action in this.actions)
{
newTrigger.actions.Add(action);
}
return newTrigger;
}
public void Active()
{
foreach (var @event in events)
{
if (Event.eventToTrigger.ContainsKey(@event))
{
Event.eventToTrigger[@event].Add(this);
}
else
{
Event.eventToTrigger.Add(@event, new HashSet<Trigger> { this });
}
}
}
public void Inactive()
{
foreach (var @event in events)
{
if (Event.eventToTrigger.ContainsKey(@event))
{
Event.eventToTrigger[@event].Remove(this);
}
}
}
// 序列化
public string Serialize()
{
return SerializationHelper.Serialize(this);
}
// 反序列化
public static Trigger Deserialize(string json)
{
return SerializationHelper.Deserialize<Trigger>(json);
}
}
[System.Serializable]
public struct Parameter
{
public string name;
public string type;
}
public static class ParameterListExtension
{
public static JObject MatchParameters(this List<Parameter> parameterList, JObject input)
{
if (parameterList == null || input == null)
{
throw new ArgumentNullException("参数列表或输入对象不能为空");
}
JObject matchedParameters = new JObject();
foreach (var parameter in parameterList)
{
if (input.TryGetValue(parameter.name, out var value))
{
if(value.GetType().ToString() != parameter.type)
{
Debug.LogError($"参数类型不匹配: {parameter.name},期望类型: {parameter.type},实际类型: {value.GetType()}");
continue;
}
matchedParameters[parameter.name] = value;
}
}
return matchedParameters;
}
}
public interface ITrigger
{
public ITrigger Copy();
public void Active();
public void Inactive();
}
public static class SerializationHelper
{
private static readonly JsonSerializerSettings settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
Formatting = Formatting.Indented
};
public static string Serialize(object obj)
{
return JsonConvert.SerializeObject(obj, settings);
}
public static T Deserialize<T>(string json)
{
return JsonConvert.DeserializeObject<T>(json, settings);
}
}
}
/*
// 示例:自定义事件、条件和动作
namespace Script.Systems.TriggerSystem.Examples
{
public class PlayerMovedEvent : Script.Systems.TriggerSystem.Event
{
public PlayerMovedEvent()
{
eventName = "PlayerMoved";
parameters.Add(new Script.Systems.TriggerSystem.Parameter
{
name = "x",
type = "float",
value = 10.5f
});
parameters.Add(new Script.Systems.TriggerSystem.Parameter
{
name = "y",
type = "float",
value = 20.5f
});
}
}
public class HealthLowCondition : Script.Systems.TriggerSystem.Condition
{
public HealthLowCondition()
{
conditionName = "HealthLow";
parameters.Add(new Script.Systems.TriggerSystem.Parameter
{
name = "threshold",
type = "float",
value = 30f
});
}
public override bool CheckCondition()
{
Debug.Log($"{conditionName}: 检查血量是否低于 {parameters[0].value}");
return true;
}
}
public class ShowWarningAction : Script.Systems.TriggerSystem.Action
{
public ShowWarningAction()
{
actionName = "ShowWarning";
parameters.Add(new Script.Systems.TriggerSystem.Parameter
{
name = "message",
type = "string",
value = "血量过低,请注意!"
});
}
public override void Execute()
{
Debug.Log($"{actionName}: 显示警告消息: {parameters[0].value}");
}
}
}
*/
Event.cs:
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using UnityEngine;
namespace Script.Systems.TriggerSystem
{
[CreateAssetMenu(fileName = "NewEvent", menuName = "Game/Event", order = 10)]
public class Event : ScriptableObject
{
public static Dictionary<Event, HashSet<Trigger>> eventToTrigger = new();
public string eventName;
public List<Parameter> parameters = new List<Parameter>();
void OnEnable()
{
eventToTrigger.Add(this, new());
GameDataManager.Instance.RegisterEvent(GetEventID());
GameDataManager.Instance.AddListener(GetEventID(), (object arguments) =>
{
JObject argumentsJObject = arguments as JObject;
foreach (var trigger in eventToTrigger[this])
{
trigger.CheckTrigger(argumentsJObject);
}
});
}
public Event Copy()
{
var newEvent = Event.CreateInstance<Event>();
newEvent.eventName = this.eventName;
newEvent.parameters = new List<Parameter>(this.parameters);
foreach (var param in this.parameters)
{
newEvent.parameters.Add(new Parameter
{
name = param.name,
type = param.type,
});
}
return newEvent;
}
public string GetEventID()
{
return $"trigger_{eventName}";
}
}
}
ActionManager.cs:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Script.Systems.TriggerSystem
{
public static class ActionManager
{
public static Dictionary<string, Type> actionList = new Dictionary<string, Type>();
public static BaseAction GetNewActionInstance(string typeName)
{
if (actionList.TryGetValue(typeName, out Type type))
{
return (BaseAction)Activator.CreateInstance(type);
}
else
{
Debug.LogError($"Action '{typeName}' not found.");
return null;
}
}
}
public interface IAction
{
string ActionName { get; }
List<Parameter> Parameters { get; }
void Execute(JObject arguments);
}
public abstract class BaseAction : IAction
{
public JObject addonArguments;
public abstract List<Parameter> Parameters { get; }
public abstract string ActionName { get; }
public abstract void Execute(JObject arguments);
// 序列化 addonArguments
public string SerializeAddonArguments()
{
return JsonConvert.SerializeObject(addonArguments, Formatting.Indented);
}
// 反序列化 addonArguments
public void DeserializeAddonArguments(string json)
{
addonArguments = JsonConvert.DeserializeObject<JObject>(json);
}
}
public class ShowWarningAction : BaseAction
{
public override string ActionName => "ShowWarning";
static ShowWarningAction()
{
ActionManager.actionList.Add("ShowWarning", typeof(ShowWarningAction));
}
public override List<Parameter> Parameters
{
get
{
return new List<Parameter>
{
new() { name = "message", type = typeof(string).ToString() }
};
}
}
public override void Execute(JObject arguments)
{
if (arguments.TryGetValue("message", out JToken message))
{
Debug.Log($"ShowWarning: {message}");
}
else
{
Debug.LogError("No message provided for ShowWarning action.");
}
}
}
public class PlaySoundAction : BaseAction
{
public override string ActionName => "PlaySound";
static PlaySoundAction()
{
ActionManager.actionList.Add("PlaySound", typeof(PlaySoundAction));
}
public override List<Parameter> Parameters
{
get
{
return new List<Parameter>
{
new() { name = "soundName", type = typeof(string).ToString() }
};
}
}
public override void Execute(JObject arguments)
{
if (arguments.TryGetValue("soundName", out JToken soundName))
{
Debug.Log($"Playing sound: {soundName}");
}
else
{
Debug.LogError("No soundName provided for PlaySound action.");
}
}
}
}
ConditionManager.cs:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Script.Systems.TriggerSystem;
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Script.Systems.TriggerSyatem
{
public static class ConditionManager
{
public static Dictionary<string, Type> conditionList = new Dictionary<string, Type>();
public static BaseCondition GetNewConditionInstance(string typeName)
{
if (conditionList.TryGetValue(typeName, out Type type))
{
return (BaseCondition)Activator.CreateInstance(type);
}
else
{
Debug.LogError($"Condition '{typeName}' not found.");
return null;
}
}
}
public interface ICondition
{
string ConditionName { get; }
bool CheckCondition(JObject arguments);
}
public abstract class BaseCondition : ICondition
{
public JObject addonArguments;
public abstract List<Parameter> parameters { get; }
public abstract string ConditionName { get; }
public abstract bool CheckCondition(JObject arguments);
// 序列化 addonArguments
public string SerializeAddonArguments()
{
return JsonConvert.SerializeObject(addonArguments, Formatting.Indented);
}
// 反序列化 addonArguments
public void DeserializeAddonArguments(string json)
{
addonArguments = JsonConvert.DeserializeObject<JObject>(json);
}
}
public class CompareCondition : BaseCondition
{
public override string ConditionName => "CompareCondition";
static CompareCondition()
{
ConditionManager.conditionList.Add("CompareCondition", typeof(CompareCondition));
}
public override List<Parameter> parameters
{
get
{
return new List<Parameter> {
new() { name = "value1", type = typeof(float).ToString() },
new() { name = "value2", type = typeof(float).ToString() }
}
;
}
}
public override bool CheckCondition(JObject arguments)
{
// 实现比较逻辑
if (arguments.TryGetValue("value1", out JToken value1) &&
arguments.TryGetValue("value2", out JToken value2))
{
return value1.ToString() == value2.ToString();
}
return false;
}
}
public class HealthLowCondition : BaseCondition
{
public override string ConditionName => "HealthLow";
static HealthLowCondition()
{
ConditionManager.conditionList.Add("HealthLow", typeof(HealthLowCondition));
}
public override List<Parameter> parameters
{
get
{
return new List<Parameter> {
new() { name = "health", type = typeof(float).ToString() },
new() { name = "threshold", type = typeof(float).ToString() }
}
;
}
}
public override bool CheckCondition(JObject arguments)
{
// 实现健康值检查逻辑
if (arguments.TryGetValue("health", out JToken health) &&
arguments.TryGetValue("threshold", out JToken threshold))
{
return (float)health < (float)threshold;
}
return false;
}
}
}