Hi all, I am new to programming and am trying to make use of some coding strategies that I have been looking into, one of which is pulling the functions out of the object. I am making a card game and have a card handler class.
public class CardHandler: MonoBehaviour
{
public static List<GameObject> CardsInHand = new List<GameObject>();
public static List<GameObject> CardsReadyToDraw = new List<GameObject>();
public List<ScriptableCard> startingCards = new List<ScriptableCard>();
public GameObject CardPrefab;
public CreateBezier curve;
public OrganizeCards organize;
public DiscardCard discard;
[SerializeField] private DrawCard drawCard;
private void Awake()
{
drawCard.Draw(1);
}
}
In my DrawCard class, I have a reference to the CardHandler. I don’t want to make CardHandler a Singleton because there may be an instance where I want two CardHandlers (two players).
The problem lies where when I call to GetComponent in my DrawCard class, I think because it is called in CardHandler it returns null because it can’t find another CardHandler.
example:
public class DrawCard: MonoBehaviour
{
private CardHandler ch;
private void Awake()
{
gameObject.GetComponent<CardHandler>();
//this returns null
}
public void Draw(int numberToDraw)
{
//Do some drawing stuff using CardHandler
}
}
TLDR:
How do I get a reference to the instance of CardHandler when the class itself is being initialized by CardHandler, and not as a component on a GameObject?
Help me to understand what you mean. At no point did I instantiate a class by saying something like Drawcard dc = new Drawcard. I instead instantiated it through unity as a part of CardHandler by defining it and dragging it in. Is this the same thing, if so, why? there is no constructor so how is this the same?
I don’t see anything being instantiated within your CardHandler class. Can you post the code you’re referring to? I suspect just a mix up in the words being used.
Typically you add a new instance of a MonoBehaviour via one of two ways. Either you call Instantiate against a prefab, which adds a clone of the prefab and all of its attached components to the hierarchy. Or you call AddComponent to add a component to an existing GameObject.
This sentence is confusing people because it’s impossible to have a MonoBehaviour that is not a component on a GameObject. Either you create it in the editor on a GameObject, or you create it with AddComponent, which attaches it to a GameObject, or you Instantiate it from a prefab, which also creates a new GameObject with the Component attached.
No matter how you created the component, GetComponent only works if you call it on the GameObject that the component is attached to.
No, that is just setting an inspector reference to something which already exists. Is the instance of DrawCard already attached to the same GameObject? (Is the Hand GameObject already in the scene hierarcy? Or is it a prefab in the Assets folder?)
Wait, the hand is a different GameObject that has the component on it Drawcard and that is where its pulling the reference from. I see that now. then why is my GetComponent ending up null?
If DrawCard is attached to Hand, and CardHandler is attached to a different object, when you GetComponent and the Hand GameObject it will return null because there is no CardHandler attached to the Hand GameObject. If you had a reference to the GameObject the CardHandler is attached to, you could GetComponent on that GameObject to get the CardHandler.
I’m sorry guys this has gotten out of hand… no pun intended. I have a game object called hand that I was not thinking the reference was pulling from. I wanted to get a reference to my CardHandl
Okay, that makes sense it does not look up the whole hierarchy. This really got out of hand, pun entirely intended! Thanks so much for your help here guys!
@soulstealrichardson Yeah, I think it’s just a case of “Oh no, the component is in another castle.”
When you use the gameObject shortcut, you are saying “the gameobject this script right here is located on.” If you are doing var handler = gameObject.GetComponent<CardHandler>();, handler will only contain a valid instance if there is a CardHandler on the same GameObject this code is on.
Coding in Unity is only a tiny (but critical) part of the picture. As much or more of the picture is controlled by how you author and arrange the GameObjects in your scenes and the prefabs that you load/instantiate.
Right, that makes a lot of sense. Like you said in some ways I’m trying to become a better author. That is why I’m learning programming patterns in the first place. Thanks so much for clearing that up form me, guys! I really appreciate it!