From 3ebf23211f8631c27ebe388830d471651f65ca66 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 11 May 2021 09:37:34 -0700 Subject: [PATCH 1/6] Update Mutliplayer Autocomponent to add Get/Set behavior context methods for any Network Properties with GenerateEventBindings=true. Known issues: not tested with container types, some jinja whitespace --- .../Source/AutoGen/AutoComponent_Header.jinja | 1 + .../Source/AutoGen/AutoComponent_Source.jinja | 62 +++++++++++++++---- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja index 14a68cddf1..137a544a34 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Header.jinja @@ -410,6 +410,7 @@ namespace {{ Component.attrib['Namespace'] }} static void Reflect(AZ::ReflectContext* context); static void ReflectToEditContext(AZ::ReflectContext* context); + static void ReflectToBehaviorContext(AZ::ReflectContext* context); static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja index fb802541ce..6467119b89 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja @@ -661,18 +661,42 @@ enum class NetworkProperties {# #} -{% macro DefineNetworkPropertyBehaviorReflection(Component, ReplicateFrom, ReplicateTo, ClassType) %} +{% macro DefineNetworkPropertyBehaviorReflection(Component, ReplicateFrom, ReplicateTo, ClassName) %} {% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %} -{% if (Property.attrib['IsPublic'] | booleanTrue == true) %} -{% if Property.attrib['Container'] == 'Array' %} -->Event("Get{{ Property.attrib['Name'] }}", &{{ ClassType }}Bus::Events::Get{{ Property.attrib['Name'] }}) -{% elif Property.attrib['Container'] == 'Vector' %} -->Event("Get{{ Property.attrib['Name'] }}", &{{ ClassType }}Bus::Events::Get{{ Property.attrib['Name'] }}) -->Event("{{ Property.attrib['Name'] }}GetBack", &{{ ClassType }}Bus::Events::{{ Property.attrib['Name'] }}GetBack) -->Event("{{ Property.attrib['Name'] }}GetSize", &{{ ClassType }}Bus::Events::{{ Property.attrib['Name'] }}GetSize) -{% else %} -->Event("Get{{ Property.attrib['Name'] }}", &{{ ClassType }}Bus::Events::Get{{ Property.attrib['Name'] }}) -{% endif %} +{% if (Property.attrib['IsPublic'] | booleanTrue == true) and (Property.attrib['GenerateEventBindings'] | booleanTrue == true) %} + ->Method("Get{{ UpperFirst(Property.attrib['Name']) }}", [](AZ::EntityId id) -> {{ Property.attrib['Type'] }} + { + AZ::Entity* entity; + AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, id); + + if (entity) + { + if (auto* networkComponent = entity->FindComponent<{{ ClassName }}>()) + { + return networkComponent->Get{{ UpperFirst(Property.attrib['Name']) }}(); + } + } + + return {{ Property.attrib['Type'] }}(); + }) + ->Method("Set{{ UpperFirst(Property.attrib['Name']) }}", [](AZ::EntityId id, const {{ Property.attrib['Type'] }}& {{ LowerFirst(Property.attrib['Name']) }}) -> void + { + AZ::Entity* entity; + AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, id); + + if (entity) + { + return; + } + + if (auto* networkComponent = entity->FindComponent<{{ ClassName }}>()) + { + if (auto* controller = static_cast<{{ ClassName }}Controller*>(networkComponent->GetController())) + { + controller->Set{{ UpperFirst(Property.attrib['Name']) }}({{ LowerFirst(Property.attrib['Name']) }}); + } + } + }) {% endif %} {% endcall -%} {% endmacro %} @@ -805,6 +829,7 @@ m_{{ LowerFirst(Service.attrib['Name']) }} = FindComponent<{{ UpperFirst(Service {% endmacro %} {# + #} {% macro DefineNetworkPropertyEditConstruction(Component, ReplicateFrom, ReplicateTo, ClassName) %} {% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %} @@ -1131,6 +1156,7 @@ namespace {{ Component.attrib['Namespace'] }} {{ DefineArchetypePropertyReflection(Component, ComponentBaseName)|indent(16) }}; } ReflectToEditContext(context); + ReflectToBehaviorContext(context); } void {{ ComponentBaseName }}::{{ ComponentBaseName }}::ReflectToEditContext(AZ::ReflectContext* context) @@ -1155,6 +1181,20 @@ namespace {{ Component.attrib['Namespace'] }} } } + void {{ ComponentBaseName }}::{{ ComponentBaseName }}::ReflectToBehaviorContext(AZ::ReflectContext* context) + { + if (auto* behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class<{{ ComponentName }}>("{{ ComponentName }}") + {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Authority', ComponentName)|indent(16) -}} +{{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Server', ComponentName)|indent(16) -}} +{{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Client', ComponentName)|indent(16) -}} +{{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Autonomous', ComponentName)|indent(16) -}} +{{ DefineNetworkPropertyBehaviorReflection(Component, 'Autonomous', 'Authority', ComponentName)|indent(16) }} + {{ DefineArchetypePropertyBehaviorReflection(Component, ComponentName)|indent(16) }}; + } + } + void {{ ComponentBaseName }}::{{ ComponentBaseName }}::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { provided.push_back(AZ_CRC_CE("{{ ComponentName }}Service")); From 0867764e5b732074a67985c4d758fab1a53910db Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Tue, 11 May 2021 22:46:21 -0700 Subject: [PATCH 2/6] Updating Autocomponent behavior context property methods to give warnings if a Get/Set fails and how users might go about fixing the issue --- .../Source/AutoGen/AutoComponent_Source.jinja | 49 ++++++++++++------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja index 423aa57706..576978f75c 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja @@ -666,36 +666,46 @@ enum class NetworkProperties {% if (Property.attrib['IsPublic'] | booleanTrue == true) and (Property.attrib['GenerateEventBindings'] | booleanTrue == true) %} ->Method("Get{{ UpperFirst(Property.attrib['Name']) }}", [](AZ::EntityId id) -> {{ Property.attrib['Type'] }} { - AZ::Entity* entity; - AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, id); - - if (entity) + AZ::Entity* entity = AZ::Interface::Get()->FindEntity(id); + if (!entity) { - if (auto* networkComponent = entity->FindComponent<{{ ClassName }}>()) - { - return networkComponent->Get{{ UpperFirst(Property.attrib['Name']) }}(); - } + AZ_Warning("Network Property", false, "{{ ClassName }} Get{{ UpperFirst(Property.attrib['Name']) }} failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str()) + return {{ Property.attrib['Type'] }}(); } - return {{ Property.attrib['Type'] }}(); + {{ ClassName }}* networkComponent = entity->FindComponent<{{ ClassName }}>(); + if (!networkComponent) + { + AZ_Warning("Network Property", false, "{{ ClassName }} Get{{ UpperFirst(Property.attrib['Name']) }} failed. Entity '%s' (id: %s) is missing {{ ClassName }}, be sure to add {{ ClassName }} to this entity.", entity->GetName().c_str(), id.ToString().c_str()) + return {{ Property.attrib['Type'] }}(); + } + + return networkComponent->Get{{ UpperFirst(Property.attrib['Name']) }}(); }) ->Method("Set{{ UpperFirst(Property.attrib['Name']) }}", [](AZ::EntityId id, const {{ Property.attrib['Type'] }}& {{ LowerFirst(Property.attrib['Name']) }}) -> void { - AZ::Entity* entity; - AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationBus::Events::FindEntity, id); - - if (entity) + AZ::Entity* entity = AZ::Interface::Get()->FindEntity(id); + if (!entity) { + AZ_Warning("Network Property", false, "{{ ClassName }} Set{{ UpperFirst(Property.attrib['Name']) }} failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str()) + return; + } + + {{ ClassName }}* networkComponent = entity->FindComponent<{{ ClassName }}>(); + if (!networkComponent) + { + AZ_Warning("Network Property", false, "{{ ClassName }} Set{{ UpperFirst(Property.attrib['Name']) }} method failed. Entity '%s' (id: %s) is missing {{ ClassName }}, be sure to add {{ ClassName }} to this entity.", entity->GetName().c_str(), id.ToString().c_str()) return; } - if (auto* networkComponent = entity->FindComponent<{{ ClassName }}>()) + {{ ClassName }}Controller* controller = static_cast<{{ ClassName }}Controller*>(networkComponent->GetController()); + if (!controller) { - if (auto* controller = static_cast<{{ ClassName }}Controller*>(networkComponent->GetController())) - { - controller->Set{{ UpperFirst(Property.attrib['Name']) }}({{ LowerFirst(Property.attrib['Name']) }}); - } + AZ_Warning("Network Property", false, "{{ ClassName }} Set{{ UpperFirst(Property.attrib['Name']) }} method failed. Entity '%s' (id: %s) {{ ClassName }} is missing the network controller. Network controllers only spawn when some form of write access is available; for example, when you're server authoritatively controlling this entity, or you're a client predictively writing to your player entity. Please check your network context before attempting to set {{ UpperFirst(Property.attrib['Name']) }}.", entity->GetName().c_str(), id.ToString().c_str()) + return; } + + controller->Set{{ UpperFirst(Property.attrib['Name']) }}({{ LowerFirst(Property.attrib['Name']) }}); }) {% endif %} {% endcall -%} @@ -1183,7 +1193,8 @@ namespace {{ Component.attrib['Namespace'] }} void {{ ComponentBaseName }}::{{ ComponentBaseName }}::ReflectToBehaviorContext(AZ::ReflectContext* context) { - if (auto* behaviorContext = azrtti_cast(context)) + AZ::BehaviorContext* behaviorContext = azrtti_cast(context); + if (behaviorContext) { behaviorContext->Class<{{ ComponentName }}>("{{ ComponentName }}") {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Authority', ComponentName)|indent(16) -}} From 9a4884ff0bc1577a4947d3c835ec144e195d5a53 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Wed, 12 May 2021 14:19:18 -0700 Subject: [PATCH 3/6] Exposing Multiplayer integral types (just wrapped ints) to bevahior context so that Network Properties using these type can be Get/Set from Script Canvas --- .../Code/Include/MultiplayerTypes.h | 11 ++++++++++ .../Source/AutoGen/AutoComponent_Source.jinja | 20 +++++++++++++++++++ .../Source/MultiplayerSystemComponent.cpp | 11 ++++++++++ 3 files changed, 42 insertions(+) diff --git a/Gems/Multiplayer/Code/Include/MultiplayerTypes.h b/Gems/Multiplayer/Code/Include/MultiplayerTypes.h index 1bee9867e3..e9f3865563 100644 --- a/Gems/Multiplayer/Code/Include/MultiplayerTypes.h +++ b/Gems/Multiplayer/Code/Include/MultiplayerTypes.h @@ -130,3 +130,14 @@ AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::PropertyIndex); AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::RpcIndex); AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::ClientInputId); AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::HostFrameId); + +namespace AZ +{ + AZ_TYPE_INFO_SPECIALIZE(Multiplayer::HostId, "{D04B3363-8E1B-4193-8B2B-D2140389C9D5}"); + AZ_TYPE_INFO_SPECIALIZE(Multiplayer::NetEntityId, "{05E4C08B-3A1B-4390-8144-3767D8E56A81}"); + AZ_TYPE_INFO_SPECIALIZE(Multiplayer::NetComponentId, "{8AF3B382-F187-4323-9014-B380638767E3}"); + AZ_TYPE_INFO_SPECIALIZE(Multiplayer::PropertyIndex, "{F4460210-024D-4B3B-A10A-04B669C34230}"); + AZ_TYPE_INFO_SPECIALIZE(Multiplayer::RpcIndex, "{EBB1C475-FA03-4111-8C84-985377434B9B}"); + AZ_TYPE_INFO_SPECIALIZE(Multiplayer::ClientInputId, "{35BF3504-CEC9-4406-A275-C633A17FBEFB}"); + AZ_TYPE_INFO_SPECIALIZE(Multiplayer::HostFrameId, "{DF17F6F3-48C6-4B4A-BBD9-37DA03162864}"); +} // namespace AZ diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja index 576978f75c..a3eef99b20 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja @@ -707,6 +707,26 @@ enum class NetworkProperties controller->Set{{ UpperFirst(Property.attrib['Name']) }}({{ LowerFirst(Property.attrib['Name']) }}); }) + ->Method("GetOn{{ UpperFirst(Property.attrib['Name']) }}ChangedEvent", [](AZ::EntityId id) -> AZ::Event<{{ Property.attrib['Type'] }}>* + { + AZ::Entity* entity = AZ::Interface::Get()->FindEntity(id); + if (!entity) + { + AZ_Warning("Network Property", false, "{{ ClassName }} GetOn{{ UpperFirst(Property.attrib['Name']) }}ChangedEvent failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str()) + return nullptr; + } + + {{ ClassName }}* networkComponent = entity->FindComponent<{{ ClassName }}>(); + if (!networkComponent) + { + AZ_Warning("Network Property", false, "{{ ClassName }} Get{{ UpperFirst(Property.attrib['Name']) }} failed. Entity '%s' (id: %s) is missing {{ ClassName }}, be sure to add {{ ClassName }} to this entity.", entity->GetName().c_str(), id.ToString().c_str()) + return nullptr; + } + + return &networkComponent->m_{{ LowerFirst(Property.attrib['Name']) }}Event; + }) + ->Attribute(AZ::Script::Attributes::AzEventDescription, AZ::BehaviorAzEventDescription{ "On {{ UpperFirst(Property.attrib['Name']) }} Changed Event", {"New {{ UpperFirst(Property.attrib['Name']) }}"} }) + {% endif %} {% endcall -%} {% endmacro %} diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index e6fb77eca7..9f45122c1d 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -78,6 +78,17 @@ namespace Multiplayer ->Version(1); } + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) + { + behaviorContext->Class("HostId"); + behaviorContext->Class("NetEntityId"); + behaviorContext->Class("NetComponentId"); + behaviorContext->Class("PropertyIndex"); + behaviorContext->Class ("RpcIndex"); + behaviorContext->Class ("ClientInputId"); + behaviorContext->Class ("HostFrameId"); + } + MultiplayerComponent::Reflect(context); } From 77899c5d96c4119d6b855648282752ee0e05e342 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Wed, 12 May 2021 20:45:58 -0700 Subject: [PATCH 4/6] Updated network property behavior context category so they are grouped nicer in the Script Canvas palette --- .../Code/Source/AutoGen/AutoComponent_Source.jinja | 4 +++- .../Code/Source/MultiplayerSystemComponent.cpp | 14 +++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja index a3eef99b20..5b53145024 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja @@ -725,7 +725,7 @@ enum class NetworkProperties return &networkComponent->m_{{ LowerFirst(Property.attrib['Name']) }}Event; }) - ->Attribute(AZ::Script::Attributes::AzEventDescription, AZ::BehaviorAzEventDescription{ "On {{ UpperFirst(Property.attrib['Name']) }} Changed Event", {"New {{ UpperFirst(Property.attrib['Name']) }}"} }) + ->Attribute(AZ::Script::Attributes::AzEventDescription, AZ::BehaviorAzEventDescription{ "On {{ UpperFirst(Property.attrib['Name']) }} Changed Event", {"New {{ Property.attrib['Type'] }}"} }) {% endif %} {% endcall -%} @@ -1217,6 +1217,8 @@ namespace {{ Component.attrib['Namespace'] }} if (behaviorContext) { behaviorContext->Class<{{ ComponentName }}>("{{ ComponentName }}") + ->Attribute(AZ::Script::Attributes::Module, "{{ LowerFirst(Component.attrib['Namespace']) }}") + ->Attribute(AZ::Script::Attributes::Category, "{{ UpperFirst(Component.attrib['Namespace']) }}") {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Authority', ComponentName)|indent(16) -}} {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Server', ComponentName)|indent(16) -}} {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Client', ComponentName)|indent(16) -}} diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index 9f45122c1d..7d74f5e071 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -80,13 +80,13 @@ namespace Multiplayer if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { - behaviorContext->Class("HostId"); - behaviorContext->Class("NetEntityId"); - behaviorContext->Class("NetComponentId"); - behaviorContext->Class("PropertyIndex"); - behaviorContext->Class ("RpcIndex"); - behaviorContext->Class ("ClientInputId"); - behaviorContext->Class ("HostFrameId"); + behaviorContext->Class(); + behaviorContext->Class(); + behaviorContext->Class(); + behaviorContext->Class(); + behaviorContext->Class(); + behaviorContext->Class(); + behaviorContext->Class(); } MultiplayerComponent::Reflect(context); From a34a240cf6a2d639790c4120b08d3342a5e7acf4 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Thu, 13 May 2021 11:53:17 -0700 Subject: [PATCH 5/6] MultiplierTypes serialized so they are available in the ScriptCanvas variable window --- .../Code/Source/MultiplayerSystemComponent.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index 7d74f5e071..64a8ad6242 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -76,9 +76,23 @@ namespace Multiplayer { serializeContext->Class() ->Version(1); - } - if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) + serializeContext->Class() + ->Version(1); + serializeContext->Class() + ->Version(1); + serializeContext->Class() + ->Version(1); + serializeContext->Class() + ->Version(1); + serializeContext->Class() + ->Version(1); + serializeContext->Class() + ->Version(1); + serializeContext->Class() + ->Version(1); + } + else if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { behaviorContext->Class(); behaviorContext->Class(); From 7cd4bbee15e4f092a19449fb64468bcf6ceb2b7e Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Thu, 13 May 2021 21:52:37 -0700 Subject: [PATCH 6/6] Jinja fix white space a bit, still dont fully understand this, but it looks a little better --- .../Source/AutoGen/AutoComponent_Source.jinja | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja index 5b53145024..134ed8dc76 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja +++ b/Gems/Multiplayer/Code/Source/AutoGen/AutoComponent_Source.jinja @@ -663,7 +663,8 @@ enum class NetworkProperties #} {% macro DefineNetworkPropertyBehaviorReflection(Component, ReplicateFrom, ReplicateTo, ClassName) %} {% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %} -{% if (Property.attrib['IsPublic'] | booleanTrue == true) and (Property.attrib['GenerateEventBindings'] | booleanTrue == true) %} +{% if (Property.attrib['IsPublic'] | booleanTrue == true) and (Property.attrib['GenerateEventBindings'] | booleanTrue == true) -%} + // {{ UpperFirst(Property.attrib['Name']) }}: Replicate from {{ ReplicateFrom }} to {{ ReplicateTo }} ->Method("Get{{ UpperFirst(Property.attrib['Name']) }}", [](AZ::EntityId id) -> {{ Property.attrib['Type'] }} { AZ::Entity* entity = AZ::Interface::Get()->FindEntity(id); @@ -728,7 +729,7 @@ enum class NetworkProperties ->Attribute(AZ::Script::Attributes::AzEventDescription, AZ::BehaviorAzEventDescription{ "On {{ UpperFirst(Property.attrib['Name']) }} Changed Event", {"New {{ Property.attrib['Type'] }}"} }) {% endif %} -{% endcall -%} +{% endcall %} {% endmacro %} {# @@ -1219,12 +1220,15 @@ namespace {{ Component.attrib['Namespace'] }} behaviorContext->Class<{{ ComponentName }}>("{{ ComponentName }}") ->Attribute(AZ::Script::Attributes::Module, "{{ LowerFirst(Component.attrib['Namespace']) }}") ->Attribute(AZ::Script::Attributes::Category, "{{ UpperFirst(Component.attrib['Namespace']) }}") - {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Authority', ComponentName)|indent(16) -}} -{{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Server', ComponentName)|indent(16) -}} -{{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Client', ComponentName)|indent(16) -}} -{{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Autonomous', ComponentName)|indent(16) -}} -{{ DefineNetworkPropertyBehaviorReflection(Component, 'Autonomous', 'Authority', ComponentName)|indent(16) }} - {{ DefineArchetypePropertyBehaviorReflection(Component, ComponentName)|indent(16) }}; + + // Reflect Network Properties Get, Set, and OnChanged methods + {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Authority', ComponentName) | indent(16) -}} + {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Server', ComponentName) | indent(16) -}} + {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Client', ComponentName) | indent(16) -}} + {{ DefineNetworkPropertyBehaviorReflection(Component, 'Authority', 'Autonomous', ComponentName) | indent(16) -}} + {{ DefineNetworkPropertyBehaviorReflection(Component, 'Autonomous', 'Authority', ComponentName) | indent(16) -}} + {{- DefineArchetypePropertyBehaviorReflection(Component, ComponentName) | indent(16) }} + ; } }