当前位置 : 主页 > 编程语言 > java >

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器

来源:互联网 收集:自由互联 发布时间:2023-02-04
更新日期:2020年2月14日。 Github源码:​​​[点我获取源码]​​​ Gitee源码:​​[点我获取源码]​​ 索引 ​​TaskEditor简介​​ ​​使用TaskEditor​​ ​​创建Task Content Asset​​ ​​

更新日期:2020年2月14日。 Github源码:​​​[点我获取源码]​​​ Gitee源码:​​[点我获取源码]​​

索引

  • ​​TaskEditor简介​​
  • ​​使用TaskEditor​​
  • ​​创建Task Content Asset​​
  • ​​打开TaskEditor窗口​​
  • ​​TaskEditor窗口详解​​
  • ​​任务内容​​
  • ​​任务内容属性详解​​
  • ​​新建任务内容类型​​
  • ​​新建任务内容​​
  • ​​任务点​​
  • ​​任务点属性详解​​
  • ​​新建任务点类型​​
  • ​​新建任务点​​
  • ​​任务点完成​​
  • ​​任务点依赖​​
  • ​​在代码中总控​​
  • ​​运行时检视面板​​

TaskEditor简介

任务编辑器,可以自定义任务点,设置任务达成条件,多个任务点组成一个任务内容,使用一系列任务内容完成角色扮演的设计。

使用TaskEditor

创建Task Content Asset

Task Content Asset(任务内容资源)为TaskEditor使用的标准资源,创建方法:Project界面右键 -> Create -> HTFramework -> TaskContentAsset

如下,新创建的Task001,点击Open按钮(或双击资源)便可以打开TaskEditor窗口编辑此资源:

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_#if

打开TaskEditor窗口

打开任意一个TaskContentAsset资源后,TaskEditor初始窗口如下图:

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_框架_02

TaskEditor窗口详解

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_unity_03

①.Task Content List(任务内容列表)

1.这里显示所有的任务内容,点击右上角的+按钮可以新增任务内容,或者创建新的任务内容类型。

2.选中任意一个任务内容后,点击右端的铅笔按钮可以打开并编辑此任务内容的脚本,点击垃圾桶按钮可以删除此任务内容。

②.Task Property(任务内容属性) 1.选中任意一个任务内容后,这里显示该任务内容的属性。

③.Task Point Area(任务点显示区域) 1.选中任意一个任务内容后,这里显示该任务内容的所有任务点。 2.右键点击可以新增任务点,或者创建新的任务点类型。

任务内容

任务内容属性详解

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_任务流程_04

当在①面板中选中一个任务内容时,②面板则显示此任务内容的属性:

1.ID:任务内容唯一标识符,不能重复(默认会自动累加,永不重复,前提是你不手动修改)。

2.Name:任务内容名称简述。

3.Details:任务内容详述。

4.Target:任务内容默认自带的一个GameObject属性,可以通过拖拽关联至场景、预制体中的任意对象,拖拽后通过ID关联,在任何时候都能找到该目标。

不过,上述为TaskContentDefault默认任务内容,我们点击编辑脚本,可以看到里面什么也没有:

/// <summary> /// 默认的任务内容 /// </summary> [TaskContent("默认")] public sealed class TaskContentDefault : TaskContentBase { }

新建任务内容类型

框架会自带TaskContentDefault这个默认任务内容类型,通过选择New Task Content Script选项启动创建向导来快捷创建新的任务内容类。

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_unity_05

如下,我们新建一个任务内容类型TaskKill:

