> For the complete documentation index, see [llms.txt](https://infinitypbr.gitbook.io/magic-pig-games/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://infinitypbr.gitbook.io/magic-pig-games/projectile-factory/overview-and-quickstart/quick-start-guide/add-projectile-factory-and-create-a-projectile-spawner.md).

# Add Projectile Factory & Create a Projectile Spawner

v1.0

In this guide, we'll set up **Projectile Factory**, create a spawning object ("[**Projectile Spawner**](/magic-pig-games/projectile-factory/projectile-factory-documentation/projectile-spawner.md)"), and get it spawning projectiles with the click of a button. Adding the same features to your existing actors will be essentially the same process.

{% embed url="<https://www.youtube.com/watch?v=Ma3_BvuM1fk>" %}

{% hint style="info" %}
Already have a character or other spawner? Feel free to skip the primative creation, and use that!
{% endhint %}

## 1. Create the spawner

For this, I'm going to copy the Projectile Spawner from the demo scenes. This object includes a cube for the base, a sphere for the hortizontal rotator, and an object to shoot things out of, which will also be our tilting transform.

{% hint style="success" %}
A Spawner will generally have a "rotating" transform for horizontal rotations, and a "tilting" transform for vertical rotations. If none are provided, the base Transform will be used. Some [**Spawn Behaviors**](/magic-pig-games/projectile-factory/projectile-factory-documentation/spawn-behavior.md) may make use of these values, but not all do.
{% endhint %}

Our Example Spawner has only one script, to keep the spawn point pointing toward the mouse position.

<figure><img src="https://2431624982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MY3N_li2jPq7az6mYfq%2Fuploads%2FiCs3H4qzcfeww8kbqSLK%2FScreenshot%202024-04-03%20at%203.37.46%E2%80%AFPM.png?alt=media&amp;token=4e76d82a-8f00-46e0-a234-fc628882dae8" alt=""><figcaption></figcaption></figure>

## 2. Add a Projectile Spawner Component & Set It Up

Add the ProjectileSpawner to this object. You'll notices a couple of red warnings in the Inspector. We'll fix these as we set it up.&#x20;

<figure><img src="https://2431624982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MY3N_li2jPq7az6mYfq%2Fuploads%2FrGSiOJXw2pTo4F4nTXiI%2FScreenshot%202024-04-03%20at%203.39.25%E2%80%AFPM.png?alt=media&amp;token=37879bdb-7638-47eb-bbaf-157b9782d4c6" alt=""><figcaption></figcaption></figure>

### Select the Collision Mask Layers

Projectile Spawners determine the default `Layers` that any Projectile will collide with. Each Projectile can override this value, but will otherwise inherit it. For the demo, we set this to include *Default* and *Actor* layers.

### Set the Target

This is optional, but in the demo scene we do have some targets available, so I'll populate this now. In your game, you'll need to have methods to set the target, which all depends on how your game works. The [**Projectile Spawner**](/magic-pig-games/projectile-factory/projectile-factory-documentation/projectile-spawner.md) documentation has more details on the `SetTarget()` method.

### Add Projectiles

We'll add the [**Projectile**](/magic-pig-games/projectile-factory/projectile-factory-documentation/projectile.md) we just created as here as well. Each list can have any number of projectiles, but needs at least one set. They can also be set at runtime.

<figure><img src="https://2431624982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MY3N_li2jPq7az6mYfq%2Fuploads%2FXfh3Mk7NAvnHTChyaBPg%2FScreenshot%202024-04-03%20at%203.45.11%E2%80%AFPM.png?alt=media&amp;token=25813697-6615-4927-9cbf-1af663ee684b" alt=""><figcaption></figcaption></figure>

### Add a Spawn Point

Each Projectile Spawner can have any number of **Spawn Points**. Each Spawn Point has a rotating and tilting transform. Some Spawn Beahviors may make use of these transforms.

<figure><img src="https://2431624982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MY3N_li2jPq7az6mYfq%2Fuploads%2FWHH6l6NYNEFtUVduEP3X%2FScreenshot%202024-04-03%20at%203.48.08%E2%80%AFPM.png?alt=media&amp;token=6db3489d-e538-4a6d-88bd-1d22c3957715" alt=""><figcaption></figcaption></figure>

### Spawn Point Manager

This spawner only has one spawn point, so we don't need to provide a [**Spawn Point Manager**](/magic-pig-games/projectile-factory/projectile-factory-documentation/spawn-point-manager.md). If we had more than one Spawn Point, a Spawn Point Manager will determine how the points are selected. You can create your own Spawn Point Manager class to customize this logic for your project, and the different spawners in it.

### Select a Trajectory

Each Projectile Spawner can also have an optional pre-launch [**trajectory behavior**](broken://pages/5oJ1xkiPJIVjpO2fhyGJ). This will be used when the `ShowTrajectory` value is `true`, prior to launching a trajectory. Individual Projectiles can also have a trajectory that displays while they are live in the world -- these are added the same as other Behaviors.

<figure><img src="https://2431624982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MY3N_li2jPq7az6mYfq%2Fuploads%2Fkk13o0qgmTBfIdgeaH2H%2FScreenshot%202024-04-03%20at%203.50.30%E2%80%AFPM.png?alt=media&amp;token=7803eb62-5276-4ada-afa3-81f19701aec3" alt=""><figcaption></figcaption></figure>

We will select the *Hit Preview Overlay* behavior.

## 3. Optional: Test It!

To test this, we can replace the demo actor with our new Projectile Spawner in one of the demo scenes.

<figure><img src="https://2431624982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MY3N_li2jPq7az6mYfq%2Fuploads%2Fu0iZWY08qZzLyjI3lIN3%2FScreenshot%202024-04-03%20at%203.53.20%E2%80%AFPM.png?alt=media&amp;token=a48a794a-35f0-4aad-8df1-adcd46e5db4b" alt=""><figcaption></figcaption></figure>

The **Demo Controller** object with the `DemoController` component already has the logic set up to spawn projectiles. Dig into that script to see how it's done.

<figure><img src="https://2431624982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MY3N_li2jPq7az6mYfq%2Fuploads%2FJHoUSnHgm83sVirWyUdk%2FScreen%20Recording%202024-04-03%20at%203.53.04%E2%80%AFPM.gif?alt=media&amp;token=06024254-c9cc-48a1-9686-4c3b7b62fd4d" alt=""><figcaption><p>It works!</p></figcaption></figure>

## 4. Connect Events

To fully use the Projectile Factory, your classes will need to know when things happen. There are two kinds of [**Events**](/magic-pig-games/projectile-factory/projectile-factory-documentation/events.md) on a Projectile Spawner -- Spawner Events and Projectile Events. The Spawner itself calls the Spawner events, and the Projectile events are passed to each Projectile it creates. Those projectiles call the Projectile events.

### Add a `ProjectileDemoActor` to the Spawner

The `ProjectileDemoActor` is a very basic "*Actor*" class -- the targets are also *Actors*, in this case NPCs. These are the things that can give and take damage.

<figure><img src="https://2431624982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MY3N_li2jPq7az6mYfq%2Fuploads%2FuHh3JYYc4oJlNO98pgWA%2FScreenshot%202024-04-03%20at%204.02.14%E2%80%AFPM.png?alt=media&amp;token=a9473553-b7e4-4321-a55e-955e2e3d2a04" alt=""><figcaption></figcaption></figure>

The details on the script don't really matter for this purpose. This section is intended to demonstrate how you can connect your classes to the projectile system, so that your players can cause damage, and take damage, from projectiles.

### Add a Projectile Event

First, let's add a Projectile Event. On this tab, expose the `On Launch` event, and drag in the spawner object from the Hierarchy view. Then select the `AddProjectileLaunched` method.

<figure><img src="https://2431624982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MY3N_li2jPq7az6mYfq%2Fuploads%2FOQIMJfPjRn8N29SeBHiT%2FScreenshot%202024-04-03%20at%204.08.02%E2%80%AFPM.png?alt=media&amp;token=ed3e81d9-1d81-4c8f-a186-9b7d611998cc" alt=""><figcaption></figcaption></figure>

The demo scene will display the number of projectiles launched in the UI. This is one way to ensure your classes know what's happening with Projectiles, by using `UnityEvents`.

### Add an Observer

Another method to connect your classes with the Projectile Factory is through [**Observers**](/magic-pig-games/projectile-factory/projectile-factory-documentation/observers-global-observers-and-observer-objects.md). View the *Setup* area on the Projectile Spawner, and add the ***Demo Actor Observer*** to the list.

<figure><img src="https://2431624982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MY3N_li2jPq7az6mYfq%2Fuploads%2FLAl5Yqztpbh6bolpg13P%2FScreenshot%202024-04-03%20at%204.10.54%E2%80%AFPM.png?alt=media&amp;token=6b8fb95c-4d59-40c5-a5f8-1f01f30fa21b" alt=""><figcaption></figcaption></figure>

Observers inherit from [**Projectile Behavior**](/magic-pig-games/projectile-factory/projectile-factory-documentation/behaviors.md), so have all the same life-cycle events that any other Behavior has. The Observer waits for `OnCollision` or `OnTrigger`, before acting.

```csharp
public ProjectileDemoActor Actor { get; set;  }
        
// In this demo, we will register the owner of the projectile OnLaunch, so that when the projectile hits another
// actor, we can apply damage to that actor. And the other actor will know where the damage came from! Often
// damage will be based on the stats of the attacking actor, so it's important to know who the attacker is.
public override void LaunchProjectile(Projectile projectile)
{
    var actor = ProjectileOwner.GetComponent<ProjectileDemoActor>();
    if (actor == null)
    {
        Debug.LogError("Projectile owner does not have a ProjectileDemoActor component!");
        return;
    }
    Actor = actor;
}

//...
        
public override void CollisionEnter(Projectile projectile, Collision collision, GameObject objectHit = null, Vector3 contactPoint = default)
{
    if (Actor == null)
        return;
    
    HitObject(objectHit);
}

// This is where we ensure the object we hit was an actor, and then send the information to our actor, which
// will handle the logic of actually doing the damage. This just says "Hey, we hit another actor!"
protected virtual void HitObject(GameObject objectHit)
{
    var actorHit = objectHit.GetComponent<ProjectileDemoActor>();
    if (actorHit == null)
        return;

    Actor.RegisterHit(Projectile, actorHit); // Send the hit information to the actor
}
```

The `HitObject` method checks to see if the object has a `ProjectileDemoActor` on it. If it does, it calls the `RegisterHit` method on the `Actor` who spawned the projectile. This is how the player actor causes damage on the targets.

Your own classes can do whatever they want with the data that comes out of Projectile Factory.

## 5. Optional: Test It!

<figure><img src="https://2431624982-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MY3N_li2jPq7az6mYfq%2Fuploads%2Fp59bijosnOpHwpZCfMhH%2FScreen%20Recording%202024-04-03%20at%204.18.07%E2%80%AFPM.gif?alt=media&amp;token=aa4897b0-6cd3-471a-856c-fd5b50432195" alt=""><figcaption></figcaption></figure>

It works! The Console shows debug log messages that are very bright. I set it up like this to draw your attention to the portions of the code that pass the damage back and forth. You can set up your logic however you'd like, of course!

## You're Done!

Next, check out how you can quickly use the 3rd Party Integrations we have provided on the [**Asset Store**](https://assetstore.unity.com/vfx/particles?aid=1100lxWw). If you have the particle package as well, you'll find ready-to-use Projectiles that work with the particles from each package!

{% content-ref url="/pages/abRFIgnSz3GcvRlZi7Vc" %}
[Use 3rd Party Integrations](/magic-pig-games/projectile-factory/overview-and-quickstart/quick-start-guide/use-3rd-party-integrations.md)
{% endcontent-ref %}
