This page lists some architectural considerations to think about when implementing systems which allow the player to interact with things in the game world. Most of this is based on first-person games, but similar guidelines can be used for other types as well.
Typical requirements
Regardless of what the player interacts with in the game, there’s usually a basic set of things the system must do:
- Allow the player to actually activate the interaction
- Check if some object can be interacted with
- Display some kind of visualization showing what the player is going to interact with, or other such information
- Display a textual description of what’s going to happen if the player activates the interaction
Implementation in Unreal Engine
The most common way to implement interactivity in Unreal is to use Interfaces. This is a solid approach, but you may also want to consider using Actor Components. A component based approach can have benefits in making it easy to add shared interaction logic into multiple actors without requiring the use of a base class.
Regardless of which approach you choose, the following suggestions should help you have a more robust system in place.
How to detect / trigger the interaction?
There are two typical approaches for this:
- Using Linetraces
- Using collision/overlap triggers
- Combination of the two
In option 1, you would typically linetrace on tick to check what the player is aiming at. This way you can immediately provide feedback on whether the thing being pointed at can be interacted with.
Option 2 can be more useful in third person perspectives where you typically aren’t aiming directly at the target. However, even in first person games it can be useful for example to trigger highlights or other details if necessary.
Considerations when creating the interaction API
When creating the API - be it interface or component - it’s important that it provides all the features that are needed.
I’d suggest considering the following when creating it:
- Who is interacting with the object?
- What data is needed to handle the interactions?
Typically this means you want to pass in at least two things into each of your interaction-related functions:
- The actor who is interacting with the object: In some scenarios, you may want to know information about the actor who’s attempting the interaction
- The hit result or component hit from a linetrace or such which is used to detect the interaction: This allows your interaction target to support multiple points of interactions, or otherwise react appropriately based on which part of it is being aimed at
Responding to interactions
In some cases it can be important to be able to give different “interaction results”.
Most of the API can typically return common data types like FText or booleans. However, especially if the interaction can fail or produce different results, it can be useful to allow for the interaction target to return information in some fashion.
Two approaches that can be useful for this:
- Create a struct that can be returned by the API to give more detailed information about the interaction result
- Create a “interaction result receiver” interface. This can be especially useful if the interaction can take some amount of time, and you want to inform the player about the result afterwards.