[TaskContent("击杀任务")]public class TaskKill : TaskContentBase{ protected override void OnStart() { base.OnStart(); } protected override void OnUpdate() { base.OnUpdate(); } protected override void OnComplete() { base.OnComplete(); }#if UNITY_EDITOR protected override int OnPropertyGUI() { int height = base.OnPropertyGUI(); GUILayout.BeginHorizontal(); GUILayout.Label("[新建任务内容]"); GUILayout.EndHorizontal(); height += 20; return height; }#endif}

然后我们就可以直接在编辑面板创建该类型的任务内容:

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_unity_06

新建任务内容

新建如下这样一个常见的击杀任务:

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_ide_07

通过重写OnPropertyGUI方法可以扩展任务内容属性面板UI:

#if UNITY_EDITOR protected override int OnPropertyGUI() { int height = base.OnPropertyGUI(); return height; }#endif

height为延续属性面板高度的参数,每添加一行UI,理论上将height+=20最合适,如下,我们在TaskKill添加一个属性:

[TaskContent("击杀任务")]public class TaskKill : TaskContentBase{ //怪物地图标记 public int Sign; #if UNITY_EDITOR protected override int OnPropertyGUI() { int height = base.OnPropertyGUI(); GUILayout.BeginHorizontal(); GUILayout.Label("怪物地图标记:"); Sign = EditorGUILayout.IntField(Sign); GUILayout.EndHorizontal(); height += 20; return height; }#endif}

查看属性面板的变化:

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_任务流程_08

任务点

一个任务内容包含多个任务点,任务内容和任务点都有一个完成标记,默认情况下,任务内容的完成标记会在其所有任务点的完成标记均为true时为true。

任务点属性详解

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_框架_09

1.ID:任务点唯一标识符,不能重复(默认会自动累加,永不重复,前提是你不手动修改)。

2.Name:任务点名称简述。

3.Details:任务点详述。

4.Target:任务点目标。

5.触发方式:此为默认任务点携带的属性。

6.指引时高亮目标:此为默认任务点携带的属性。

7.持续时间:此为默认任务点携带的属性。

如下,我们点击【铅笔】按钮,打开TaskPointDefault默认任务点:

[TaskPoint("默认")] public sealed class TaskPointDefault : TaskPointBase { [SerializeField] private TaskTrigger _trigger = TaskTrigger.MouseClick; [SerializeField] private bool _highlighting = true; [SerializeField] private float _duration = 0; private TaskTarget _target; protected override void OnStart() { base.OnStart(); if (GetTarget == null) { Log.Error("任务点 " + GetName + " 的目标为空,这是不被允许的!"); } else { _target = GetTarget.GetComponent<TaskTarget>(); } } protected override void OnUpdate() { base.OnUpdate(); switch (_trigger) { case TaskTrigger.MouseClick: if (Main.m_Input.GetButtonDown(InputButtonType.MouseLeft)) { if (Main.m_Controller.RayTargetObj && Main.m_Controller.RayTargetObj == GetTarget) { Complete(); } } break; case TaskTrigger.StateChange: if (_target != null && _target.State == TaskTargetState.Done) { Complete(); } break; } } protected override void OnGuide() { base.OnGuide(); if (_highlighting && GetTarget) { Collider collider = GetTarget.GetComponent<Collider>(); if (collider && collider.enabled) { switch (Main.m_TaskMaster.GuideHighlighting) { case MouseRay.HighlightingType.Normal: GetTarget.OpenHighLight(); break; case MouseRay.HighlightingType.Flash: GetTarget.OpenFlashHighLight(); break; case MouseRay.HighlightingType.Outline: GetTarget.OpenMeshOutline(); break; } } } } protected override IEnumerator OnComplete() { yield return base.OnComplete(); if (!_duration.Approximately(0)) { yield return YieldInstructioner.GetWaitForSeconds(_duration); } } /// <summary> /// 默认的任务点触发类型 /// </summary> public enum TaskTrigger { /// <summary> /// 鼠标点击目标触发 /// </summary> MouseClick, /// <summary> /// 目标状态变为Done时触发 /// </summary> StateChange }#if UNITY_EDITOR protected override int OnPropertyGUI() { int height = base.OnPropertyGUI(); GUILayout.BeginHorizontal(); GUILayout.Label("触发方式:", GUILayout.Width(90)); _trigger = (TaskTrigger)EditorGUILayout.EnumPopup(_trigger); GUILayout.EndHorizontal(); height += 20; GUILayout.BeginHorizontal(); GUILayout.Label("指引时高亮目标:", GUILayout.Width(90)); _highlighting = EditorGUILayout.Toggle(_highlighting); GUILayout.EndHorizontal(); height += 20; GUILayout.BeginHorizontal(); GUILayout.Label("持续时间:", GUILayout.Width(90)); _duration = EditorGUILayout.FloatField(_duration); GUILayout.EndHorizontal(); height += 20; return height; }#endif }

新建任务点类型

框架会自带TaskPointDefault这个默认任务点类型,通过空白处点击右键,选择New Task Point Script选项启动创建向导来快捷创建新的任务点类。

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_任务流程_10

如下,我们新建一个任务点类型TaskPointKill:

[TaskPoint("TaskPointKill")]public class TaskPointKill : TaskPointBase{ protected override void OnStart() { base.OnStart(); } protected override void OnUpdate() { base.OnUpdate(); } protected override void OnGuide() { base.OnGuide(); } protected override IEnumerator OnComplete() { yield return base.OnComplete(); } protected override void OnAutoComplete() { base.OnAutoComplete(); } protected override void OnEnd() { base.OnEnd(); }#if UNITY_EDITOR protected override int OnPropertyGUI() { int height = base.OnPropertyGUI(); GUILayout.BeginHorizontal(); GUILayout.Label("[新建任务点]"); GUILayout.EndHorizontal(); height += 20; return height; }#endif}

然后我们就可以直接在编辑面板创建该类型的任务点:

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_框架_11

新建任务点

我们新建如下两个任务点,用来细分任务内容:

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_ide_12

不过,我们的任务点目前并不知道如何才算杀了黄蜂,所以我们要在TaskPointKill中写一些东西:

[TaskPoint("击杀任务点")]public class TaskPointKill : TaskPointBase{ //任务的击杀目标 public string KillTarget; //任务的击杀数量 public int KillNumber; protected override void OnUpdate() { base.OnUpdate(); if (KillPool.Target[KillTarget].KillNumber >= KillNumber) { Complete(); } } protected override IEnumerator OnComplete() { yield return base.OnComplete(); //等待1秒后再改变自身完成状态 yield return YieldInstructioner.GetWaitForSeconds(1); }#if UNITY_EDITOR public override int OnPropertyGUI() { int height = base.OnPropertyGUI(); GUILayout.BeginHorizontal(); GUILayout.Label("任务击杀目标:"); KillTarget = EditorGUILayout.TextField(KillTarget); GUILayout.EndHorizontal(); height += 20; GUILayout.BeginHorizontal(); GUILayout.Label("任务击杀数量:"); KillNumber = EditorGUILayout.IntField(KillNumber); GUILayout.EndHorizontal(); height += 20; return height; }#endif}

查看属性面板的变化:

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_unity_13

任务点完成

任务点的OnUpdate会每帧执行,当此任务内容激活,且此任务点激活时:

public override void OnUpdate() { base.OnUpdate(); if (KillPool.Target[KillTarget].KillNumber >= KillNumber) { Complete(); } }

所以,在OnUpdate中判断合适的时机,调用Complete(),便是标记此任务点完成。

任务点依赖

对于如上的两个简单的任务点,不存在任何的依赖(连线),也就不存在任何的先后关系,先杀大黄蜂或是先杀小黄蜂都可以,只要两个任务点完成,整个任务内容就算完成。

但是,如果我们的要求是先杀3只小黄蜂,然后再杀2只大黄蜂,那么就要用到接下来的任务点依赖了。

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_ide_14

注意:任务点杀死2只大黄蜂的左侧连接至任务点杀死3只小黄蜂的右侧,表示任务点杀死2只大黄蜂依赖于杀死3只小黄蜂,如果A依赖于B,则必须B任务点完成以后,A任务点才会激活。

注意:请不要在任务内容和任务点中定义不可序列化类型的字段,对于GameObject这个常用的类型,理论上他是可以序列化的,但我们的TaskContentAsset资源是全局的,并不针对某一个Prefab,所以GameObject在这里也是不可序列化类型。

注意:在这里可以使用TaskGameObject代替GameObject。

如下,定义一个TaskGameObject字段,在OnPropertyGUI中必须使用TaskGameObjectField才能画出该字段:

public TaskGameObject Target;#if UNITY_EDITOR public override int OnPropertyGUI() { int height = base.OnPropertyGUI(); GUILayout.BeginHorizontal(); GUILayout.Label("任务击杀目标:"); KillTarget = EditorGUILayout.TextField(KillTarget); GUILayout.EndHorizontal(); height += 20; GUILayout.BeginHorizontal(); GUILayout.Label("任务击杀数量:"); KillNumber = EditorGUILayout.IntField(KillNumber); GUILayout.EndHorizontal(); height += 20; TaskGameObject.DrawField(Target, "Target:", 50, Anchor.width); height += 20; return height; }#endif

查看属性面板变化:

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_#if_15

我们可以拖拽Scene中的任意GameObject到属性面板:

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_unity_16

我们把鼠标放在TaskGameObject字段的名称(比如这里的Target)上,会显示该对象的GUID,任何时候,当对象丢失时,任务执行器会通过GUID找到他,只要场景中存在这个对象,不管他是名字改变了,还是层级改变了!只有点击后面的垃圾桶按钮才能彻底删除这个对象。

在代码中总控

1、首先,需要将TaskContentAsset资源指定给TaskMaster(静态指定和动态指定均可):

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_unity_17

2、然后,开始整个Task流程:

//重新编译所有任务内容 Main.m_TaskMaster.RecompileTaskContent(); //任务流程开始 Main.m_TaskMaster.Begin();

3、终止整个Task流程:

//任务流程终止 Main.m_TaskMaster.End();

4、监听全局事件:

//任务流程开始事件 EventTaskBegin //任务流程结束事件 EventTaskEnd //任意任务内容激活事件 EventTaskContentStart //任意任务内容完成事件 EventTaskContentComplete //任意任务点激活事件 EventTaskPointStart //任意任务点完成事件 EventTaskPointComplete

运行时检视面板

在编辑器中运行时将会出现运行时检视面板(Runtime Data),主要用以调试或数据监测,目前面板如下:

【Unity】 HTFramework框架(三十)TaskEditor任务编辑器_#if_18

1.No Runtime Data!

上一篇:基于springboot的网上零食购物系统
下一篇:没有了
网友评论