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. Dismiss Notice

using GetComponents with instantiated prefabs?

Discussion in 'Scripting' started by tubbz0r, Jul 12, 2014.

  1. tubbz0r

    tubbz0r

    Joined:
    May 24, 2014
    Posts:
    72
    I am attemping to use GetComponent with my player who is instantiated in the game (once joined a lobby) and I'm trying to access the movement.cs component in the prefab however I am having no luck.
    Here is the current error I am getting:

    "error CS0120: An object rederence is required to access non-static member 'UnityEngine.Component.GetComponent(system.Type)'

    I tried to do this:

    Code (CSharp):
    1. Debug.Log ("Heal casted!");
    2.             Spell4.cast = false;
    3.             Movement movement = Movement.GetComponent("Movement");
    4.             movement.currentHealth += 10;
    5.             movement.Player.Intellect += 2;
     
    Last edited: Jul 15, 2014
  2. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
  3. tubbz0r

    tubbz0r

    Joined:
    May 24, 2014
    Posts:
    72
    Movement is a class that is a script though? I'm a little confused when you say variable that contains the player reference, are you talking about variables in my movement class?

    The problem with getting the GameObject (player) is that its instantiated so I cant do Player = SkelePlayer.GetComponent(Movement);

    (SkelePlayer is the player prefab that is created once joining a room), the movement class is one of the components in this player prefab
     
  4. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
    Movement is a class but it is not an instance of that class. You could have a dozen GameObjects each with the Movement script attached, and for each one the variables can be different, so if you're going to access an instance of it, Unity needs to be certain which one you want.

    Let's try this:

    You've attached the Movement script to your player GameObject, right? Is the script where you're trying to call GetComponent also attached to the player GameObject? If so, then just call GetComponent("Movement"); directly.
    http://docs.unity3d.com/ScriptReference/Component.GetComponent.html


    If you're trying to get the player from a different GameObject, either put the result from the Instantiate call when you Instantiate it into a variable:
    http://docs.unity3d.com/ScriptReference/Object.Instantiate.html
    Or get the player's GameObject from a Find or FindWithTag or something:
    http://docs.unity3d.com/ScriptReference/GameObject.FindWithTag.html
    http://docs.unity3d.com/ScriptReference/GameObject.Find.html
     
  5. laurelhach

    laurelhach

    Joined:
    Dec 1, 2013
    Posts:
    229
    If your Movement script is on the player, you can just create your reference like that.
    Otherwise you need to use FindGameObjectWithTag like rrh suggested.

    Code (csharp):
    1.  
    2. // Variable Declaration
    3. Movement movement;
    4.  
    5. void Start(){
    6.      movement = GetComponent<Movement>();
    7.      movement.currentHealth +=10;
    8.      //movement.Player.Intellect += 2; // this seems to be not correct
    9.      movement.Intellect += 2; // is it what you meant? also your variable should start with a lower case "i" instead of "I"
    10. }
    11.  
    PS: Also you talk about instanciated prefabs. Are you talking about loading a player in the scene (player prefab is already in the scene), or you actually use Instanciate to spawn the player.
     
    Last edited: Jul 14, 2014
  6. tubbz0r

    tubbz0r

    Joined:
    May 24, 2014
    Posts:
    72
    Yup, my Movement script is attached to my player GameObject, the script where im trying to call GetComponent isnt attached to the player GameObject due to the class inheriting from a class written by me. (I think it must derive from MonoBehaviour for me to be able to attach it to my playerObject).

    this is what I have done so far:


    BasemageClass:


    Code (CSharp):
    1. if (Spell4.isCast())
    2.         {
    3.             //Heal
    4.             GameObject player;
    5.             player = GameObject.FindGameObjectWithTag("Player");
    6.             player.GetComponent<Movement>().currentHealth+= 5;
    7.  
    8.             Debug.Log ("Heal casted! HP now " + player.GetComponent<Movement>().currentHealth);
    9.             Spell4.cast = false;
    10.  
    11.         }
    the game does run however then it comes to the line "player.GetComponent<Movement>().currentHealth+=5;"
    it gives an error NullReferenceException: Object reference not set to an instance of an object
     
  7. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
    GameObject.FindGameObjectWithTag("Player"); will return null if there's no game object with the Tag "Player"

    If player isn't null, player.GetComponent<Movement>() will return null if player doesn't have a Movement script attached.

    If you put Debug.Log between the two, like
    if (player==null) Debug.Log("player is null");
    just to be sure which of the two is the problem, then double-check that it has the tag you expect and/or the component attached that you expect.
     
  8. tubbz0r

    tubbz0r

    Joined:
    May 24, 2014
    Posts:
    72
    I was so sure everything was supposed to work haha so turns out restarting my PC made it work :p
    really appreciate the help rrh! thank you!