Action Gameplay Quickstart

Overview

This page will walk you through how the features are implemented in the "CombatGym" example. This will not be as extensive as the individual component and feature pages, but should serve as a good starting place for creating your own Action Gameplay experience.

If you're unsure of how to create your own assets you can consider duplicating or extending one of the assets listed in this guide.

Character Setup

As our Morpheus Character needs additional components not present on the default Morpheus Character, we have created our own called BPM_Combat_PlayerCharacter. This has the Blueprint BPM_M2_PlayerCharacterBase as its parent class to reduce the amount of setup needed for basic MSquared compatibility.

The Health Component is attached to this already, so next we added our own instances of the Combat Component and Shootable Component.

Currently the Combat Component isn't backed by a Blueprint instance of the M2M_CombatComponent but we imagine having a separate Blueprint for this component would be the standard use case.

You can think of the responsibilities as such:

  • Health Component - State management for your character. Allows the Shootable Component to make informed decisions on how to handle the "Shoot" interaction.

  • Combat Component - Add to any MorpheusActor that wants to shoot at a target. Handles raycasting and sending an RPC to the Target's Shootable Component for validation.

  • Shootable Component - Add to any MorpheusActor that should be able to be shot at. Responsible for validating whether the Target believes they should accept the interaction and also what they will do as a result of that (such as take damage).

Health Component

All JM_Characters have a HealthComponent. This provides functions to take damage, heal, and the above events. When a player's health gets to zero, the player will die and respawn after a time.

Our Health Component events are implemented directly within the Character's Event Graph and we also react to them in WBP_Healthbar. You will see that these events are used primarily for visual feedback, updating the state of our Health UI and debug logging.

The default behaviour of death and respawning is to disable player input, wait for RespawnTime seconds, and reset the player's health state and move them back to a spawn point. This can be changed in the respawn functions on the character, e.g. Respawn.

Combat Component

Our Combat Component events are implemented directly within the Character's Event Graph. You will see that these events are used primarily for visual feedback and debug logging.

Shootable Component

Our Shootable Component events are implemented directly within the Character's Event Graph. You will see that these events are used primarily for visual feedback and debug logging.

We have a Blueprint instance of this attached to the character, allowing us to isolate logic outside of the main Character Event Graph. Not all logic is handled there, but there is no reason that couldn't be the case.

If you open BPM_ShootableComponent itself you will see how we have overridden the default implementations for our BlueprintNativeEvents. These will be explained in more detail in Shootable Component, but here we explore our specific implementations.

LocalIsShotValid

Shooter: "Do I think my shot will be received and responded to?"

Called by the Shooter on the shooter client's local instance of the Target. The Shooter will bypass sending an RPC to the Target if this returns false.

If it returns true, the Shooter sends the Target and RPC and will await an acknowledgement. The delegate LocalOnHitReceived is fired which allows us to handle visual feedback to avoid delayed reaction in waiting for a networked acknowledgement.

AuthIsShotValid

Target: "Should I respond to this shot?"

Called on the Target on Target's authoritative client. In the example implementation above, we say we will acknowledge the shot as long as the owner of this component inherits from JM_CharacterBase and can take damage.

If this returns true, an acknowledgement will be send to the Shooter's client. The contents of the acknowledgement are determined by ValidShotReceived.

If this returns false, the Target will fire the AuthInvalidShotReceived delegate locally. This could be used to show some visual effect to show we resisted the shot.

ValidShotReceived

Target: "Process the effects of the shot! What do I tell the Shooter that their shot did to me?"

Called on the Target after they have validated that they will accept the Shooter's Shot.

It is here that we action taking damage via the Health Component. We will then report back to the shooter how much damage was taken and whether that was enough to kill the Target.

Player Controller

There are a number of different ways you may trigger a shot from the Combat Component. You could extend the Player Controller or create a gadget that will handle input and trigger one of the Shoot functions. For the sake of simplicity, we have chosen to override the Player Controller with our own: BP_Combat_PlayerController. This extends the BP_PlayerController Blueprint that handles a lot of the default MSquared related controller setup and input processing.

While not implemented this way, it would be better practice that this logic for populating the params to pass to the Shoot function would exist within the Combat Component itself. Then the Player Controller or any number of devices could use a single path to action a Shot, and not have to define all this themselves.

We use the camera as the origin of our shot, however in a previous demo that featured weapons in the hands of players, we were using the tip of a pistol as the origin. This origin point is completely configurable.

The debug line is only shown locally to the Shooter, and not intended to be seen by other clients. If You wanted to implement projectile trails, this would need to be done by tying in to the events fired by the Morpheus Actor.

Render Target

We found that some of the assets used for the randomised render targets for our Characters were lacking physics assets. We have a workaround for when this is the case, in which we use the render target's capsule component for detecting collisions when shot.

This can be seen in BP_M2_Combat_PlayerCharacter .

Map Setup

If you open the map called "CombatGym" you will see a mostly empty greybox map with a large number of player starts. This is largely a duplicate of the standard TestMap with a few changes.

  • Singletons -> Player Spawner Class

    • BPM_M2_Combat_PlayerSpawnerExample

      • Configured to use our BPM_Combat_PlayerCharacter Morpheus Actor

  • GameMode -> GameMode Override

    • BP_Combat_GameMode

  • Roles -> Default Role

    • DT_Combat_Roles

      • Assigns the DA_Combat_Pawns asset for Pawn Lod Level Set

        • We replaced the Base Pawn and LOD0 Actor Class with our character used as the Render Target, BP_M2_Combat_PlayerCharacter.

Game Mode

We extended from BP_GameMode to create our own mode for the CombatGym. This is a fairly lightweight Blueprint. The only logic featured is to set up the health bar displayed locally for your player.

As previously explained, we replaced the Player Controller so that was one of the changes made to the default values in our Game Mode.

Enable Low Latency Mode

All of this will work, but it will feel like the fidelity is too low. To fix this you will need to enable Low Latency Mode through your Live Config.

Raytracing For Crowd Members

As any character rendered at LOD1 will not have a skeletal mesh on the CPU we can use to raycast to, additional setup is needed to support being able to shoot more than the nearest ~30 Players.

This is detailed in Enabling Raytracing for Crowd Members. A short explanation is that you will need to place a Raycastable Crowd Singleton into your map and configure how you want it to manage these additional raycastable actors.

Last updated