Welcome back. So we've created a Singleton or a gameplay 欢迎回来。所以我们创建了一个单例或者一个游戏
tags and we have a function. It's static called 标签，我们有一个函数。它是静态的
initialize native gameplay tags now so 现在初始化本机游戏标签
far. We're just adding a native gameplay tag for attributes 做。我们只是为属性添加原生游戏标签
secondary armor. 二级装甲。
Now we need to call this function at some point. And that's why we're 现在我们需要在某个时刻调用这个函数。这就是为什么我们
going to create our very own asset manager. Now. 将创建我们自己的资产管理公司。现在。
What's an asset manager? It's another Singleton and it 什么是资产管理人？这是另一个 Singleton，它
has to do with loading primary assets 与加载主要资源有关
and it's where we can initialize this 这是我们可以初始化的地方
Singleton where we can call this function. Now, the 我们可以在 Singleton 中调用这个函数。现在
asset manager is a Singleton and that 资产管理器是一个单例，并且
there is only a single one in the 中只有一个
whole project and we set that at the project level. 整个项目，我们将其设置在项目级别。
So we're gonna learn how to do that. But first we have to 所以我们要学习如何做到这一点。但首先我们必须
create the class for it. So we're gonna do that. We're gonna go 为它创建一个类。所以我们要这么做。我们要去
ahead and press run no need to 向前并按运行，无需
run in debug mode at this point in time. We're just gonna make a new 此时以调试模式运行。我们只是要制作一个新的
class our new asset manager. 我们新的资产管理公司。
So to make our asset manager. 所以要做我们的资产经理。
Will go into our C++ classes or a 将进入我们的 C++ 课程或
public folder. We'll go ahead and put it here new C++ 公共文件夹。我们将继续将其放在这里 new C++
class. We're going to choose all classes and search for 班级。我们将选择所有类别并搜索
asset manager. 资产管理者。
And we're going to choose asset manager. We'll click next we'll 我们将选择资产管理人。我们将点击下一步
go ahead and let it go into Aura public and we'll 继续让它进入 Aura public 我们会
call this. 打电话给这个。
Or asset manager. Let's create the class and close 或者资产经理。让我们创建类并关闭
the editor. 编辑。
And now we can start to Define this single ten, which is 现在我们可以开始定义这一个十，即
going to be quite simple as with our other Singleton. We're 就像我们的其他 Singleton 一样非常简单。是
going to have a static get function. So let's 将有一个静态获取函数。让我们
make a public section and we'll have a function that's 创建一个公共部分，我们将有一个函数
static that returns an aura 返回光环的静电
asset manager reference a reference to the one and 资产管理器引用了一个引用和
only asset manager. 只有资产管理公司。
We'll call this get and we'll go ahead and generate this 我们将调用此 get，然后我们将继续生成此
definition. And what does the get function return? 定义。 get 函数返回什么？
Well, it's going to return the engines asset 嗯，它将返还引擎资产
manager, but we're going to cast it to this type. 经理，但我们将把它转换为这种类型。
So we're going to set the asset manager. We're going 所以我们要设置资产管理器。本来打算
to do that in one of our config files and we'll see that very shortly. 在我们的一个配置文件中执行此操作，我们很快就会看到这一点。
But once our project has this class set to 但是一旦我们的项目将此类设置为
be its asset manager. Then we can Define 担任其资产管理者。然后我们可以定义
the static get function to return 要返回的静态 get 函数
that asset manager cast to this class. Now, 该资产经理投向此类。现在，
we get the engines asset manager from 我们从以下地方获得引擎资产管理器
G engine asset manager. G发动机资产经理。
So that's what we're going to cast now first. We're going to assert that 这就是我们现在要首先投射的内容。我们要断言
g engine is valid. g 引擎有效。
It should be if it's not we're going to crash intentionally because 应该是这样，否则我们就会故意坠毁，因为
then we have larger problems. Now, we're 那么我们就会遇到更大的问题。现在，我们是
going to take its asset manager and cast so cast. 将采取其资产管理人和演员阵容。
What are we gonna cast to we're gonna cast to you or asset 我们要投射什么 我们要投射给你或资产
manager? 经理？
Now this is going to return a pointer for us so we 现在这将为我们返回一个指针，所以我们
can have a pointer to you are asset manager 可以有一个指针指向您是资产经理
called. 叫。
our asset manager 我们的资产经理
But this function doesn't return a pointer. It returns a reference. 但这个函数不返回指针。它返回一个引用。
So we're going to return the dereferenced pointer 所以我们将返回取消引用的指针
or asset manager. 或资产管理人。
And of course, we could just de-reference this and return 当然，我们可以取消引用它并返回
it like this. 像这样。
If we wanted to do it that way. 如果我们想这样做的话。
But I'm going to just do it this way. Okay, so that's the 但我打算这样做。好的，我知道这就是
first thing we have to do is we need to define the get 我们要做的第一件事是定义 get
function which will return this 将返回 this 的函数
actual type. 当前类型。
Now once we've done that our asset manager needs to 现在，一旦我们完成了我们的资产经理需要
override a function that exists on the asset manager 覆盖资产管理器上存在的函数
class. That's a protected function. So we'll make a protected section 班级。这是一个受保护的函数。所以我们将创建一个受保护的部分
and it's a virtual void function called start 这是一个名为 start 的虚函数
initial loading. This is called 初始加载。这就是所谓的
very early on and this is when we start the 很早就开始了，这就是我们开始的时候
initial loading for our assets for the game and this 游戏资产的初始加载
is the perfect place for us to call that initialize native 是我们调用初始化本机的最佳位置
tags function that we have here in Aura gameplay 我们在 Aura 游戏中拥有的标签功能
tags. It's a static function we can call that here. That's 标签。这是一个静态函数，我们可以在这里调用它。那是
what we're going to do. So here and start initial 我们要做什么。所以在这里开始初始
loading after calling super. 调用 super 后加载。
We're going to load the native tags. So that means we need our 我们将加载本机标签。所以这意味着我们需要我们的
Aura gameplay tags header file included here. 此处包含 Aura 游戏标签头文件。
So let's go ahead and include or a gameplay tags 因此，让我们继续添加游戏标签
dot h and we'll use f or 点 h 我们将使用
a gameplay tags. 到游戏标签。
double colon initialize native gameplay tags 双冒号初始化原生游戏标签
This will call that function and what's that going to do? Well, it's 这将调用该函数，它会做什么？嗯，这是
going to initialize native gameplay tags. It's going to 将初始化本机游戏标签。它将
get the gameplay tag manager and call add 获取游戏标签管理器并调用 add
native gameplay tag, and that's going to create our attribute 原生游戏标签，这将创建我们的属性
secondary armor gameplay tag. So 次要装甲游戏标签。我知道
now the last thing to do is set this Aura 现在要做的最后一件事就是设置这个光环
asset manager to be our projects asset manager. 资产经理成为我们的项目资产经理。
Right. So how do we do that? 正确的。那么我们该怎么做呢？
Well, first of all, I'm going to go ahead and compile just to 好吧，首先，我要继续编译
make sure we have no compiler errors. 确保我们没有编译器错误。
And to set the asset manager for our project we go to 要为我们的项目设置资产管理器，我们需要
our config files. 我们的配置文件。
So let's go into our projects config folder and the 所以让我们进入我们的项目配置文件夹和
config file we're interested in is default engine dot 我们感兴趣的配置文件是默认引擎点
in I so here. We have a number 在我知道这里。我们有一个号码
of settings and the one we're interested in 设置和我们感兴趣的设置
setting is our asset manager. We can specify that here 设置是我们的资产管理器。我们可以在这里指定
now first control F to search 现在首先检查 F 进行搜索
for asset manager and make sure that you 对于资产经理并确保您
don't have it set already so we don't have asset manager 还没有设置，所以我们没有资产管理器
set. So here's how we set it. 放。我们是这样设置的。
Find the section scriptengine.engine. Here's 找到 scriptengine.engine 部分。这是
how we actually set it just under 我们实际上是如何将它设置在下面的
whatever lines you have under this script /engine.engine. 脚本 /engine.engine 下的任何行。
We're going to specify the 我们将指定
asset manager by typing asset manager 通过输入 asset manager 来进行资产管理
class name equals. 类名等于。
script and that's forward slash script 脚本，这是正斜杠脚本
forward slash and then we use our project name. 正斜杠，然后我们使用我们的项目名称。
That's Aura Dot and then our asset manager 那是 Aura Dot，然后是我们的资产经理
class name or a asset manager now, 现在的类名或资产管理器，
we don't put the you for Aura 我们不会把你当作光环
asset manager. 资产管理者。
We leave that off. 我们将其保留。
So this is how we specify Aura asset manager to be our projects 这就是我们指定 Aura asset manager 作为我们的项目的方式
asset manager we go to script /engine.engine here 资产管理器我们在这里转到脚本/engine.engine
in default engine.ini and we say asset manager 在默认的engine.ini中，我们说资产管理器
class name equals slash script / 类名等于斜杠脚本/
aura or your project name dot Aura aura 或您的项目名称点 Aura
asset manager or your asset manager name. Let's go ahead and 资产经理或您的资产经理姓名。让我们继续吧
save and close that. 保存并关闭它。
And now we can go ahead and compile and launch 现在我们可以继续编译并启动
the engine. Let's go ahead and do that. 引擎。让我们继续这样做吧。
I just hit the debug button. 我刚刚按下了调试按钮。
So now that we've compiled and launched the engine, let's just 现在我们已经编译并启动了引擎，让我们
go to edit project settings gameplay tags. 去编辑项目设置游戏标签。
And let's take a look at our gameplay tags attributes. And 让我们看一下我们的游戏标签属性。和
here we have secondary and if we expand that 这里我们有次要的，如果我们扩展它
here's armor if we hover over it. It says 如果我们将鼠标悬停在它上面，这就是盔甲。它说
attributes dot secondary dot armor and in 属性点 次要点 护甲 和
parentheses native now, if we go to our 现在括号是原生的，如果我们去我们的
other ones like vital health, for example, 其他例如重要的健康，
the parentheses doesn't say native. It says the 括号里没有说native。它说
dot I and I file where this is defined so we 点 I 和 I 文件定义了这个，所以我们
don't have this defined and c++? That's what 没有这个定义和c++吗？就是这样
our native gameplay tags are and that's fine. We 我们的原生游戏标签就这样结束了。我们
may not care about accessing the health tag from 可能不关心从以下位置访问健康标签
within c++? If we just want to access it 在c++中？如果我们只是想访问它
within blueprint and there's no need for it to be a native tag 在蓝图中，不需要它是原生标签
then fine. But what about tags that we already have 然后结束。但是我们已经拥有的标签又如何呢？
like our primary attributes that are 就像我们的主要属性一样
not native. They're defined in our primary attributes 不是本地人。它们在我们的主要属性中定义
data table. What about those? What if 数据表。那些呢？如果什么
we want those to be native? Well, we can make those native we can 我们希望那些是本地的？好吧，我们可以让那些本地人成为我们可以的
just remove the 只需删除
Able from the gameplay tag table list by hitting the trash can icon 能够通过点击垃圾桶图标从游戏标签表列表中
now. We don't have those primary attributes 现在。我们没有这些主要属性
careful doing this if you're using those 如果您正在使用这些，请小心执行此操作
attributes in assets and blueprints. Well now those 资产和蓝图中的属性。那么现在那些
will be gone and they'll have to be set all over again. But 将会消失，并且必须重新设置。但
the cool thing is we can now add gameplay tags 很酷的是我们现在可以添加游戏标签
to our project natively in our Aura gameplay 在我们的 Aura 游戏中原生地添加到我们的项目
tag Singleton and we now have our own Aura asset Singleton 标签，我们现在拥有自己的 Aura 资产
manager that starts the initial loading. That's what 开始初始加载的管理器。就是这样
calls initialized native gameplay tags. That's great. The last 调用初始化的本机游戏标签。那太棒了。最后
piece of the puzzle is well, how do we use these gameplay tags 拼图很好，我们如何使用这些游戏标签
in our code, right? 在我们的代码中，对吗？
Well, let's just see how we can do that. 好吧，让我们看看如何做到这一点。
Where is a good place to test out accessing our 哪里是测试访问我们的好地方
gameplay tags and code? Well, I think perhaps in our 游戏标签和代码？嗯，我想也许在我们这里
ability system components dot CPP. We 能力系统组件点 CPP。我们
have ability actor info set. Let's 有能力演员信息集。让我们
just test it out here. 在这里测试一下。
I'd like to access our native gameplay tag armor and 我想访问我们的原生游戏标签盔甲和
then just prove to myself that I've accessed 然后向自己证明我已经访问过
It by Say printing a message to the screen that 比如说在屏幕上打印一条消息
way we'll see how we can access those tags. Now F 我们将看到如何访问这些标签。现在F
or a gameplay tags has that static get function. 或者游戏标签具有静态获取功能。
It's F or a gameplay tags. 这是用于游戏标签。
double colon get 双冒号获取
Now as soon as I did that of course writer includes or a 现在，一旦我这样做了，当然作者包括或
gameplay tags for me, so you'll have to make sure that you 我的游戏标签，所以你必须确保你
do that. 去做。
And what is this return? Well, it returns our gameplay tags 而这个回报是什么？好吧，它返回我们的游戏标签
the one and only Singleton right? We can 唯一的单例对吧？我们可以
store that and we'll store it in a const 存储它，我们将它存储在 const 中
reference. 参考。
We don't want to make a copy of it. We'll call this const F 我们不想复制它。我们将其称为 const F
or a gameplay tags reference gameplay tags. 或游戏标签引用游戏标签。
And now that we have that Singleton we can access the 现在我们有了 Singleton，我们可以访问
tags. We can say gameplay tags Dot 标签。我们可以说游戏玩法标签 Dot
and well too bad. We 也太糟糕了。我们
don't have a variable on that Singleton for 该 Singleton 上没有变量
our armor, right? That's what we need. And that's 我们的铠甲，对吧？这就是我们所需要的。那就是
what we're going to add to it now. So we go back to Aura gameplay tags, 我们现在要添加什么。所以我们回到 Aura 游戏标签，
and we need a public armor gameplay 我们需要公共装甲游戏
tag variable. 变量标签。
So let's add that variable. It's going to be an F gameplay 那么让我们添加该变量。这将是一个F游戏
tag called. Here's the convention. 标签称为。这是大会。
We'll use we'll say attributes underscore. 我们将使用我们所说的属性下划线。
secondary 中学
underscore armor 下划线装甲
So we'll just use underscores in place of the dot for 所以我们只使用下划线代替点
the gameplay tag. 游戏标签。
Now we need to set this right and we know that we're creating the 现在我们需要纠正这一点，我们知道我们正在创建
gameplay tag in the CPP file CPP 文件中的游戏标签
here with ADD native gameplay tag. 这里添加了本机游戏标签。
How do we associate that tag with our actual gameplay 我们如何将该标签与我们的实际游戏玩法相关联
tag variable? Well, add native 变量标签？好吧，添加原生
gameplay tag returns that tag. So what we can do 游戏标签返回该标签。那么我们能做什么
is just store it in our new variable attributes 只是将其存储在我们的新变量属性中
secondary armor. 二级装甲。
So we'll say attributes secondary armor equals. 所以我们会说属性次要护甲等于。
Now we get the red squiggles because this is a static function. 现在我们得到红色波浪线，因为这是一个静态函数。
So we have to have some object of 所以我们必须有一些对象
this type. Well, we know there's only one object of 这个类型。好吧，我们知道只有一个对象
this type and we need to set the gameplay tag on 这种类型，我们需要将游戏标签设置为
that object. So we say gameplay tags dot attributes 那个物体。所以我们说游戏玩法标签点属性
secondary armor. See we have access to the one 二级装甲。看看我们是否可以访问该
and only instance of it here. So that's how we do 这里只是一个例子。所以我们就是这样做的
it. en.
So now that this is happening. We're storing 所以现在这件事正在发生。我们正在存储
attributes secondary armor. 属性副甲。
Then in our Aura ability system component we can 然后在我们的Aura能力系统组件中我们可以
take our gameplay tags. 获取我们的游戏标签。
And we can access attributes secondary armor. And because 我们可以访问属性辅助装甲。并且因为
this is a gameplay tag and gameplay tags have the 这是一个游戏标签，游戏标签有
ability to be converted to Strings. We can call two string we 转换为字符串的能力。我们可以称两个字符串为
can print a message with this. I'm going 可以用它打印一条消息。我要去
to go ahead and comment it out while I'm working and just add 在我工作时继续将其注释掉并添加
a debug message G engine. 调试消息 G 引擎。
Add on screen debug message. I'll use a key of negative one 添加屏幕调试消息。我将使用负一键
time to display can be 10 seconds 10.f 显示时间可以是10秒10.f
color can be F color. 颜色可以是F色。
Orange and the message can be F string. 橙色和消息可以是F字符串。
print f 打印 f
will have text that says tag percent s 将有文字显示标签百分比 s
followed by an asterisk and we'll use this 后跟一个星号，我们将使用它
expression here gameplay tags dot attributes secondary 此处表达游戏玩法标签点属性次要
armor dot two string. 盔甲点两串。
We'll put that right there. 我们会把它放在那里。
And we get a semicolon at the end. 最后我们得到一个分号。
So just an on-screen debug message that's going 所以只是屏幕上的调试消息
to prove to us that we're actually accessing a 向我们证明我们实际上正在访问
gameplay tag that was created natively. I'm going 本地创建的游戏标签。我要去
to go ahead and remove this comment here and to make things easier to 继续并删除此处的评论并使事情变得更容易
read let's put things on their own lines here. 阅读让我们把事情放在自己的行上。
Like so we'll go ahead and do that. So all 就像这样，我们将继续这样做。我无所不知
that's left to do is play test the game start the 剩下要做的就是玩测试游戏开始
game and see if we get this orange debug message proving 游戏，看看我们是否收到橙色调试消息证明
that we've accessed gameplay tags natively 我们已经原生访问了游戏标签
in code and we've accessed gameplay 在代码中，我们已经访问了游戏玩法
tags dots attributes secondary armor. Let's 标签点属性辅助护甲。让我们
go ahead we'll run in debug mode and we'll test this 继续，我们将在调试模式下运行，我们将对此进行测试
out. 出去。
Okay moment of truth. Let's press play. 好吧，关键时刻。让我们按下播放键。
And check it out tag dot attribute secondary armor. 并查看标签点属性辅助装甲。
Now, we've got it printed four different 现在，我们已经打印了四种不同的
times, but that's just because we're printing this from within 次，但这只是因为我们是从内部打印的
the ability system component and each of 能力系统组件和每个
these enemies has one 这些敌人有一个
if we just take one of these enemies such as this one and hit delete 如果我们只选择其中一个敌人（例如这个）并点击删除
and remove it. Now. There are only three ability system 并将其删除。现在。能力系统只有三个
components and if we press play we only see the message three times, 如果我们按下播放键，我们只会看到该消息三次，
so don't let that trip you up. It's only being 所以不要让这个绊倒你。这只是
created once but we're printing the message here in 创建一次，但我们在此处打印消息
ability actor info set which happens three times 发生三次的能力演员信息集
at least in a standalone game. 至少在独立游戏中是这样。
So this is great. We now have our asset manager. It's now 所以这很棒。我们现在有了资产经理。下雪了
set in our project and we have a 在我们的项目中设置，我们有一个
Singleton or a gameplay tags where we can 单例或游戏标签，我们可以
Define our native gameplay tags now writers 现在定义我们的原生游戏标签
only letting me put a single space here. So what 只让我在这里留一个空格。所以呢
I'd like to do is add three more spaces, so there's 我想做的是再添加三个空格，所以有
at least four here just so this looks nice and indented. 这里至少有四个，这样看起来就很漂亮并且有缩进。
Okay. 好的。
Great job. So now that we can add native gameplay tags. 做得好。现在我们可以添加原生游戏标签了。
I'd like to add all of our attribute tags 我想添加我们所有的属性标签
here to Aura gameplay tags, and then we can 这里是 Aura 游戏标签，然后我们可以
access those tags and use them in c++, so 访问这些标签并在 C++ 中使用它们，所以
we'll be doing that next. 我们接下来就会这样做。
Great job, and I'll see you soon. 干得好，很快就会见到你。