在GAS中,对所有战斗相关的实例(效果,buff,技能,状态)都有一个或多个gameplaytag,这个标签的作用是用于区分实例是否是同一个配置来源。
由于我们希望实现的目的是所有的技能、效果等都是可配置的,而目前来说一个效果的配置是存储在scriptableObject中,多个效果实例在代码层面上,都是一个类型,仅仅是读取的配置项不同。而为了区分它们,以便对同一效果进行区分对待,比如有的技能多次命中会刷新时间eg:大部分的眩晕技能),有的技能多次命中则叠加层数(eg:小鱼人的敏捷偷取),这里就抽象出一层标签。
其实使用约定好格式的字符串或者枚举类也可以达成这个目的。但是这一层gameplaytag的封装,使得区分的方式更加多样,这就比枚举类要功能更强(可以在gameplaytag这个类中增加各种区分方法),并且更不容易因为约定的字符串写错或数量太大难以维护。
我们来看代码,代码非常简单。
using UnityEngine;
public class GameplayTagScriptableObject : ScriptableObject
{
/// <summary>
/// 父级标签
/// </summary>
[SerializeField]
private GameplayTagScriptableObject parent;
public GameplayTagScriptableObject Parent => parent;
/// <summary>
/// 是否另一标签的衍生标签
/// </summary>
/// <param name="other"></param>
/// <param name="serchLimit"></param>
/// <returns></returns>
public bool IsDescendantOf(GameplayTagScriptableObject other, int searchLimit = 4)
{
int i = 0;
GameplayTagScriptableObject tag = Parent;
while (searchLimit > i++)
{
// tag will be invalid once we are at the root ancestor
if (!tag) return false;
// Match found, so we can return true
if (tag == other) return true;
// No match found, so try again with the next ancestor
tag = tag.Parent;
}
// If we've exhausted the search limit, no ancestor was found
return false;
}
}
一个parent,可以为空,用于配置自己的父级,一个方法用于确认标签是否是另一个标签的衍生层级。
这样我们就有了一套分层级的标签结构,使用恰当的话在开发中就不需要对很多实例进行类型判断,开销也会小一些。