Instantiating prefabs from unattached scripts

Hi there!

I come from a fairly solid C# background, but I’m still working out how Unity scripts play with the Unity ecosystem at large.

I’m building myself a simple weapon system. The player control script I have has an IWeaponBehavior that tells the script if the weapon can shoot, and allows the script to shoot the weapon.

Inside of an implementation of IWeaponBehavior, I want to Instantiate a bullet prefab, position it, and send it on its way when its Shoot method is called. Roughly, I have the following:

public class PistolBehavior : MonoBehaviour, IWeaponBehavior
{
    float timeSinceLastShot;
    float fireDelay = 1;

    public GameObject bulletPrefab;

    public int ShotSpeed { get; private set; } = 5;

    public bool CanShoot()
    {
        return timeSinceLastShot + fireDelay < Time.time;
    }

    public void Shoot(Vector2 firePoint, Transform aim, float fireOffset)
    {
        if (!CanShoot())
            return;

        var aimAngle = aim.eulerAngles.z * Mathf.Deg2Rad;
        var fireDirection = new Vector2(Mathf.Cos(aimAngle), Mathf.Sin(aimAngle));
        var bullet = Instantiate(bulletPrefab, firePoint + (fireDirection * fireOffset), Quaternion.identity);
        bullet.GetComponent<Rigidbody2D>().velocity = fireDirection * ShotSpeed;
        timeSinceLastShot = Time.time;
    }
}

And in the Unity Inspector when I select the PistolBehavior script, I have this, where I’ve inserted my bullet prefab:

However when I run the game and attempt to shoot, I get the error message
“ArgumentException: The Object you want to instantiate is null.”, referencing the point where I instantiate my bullet.

I’ve looked around and have seen other suggestions, such as loading prefabs from a Resources folder, but attempting to do so that way also gave me the same error.

What’s the “right” way to do this? Coming from a non-game-programming background, my setup seems reasonable to me. Am I barking up the wrong tree? Is there a “Unity” way to do this?

Is that script on any objects!? The Warning about the default references means it should be on an object (See Pic!)

5260622--526202--Unity.PNG

The field you’ve filled there is only for editor purposes, it means that if you attach that script to something outside of play mode, the field on that instance is automatically set to that value.

I’ve never actually found it useful, and it keeps confusing new Unity users.

@smaDevelopment2 's advice is correct. If you can’t do that (because eg. you’re adding your PistolBehaviour at runtime), you’ll need to fetch the prefab from somewhere. The common way to do that for prototyping and such is to load from Resources, if that’s not working then you’re doing something different wrong there.