# Projectile System

While Projectiles (Physical Bullets) can be used, FPS Framework uses Hitscan (Raycast) by default, which are the most common performant method in all first-person shooter games. If you would like to use hitscan you can check this out.

## Creating a new projectile

To create a new projectile first create an empty game object and add the component **"Projectile"** to it. Your game object's inspector should look like this:

<div align="left"><figure><img src="/files/MSc0vPAHaU1KV2uWlrK7" alt="" width="536"><figcaption><p>Default projectile's inspector</p></figcaption></figure></div>

This is the default values (Could be different depencing on the current version of FPS Framrwork that you are using.

### Fields

<table><thead><tr><th width="235">Name</th><th>Description</th></tr></thead><tbody><tr><td>Hittable layers</td><td>The layers which this projectile can detect</td></tr><tr><td>Decal direction</td><td>The direction of the decal according to the normal value of the raycast</td></tr><tr><td>Penetration strength</td><td>This amount, which may be referred to as the projectile's "health," is set by the "Default Decal" component and decreases each time the projectile hits an item. The default health damage value is 10 in the event that this component is unavailable.</td></tr><tr><td>Speed</td><td>The speed of the projectile</td></tr><tr><td>Gravity</td><td>The gravity multiplier to this projectile. A value of 2 is equal to Physics.gravity * 2</td></tr><tr><td>Force </td><td>The force the projectile can apply when it hits an object.</td></tr><tr><td>Lifetime</td><td>The time after which the projectile automatically destroys itself.</td></tr><tr><td>Default decal</td><td>The default hit impact effect if there's no "Custom Decal" component on the object that got hit.</td></tr><tr><td>Destroy on impact</td><td>If on the projectile will automatically destroy itself on the first hit.</td></tr><tr><td>Use source velocity</td><td>If on the projectile will add the force of the shooter to its initial velocity.</td></tr><tr><td>Use auto scaling</td><td>If on the projectile will scale itself to always look the same to the shooter.</td></tr><tr><td>Scale multiplier</td><td>The scale of the projectile which the projectile needs to maintain, this is not affected by "Use auto scaling" toggle.</td></tr><tr><td>Range</td><td>The range of the projectile in which it can deal damage.</td></tr><tr><td>Damage range curve</td><td>How the damage is affected by its travel distance.</td></tr></tbody></table>

### Ignoring hits

To ignore hits from all projectiles to a certian game object, you can do these

* Assgin a layer to that game object and remove it from the hittable layers
* Add the component "IgnoreHitDetection" to the game object you want to ignore hits.

This is how your game object's inspector that ignores hits look like:

<div align="left"><figure><img src="/files/oHxqFTRauNcMaWdHJr2t" alt="" width="548"><figcaption><p>Ignore hit detection's inspector</p></figcaption></figure></div>

## Callback Methods

The projectile can send messages to your custom scripts via a callback function like unity's callbacks e.g OnTriggerEnter(). These callback methods are identified in your script via interfaces you implment.

### Hit callbacks

When trying to detect hits to your object, you would implement IOnHit interface like this:

```csharp
using Akila.FPSFramework;

public class Test : MonoBehaviour, IOnHit
{
    public void OnHit(HitInfo hitInfo)
    {
        throw new System.NotImplementedException();
    }
}
```

With the function `OnHit(HitInfo hitInfo)` Implemented, if the object the component Test is attached to has a collider and was hit, `OnHit` method will be called. This could be used to then for example, play a sound when the player is hit:

```csharp
using Akila.FPSFramework;

//This component attached to the player object
public class Test : MonoBehaviour, IOnHit
{
    //This audio source assgined through editor
    public AudioSource audioSource;
    
    public void OnHit(HitInfo hitInfo)
    {
        //Call the Play() method or do any logic you want.
        audioSource.Play();
    }
}
```

This interface has varients like `IOnHitInParent` which is called when the parent is hit, or `IOnHitInChildren` which is called when any of the children are hit.

### Nearby events

When trying to detect the projectile passing by in the "Nearby Range" to your object, you would implement `IOnProjectileFlyBy` interface like this:

```csharp
using Akila.FPSFramework;

public class Test : MonoBehaviour, IOnProjectileFlyBy
{
    public void OnProjectileFlyBy(Projectile projectile)
    {
        throw new System.NotImplementedException();
    }
}
```

With the function `OnProjectileFlyBy(Projectile projectile)` Implemented, if the object the component Test is attached to has a collider and projectile passes by, `OnProjectileFlyBy` method will be called. This could be used to then for example, play a sound when projectile passes by:

```csharp
using Akila.FPSFramework;

//This component attached to the player object
public class Test : MonoBehaviour, IOnProjectileFlyBy
{
    //This audio source assgined through editor
    public AudioSource audioSource;
    
    public void OnProjectileFlyBy(Projectile projectile)
    {
        //Call the Play() method or do any logic you want.
        audioSource.Play();
    }
}
```

Much like `IOnHit` interface this interface has varients like `IOnHitInParent` which is called when the parent is hit, or `IOnHitInChildren` which is called when any of the children are hit.

### Transferring into explosive projectile

You only need to add the "Explosive" component to the same game object that already has the projectile on it in order to change this projectile from being a simple "Bullet" to an explosive one. The rest is explanined in [Explosive](/fps-framework/tutorials/character/explosive.md)


---

# 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://akila.gitbook.io/fps-framework/tutorials/character/firearm/other/projectile-system.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.
