#Unity Inexplicably Crashing

1 messages Β· Page 1 of 1 (latest)

winter gull
#

@limber raft Don't want to overflow the main channel πŸ™‚

limber raft
#

Good call

#

StackOverflow means it either ran into a recursive loop somewhere or there is an extremely large call stack in the game (almost definitely the former)

winter gull
#

I added some code that was new to me

#

AddComponent() instead of new(), for example

#

Maybe I made a mistake there?

#

If you check the github the scripts will be easier to see, it was DecoderButton.cs that I was working on.

limber raft
#

The Stack refers to the call stack, which is a stack that holds each open method call running. You can see the stack when you Debug.Log where it tells you which methods called which methods.

StackOverflow means that there are too many methods in the call stack. Considering that a call stack is usually a large capacity, filling it means something went wrong and not crashing could take destabilize the computer.

winter gull
#

Got it

limber raft
#

new isn't often used in Unity for very specific reasons (mostly needing to track objects that require callbacks like Update).

If you want to add a component to a gameobject, GameObject.AddComponent<T> is the correct method. Though, where did you add it?

winter gull
#

Looking over it I don't see where anything recursive might be happening

winter gull
limber raft
#

What method are you inside of? What kind of component is being added?

winter gull
#

But that seems wrong

#

How can you add a class to an object

#

I'm inside Awake()

#
using System;
using UnityEngine;

public class DecodeButton : MonoBehaviour
{
    ReadStringInput plaintextStringInput;
    ReadStringInput shuffleStringInput;

    Decoders decoderScript;

    void Awake()
    {
        // Instantiate GameObjects for each of the text box inputs (for the plaintext and the shuffle).
        GameObject plaintextGameObject = new GameObject("ReadStringInput");
        plaintextStringInput = gameObject.AddComponent<ReadStringInput>();

        GameObject shuffleGameObject = new GameObject("ReadStringInput");
        shuffleStringInput = gameObject.AddComponent<ReadStringInput>();

        // Instantiation for usage of other scripts
        GameObject decoderGameObject = new GameObject("Decoders");
        decoderScript = gameObject.AddComponent<Decoders>();
    }

    void OnClick()
    {
        int shuffle;
        Int32.TryParse(shuffleStringInput.input, out shuffle);
        string output = decoderScript.CaesarCipher(plaintextStringInput.input, shuffle);
    }
}
limber raft
winter gull
#

The full script ^

winter gull
limber raft
#

Do ReadStringInput or Decoders use AddComponent in their own awakes?

winter gull
#

Neither of them have an Awake()

#

But there is stuff in Decoders.Start

limber raft
#

My guess was that adding the component creates a new instance and has it's Awake method called immediately. If that Awake method calls back to the original, or something similar, you'll get never ending new components

#

What is inside Decoders.Start?

winter gull
#

That makes sense

#
void Start()
{
    // Fetch lists from ListConstants.cs to ensure that it is fully updated.
    upperAlphabet = ListConstants.upperAlphabet;
    lowerAlphabet = ListConstants.lowerAlphabet;
    integers = ListConstants.integers;
}   
#

Just setting local variables from variables set in another script

#

