Repository navigation
PlotFlowController
muxigame edited this page Nov 24, 2021
·
1 revision
GalForUnity.Controller.PlotFlowController 是剧情流控制器,管理着剧情的始终。
GalForUnity.Controller.PlotFlowController是GalForUnity最重要的类之一,他掌管着剧情执行的始终,他在Unity的Update方法中监听着用户触屏操作,并且一跳跳的执行着满足的条件的剧情,通常情况下,优先级由一下情况排序:替换事件>固定事件>特殊事件>常规事件,并且各种事件的功能均不相同,在正常的游戏逻辑里,固定剧情是最先执行的,所有同类型的剧情则会根据优先级执行。对于一个正在执行的剧情,在一个正常的执行流程内,不能终止其执行,在一个正常的剧情流程内,替换剧情可以在任何时间任何情况下替换掉满足替换条件的剧情。
| 名字 | 描述 |
|---|---|
| GraphData currentGraphData | 当前接受剧情流控制器管控的剧情图数据,并不是所有的剧情图在在剧情流控制器中都可以访问到 |
| GfuGraph CurrentGraph | 当前接受剧情流控制器管控的剧情图,并不是所有的剧情图在在剧情流控制器中都可以访问到 |
| PlotModel currentPlotModel | 当前正在执行的剧情模型 |
| PlotModelList ReadyExecutePlotModelSet | 所有待执行剧情的列表引用 |
| Dictionary<string, List> PlotModels | 所有剧情的列表引用 |
| 名字 | 描述 |
|---|---|
| void ExecuteGraph(GraphData graphData) | 执行指定剧情图 |
| void ExecutePoltItem(PlotItem plotItem) | 执行单个剧情项 |
using System;
using System.Collections.Generic;
using GalForUnity.Attributes;
using GalForUnity.Graph;
using GalForUnity.Model;
using GalForUnity.Model.Plot;
using GalForUnity.System;
using GalForUnity.System.Event;
#if LIVE2D
using Live2D.Cubism.Framework.Motion;
#endif
using UnityEngine;
using UnityEngine.Serialization;
using GraphData = GalForUnity.Graph.Data.GraphData;
namespace GalForUnity.Controller{
// ReSharper disable all MemberCanBePrivate.Global
/// <summary>
/// 剧情流控制器,控制着剧情的流程,执行着剧情的流程,剧情逻辑的核心
/// </summary>
public class PlotFlowController : MonoBehaviour{
// [Rename(nameof(plotMode))] public PlotMode plotMode;
// [Rename(nameof(SceneGraph))]
/// <summary>
/// 当前接受剧情流控制器管控的剧情图数据,并不是所有的剧情图在在剧情流控制器中都可以访问到
/// </summary>
[FormerlySerializedAs("SceneGraph")] [HideInInspector]
public GraphData currentGraphData;
/// <summary>
/// 当前接受剧情流控制器管控的剧情图,并不是所有的剧情图在在剧情流控制器中都可以访问到
/// </summary>
public GfuGraph CurrentGraph;
/// <summary>
/// 当前正在执行的剧情模型
/// </summary>
[Rename(nameof(currentPlotModel))]
public PlotModel currentPlotModel;
/// <summary>
/// 所有待执行剧情的列表引用
/// </summary>
public PlotModelList ReadyExecutePlotModelSet;
/// <summary>
/// 所有剧情的列表引用
/// </summary>
// public DailyStateChecker AllPlotModelSet;
public Dictionary<string, List<PlotModel>> PlotModels = new Dictionary<string, List<PlotModel>>();
private void OnEnable(){
PlotModels.Add("" + PlotType.date, new List<PlotModel>());
PlotModels.Add("" + PlotType.plot, new List<PlotModel>());
EventCenter.GetInstance().AddEventListening("date", Date);
EventCenter.GetInstance().OnPlotWillExecuteEvent = Plot;
EventCenter.GetInstance().OnGraphExecutedEvent = OnGraphExecuted;
EventCenter.GetInstance().OnGraphExecutedEvent += (x) => {
};
ReadyExecutePlotModelSet = PlotModelList.GetInstance();
}
private void Update(){
//无时无刻检查剧情是否通过日期检查
DailyStateChecker.GetInstance().Check(GameSystem.Data.CurrentRoleModel, GameSystem.Data.CurrentSceneModel);
if (!currentGraphData){
ExecuteGraph();
}
if (currentGraphData && !currentGraphData.isPlay){
Debug.Log("进入剧情");
ExecuteGraph();
}
}
private void ExecuteGraph(){
var plotModel = ReadyExecutePlotModelSet.GetPlot();
if (plotModel){
var invoke = EventCenter.GetInstance().OnPlotWillExecuteEvent.GetInvocationList();
List<bool> replace = new List<bool>();
foreach (var @delegate in invoke){
replace.Add( (bool)@delegate.Method.Invoke(@delegate.Target, new object[] {
plotModel, GameSystem.Data.CurrentRoleModel
}));
}
if (!replace.TrueForAll((b => !b))){
ReadyExecutePlotModelSet.PopPlot();
} else{
PlotModel plotModel2 = ReadyExecutePlotModelSet.PopPlot();
currentPlotModel = plotModel2;
ExecuteGraph(plotModel2.SceneGraph.graphData);
}
}
}
/// <summary>
/// 执行指定剧情图
/// </summary>
/// <param name="graphData"></param>
/// <exception cref="ArgumentException">剧情图不是一个已经支持的类型</exception>
public void ExecuteGraph(GraphData graphData){
currentGraphData = graphData;
if (currentGraphData is Graph.Data.Property.PlotItemGraphData){
CurrentGraph = new PlotItemGraph(graphData);
CurrentGraph.Play(this);
} else if (currentGraphData is Graph.Data.Property.PlotFlowGraphData){
CurrentGraph = new PlotFlowGraph(graphData);
CurrentGraph.Play(this);
} else{
throw new ArgumentException("Unknown Graph,Support Type is PlotItemGraphData and PlotFlowGraphData");
}
}
private void OnGraphExecuted(GfuGraph gfuGraph){
if (gfuGraph.IsCaller(this)){
if (currentPlotModel.plotRequire.overDay) GameSystem.Data.CurrentTime=GameSystem.Data.CurrentTime.NextDay();
currentPlotModel = null;
currentGraphData = null;
}
}
/// <summary>
/// 初始化剧情流控制器
/// </summary>
public void InitialPlowFlowController(){ }
private void Date(){
foreach (var plotModel in PlotModels["date"]){
if (plotModel.Check(GameSystem.Data.CurrentRoleModel.roleData, GameSystem.Data.CurrentSceneModel)){
ReadyExecutePlotModelSet.Add(plotModel);
}
}
}
private bool Plot(PlotModel model, RoleModel roleModel){
foreach (var plotModel in PlotModels["plot"]){
if (plotModel != model && plotModel.plotRequire.triggerPlot == model){
if (plotModel.plotRequire.NormalCheck(GameSystem.Data.CurrentRoleModel.roleData, GameSystem.Data.CurrentSceneModel)){
CanRepetitionCheck(plotModel);
if (plotModel.plotRequire.triggerType == TriggerType.before){
ReadyExecutePlotModelSet.Insert(0, plotModel);
return false;
} else if (plotModel.plotRequire.triggerType == TriggerType.after){
ReadyExecutePlotModelSet.Insert(1, plotModel);
return false;
} else{
ReadyExecutePlotModelSet.Insert(1, plotModel);
return true;
}
}
}
}
return false;
}
private void CanRepetitionCheck(PlotModel model){
if (!model.plotRequire.repeatability){
PlotModels["plot"].Remove(model);
DailyStateChecker.GetInstance().CancelRegister(model.plotRequire);
}
if (model.plotRequire.repetitionCount != 0){
model.plotRequire.repetitionCount--;
} else{
PlotModels["plot"].Remove(model);
DailyStateChecker.GetInstance().CancelRegister(model.plotRequire);
}
}
/// <summary>
/// 执行单个剧情项,
/// </summary>
/// <param name="plotItem">剧情项</param>
public bool ExecutePoltItem(PlotItem plotItem){
// bool Played = false;
GameSystem.Data.ShowPlotView.ShowAll(plotItem.name, plotItem.speak, plotItem.background, plotItem.audioClip); //显示所有内容
if (plotItem.Animations!=null){
#if LIVE2D
var cubism = GameSystem.Data.CurrentRoleModel.gameObject.GetComponent<CubismMotionController>(); //找到动画的所属的模型控制器
for (int i = 0, length = plotItem.Animations.Count; i < length; i++){
if (plotItem?.Animations[i] != null){
if (cubism.IsPlayingAnimation(i)){ //当播放新动画时,如果没有新动画,继续之前的动画停止之前在播放的动画
cubism.StopAllAnimation();
}
cubism.PlayAnimation(plotItem.Animations[i], i, 3, true, 1); //并行播放所有动画
// Played = true;
}
}
#endif
EventCenter.GetInstance().OnPlotItemExecutedEvent.Invoke();
return true;
}
return true;
}
}
}