Repository navigation
PlotModel
muxigame edited this page Nov 24, 2021
·
1 revision
GalForUnity.Plot.PlotModel是剧情模型的实现类,管理着剧情的一切他继承自MonoBehavior
在1.0b中它拥有两个属性分别是剧情要求(PlotRequire)和剧情流(PlotFlow),但是在1.0r版本,它更新了一个非常重要的功能结束活动模型(ActionModel),然而在1.1b版本中,ActionModel已被废弃,原因是PlotScript的功能和他重叠了,日后会决定删除或是拓展ActionModel。
同时1.1b版本中剧情要求被基础到了剧情模型当中,且不再是单独组件。
| 1.0b | 1.0r | 1.1b |
|---|---|---|
![]() |
![]() |
![]() |
正常情况下,当您为一个对象附加剧情模型,那么剧情模型会自动附加剧情流和剧情要求。当然您也可以再另外的对象上创建剧情流和剧情要求,再手动附加到剧情模型上,这样做的好处是能将剧情要求和剧情流独立开来,易于管理和维护。
| 字段名称 | 描述 |
|---|---|
| PlotRequire plotRequire | 剧情被触发的前提要求,可以定义角色数值等等,剧情要求内要求的所有数值均被满足后,才可触发绑定的剧情流 |
| GfuSceneGraph SceneGraph | 场景剧情图,您可以通过他间接引用资源中的场景图 |
| ActionModel actionModel | 剧情执行完毕后要执行的操作,如变更数值,变更场景等 |
| 方法名称 | 描述 |
|---|---|
| void ToExecuteList() | 将剧情模型添加到待执行列表 |
| bool CheckWhthExecuteList(RoleData roleData, SceneModel sceneModel) | 检查剧情是否满足触发要求,并将剧情模型添加到待执行列表 |
| bool CheckWhthExecuteList(RoleModel roleModel, SceneModel sceneModel) | 检查剧情是否满足触发要求,并将剧情模型添加到待执行列表 |
| bool Check(RoleData roleData, SceneModel sceneModel) | 检查剧情是否满足触发要求 |
| int Compare(PlotModel x, PlotModel y) | 实现自IComparable,此接口将允许对象进行比较 |
| int CompareTo(object obj) | 实现自IComparable,此接口将允许对象进行比较 |
using System;
using GalForUnity.Attributes;
using GalForUnity.Controller;
using GalForUnity.Graph;
using GalForUnity.InstanceID;
using GalForUnity.Model.Scene;
using GalForUnity.System;
using GalForUnity.System.Event;
using UnityEngine;
using UnityEngine.Serialization;
namespace GalForUnity.Model.Plot {
/// <summary>
/// PlotModel即剧情模型,管理着剧情要求和剧情流,在某种意义上说是剧情本身,需要剧情细节请访问PlotFlow,需要知道剧情要求请访问PlotRequire,在引用上和PlotRequire是互相引用关系
/// </summary>
// [RequireComponent(typeof(PlotRequire))]
[RequireComponent(typeof(GfuInstance))]
public class PlotModel : MonoBehaviour,IComparable {
// ReSharper disable all MemberCanBePrivate.Global
[Rename(nameof(plotRequire))]
[Tooltip("默认挂载当前对象存在的剧情要求(PlotRequire)如果当前对象不存在剧情要求,则会自动创建")]
[SerializeField]
public PlotRequire plotRequire;
// [Rename("剧情流(已废弃)")]
// [Tooltip("默认挂载剧情流(PlotFlow),如果当前对象不存在剧情流,则会自动创建")]
// public PlotFlow plotFlow;
[FormerlySerializedAs("PlotFlowGraph")]
[Rename(nameof(SceneGraph))]
[Tooltip("当剧情流图存在时,默认执行剧情流图中的内容")]
public GfuSceneGraph SceneGraph;
[Rename(nameof(actionModel))]
[Tooltip("剧情结束完后,执行指定的操作")]
#pragma warning disable 612
public ActionModel actionModel;
#pragma warning restore 612
/// <summary>
/// 在开始时,向剧情酷注册本剧情,如果剧情列表的角色要求里存在null要求,则所有场景中,只要角色数据满足要求。都会触发本事件;
/// </summary>
void Start(){
if (!SceneGraph &&gameObject.TryGetComponent(out GfuSceneGraph gfuSceneGraph)) SceneGraph = gfuSceneGraph;
plotRequire.plotModel = this;
if (plotRequire.sceneModels == null || plotRequire.sceneModels.Length == 0){
DailyStateChecker.GetInstance().RegisterPlotModel(SceneModel.NULL, this); //将空场景进行注册,所有场景均可以触发当前剧情
} else{
for (int i = 0, length = plotRequire.sceneModels.Length; i < length; i++){
SceneModel sceneModel;
if ((sceneModel = plotRequire.sceneModels[i]) == null){
sceneModel = plotRequire.sceneModels[i] = SceneModel.NULL;
DailyStateChecker.GetInstance()
.RegisterPlotModel(SceneModel.NULL,
this); //一旦发现未装填的空场景,将会立刻将剧情置为不需要剧情要求,所有场景均可以触发当前剧情,并取消已注册的剧情
return;
}
// Debug.Log("DailyStateChecker.GetInstance().RegisterPoltModel(sceneModel, this)");
DailyStateChecker.GetInstance().RegisterPlotModel(sceneModel, this); //将所有场景进行注册
}
}
}
public void ToExecuteList(){
_gameTime = GameSystem.Data.CurrentTime;
Debug.Log("检查通过");
if (!PlotModelList.GetInstance().HasPlot(this)){
PlotModelList.GetInstance().Add(this);
}
}
private GameTime _gameTime;
public bool CheckWhthExecuteList(RoleData roleData, SceneModel sceneModel) {
if (_gameTime == GameSystem.Data.CurrentTime) return false;
return CheckWhthExecuteList(roleData.RoleModel, sceneModel);
}
public bool CheckWhthExecuteList(RoleModel roleModel, SceneModel sceneModel){
if (_gameTime == GameSystem.Data.CurrentTime) return false;
if (!plotRequire.Check(roleModel.roleData, sceneModel)) return false;
EventCenter.GetInstance().PlotRequireCheckOkEvent.Invoke(this, roleModel); //触发剧情前提条件验证完成事件
ToExecuteList();
//如果剧情是不可重复的
if(!plotRequire.repeatability) DailyStateChecker.GetInstance().CancelRegister(sceneModel,plotRequire);
else if(!plotRequire.Check(roleModel.roleData, sceneModel)) DailyStateChecker.GetInstance().CancelRegister(sceneModel,plotRequire);
return true;
}
/// <summary>
/// 检查剧情是否满足触发要求
/// </summary>
/// <param name="roleData">角色数据</param>
/// <param name="sceneModel">场景数据</param>
/// <returns></returns>
public bool Check(RoleData roleData, SceneModel sceneModel) {
return plotRequire.Check(roleData, sceneModel);
}
public int Compare(PlotModel x, PlotModel y)
{
if (x is null) throw new NullReferenceException();
if (!(y is null))
return x.plotRequire.priority - y.plotRequire.priority;
throw new NullReferenceException();
}
public int CompareTo(object obj)
{
if (!(obj is null))
if(obj is PlotModel p)
return plotRequire.priority - p.plotRequire.priority;
throw new NullReferenceException();
}
}
}

