Unity2D - Why when I created an object of a class and initialized its properties, I got an error while running the game? - class

So I created a class named "TextManager" so I could create some objects and initialize some text in the new object's array. The problem is, I declared a new object of the class, gave the value I wanted, initiliazed the object in the Start() function and it gave me an error.
Here's the TextManager class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TextManager : MonoBehaviour
{
public string description;
public string[] texts;
public TextManager() { }
public TextManager(string pDescription, string[] pTexts)
{
this.description = pDescription;
this.texts = pTexts;
}
}
Now here's the script to add to a gameObject:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GameController : MonoBehaviour
{
[SerializeField] Text mainText;
[SerializeField] GameObject frame;
private int currentPart = 0;
private int changeState = 0;
private float timer = 0.0f;
private bool coroutineStarted = true;
private TextManager introTXT = new TextManager;
private void Start()
{
mainText.text = "";
introTXT.description = "intro";
introTXT.texts[0] = "Text1";
introTXT.texts[1] = "Text2";
introTXT.texts[2] = "Text3";
introTXT.texts[3] = "Text4";
introTXT.texts[4] = "Text5";
introTXT.texts[5] = "Text6";
}
}
And here's the error I got:
NullReferenceException
I don't know why I got a null reference exception... So I'll be waiting for some help.
Thanks in advance guys :)

Related

error CS0117: 'ScoreSystem' does not contain a definition for 'HighscoreKey'

i was just writing my script and this appeared while trying to test the game. heres my script
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using TMPro;
public class MainMenu : MonoBehaviour
{
[SerializeField] private TMP_Text HighscoreText;
private void Start()
{
int Highscore = PlayerPrefs.GetInt(ScoreSystem.HighscoreKey, 0);
HighscoreText.text = $"High Score: {Highscore}";
}
public void Play()
{
SceneManager.LoadScene(1);
}
}
please help me, tq
The error is very clear: it says that inside the Score System class, it did not find the HighscoreKey variable.
To make this work, if you created the ScoreSystem class yourself, you should add a static string variable called HighscoreKey.
Like this:
public static string HighscoreKey = “…”;
Good Work!

Unity The name 'PrefabUtility' does not exist in the current context

I'm trying to build a Unity game, and keep getting the error:
Assets\charaterselection.cs(34,9): error CS0103: The name 'PrefabUtility' does not exist in the current context
The issue is I imported UnityEditor, I'm not sure what's going on
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.SceneManagement;
public class charaterselection : MonoBehaviour
{
public SpriteRenderer sr;
public List<Sprite> skins = new List<Sprite>();
private int selecectedSkin;
public GameObject player;
public void Next()
{
selecectedSkin=selecectedSkin+1;
if (selecectedSkin== skins.Count)
{
selecectedSkin=0;
}
sr.sprite= skins[selecectedSkin];
}
public void back()
{
selecectedSkin = selecectedSkin - 1;
if (selecectedSkin < 0)
{
selecectedSkin = skins.Count - 1;
}
sr.sprite = skins[selecectedSkin];
}
public void play()
{
PrefabUtility.SaveAsPrefabAsset(player, "Assets/Players/FROGY.prefab");
SceneManager.LoadScene(1);
}
}
Thank you guys for your help, I literately just made a file called "Editor" and it worked.

Serialized Properties do not change in custom editor

I created an object and editing it with a custom editor
private variables are edited via SerializedProperties
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
using UnityEditor;
using UnityEngine.Video;
[CustomEditor(typeof(StreamVideo))]
public class StreamVideoEditor : Editor
{
StreamVideo script;
private SerializedProperty _playOnAwake;
private SerializedProperty _hideObjectOnStart;
private SerializedProperty _loop;
private SerializedProperty _Object2hide;
private SerializedProperty _volume;
protected virtual void OnEnable()
{
script = (StreamVideo)target;
_playOnAwake = serializedObject.FindProperty("playOnAwake");
_hideObjectOnStart = serializedObject.FindProperty("HideObjectOnStart");
_loop = serializedObject.FindProperty("loop");
_Object2hide = serializedObject.FindProperty("ObjectToHide");
_volume = serializedObject.FindProperty("Volume");
RequiresConstantRepaint();
}
public override void OnInspectorGUI()
{
serializedObject.Update();
_playOnAwake.boolValue = EditorGUILayout.Toggle("Play on Awake", _playOnAwake.boolValue);
_hideObjectOnStart.boolValue = EditorGUILayout.Toggle("Hide Object On Start", _hideObjectOnStart.boolValue);
_loop.boolValue = EditorGUILayout.Toggle("Loop", _loop.boolValue);
if (_hideObjectOnStart.boolValue)
{
EditorGUILayout.ObjectField(_Object2hide, new GUIContent("Object to hide"));
}
...
}
}
no error and everything is shown fine BUT
I cannot change any object which is defined by a serializedObject.
I can't for instance to change any toggle;
there is almost no info about it on the web
has anyone encountered the issue?
got any solution?

Get float from class in a SerializedProperty

