Skip to content

Create a New NPC Interactable Component

Overview

An NPC interaction in MIP consists of four parts working together:

  • A C++ interactable component implementing IMIPInteractableComponentInterface
  • An Interaction Listener Object (Blueprint) mapping interaction tags to temp-state tags
  • An Interaction Definition Asset holding the unique interaction tag, icon, and display name
  • Wiring in the Player Controller to bind component → listener

Step 1: Create the C++ Interactable Component

Create a new C++ class, derive from UMIPBasePlayerControllerComponent (or any UActorComponent), and implement IMIPInteractableComponentInterface.

public IMIPInteractableComponentInterface

Implement interface

Add the required interface overrides and the listener object properties:

#pragma region InteractableComponentInterface

protected:
    virtual void OnInteractedServer_Implementation(UObject* InObject, const FGameplayTag& InInteractionTag) override;
    virtual void OnInteractedClient_Implementation(UObject* InObject, const FGameplayTag& InInteractionTag) override;
    virtual void OnEndInteractedServer_Implementation(UObject* InObject, const FGameplayTag& InInteractionTag) override;
    virtual void OnEndInteractedClient_Implementation(UObject* InObject, const FGameplayTag& InInteractionTag) override;

protected:
    UPROPERTY()
    UMIPInteractionListenerObject* InteractionListenerObject;

    UPROPERTY(EditAnywhere, Category = Editables)
    TSubclassOf<UMIPInteractionListenerObject> InteractionListenerObjectClass;

#pragma endregion InteractableComponentInterface

Required interface functions


Step 2: Initialize the Interaction Listener on BeginPlay

Call InitializeInteractionListenerObject in BeginPlay so the component can listen and validate interaction events.

void UMIPNewNPCInteractableComponent::BeginPlay()
{
    Super::BeginPlay();

    InteractionListenerObject = InitializeInteractionListenerObject(GetPC(), this, InteractionListenerObjectClass);
}

Initialize listener

Warning

If InteractionListenerObject is not initialized here, the interaction system will not work.


Step 3: Add the Component to the Player Controller

Option A — Blueprint

Add Blueprintable to the component's UCLASS macro:

UCLASS(Blueprintable, ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))

Blueprintable UCLASS

Compile, then open BP_MIP_PC and add the new component.

Add component to BP_MIP_PC

Option B — C++

Declare the component in AMIPBasePlayerController inside the COMPONENTS region:

Declare in player controller

Then CreateDefaultSubobject in the constructor:

CreateDefaultSubobject


Step 4: Create an Interaction Definition Asset

Create a new MIPInteractionInstanceDefinitionAsset in the Content Browser.

Create asset — context menu

Asset created

Configure the asset:

Field Description
DisplayName Human-readable name shown in the interaction widget
ItemIcon Icon displayed for this interaction
AlwaysShow Whether the interaction shows without needing proximity range
InteractionTag Unique gameplay tag for this interaction type (e.g. Interaction.MyNewInteraction)

Configure definition asset


Step 5: Create an Interaction Listener Blueprint

Create a Blueprint class in /ModularInventoryPlus/InteractionListeners/ derived from MIPInteractionListenerObject.

Create listener blueprint

In Class Defaults, configure InteractionAndTempTagMap:

Key Value
Interaction.MyNewInteraction Player.TempState.MyNewTempState

Configure InteractionAndTempTagMap

Anti-Cheat

The server checks the mapped TempState tag before allowing the interaction to proceed. Always assign a unique temp-state tag per interaction type.


Step 6: Assign the Listener in the Player Controller

Open BP_MIP_PC, find the new interactable component, and set its InteractionListenerObjectClass to the Blueprint listener created in Step 5.


Step 7: Assign to the InteractionInstancesDefinitionAsset

Create (or open) a MIPInteractionInstancesDefinitionAsset (not to be confused with MIPInteractionInstanceDefinitionAsset) and add the definition asset from Step 4 to its list.

Warning

Make sure you use MIPInteractionInstancesDefinitionAsset (plural) — the container asset — not the single-definition asset.

Interaction instances definition asset

When visiting an NPC that uses this asset, the new interaction will appear in the dialog widget:

NPC dialog widget showing interaction

Interacting will print the confirmation log:

Log output on interaction


Step 8: Show Toggle Widgets on Interaction (Project Settings)

When a player interacts with the NPC using your interaction tag, MIP can automatically show and hide toggleable widgets (e.g. an inventory panel, a feature panel). This is driven by InteractionTagAndWidgetTags in the MIP Project Settings — no code required.

How to configure it:

  1. Open Edit → Project Settings
  2. In the search box type InteractionTagAndWidgetTags
  3. Under the MIP settings category, find the InteractionTagAndWidgetTags map
  4. Click + to add a new entry:
Field Value
Key Your interaction tag — e.g. Interaction.Seal
Value One or more Widget.Toggleable.* tags — e.g. Widget.Toggleable.Seal, Widget.Toggleable.Inventory

When the player interacts with an NPC that has your interaction tag, every widget whose tag appears in the value container will be shown automatically. When the interaction ends, they are hidden again.

Info

InteractionTagAndWidgetTags is defined in MIPSettings (Setting/MIPSettings.h). The key filter is Interaction.* and the value filter is Widget.Toggleable.*, so the tag picker in the editor will only show valid options for each field.


Implementation Example — Server & Client

Below is how UMIPPlayerExchangeManager handles the same pattern as a reference:

Server and client implementation example

  • Server (OnInteractedServer): calls GenerateExchangeItem on interact, resets on end-interact.
  • Client (OnInteractedClient): calls GenerateExchangeItem for the client and shows/hides widgets.

To control which widgets appear on the client, the built-in implementation calls:

ClientWidgetsManagerComponent->ShowWidgetsOnInteractionWithNPC(InInteractionTag, true);

This reads from InteractionTagAndWidgetTags configured in Project Settings — see Step 8 for setup details.

InteractionTagAndWidgetTags config

Widget tags assigned


See Also