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.
Related
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 :)
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.
I have setup a Scriptableobject in database called "Card" and am attempting to make a searchable list of those items in the scriptableobject. I attached CardDatabase script to an empty gameobject called _CardDatabase. I am not sure if I am attaching it incorrectly or what I have done wrong here.
I am still getting the following error:
NullReferenceException: Object reference not set to an instance of an object
CardDatabase.GetCardByID (System.String abbr) (at Assets/Scripts/CardDatabase.cs:33)
// CardDatabase.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class CardDatabase : MonoBehaviour
{
public CardList cards;
private static CardDatabase instance;
private void Awake()
{
if (instance = null)
{
instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
public static Card GetCardByID(string abbr)
{
return instance.cards.AllCards.FirstOrDefault(i=> i.abbr == abbr);
}
}
// CardList.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "New Cards Database",menuName = "Cards Database")]
public class CardList : ScriptableObject
{
public List<Card> AllCards;
}
This is my Example class and MonoBehaviour script:
using UnityEngine;
using System;
[Serializable]
public class TestSerializableClass
{
public int a;
public string b;
}
public class TestScript : MonoBehaviour
{
public TestSerializableClass field1;
[HideInInspector] public TestSerializableClass field2;
}
and this is the editor script for the MonoBehaviour Script
using UnityEditor;
[CustomEditor(typeof(TestScript))]
public class TestScriptEditor : Editor
{
SerializedProperty testClass;
public override void OnInspectorGUI()
{
DrawDefaultInspector();
SerializedProperty testField = serializedObject.FindProperty("field2");
EditorGUILayout.PropertyField(testField, true);
}
}
This is how my inspector for TestScript looks.
Why doesn't it draw the "field2" varialble like the first one?
Can I do it with Editor script and property field? How?
(the includeChildre flag is true)
Remove the HideInInspector attribute from field2
What in the name of god am I doing wrong here? Every time I run the game I get this: "NullReferenceException: Object reference not set to an instance of an object". I know what that means I just don't get why it is saying that?
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
public class Inventory : MonoBehaviour {
public static Inventory instance;
public List<InventoryItems> INVENTORY_ITEMS = new List<InventoryItems>();
void Awake(){
instance = this;
}
void Start(){
Debug.Log(instance.INVENTORY_ITEMS); // ERROR
Debug.Log(INVENTORY_ITEMS); // ERROR
}
}
[Serializable]
public struct InventoryItems
{
public string name;
}
This is how you should write this code:
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
public class Inventory : MonoBehaviour {
public static Inventory instance;
public List<InventoryItems> INVENTORY_ITEMS;//do not initialize here
void Awake(){
instance = this;
INVENTORY_ITEMS = new List<InventoryItems>();//init here instead
}
void Start(){
Debug.Log(instance.INVENTORY_ITEMS); //no ERROR
Debug.Log(INVENTORY_ITEMS); //no ERROR
}
}
[Serializable]
public struct InventoryItems
{
public string name;
}
Added note:
The reason for this error is that the value of a public serializable member in monobehaviour is being read from the editor (inspector) overwriting any value being assigned to it prior to Awake.
I suggest either change the list accessor to internal, or make it a property, or keep it public but let inspector handle the initialization and adding the initial elements.
Added another note:
According to Programmer and Uri Popov, your original code most certainly will work on unity 5.4 and later.