# Character Interaction System

## Intro

Character Interaction System is a comprehensive, flexible, yet very accessible and easy-to-master system for creating interactions in your game.&#x20;

With it, you can create various types of interactions, ranging from a simple light switch to complex cases, like a door where different animations should play from different sides depending on the current state of the door and from which side it is being opened.&#x20;

The plugin is written using C++, but you absolutely don’t need to know the language to work with it.&#x20;

All necessary functionalities and interfaces for customization have been moved to blueprints.&#x20;

Also, this system is replicated and ready for integration into your multiplayer projects.&#x20;

All assets used in the trailer can be found in the example project via the link below.

**Main Features:**

* Use C++ or Blueprints to work with system
* Easy to setup on any actor
* Highly expandable and customizable system
* Multiplayer Support
* Basic widgets and world markers for interactable objects
* Supports different types of interactions
* Supports interaction interruptions

Included many different types of interactions in Example Project:

* Doors
* Crates
* Buttons
* Levers
* Code Locks
* Valves
* And MORE!

Playable Demo: [Link](https://drive.google.com/drive/folders/1CA02MXe88n0qjkmKLc3Mnx_VWaGCcvmP?usp=sharing)

## Basic Setup

{% hint style="warning" %}
First of all, enable the display of plugin content in the settings.
{% endhint %}

<div align="left"><figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FdRMEwm18wW1VQIRc954A%2Fimage.png?alt=media&#x26;token=e1c2205a-3563-415c-869f-0966607b5f6e" alt=""><figcaption></figcaption></figure></div>

Also, to learn how to work with the plugin, I advise looking at the example project and studying the component settings there. Various use case scenarios of the plugin are presented there, which will answer many potential questions.

### Step 1

To start working with the plugin, you need to add the CISCharacterInteraction component to your character.

<div align="left"><figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FgJnupt5W5yXDD9k7sry7%2Fimage.png?alt=media&#x26;token=977966bf-84d1-4d34-996c-eea38f6d2361" alt=""><figcaption></figcaption></figure></div>

### Step 2

The next step is to add a sphere or any other shape to your character. This sphere will be responsible for overlaps and subsequent processing of your interactive objects. Set the collision settings based on the requirements of your project.

<figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2F2BT42zgg61SF3Q3YdFct%2Fimage.png?alt=media&#x26;token=657a2e53-89b5-49f4-abb6-eeedecba0002" alt=""><figcaption></figcaption></figure>

### Step 3

Next, you need to configure the component added earlier.

<figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2F2LrIj0SENSCwjPoKBPne%2Fimage.png?alt=media&#x26;token=4debbf79-04cf-4350-80c7-a7023865346b" alt=""><figcaption></figcaption></figure>

Now, let’s consider not all parameters, but only the most necessary ones for the plugin to operate. Other parameters can help make working with the plugin more flexible, and we will consider them in a separate section of the documentation.

**InteractionAngle** - The necessary angle between the character and the interactive object to begin interaction with it.

<div align="left"><figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FcsguLeQuPn7z9Do8jg0N%2Fimage.png?alt=media&#x26;token=f445d7d1-c2be-4bb0-8bae-2f7978967ab0" alt="" width="375"><figcaption></figcaption></figure></div>

**TimeToUseObject** - the time that must pass after pressing the interaction button to interact with the object.

**TriggerComponents** - Triggers responsible for overlaps with interactive objects. You are unlikely to need more than one. Choose the component previously added to your actor (Sphere) here.

<figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2F55gBWjKRo551duoNzozQ%2Fimage.png?alt=media&#x26;token=f25f7844-0c12-4871-af80-7ca20741d0b6" alt=""><figcaption></figcaption></figure>

### Step 4

The next step is to add the CISInteractionObject component to your future interactive object\
![](https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FRPURSFb0ndqX7QsV7pwl%2Fimage.png?alt=media\&token=87e98259-38b1-424f-8b2a-d3d33ffc61e8)

<figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FdlcsjzfNDLV8lNlLaPnU%2Fimage.png?alt=media&#x26;token=0be8d513-754b-4713-9d6b-3c1d9b846eff" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Let's start by clarifying that the actions for interacting with an object are selected based on the current state of the object. For example, if the current state of the door is "closed," the available action for it would be to open the door. In the case of simple interactions without changing the state of the object, these settings can be neglected. The states of the object are described in the form of FGameplayTag.
{% endhint %}

Let's go through the parameters:

* **AngleDetectionComponent**: The component by which the angle between the character and the object will be determined; choose one of the available ones in the actor.
* **OverrideCharacterInteractionAngle**: In case you need to use some custom interaction angle for the object, you can override it using this parameter.
* **OverrideObjectUseTime**: In case you need to override the button hold time for the object to be used for a specific object, use this parameter.
* **ObjectInterruptionType**: Use this setting if there is a need to interrupt the active action in some way.
* **VisibleConditions**: Conditions when the object is already somehow visualized for interaction, but it is still impossible to interact with it. Will be considered in detail in a separate section.
* **UsableConditions**: Conditions for interacting with the object. Will be considered in detail in a separate section.
* **ObjectPriority**: The priority of using the object, for cases when there are several objects nearby available for interaction.
* **OverrideDataObjectClass**: Will be considered in detail in a separate section.
* **InitialObjectState**: The initial state of the object at the moment of play begin.
* **Usable**: Whether this object can be used. Can be changed at runtime.

#### **InteractionSides**&#x20;

Each interactive object can have one or several sides for interaction with different actions for each side.

Taking a door as an example - it has 2 sides for interaction - front and back, with specific settings of available angles. Interaction from one side will open the door towards oneself, and from the other side, away from oneself.

<div align="left"><figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FxkqzFiGJGkDuqbuMPwVk%2Fimage.png?alt=media&#x26;token=dc724672-dfc1-43d5-ad07-87613242671b" alt="" width="375"><figcaption></figcaption></figure></div>

\
In a simpler case, like a button, it has one side for interaction with a 360-degree radius because it doesn’t matter which side we press it from.

<div align="left"><figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FWGkgKfI4D486dq3qM50C%2Fimage.png?alt=media&#x26;token=4045c8f6-c5c7-403c-bc33-7578aad0ef23" alt="" width="375"><figcaption></figcaption></figure></div>

<figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FH10BYsdkJS34myRcVupn%2Fimage.png?alt=media&#x26;token=49bba7de-90b2-4644-8695-6b59a2d7d036" alt=""><figcaption></figcaption></figure>

* **InteractionAngle Min/Max**: Available angles for interacting with the side.
* **AngleSide**: A parameter that inverts the angle.
* **InteractionObjectSideMoveHandler**: If you need the character to first approach the object before or during interaction, you will need to create and implement an object of this class. See detailed descriptions on working with it in a separate section; we will not consider it for the basic implementation. You can also see the implementation in the ExampleProject.
* **ActionExecutionType**: Setting the type of interaction with the object, either parallel to the MoveHandler's work or after the character has stood at the necessary point.
*

```
<figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2F0ssD5hwRCu9AmZeviasI%2Fimage.png?alt=media&#x26;token=60c1cb9d-726b-4dd6-9775-2a059883efe7" alt=""><figcaption></figcaption></figure>
```

* **InteractionObjectSideActions**: A list of available actions for the side, depending on the current state of the object.
  * **RequiredStateTag**: The current state of the object necessary for activating this action.
  * **InteractionObjectAction**: The action for the object. In the example with the closed door, the action will be "open the door," i.e., play animation on the character and door, after which change the door state to "Open."

But let’s consider a simpler version - switching the light of a bulb.

\
**Lightbulb Implementation Example**
------------------------------------

First and foremost, add the **WBP\_InteractionPanel** widget to your HUD.

<div align="left"><figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FNCYnrxCeVhI2g3q0RWMW%2Fimage.png?alt=media&#x26;token=281ba62a-34ec-4b78-a86f-44fd94f6e9a0" alt=""><figcaption></figcaption></figure></div>

In your character, within the **CISCharacterInteraction** component, select **DataObject** as shown in the screenshot below.

<figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FxtlucZYuuHcuid9toeFS%2Fimage.png?alt=media&#x26;token=c268904c-67cd-4647-84bb-bd8752964345" alt=""><figcaption></figcaption></figure>

Also, add the respective logic to the character for your interaction button.

<div align="left"><figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FQleOsecFufu631YwiC8F%2Fimage.png?alt=media&#x26;token=df2a4200-907e-4e2f-8bc5-4cd36aa9c690" alt="" width="375"><figcaption></figcaption></figure></div>

Create a new actor **BP\_LightSwitcher**. Let it inherit from **BP\_CISBaseInteractableActor**.&#x20;

First things first, add a **PointLight** component to your actor.

<div align="left"><figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2Fve8amzwSbtk3SKF6xD79%2Fimage.png?alt=media&#x26;token=6417db19-8aba-4bed-9a99-b488afaadc5e" alt=""><figcaption></figcaption></figure></div>

Next, create two gameplay tags: Interaction.Switcher.On and Interaction.Switcher.Off.

<figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2F3zs09iDEfjqnLQmNprz6%2Fimage.png?alt=media&#x26;token=9b667253-4524-418a-b799-5d7c1db496b7" alt=""><figcaption></figcaption></figure>

Configure two actions for the previously created side; one action will be when the lightbulb is off, and another when it is on.

<figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2F7PJig0AUh3i2PSgdX6Em%2Fimage.png?alt=media&#x26;token=554706c5-57c5-423a-86b2-32f3d496048a" alt=""><figcaption></figcaption></figure>

Also, set up the InitialObjectState, so the lightbulb is initially off.

<div align="left"><figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2F0DgV7hm3LmHiRifeT5YW%2Fimage.png?alt=media&#x26;token=0f84d231-6006-4a3c-99b7-e4cdd5bcd916" alt=""><figcaption></figcaption></figure></div>

Subscribe to the object state change event in your lightbulb actor.

<div align="left"><figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FljEDLDj29rBRreaR30TH%2Fimage.png?alt=media&#x26;token=ebbf154c-7511-4c49-87e7-1862322fb77f" alt=""><figcaption></figcaption></figure></div>

Implement switch logic for the states when the lightbulb is on and off.

<div align="left"><figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FdB9zvZR5jpj3cvHtua2A%2Fimage.png?alt=media&#x26;token=3b6f3228-3c52-4037-b19a-5a3f7cc04c9e" alt=""><figcaption></figcaption></figure></div>

Change the visibility of your lightbulb depending on the state.

<div align="left"><figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FUaOqxVfu2s64ISvllaty%2Fimage.png?alt=media&#x26;token=18403a56-6347-437a-bfca-0aae3352dcc0" alt=""><figcaption></figcaption></figure></div>

Create a new blueprint action for your lightbulb; it should inherit from **CISInteractionObjectAction**.\
&#x20;![](https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FAiu21csahKLuwic5Rdsj%2Fimage.png?alt=media\&token=9ec46534-3569-4d7b-9cc5-9ca31c715007)

{% hint style="info" %}
In this case, we won't implement any particular logic in the action. It's only necessary for the internal system's operation to toggle object states. A detailed description of more complex cases will be in a separate section.
{% endhint %}

Add the created action for both states of your object.

<figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FBsIW5320YONP8Z6Gm02E%2Fimage.png?alt=media&#x26;token=bc9f2fd6-aefb-4970-9a11-27dae501e2c8" alt=""><figcaption></figcaption></figure>

Configure the new state after completing the action so that for the lightbulb's On state, it changes to Off and vice versa.

Done! Here is the result.<br>

<div align="left"><figure><img src="https://103152989-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F29yzWK4hGQ2PluXn73VV%2Fuploads%2FqSkvRgvBGJLOSUCyTP7W%2Fbandicam%202023-10-29%2014-08-12-412.gif?alt=media&#x26;token=af5c5934-d4cb-458d-95cc-3f63af46a1f2" alt=""><figcaption></figcaption></figure></div>
