Enabling Raytracing for Crowd Members

Experimental - Usable, but you must talk to us to understand the implications

Overview

Any characters outside of the nearest ~30 actors to the local character is not in lod0, which means they are a crowd member. The meshes of crowd members do not exist on the CPU for performance reasons, so by default you can't raytrace to them.

RaycastableCrowdActors are a simple way to add basic collisions to the crowd members that in the centre of the local player's screen, for the purpose of raytracing with hitscan weapons.

How it works

The user specifies an actor class (the Raycastable Crowd Actor class) that is used as a non-replicated actor to handle the collisions for a crowd member. Instances of these actors are spawned at the start of the game, and teleported each frame to the transforms of the N most relevant crowd members.

The most relevant crowd members currently are the crowd members that are in the centre of the local player's screen.

These raycastable actors should be invisible, but can be visible for debugging purposes. When a player attempts to raytrace to a crowd member that's in the centre of their screen, they will get a hit result on the Raycastable Crowd Actor that is in the crowd member's position. The ARaycastableCrowdActor object has GetMorpheusActor which allows the user to get the MA that the raycastable actor is currently representing.

Usage

Example usage can be found in the CombatGym map.

Create a BP class that inherits from Raycastable Crowd Singleton. This singleton handles the spawning of the raycastable actors and allows you to set some parameters.

In World Settings, add this class as an item in the Non Morpheus Singletons.

Now, we need to create our raycastable crowd actor. Create an actor that inherits from ARaycastableCrowdActor, and add some type of component that can handle collision. For example, a capsule component, or a skeletal mesh. Here, I've used the basic human skeletal mesh.

Make sure you set this actor up for raytracing with the Shootable channel.

I've left this actor Visible for now, but you can untick Visible in the details panel when you're satisfied that the raycastable actors are behaving correctly.

Finally, we need to set our raycastable crowd singleton to use this actor by setting the Raycastable Crowd Actor Class property.

To test this locally, go into PIE in your map, and enter the console command ImprobableLiveConfig.SetOverride game PlayerClient.Rendering.NumInLoD0 0 to force all players to become crowd members. If your raycastable actor is Visible, you will be able to see the raycastable mesh overlayed on your crowd actors.

It's important to make sure the raycastable actor mesh is not offset from the crowd transform. You may need to adjust the offset in your raycastable actor mesh to make sure it's property aligned with the crowd actor.

Changing the raycastable actor properties at runtime, per actor

The above flow is suitable for the basic case where all crowd members in the game are always the same shape, so you can use the same unchanged raycastable actor for everyone. In many cases, you'll want different shapes or sizes for different actors, and for these to change in the game. For example, if different players have differently sized avatars, or if a player has a forcefield that disappears part way through the game.

To implement this, bind to the event UpdateRaycastableActor in the RaycastableCrowdComponent that's on the Morpheus character. This event is executed whenever your character is assigned a new raycastable actor.

To change the state of the raycastable actor when it may already be assigned to your actor, call ForceRaycastableCrowdActorUpdate. You should use this when you want the state of your raycastable actor to change (e.g. if a forcefield around the character disappears). This will cause UpdateRaycastableActor to be executed on your character, only if your character currently has a raycastable actor.

Here's an example demonstrating the forcefield example. I've created my BP class of RaycastableCrowdActor.

To set up the raycastable state for my actor correctly, I need to use the UpdateRaycastableActor event to configure the raycastable actor for my player.

Then, in order for the raycastable actor to correctly update when the forcefield on the player should disappear, I call ForceRaycastableCrowdActorUpdate.

There's also an event OnRaycastableActorAssigned which is called when the character is assigned a raycastable actor, but not when ForceRaycastableCrowdActorUpdate is called.

Limitations

Currently, the group of crowd actors that become raycastable are the N in the closest of the player's screen. This isn't suitable for all games, and in future this will be customisable from world builder.

A big limitation is that the raycastable actor does not animate alongside the crowd member. This means, in the skeletal mesh example, that the raycastable actor's legs and arms don't match the crowd member's legs and arms if the actor is in a running animation, for example. This limits the nature of the gameplay you can perform this. Fixing this is planned for the future but is estimated at 3-4 weeks of work.

Last updated