Those local variables are defined above Start() here```cs
// Pre-defining the ordered alphabets and integers for ease of access in all functions that need it
char[] upperAlphabet;
char[] lowerAlphabet;
int[] integers;

limber raft
#

yeah that seems fine

winter gull
#

No instantiations so nothing recursive

limber raft
#

It only crashes when you hit play, right?

winter gull
#

Correct

#

Just retested, and it still happens

limber raft
#

So it's definitely something in the game code. You might need to go through your git history and look at the recent changes made to code to track it down. git bisect is a good tool for that.

git bisect makes you pick a commit you know works and a commit you know doesn't and it helps do a search for the commit that caused the issue. Helps narrow things down when looking.

winter gull
#

GitHub Desktop can do that for me I believe

#

Let me go and see

#

This is super annoying

#

Can IDEs not detect recursive functions?

limber raft
#

I've been there πŸ˜…

winter gull
#

I just switched to VS22 from VSCode and they seem like they can do anything

#

So this is kind of surprising

#

But I guess it understands Unity less

limber raft
#

No, it's actually really hard to detect that, regardless of unity.

winter gull
#

Oh fair enough then

#

If you can't, it can't, I guess

limber raft
#

Some types of infinite loops fall into the same category. It's just one of those things you need to be careful about

winter gull
#

Oh

#

I found the code that creates the issue

#

It's the

// Instantiation for usage of other scripts
GameObject decoderGameObject = new GameObject("Decoders");
decoderScript = gameObject.AddComponent<Decoders>();
#

And look what happens when I run the game

#

It creates a bunch of objects

#

I don't think that's meant to happen

#

Just for reading a string

#

But I'm completely flabbergasted by how overcomplicated it is to simply read a string from an Input Field

limber raft
#

yeah, that's weird.

winter gull
#

So I don't claim to understand it all

#

It should only be creating two GameObjects, correct? Not 4?

limber raft
#

It shouldn't be too difficult.

#

InputField.TextComponent.text or something like that?

winter gull
#
ReadStringInput plaintextStringInput;
ReadStringInput shuffleStringInput;

Decoders decoderScript;

void Awake()
{
    // Instantiate GameObjects for each of the text box inputs (for the plaintext and the shuffle).
    GameObject plaintextGameObject = new GameObject("ReadStringInput");
    plaintextStringInput = gameObject.AddComponent<ReadStringInput>();

    GameObject shuffleGameObject = new GameObject("ReadStringInput");
    shuffleStringInput = gameObject.AddComponent<ReadStringInput>();
}
winter gull
limber raft
#

That sounds very wrong

winter gull
limber raft
#

Can you try that code? I'm fairly certain it is like that

winter gull
#

Sure let me figure out how to get that in

#

It's because it's TextMeshPro

#

So you have to do some weird stuff

limber raft
#

Oh actually it's easier than that

winter gull
limber raft
#

Sorry, it's just InputField.text or TMP_InputField.text for TMP stuff

winter gull
#

How do I specify which Input Field though?

limber raft
#

swap out the name of the class with the actual variable name

#

Do you have a reference to the input field already?

winter gull
#

A reference being an instantiation?

limber raft
#

Just a reference to the instance when the game is running. Are you creating it programatically or is it in the serialized scene?

winter gull
#

Programatically

#

I think...

#

I seriously need to know more about how this editor works before making an app

#

I'm definitely not serializing anything though

winter gull
limber raft
#

If you use the scene view to create objects, that's a serialized scene

winter gull
#

Then yes I am, but not for reading the input field, as you saw that was creating a new gameobject from the script

limber raft
winter gull
#

The Input Field was created in the scene view

limber raft
#

In that case, the easiest way would be with a drag and drop reference

#

For whatever script is handing this and exists in the scene, you can create a member variable to hold an InputField reference and make sure it is serialized. In the Scene view, if you select that script, you'll be able to drag and drop the InputField onto it.

winter gull
#

Yes

#

I don't have any scripts that exist in the scene, how do i do that?

limber raft
#

Then you can use the variable to get the text

limber raft
winter gull
#

I'm confused on what the variable would actually be called

limber raft
#

anything you want

winter gull
#

Sorry the value of the string of the input field

winter gull
#

What would it actually be in my case

limber raft
#

The variable name

#

you need to declare one

#

Are you familiar with member variables?

winter gull
#

Aren't they just stuff that's in the class

winter gull
#

Are member variables

limber raft
#

Yup

winter gull
#

Okay

limber raft
#

If you create a new one of with the type TMP_InputField, you can turn that into a drag and drop reference in the component's inspector

winter gull
#

And before the variable I put [SerializeField], right? This is from my memory of like 2 years ago

#

So hopefully correct

limber raft
#

It needs to be set up for Unity to know it should be serialized. You can do that be either

  • making the variable public
  • using [SerializeField]
winter gull
#

Is one of these better than the other?

limber raft
#

the second one is generally safer and better practice

winter gull
#

I won't need to access it from another script so making it public seems more confusing

#

Yes I agree cool

#

And what do I drag and drop into the inspector?

#

The input field itself or the text area?

limber raft
#

The InputField itself, yup

winter gull
#

Okay brilliant

#

That makes sense, dumb question haha

limber raft
#

Hey, you never know!

winter gull
#

I'm going to try Debug.Logging the TMP_InputField.Text

#

With this:

public void OnClick()
{
    Debug.Log(plaintextInputField.text);
}
limber raft
#

But there is text in the field?

winter gull
#

Yes

#

Oh

#

No there was not

#

I say the greyed out Enter Text... and thought there was

#

Imagine if I spent hours figuring that out as well

#

πŸ˜‚

#

Well Andrew

#

You've taken me from thinking my project is unrecoverable to having a fully working project so far

limber raft
#

Awesome!

winter gull
#

Much appreciated 😁

#

People like you that let newbies like me do this sort of thing

#

I'm definitely going to go and do some reading though

limber raft
#

Ahaha. No problem! Good luck with the rest of the project

winter gull
#

Thanks mate πŸ™‚

winter gull
#

Yay... it's happening again.

#

I've got another StackOverflow