Skip to content

PlotModel

muxigame edited this page Nov 24, 2021 · 1 revision

剧情模型 Plot Model

$\textcolor{RedOrange}{GalForUnity.Model.Plot.PlotModel:MonoBehavior}$

GalForUnity.Plot.PlotModel是剧情模型的实现类,管理着剧情的一切他继承自MonoBehavior

功能

在1.0b中它拥有两个属性分别是剧情要求(PlotRequire)和剧情流(PlotFlow),但是在1.0r版本,它更新了一个非常重要的功能结束活动模型(ActionModel),然而在1.1b版本中,ActionModel已被废弃,原因是PlotScript的功能和他重叠了,日后会决定删除或是拓展ActionModel。

同时1.1b版本中剧情要求被基础到了剧情模型当中,且不再是单独组件。

1.0b 1.0r 1.1b
image-20201229115752859 image-20210104155355433 image-20211121210752305

正常情况下,当您为一个对象附加剧情模型,那么剧情模型会自动附加剧情流和剧情要求。当然您也可以再另外的对象上创建剧情流和剧情要求,再手动附加到剧情模型上,这样做的好处是能将剧情要求和剧情流独立开来,易于管理和维护。

字段

字段名称 描述
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();
        }
    }
}

Clone this wiki locally