#Unity Inexplicably Crashing
1 messages Β· Page 1 of 1 (latest)
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)
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.
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.
Got it
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?
Looking over it I don't see where anything recursive might be happening
I'm using gameObject.AddComponent. Does that matter?
What method are you inside of? What kind of component is being added?
The component being added is a class
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);
}
}
Yeah, that's what I thought might be the case. Is the component you are adding inside awake the same type as the script you are in?
The full script ^
No, they're not of type DecodeButton, but rather of type of other scripts
Do ReadStringInput or Decoders use AddComponent in their own awakes?
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?
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;
yeah that seems fine
No instantiations so nothing recursive
It only crashes when you hit play, right?
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.
GitHub Desktop can do that for me I believe
Let me go and see
This is super annoying
Can IDEs not detect recursive functions?
I've been there π
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
No, it's actually really hard to detect that, regardless of unity.
Some types of infinite loops fall into the same category. It's just one of those things you need to be careful about
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
yeah, that's weird.
So I don't claim to understand it all
It should only be creating two GameObjects, correct? Not 4?
It shouldn't be too difficult.
InputField.TextComponent.text or something like that?
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>();
}
According to the internet you have to create an object and stuff
That sounds very wrong
Not sure why it can't be like this though
Can you try that code? I'm fairly certain it is like that
Sure let me figure out how to get that in
It's because it's TextMeshPro
So you have to do some weird stuff
Oh actually it's easier than that
Would I replace InputField with the gameobject's name? That doesn't seem right
Sorry, it's just InputField.text or TMP_InputField.text for TMP stuff
How do I specify which Input Field though?
swap out the name of the class with the actual variable name
Do you have a reference to the input field already?
A reference being an instantiation?
Just a reference to the instance when the game is running. Are you creating it programatically or is it in the serialized scene?
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
What would this actually be? I'm a tad confused
If you use the scene view to create objects, that's a serialized scene
Then yes I am, but not for reading the input field, as you saw that was creating a new gameobject from the script
you need a reference to the runtime InputField component instance. There are a bunch of ways to get it but it depends on how they are created
The Input Field was created in the scene view
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.
Then you can use the variable to get the text
You most likely do if your code is executing. All I mean is that there is a gameobject in the scene with one of your components attached to it
I'm confused on what the variable would actually be called
anything you want
Sorry the value of the string of the input field
This
What would it actually be in my case
Aren't they just stuff that's in the class
For example here, plaintextStringInput and shuffleStringInput
Are member variables
Yup
Okay
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
And before the variable I put [SerializeField], right? This is from my memory of like 2 years ago
So hopefully correct
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]
Is one of these better than the other?
the second one is generally safer and better practice
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?
The InputField itself, yup
Hey, you never know!
I'm going to try Debug.Logging the TMP_InputField.Text
With this:
public void OnClick()
{
Debug.Log(plaintextInputField.text);
}
But there is text in the field?
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
Awesome!
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
Ahaha. No problem! Good luck with the rest of the project
Thanks mate π