Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Need help of calling an instantiate from another script!

Discussion in 'Scripting' started by abdelrahmanyoussry509, Apr 21, 2020.

  1. abdelrahmanyoussry509

    abdelrahmanyoussry509

    Joined:
    Jan 26, 2020
    Posts:
    14
    hey i am new to coding and unity so i dont know how to explain properly but here goes:
    i am trying to create is when player comes near object(weapon) and when he presses e it gets pushed towards him then we destroy the object and we instantiate the weapon in the player's hand (as if he picked it up) but when i instantiate i always get this error:
    NullReferenceException: Object reference not set to an instance of an object
    pickup.OnTriggerStay (UnityEngine.Collider target) (at Assets/scripts/pickup.cs:48)


    Gun script:

    Code (CSharp):
    1. public gungen[] loadout;
    2.     public Transform WeaponParent;
    3.     private int LastWeapon = 2028;
    4.     private GameObject lastrealweapon;
    5.  
    6.     void Start()
    7.     {
    8.      
    9.     }
    10.  
    11.        public IEnumerator GunPicked()
    12.         {
    13.             print("gun is getting picked up");
    14.             yield return new WaitForSeconds(2);
    15.  
    16.             equip(0);
    17.         }
    18.      
    19.  
    20.  
    21.     void Update()
    22.     {
    23.  
    24.         if (Input.GetKeyDown(KeyCode.Alpha1))
    25.         {
    26.          
    27.             equip(0);
    28.          
    29.         }
    30.         if (Input.GetKeyDown(KeyCode.Alpha2))
    31.         {
    32.             equip(1);
    33.         }
    34.         if (Input.GetKeyDown(KeyCode.Alpha3))
    35.         {
    36.             equip(2);
    37.         }
    38.         if (Input.GetKeyDown(KeyCode.K))
    39.         {
    40.             Destroy(lastrealweapon);
    41.         }
    42.  
    43.  
    44.     }
    45.  
    46.    public  void equip(int invintroy)
    47.     {
    48.         Vector3 rot = WeaponParent.transform.rotation.eulerAngles;
    49.         rot = new Vector3(rot.x , rot.y, rot.z );
    50.         if(LastWeapon != invintroy)
    51.         {
    52.          
    53.  
    54.             GameObject newEquipment = Instantiate(loadout[invintroy].prefab, WeaponParent.position, Quaternion.Euler(rot), WeaponParent) as GameObject;
    55.             newEquipment.transform.localPosition = Vector3.zero;
    56.             newEquipment.transform.localEulerAngles = Vector3.zero;
    57.          
    58.             LastWeapon = invintroy;
    59.             if(lastrealweapon != newEquipment)
    60.             {
    61.                 Destroy(lastrealweapon);
    62.             }
    63.             lastrealweapon = newEquipment;
    64.          
    65.         }
    66.  
    67.  
    68.      
    69.  
    70.          
    pickup script:

    Code (CSharp):
    1.  public Transform Player;
    2.     public Rigidbody rb;
    3.     public float multiplier;
    4.     private Vector3 uping;
    5.     private bool IsPickingUp = false;
    6.     private GameObject target;
    7.     // Start is called before the first frame update
    8.     void Start()
    9.     {
    10.  
    11.     }
    12.  
    13.     // Update is called once per frame
    14.     void Update()
    15.     {
    16.  
    17.         rb = GetComponent<Rigidbody>();
    18.      
    19.  
    20.     }
    21.  
    22.     void OnTriggerStay(Collider target)
    23.     {
    24.         if (target.tag == "Player")
    25.         {
    26.             if (Input.GetKeyDown(KeyCode.E))
    27.             {
    28.                 IsPickingUp = true;
    29.  
    30.              
    31.             }
    32.             if (IsPickingUp)
    33.             {
    34.              
    35.                 rb.AddForce((Player.position - transform.position) *10);
    36.                 uping = Vector3.up;
    37.                 rb.AddForce(uping *multiplier );
    38.                 rb.transform.Rotate(0, 0, Random.Range(150,360) * Time.deltaTime);
    39.                 print("working");
    40.                 IsPickingUp = true;
    41.  
    42.                 StartCoroutine(GetComponent<Gun>().GunPicked());
    43.             }
    44.          
    45.  
    46.          
    47.         }
    48.      
    49.  
    50.     }

    sorry for messy code i am fairly new to unity and c# and coding in general :D hope you can help me!
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,735
    Look carefully at the error you are getting. It's quite descriptive and should lead you right to the answer:

    First, this is a NullReference exception with a description "Object reference not set to an instance of an object". This means you are trying to call a method or get data from an object, but the object you are trying to do that for is null. It's like asking "Hey how many people are in that car?" but then you don't specify which car you're talking about. Unity doesn't know what to do.

    Next, it is telling you which file and method this is happening in (class: pickup, method: OnTriggerStay(Collider target)), and finally, it's even telling you the file and line number where the error is happening! In this case the file is Assets/scripts/pickup.cs and the line number is 48. Since you didn't paste the entire file it's hard to tell exactly where line number 48 is in your code, but that will be where your problem is. My guess is it's probably this line:
    Code (CSharp):
    1. StartCoroutine(GetComponent<Gun>().GunPicked());
    Most likely there is no Gun component on your GameObject, so GetComponent() returns null, and then you get this error when you try to call GunPicked() method on the null reference.

    Additionally, I would move this code:
    Code (CSharp):
    1.   // Update is called once per frame
    2.     void Update()
    3.     {
    4.         rb = GetComponent<Rigidbody>();
    5.     }
    from the Update() method into Start() for a few reasons. First, there's no reason to do this every single frame, it's a waste as the rigidbody component is not likely to change on a given GameObject. Second, it's possible that OnTriggerEnter() is getting called before this Update() method. Start() will be more likely to run beforehand and make sure that rb is not null when you reference it in OnTriggerEnter()
     
    abdelrahmanyoussry509 likes this.
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,748
    We can't tell which script or which line the error refers to because you cut off the beginning of both scripts.
     
  4. abdelrahmanyoussry509

    abdelrahmanyoussry509

    Joined:
    Jan 26, 2020
    Posts:
    14
    THANK YOU so MUCH I fixed it by doing
    StartCoroutine(FindObjectOfType<Gun>().GunPicked());
    and it worked like a charm!
    i just could not figure out how do i grab it form another script so when you toled me it needs to have same component in the game object i searshed for a code that would grab the component from diffrent object !
     
  5. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,748
    FindObjectOfType<>() is a very slow function call. If you're going to use it, use it once in Start() and cache the result.

    Better yet, make it a public variable and drag the Gun into the player's inspector window to assign the reference.
     
  6. abdelrahmanyoussry509

    abdelrahmanyoussry509

    Joined:
    Jan 26, 2020
    Posts:
    14
    I thought about that but I need the gun to be in the other script so if I changed anything i don't mix between then and what do you mean by slow? I don't understand
     
  7. matkoniecz

    matkoniecz

    Joined:
    Feb 23, 2020
    Posts:
    170
    It is slow to execute, executing many expensive functions will reduce performance of your program.