I am trying to start using sciptable objects as describe in this talk. Here is my code:
Here is my FloatVariable:
using UnityEngine;
[CreateAssetMenu]
public class FloatVariable : ScriptableObject
{
public float value;
}
Here is my FloatReference:
using UnityEngine;
using System;
[Serializable]
public class FloatReference
{
public bool use_constant = true;
public float constant_value;
public FloatVariable variable_value;
public float v
{
get
{
return use_constant ? constant_value : variable_value.value;
}
set
{
if (use_constant) throw new Exception("Cannot assign constant_value");
else variable_value.value = value;
}
}
}
Here is my GameplayManager where I have one FloatReference value:
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEditor;
using System;
public class GameplayManager : MonoBehaviour
{
public FloatReference pl_orb_mode;
}
Here is my GameplayManagerEditor where I try to get float from FloatVariable class:
using UnityEngine;
using UnityEditor;
using System;
[CustomEditor(typeof(GameplayManager))]
public class GameplayManagerEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
SerializedProperty pl_orb_mode = serializedObject.FindProperty("pl_orb_mode");
SerializedProperty variable = pl_orb_mode.FindPropertyRelative("variable_value");
SerializedProperty the_value = variable.FindPropertyRelative("value");
float test = the_value.floatValue;
Debug.Log(test);
}
}
When I try to get my float test = the_value.floatValue; I get an error:
NullReferenceException: Object reference not set to an instance of an object
GameplayManagerEditor.OnInspectorGUI () (at Assets/Shared/Scripts/Editor/GameplayManagerEditor.cs:18)
So I can get the FloatVariable variable class as a SerializedProperty but I can't get its value property. Why is that so and how to make it work?
Because FloatVariable is inherit from ScriptableObject, so variable_value becomes a reference not a property in SerializedObject.
You have 2 choice.
Don't use ScriptableObject:
[Serializable]
public class FloatVariable
{
public float value;
}
Or edit the reference object:
var so = new SerializedObject(((GameplayManager)target).pl_orb_mode.variable_value);
var the_value = so.FindPropertyRelative("value");
...
so.ApplyModifiedProperties();
Notice that the second way since FloatVariable is a reference object, change on it will change all other objects that refer to it.

Get reference to a function to execute from the unity inspector for OnClick of a dynamically instantiated Button

I want to know how I can get a reference to a particular function on any another script through the unity inspector for adding it to a on-click listener of a dynamically instantiated button. I tried a public UnityEvent to get reference to the functions (just like in the onclick of a static button) but I am unsure how to add it to the on-click listener(button.onClick.AddListener(functionName)) as a listener looks for a action.
Is there anything I am missing out ? Or is there any other approach to this?
Thanks.
This is the idea -
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class DynamicButton : MonoBehaviour
{
public Button MainButton;
public GameObject ButtonPrefab;
[System.Serializable]
public class ButtonInfo
{
public Sprite sprite;
public UnityEvent ButtonEvent; //take reference to a particular function
}
public ButtonInfo[] ButtonCount;
void Start()
{
PlaceButtons();
}
void PlaceButtons()
{
int NoButton = ButtonCount.Length;
for (int i = 0; i < NoButton; i++)
{
Vector3 newPos = new Vector3(i*10, i*10,0);
GameObject go = Instantiate(ButtonPrefab, newPos, Quaternion.identity);
go.GetComponent<Image>().sprite = ButtonCount2To6[i].sprite;
go.GetComponent<Button>().onClick.AddListener(); //This is where I want to add the particular function that i want to execute when the button is clicked
go.transform.parent = MainButton.transform;
go.transform.localPosition = newPos;
}
}
}
What you have to do is Invoke the event instead of adding it to the onClick event. You don't have to find out / copy the listeners of each UnityEvent but instead invoking the UnityEvent is enough. The UnityEvent than calls all its listeners you assigned e.g. in the Inspector. This can be done by a simple lambda function:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class DynamicButton : MonoBehaviour
{
public Button MainButton;
public GameObject ButtonPrefab;
[Serializable]
public class ButtonInfo
{
public Sprite sprite;
public UnityEvent ButtonEvent; //take reference to a particular function
}
public ButtonInfo[] ButtonCount;
private void Start()
{
PlaceButtons();
}
private void PlaceButtons()
{
int NoButton = ButtonCount.Length;
for (int i = 0; i < NoButton; i++)
{
Vector3 newPos = new Vector3(i*10, i*10, 0);
GameObject go = Instantiate(ButtonPrefab, newPos, Quaternion.identity);
// What is ButtonCount2To6?? It probably should rather be ButtonCount[i] ?
go.GetComponent<Image>().sprite = ButtonCount2To6[i].sprite;
// since the lambda will have no acces to i you have to get the reference to the according ButtonInfo first
var accordingButtonInfo = ButtonCount[i];
// Add the Invoke call as lambda method to the buttons
go.GetComponent<Button>().onClick.AddListener(() => {
accordingButtonInfo .ButtonEvent.Invoke();
});
go.transform.parent = MainButton.transform;
go.transform.localPosition = newPos;
}
}
}
see also this post