本文内容
第27章 ScriptCanvas
第27章 ScriptCanvas
介绍
注意:本章的资源可以在 GitHub 上找到,网址为: https://github.com/AMZN-Olex/O3DEBookCode2111/tree/ch27_scriptcanvas
我们本章的目标是让鸡用拍打的动作来庆祝每个进球。我们创建了动画图来支持该动画。每当进球时,我们需要将 ‘Celebrating’ animation 参数设置为 true。我们可以使用 C++ 来做到这一点,但这是一个很好的机会,可以向您展示如何使用可视化脚本执行相同的工作。
Script Canvas 是 O3DE 中的一个可视化脚本工具。例如,这是一个可视化节点,它等效于 SetNamedParameterBool 的 C++ 方法,该方法类似于我们在前面章节中使用的方法。
例 27.1.Set Named Parameter Bool
提醒一下,GoalDetectorComponent 会在进球得分时发出通知。
void GoalDetectorComponent::UpdateUi()
{
UiScoreNotificationBus::Broadcast(
&UiScoreNotificationBus::Events::OnTeamScored, m_team);
}
我们需要注册才能接收此事件,并将 Anim Graph 组件上的 Celebration 参数设置为 true。
Behavior Context
为了让 Script Canvas 为您提供新的自定义通知事件总线的节点,我们必须将该事件总线反映到 Behavior Context。以下是反映通知总线的步骤。
- 这是我们反映的公交车。
class UiScoreNotifications
:
public AZ::ComponentBus
{
public:
virtual void OnTeamScored(int team) = 0;
};
using UiScoreNotificationBus = AZ::EBus<UiScoreNotifications>;
- 为其创建行为处理程序。
class ScoreNotificationHandler
- 从您希望反射到脚本的事件总线和 AZ::BehaviorEBusHandler 继承。
class ScoreNotificationHandler
: public UiScoreNotificationBus::Handler
, public AZ::BehaviorEBusHandler
- 列出您希望通过宏反射AZ_EBUS_BEHAVIOR_BINDER所有方法。在本例中,只有 OnTeamScored。
AZ_EBUS_BEHAVIOR_BINDER(ScoreNotificationHandler,
"{33B5BC25-622B-4DF0-92CF-987CC6108C31}",
AZ::SystemAllocator,
OnTeamScored);
提示:如果有更多方法要反映,则可以在宏末尾一次列出一个方法。
AZ_EBUS_BEHAVIOR_BINDER(ScoreNotificationHandler, "{33B5BC25-622B-4DF0-92CF-987CC6108C31}", AZ::SystemAllocator, Method1, Method2, Method3);
- 覆盖每个方法以调用由 AZ_EBUS_BEHAVIOR_BINDER 生成的 FN_
方法。例如,OnTeamScored 有 FN_OnTeamScored 。
void OnTeamScored(int team) override
{
Call(FN_OnTeamScored, team);
}
- 向 BehaviorContext 注册此处理程序。它可以在任何 Reflect 方法中完成。例如,在 GoalDetectorComponent 中。这是一个好位置,因为它会在其上调用事件。另一个不错的选择是将其放在 Gem 或项目的 system 组件中。
void GoalDetectorComponent::Reflect(AZ::ReflectContext* rc)
{
//...
if (auto bc = azrtti_cast<AZ::BehaviorContext*>(rc))
{
bc->EBus<UiScoreNotificationBus>("ScoreNotificationBus")
->Handler<ScoreNotificationHandler>();
}
}
提示:如果要将要从 Script Canvas 调用的方法反映到 C++ 中,则只需几行 C++ 代码。例如,下面是我们在本章开头看到的 SetNamedParameterBool 的反射。
behaviorContext->EBus<AnimGraphComponentRequestBus>( "AnimGraphComponentRequestBus") > Event("SetNamedParameterBool", > &AnimGraphComponentRequestBus::Events::SetNamedParameterBool)
你可以在这里看到这个定义:C:\git\o3de\Gems\EMotionFX\Code\Source\Integration\Components\AnimGraphComponent.cpp。
构建 Canvas
编译项目后,您可以重新打开 Editor 并创建新的脚本画布。以下是从 Script Canvas 设置 Celebration 参数的步骤。
- 转到 Chicken_Actor 实体。(它有 Anim Graph (动画图形) 组件。
- 将 Script Canvas 组件添加到实体。
- 使用 Script Canvas 中的工具或从 Script Canvas 组件上的图标→打开 Script Canvas 编辑器。
- 进入 Script Canvas 编辑器后,使用 File → New Script 启动新脚本。
- 在 Node Pallete 中,搜索“Score Notification Bus”。
- 将 OnTeamScored 拖放到空白的画布空间中。
- 在 Node Palette 中搜索 “Set named parameter bool”。也可以将其拖放到画布中。
- 将 OnTeamScored 的执行行连接到“Set Named Parameter Bool”节点上的 In execution 连接器。通知节点将在调用事件时开始执行脚本。执行将传递到 “Set Named Parameter Bool” 节点。之后,Out 连接器会将执行传递给下一个节点(如果已连接)。
图 27.1.两个 Script Canvas 节点
- 在“Set Named Parameter Bool”节点上,将 Value 设置为 Celebrating。
- 将布尔值设置为选中。
- 将画布保存在项目或其中一个 Gem 下,例如在 C:\git\book\MyProject\scriptcanvas\celebrate.scriptcanvas 中。
- 返回到Chicken_Actor实体。
- 在 Script Canvas 组件上,将新画布分配给 Script Canvas Source File(Script Canvas 源文件)属性。
例 27.2.Chicken_Actor 具有 Script Canvas 组件的实体
使用此组件,每当进球时,鸡都会播放庆祝拍打动作两秒钟。
小结
注意:本章的源代码和资源可以在 GitHub 上找到,网址为: https://github.com/AMZN-Olex/O3DEBookCode2111/tree/ch27_scriptcanvas
以下是本章中的 C++ 代码更改。
例 27.3.GoalDetectorComponent.cpp 中的新代码
void GoalDetectorComponent::Reflect(AZ::ReflectContext* rc)
{
//...
if (auto bc = azrtti_cast<AZ::BehaviorContext*>(rc))
{
bc->EBus<UiScoreNotificationBus>("ScoreNotificationBus")
->Handler<ScoreNotificationHandler>();
}
}
例 27.4. UiScoreBus.h
#pragma once
#include <AzCore/Component/ComponentBus.h>
#include <AzCore/RTTI/BehaviorContext.h>
namespace MyGem
{
class UiScoreNotifications
:
public AZ::ComponentBus
{
public:
virtual void OnTeamScored(int team) = 0;
};
using UiScoreNotificationBus = AZ::EBus<UiScoreNotifications>;
/// NEW
class ScoreNotificationHandler
:
,
public UiScoreNotificationBus::Handler
public AZ::BehaviorEBusHandler
{
public:
AZ_EBUS_BEHAVIOR_BINDER(ScoreNotificationHandler,
"{33B5BC25-622B-4DF0-92CF-987CC6108C31}",
AZ::SystemAllocator, OnTeamScored);
void OnTeamScored(int team) override
{
Call(FN_OnTeamScored, team);
}
};
}
注意:您可以在以下位置找到有关如何将各种类、结构和接口反射到 Behavior Context 的文档: https://docs.o3de.org/docs/user-guide/programming/components/reflection/behavior-context/