The promised follow-up! You don't need to read up on part one, but do so if you're curious on how to make a custom TargetData. In this tutorial, we'll go over using a TargetData in Blueprints. Sound good? Let's go!
Disclaimer! This post assumes that you know the basics of UnrealEngine's Gameplay Ability System. If you don't know what a GameplayAbility or how to apply GameplayEffects, this tutorial will probably not going to make much sense. I'd suggest following Tranek's GAS Documentation on GitHub or watch the official Guided Tour of Gameplay Abilities by UnrealEngine.
Why use TargetData?
Before we get started, I want to reiterate something that I wrote in part one:
the reason we use TargetData is that it allows a networked sharing of data. There are other ways of doing things without TargetData, but this is available to you out of the box.
For example, say we want to teleport two networked players to another place on the map. Perhaps there's an ability that allows you to immediately teleport you and a teammate somewhere else. You could call SetActorLocationAndRotation node within your GameplayAbility:
But this has the following issues - OtherPlayer, SelfTeleportLocation, and OtherTeleportLocation will either have to be hard coded, networked, or calculated by both client and server.
- If we calculate on both client and server, we need our inputs to be non-changing data, as the network delay will cause different outcomes.
- If there are any lost packets or delays in networking, we'll have to create a way to roll back changes.
Using the TargetData system fly past these issues by allowing all data to be dynamic and sent to the server to send out to all interested clients. What's more, it has rollback networking as a feature, allowing any discrepancies to self correct.
This does mean that we need to do a little bit more set up and have multiple pieces, but the outcome is streamlined and easier than fixing any of the issues mentioned above.
Event Gameplay Ability
Let's start from the end, shall we? What we'll call the Event Gameplay Ability is a Gameplay Ability that is activated through an event. Pretty self explanatory. In the example above, we'd have both players to have an Event Gameplay Ability. We'll go over the next section how to grant these abilities onto them. Below is an example of a simple Event Gameplay Ability:Instead of activating an ability through the Event ActivateAbility node, we use the Event ActivateAbilityFromEvent node. Notice that this node has an Event Data Target Data input (you may need to split the input parameter). This is the TargetData we'll be building in the Instigator Gameplay Ability section.
Important to note, the TargetData input parameter is actually a TargetDataHandle, so it can contain multiple TargetData, hence our check if the TargetData has an endpoint. To learn more about the anatomy of TargetData, check out Tranek's GAS Documentation or part one of this tutorial.
There's a few other "boiler plate" items to take care. You'll want the Net Execution Policy to be set to Server Initiated. This is because when we send the event in the next section, we're telling the server to broadcast the Event Gameplay Ability to the necessary server and client instances. We'll also want to add as many Ability Triggers that you want this ability to respond to. For our purposes, it would probably be a tag: Event.Teleport.
With that, we're halfway done! Or a third of the way, depends on how which approach you take in the next section. Instigator Gameplay Ability
The Instigator Gameplay Ability is the Gameplay Ability that sends the event along with it's data to the server. Any Gameplay Ability can be an instigator, even an Event Gameplay Ability.
Side note - Creating a TargetData using GameplayAbilityTargetData_LocationInfo drops the rotator from the transform. Unsure why this was done this way, but it's simple to create your own custom TargetData that doesn't drop that information. I'll leave it as a challenge to you to do so.
This assumes that the actor we're sending the event to already has the ability granted to them. Depending on our approach, it might be passive or granted.
Passive Ability Approach
This is the simpler of the two approaches. It assumes that the ability is always on the player because it is a passive ability. Granting passive abilities is unique to different projects, so we won't be going into it right now. While this is the simpler of the two options, it should be reserved for abilities that occur often. For example, in SLIMECORE, knocking the player around happens often enough that we feel comfortable adding a passive ability. Teleport on the other hand, will only happen every so often, so we're going to go with the granted ability approach.
Granted Ability Approach
For this approach, we'll have to add a couple of nodes to our original Instigator Gameplay Ability blueprint.
The way we grant abilities is through a GameplayEffect, in this case GE_GrantTeleport. Granting abilities requires a client-server sync, so we add a WaitGameplayTagAdd node, waiting for a tag that the GameplayEffect will add. So this is how the GameplayEffect ends up looking like:
In Summary...
That's it! Using TargetData is much easier that creating your own, but I felt compelled to do the other tutorial first since it's what less information is available on the internet and also the more interesting problem space to tackle. Hopefully with these two tutorials your third eye has opened and you can level up your GAS game.
Until next time!
- Francisco
No comments:
Post a Comment