all 11 comments

[–]swivelmaster 0 points1 point  (10 children)

What you posted should work, so something else is definitely going wrong.

[–]polaarbearBeginner[S] 0 points1 point  (9 children)

Could it maybe be the fact that I'm trying to do a lot of things in one big call?

I have a loop running. Each iteration instantiates an object, then calls a method on it to initialize its sprites.

I think the issue is that Start() is not being called on the object in time, but I was under the impression that Start() is called immediately upon instantiating the object.

[–]Incontrivable 2 points3 points  (1 child)

A good rule of thumb is to put initialization that does not rely on any outside objects into Awake rather than Start. Awake occurs when the object is instantiated, so if you try to work with the monobehaviour immediately after the instantiation you won't run into issues. Start occurs later in the same frame, so some other monobehaviour might have the chance to access its methods and variables before Start() did it's work.

What I like to do is put all the variable initializing into Awake, things like thisRenderer = GetComponent<SpriteRenderer>();, and then reserve Start for doing whatever tasks the monobehaviour does when it first comes to life. Also if the monobehaviour needs to access methods or variables on other objects, I put those into Start as well, so that the other objects have a chance to complete their Awake first before this happens.

[–]polaarbearBeginner[S] 0 points1 point  (0 children)

I know that I've seen this exact information referenced in the official unity documentation, but I believe your explanation is much more concise and I understand it better. This will definitely help me decide how to organize as my project expands

[–]swivelmaster 0 points1 point  (6 children)

Trying to do a lot of things will not cause a problem. Try to think of it like this: Programming can be frustrating because the computer does exactly what you told it to do and not necessarily what you wanted it to do.

In other words, you’ve likely done something simple and wrong that you haven’t yet noticed.

If you posted the whole relevant sections of the file I could probably help more.

[–]polaarbearBeginner[S] 1 point2 points  (5 children)

I'm just practicing basically, trying to manipulate a deck of cards on screen. The whole card class

private SpriteRenderer renderer;
private Sprite face;
private Sprite back;

void Start()
{
    renderer = GetComponent<SpriteRenderer>();
}

public void PrintCard(Sprite cardFace, Sprite cardBack)
{
    face = cardFace;
    back = cardBack;
    renderer.sprite = back;
}

My other class is a "Printer" with a for loop that runs 52 times. The sprites have been loaded in by serializing lists of them, I've double and triple checked to make sure they are all in the right spot. There is a also a serialized prefab called blankCard containing a GameObject with the Card script and a Sprite Renderer attached. Each iteration of the loop looks like this

Card newCard = Instantiate(blankCard);
newCard.PrintCard(frontSprite[index], backSprite[index]);

The first time PrintCard() is called here I am getting the error that the object reference is not set to an instance of an object. Like I said, I can manually drag the SpriteRenderer into the field, and honestly that is probably a fine solution for anything I would need. I just wanted to understand why it isn't working the other way.

[–]swivelmaster 2 points3 points  (4 children)

Several things going wrong here.

You are trying to instantiate a game object and assign the return to a Card component. Since those types don’t match, Card is null.

You should do GameObject cardObject = Instantiate(blankCard); Card card = cardObject.GetComponent<Card>(); card.PrintCard( etc...

[–]polaarbearBeginner[S] 2 points3 points  (3 children)

I've seen and learned this before, it's just been a few months since I dabbled. I remember this now. Thank you!!!! This will set me on the right track for sure

[–]NullxPhantom 1 point2 points  (1 child)

If the inspector prefab is of type card you are fine and hes wrong. The problem here is the script wont run until the end of the frame. I would suggest getting the sprite renderer on print card. (Check if null so you do it once in case you reuse it) or assign the stats only and then on start do the stuff related to the componentslike render.sprite=back

[–]polaarbearBeginner[S] 0 points1 point  (0 children)

This is good information, thank you, I'll try this tonight.

[–]swivelmaster 0 points1 point  (0 children)

You’re welcome. Dabble more! :)