Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Instantiating prefabs from unattached scripts

Discussion in 'Prefabs' started by jc310xc, Dec 7, 2019.

  1. jc310xc

    jc310xc

    Joined:
    Apr 14, 2013
    Posts:
    1
    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:
    Code (csharp):
    1. public class PistolBehavior : MonoBehaviour, IWeaponBehavior
    2. {
    3.     float timeSinceLastShot;
    4.     float fireDelay = 1;
    5.  
    6.     public GameObject bulletPrefab;
    7.  
    8.     public int ShotSpeed { get; private set; } = 5;
    9.  
    10.     public bool CanShoot()
    11.     {
    12.         return timeSinceLastShot + fireDelay < Time.time;
    13.     }
    14.  
    15.     public void Shoot(Vector2 firePoint, Transform aim, float fireOffset)
    16.     {
    17.         if (!CanShoot())
    18.             return;
    19.  
    20.         var aimAngle = aim.eulerAngles.z * Mathf.Deg2Rad;
    21.         var fireDirection = new Vector2(Mathf.Cos(aimAngle), Mathf.Sin(aimAngle));
    22.         var bullet = Instantiate(bulletPrefab, firePoint + (fireDirection * fireOffset), Quaternion.identity);
    23.         bullet.GetComponent<Rigidbody2D>().velocity = fireDirection * ShotSpeed;
    24.         timeSinceLastShot = Time.time;
    25.     }
    26. }
    And in the Unity Inspector when I select the PistolBehavior script, I have this, where I've inserted my bullet prefab:

    BulletTroubleshooting.png

    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?
     
  2. smaDevelopment2

    smaDevelopment2

    Joined:
    May 17, 2018
    Posts:
    2
    Is that script on any objects!? The Warning about the default references means it should be on an object (See Pic!)
     

    Attached Files:

  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    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.