# Game Modules 4 Integration

[**Game Modules 4**](https://assetstore.unity.com/packages/tools/game-toolkits/game-modules-4-make-your-game-flexible-tools-with-stats-items-sa-246034?aid=1100lxWw) and [**Projectile Factory**](https://assetstore.unity.com/packages/tools/particles-effects/projectile-factory-behavior-based-projectile-system-281692?aid=1100lxWw) work great together, and can be connected with just a few steps.

This document will walk through the setup required to get a character who uses Game Modules 4 for stats, conditions, and other game data to spawn projectiles that can cause damage to other [**Game Module Actors**](/magic-pig-games/game-modules-4/module-documentation/game-modules-actor.md) in the scene.

*This guide assumes you have imported the latest **Game Modules 4** and **Projectile Factory** packages from the Package Manager.*

{% embed url="<https://youtu.be/ffFhVkHwNJg>" %}
This video walks through the steps below as taken in one of my own prototype projects.
{% endembed %}

## 1. Import the `GameModules4Integration.unitypackage` files

Find `GameModules4Integration.unitypackage` and import it into your project. It will be located at `Assets/Magic Pig Games/Projectile Factory/Game Modules 4 Integration/GameModules4Integration.unitypackage`

## 2. Update IAmGameModulesActor interface

The `IAmGameModulesActor` interface should be added to your "Actor" object -- this is the object which has the data that inherits from `GameModulesActor`.

<figure><img src="/files/2MzQwEoqUEnMVwxMfEij" alt=""><figcaption><p>IAttackable is commented out -- replace this with your own Interface that has a TakeDamage() method on it!</p></figcaption></figure>

### Create a custom interface

The interface has a `CustomAction()` method defined. To take advantage of this, you'll need to create a custom interface that has custom methods. For this, we will require a `TakeDamage()` method.&#x20;

You'll need to update the signature to fit your project, allowing you to pass in the required data needed to propertly compute damage.

```csharp
// This is the method in the IAttackable interface.
public interface IAttackable
{
    // ... Other methods/properties
    public void TakeDamage(float damage, IAmGameModulesActor attacker);
}
```

{% hint style="success" %}
This interface is custom for your project. It can have additional methods and properties as needed. You can call any defined methods in the same way shown later in this setup process, using the `CustomAction()` method defined in `IAmGameModulesActor`.
{% endhint %}

## 3. Implement IAmGameModulesActor

Your actor class should implement `IAmGameModulesActor`. In the snippet below, you can see my `AttackableObject` implements `IAmGameModulesActor`.

The `Actor` class (`data`, below), is a `GameModulesActor`, so the required properties all pull from there.

```csharp
// Example from my own game. You can probably copy this and just be sure to connect
// the GameModulesActor variable properly. (data, in this example)
public class AttackableObject : MonoBehaviour, IAmGameModulesActor
{
     // Required for IAmGameModulesActor
     public IAmGameModulesActor ActorObject => this;
     public GameModulesActor GameModulesActor => data;
     public GameStatList Stats => data.stats;
     public GameConditionList Conditions => data.conditions;
     public GameItemObjectList Inventory => data.inventoryItems;
     public GameItemObjectList Equipment => data.equippedItems;
     public GameQuestList Quests => data.quests;
     public void CustomAction(Action<IAmGameModulesActor> action)
     {
          action?.Invoke(this);
     }
     // End of IAmGameModulesActor
        
     [Header("In Game Data")]
     // This is the GameModulesActor that holds all of the data for this actor.
     public Actor data;
     
//...
```

## 4. Add Game Modules connections to Projectile

{% hint style="success" %}
If you don't have either of these objects available, you can create them. Right click in your project and select `Create/ProjectileFactory/...` and then find either `Spawn Behavior Mod` or `Collision Behavior` and then the correct object, as named below.&#x20;

This will create the object in your project, and the Projectile window will find them. No additional setup is required for either of these objects.
{% endhint %}

### Spawn Behavior Modification

The "Connect Game Modules" Spawn Behavior Modification is used to connect the Projectile with another compnent we'll add later.

<figure><img src="/files/ydppz7zwHMFqioXjz1gw" alt=""><figcaption></figcaption></figure>

### Collision Behavior

The "Game Modules Connection Hit" Collision Behavior calls the proper method on the connection component (the one we'll add later), on collision. This is what actually starts the "Take Damage" process.

<figure><img src="/files/CwrV6Q7os2KaC3bJ1LV2" alt=""><figcaption></figcaption></figure>

## 5. Modify `ProjectileGameModulesConnection.cs`

Find and load `ProjectileGameModulesConnection` in your script editor. There are sections we need to update to work with the `Interface` you created earlier.

{% hint style="info" %}
The two sections we are updating are in the `DoDamage()` method, and have comments that start with "SEE THE DOCUMENTATION..." along with `Debug.LogWarning()` messages.
{% endhint %}

➡️ First, remove the Debug.LogWarning() messages, and the "SEE THE DOCUMENTATION..." comments.

➡️ Uncomment the attackedActor lines as well.

### Update the `CustomAction()` action call

The `CustomAction()` method will call another method you have defined on your custom Interface, including the `TakeDamage()` method withe the signature required for your project.

In the example below, my  "TakeDamage" method passes in the damage and the attacking actor.&#x20;

```csharp
public void DoDamage(GameObject objectHit)
{
    // Try to get the IAmGameModulesActor component in the object hit
    if (objectHit.TryGetComponent(out IAmGameModulesActor attackedActor))
    {
        attackedActor.CustomAction(actor => actor.TakeDamage(Actor.NextMeleeDamage, Actor));
        return;
    }

    // If not found, try to get the IAmGameModulesActor component in the parent objects
    var parent = objectHit.transform.parent;
    while (parent != null)
    {
        if (parent.TryGetComponent(out attackedActor))
        {
            attackedActor.CustomAction(actor => actor.TakeDamage(Actor.NextRangeDamage, Actor));
            return;
        }
        parent = parent.parent; // Move up to the next parent
    }

    Debug.Log("No IAmGameModulesActor component found in the object or its parents.");
}
```

## 6. That's it!

If your `TakeDamage()` method is properly connected to actually remove health and do all the other fun stuff that happens in your game, you should be all set, and can test it out.

<figure><img src="/files/YvG97Pvd5tfSO4zrA1Fu" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://infinitypbr.gitbook.io/magic-pig-games/projectile-factory/game-modules-4-integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
