Unity: Publics don't show up in default references/inspector..? - c#

I've been trying for hours now, but I have no idea what is wrong.
Normally, when you define a public object/var in Unity C#, it shows up in the inspector or default references where you can drag something to it.
Here's my test code:
using UnityEngine;
using System;
using System.Collections;
[Serializable]
public class modGlobals : MonoBehaviour {
public static GUIStyle defaultMask;
public GUIStyle trollo;
}
Aaaaaand...
I tried several options, wrote the thing in MonoDev as also in Visual Studio, put all my files in an namespace, w and w/o Serializable attribe but.. What could be wrong?
Thanks for help!

Yes you do need to attach it to a gameObject in the scene in order to show the public members in the property inspector, since your script inherits from MonoBehaviour.
This is what I got.
Additionally, you cannot expose static members in the property inspector - even when marked as SerializableAttribute. System.SerializableAttribute is not valid on this declaration type. It is valid on `class, struct, enum, delegate' declarations only.
In relation to your comment about requiring a globally accessible script with objects, you have a couple options, such as
Singleton script attached to gameObject (example), set with DontDestroyOnLoad() so it persists between scene changes.
Static class

Related

Unity Custom Editor NullReferenceException When SerializedProperty Has Any Accessor

I am trying to make a custom editor in Unity for a ScriptableObject class which has private fields like such:
But has soon as one of my fields has an accessor (I also tried properties with get;), I get the following error when I try to see my ScriptableObject in the inspector.
I made some tests and it works perfectly without accessors. For instance, I can see the field "test".
Here is the code for my custom editor:
Any idea? I would not believe a custom editor for a class that has accessors would not be supported.
Thank you!
This has nothing to do with an "accessor". And note that properties are not serialized by Unity at all.
The mistake is pretty simple: Your field's name is not ingredients but rather _ingredients!
Therefore FindProperty("ingredients") returns null since it doesn't find any field called ingredients.
(This is assuming of course that Item is a [Serializable] type at all.)
To avoid exactly this type of issues I usually prefer to embed the editor into the type itself and use e.g.
public class YourType : MonoBehaviour /*or ScriptableObject*/
{
[SerializeField] private int _someField;
#if UNITY_EDITOR
[CustomEditor(typeof(YourType))]
private class YourTypeEditor : Editor
{
private SerializedProperty _someFieldProperty;
private void OnEnable()
{
_someFieldProperty = serializedObject.FindProperty(nameof(_someField));
}
...
}
#endif
}
so whenever you rename the fields it will be fixed in the Inspector automatically

"The script don't inherit a native class that can manage a script."

I don't know why but when I add my code in some object it gives this error, could someone help me?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Room : MonoBehaviour
{
void OnTriggerStay2D (Collider2D other){
if (other.CompareTag("Player")){
CameraController.instance.SetPosition(new Vector2(transform.position.x, transform.position.y));
}
}
}
The generic reason for this is when you have a script file that is named different the class name. Ensure that your c# script file matches the name of your class. i.e. both should be Room.
I had the same problem in Unity, when I tried to attach a script to an object.
After trying/isolating a lot of "google solutions" that didn't help in my case, like checking the name of the script and the class. (I already encountered that when I renamed a script earlier :P)
So to refocus, I first fixed an issue in another script(which had a typo), for another model in the same project.
After that the first thing I did was simply drag the script to the model again.. and it worked...
I'll add this option to my list of options when I'll encouter this “The script don't inherit a native class that can manage a script.” again...

Object Reference Not Set to an Instance - Unity2D

I have this simple code to change the sprite of an image everytime I click a button.
using UnityEngine;
using UnityEngine.UI;
public class SampleChange : MonoBehaviour {
public Sprite sampleSprite;
public Image sampleImage;
public void Start()
{
sampleImage = GetComponent<Image>();
}
public void changeColor()
{
sampleImage.gameObject.GetComponent<Image>();
sampleImage.sprite = sampleSprite;
}
}
I attached this script to an EmptyGameObject and Loaded the function on the Button that is parented on a Canvas alongside the Image. I already also placed the Image and Sprite objects in the inspector:
Inspector Settings
When I run the game and click the Button, it gives me this error:
NullReferenceException: Object reference not set to an instance of an object
SampleChange.changeColor () (at Assets/Scripts/SampleChange.cs:18)
The cs:18 is the sampleImage.sprite = sampleSprite;. I really don't know why it's not working.
OK simple,
public Image sampleImage;
that means
you will set "sampleImage" variable in the inspector, in the editor, before you hit Play
But this one ..
sampleImage = GetComponent<Image>();
means
you will set "sampleImage" variable in code when the scene is running.
You have to sort it out and do it "one way or the other".
Suggest you use the first method while U learning.
(If you do use the second method, the "Image" must actually be on the game object which is holding the script in question. If you struggle with that, I would urge you to ask a separate question, or just study up on the basics using Unity tutorials.)
Cheers
It appears that you have no constuctor defined for your class and that you are just trying to call the changeColor() method as if it were a static function of the class. You need to construct objects of your class and then call the methods you defined on those objects, not on the class itself.

What is MonoBehaviour in Unity 3D?

using UnityEngine;
using System.Collections;
public class VariablesAndFunctions : MonoBehaviour
{
int myInt = 5;
}
The full code is here Unity Official Tutorials
What is the purpose of MonoBehaviour
MonoBehaviour is the base class from which every Unity script derives. It offers some life cycle functions that are easier for you to develop your app and game.
A picture is worthy of thousands of words.
Source of the image: https://docs.unity3d.com/uploads/Main/monobehaviour_flowchart.svg
While the following statement is correct,
"MonoBehaviour is the base class from which every Unity script derives" -
I honestly feel it can be misleading to beginners. The phrase - "every Unity script" - being the culprit.
It gives a beginner the notion that all scripts created in unity must extend Monobehaviour. Which is not the case. You can create scripts that house classes that extend the c# base object class. In doing so, your script is then categorised as not a Unity script but nothing stops it from interacting with other Unity scripts and vice versa.
MonoBehaviour is another class that VariablesAndFunctions is inheriting from. This allows the inheritor to use the methods and variables of the other class providing they have the correct access level modifier set.
In the below example Class1 inherits from Base and so can use the protected method Method1
public class Base
{
protected void Method1 { /*...*/ }
}
public class Class1 : Base
{
public void Method2 { Method1(); }
}
Note in this particular example it would be better for Method1 to be marked as abstract or virtual so then Class1 can override it like so:
protected override Method1()
{
//...
base.Method1(); //Call the implementation of Method1 in Base here
//...
}
In particular though MonoBehaviour is described as being:
MonoBehaviour is the base class from which every Unity script derives.
Therefore when doing scripting in unity, you use this base class to better control how things are accessed so you do not need to do it yourself.
Monobehavior is what most of your scripts inherit from,
if you go to the documentation Click here!
you will see a bunch of variables and methods you get from this Inheritance.
such as:
Public Methods
Messages
Properties
Public Methods
Static methods
The most commonly used method (its under message in the documentation but honestly its better to see it as a function) is Update , its the main game loop, the speed at which the update function is called is based on your fps. But the important thing to take away is that if you didn't inherit from monobehavior, you wouldn't have access to this game loop.
Another important function that you get from Monobehavior is Start, which is called once on a script, and it's called after awake, so if you want to set some variables up you can do it here.
The important thing to take is that if you made a simple C# class that inherits from nothing, you wouldn't have access to these methods discussed. Monobehavior gives you access to many functions that help you build your game.
There are other behaviors your scripts can inherit from like ScriptableObject and StateMachineBehaviour, which give you access to other methods, but Monobehavior is the most common behavior your scripts will inherit from.
It's also good to note that whenever you use Monobehavior, it comes with a transform, some other scripts (Scriptable objects) don't come with a transform. The transform is simply a position in your game/scene where the gameobject lies its an x,y,z coordinate with rotation and scale.

seting universal spawn prefab

we've been banging our heads with this one, in theory, having a public static object to hold the prefab which is to be spawned should have solved this, but the script gets a static variable when the static keyword is not there, but still the objects get individual variables, while when I add the static keyword, the script's variable disappears. Are we doing something wrong? This is the exact definition:
public static Object prefab;
I too am still new with Unity, but will offer some personal research / findings. I too hate to explicitly have some object with public properties exposed so you can "stick" an object prefab in a scene. If trying to build a system / game components dynamically, knowing what / when to add would be your discretion. I too liked the approach of having a STATIC available so you can just go to it at any time you needed another "thing".
I found that using "Resources" could allow you to load a prefab via code without the need of having a scene object to drag controls to, such as for a master list.
In you default "Assets" folder, Create a folder "Resources" (not sure if case-sensitive). Anyhow, I put all my other stuff in respective folders under that... materials, prefabs, sprites, textures, whatever... So now, in my "Prefab" folder, I could have a prefab for a "Hero", "Laser", "Shield", whatever.
Now, how to get these pieces into your STATIC class. You could create a special method that you call to just load them via the resources class of Unity, then, create function that will return a CLONE of the item in question. This way, you leave the original alone, and have your own to work with in your game as needed.
Something like...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using System.Collections;
namespace Assets.Scripts
{
public static class MyGameObjManager
{
private static bool alreadyLoaded;
public static GameObject myHero { get; private set; }
public static GameObject myWeapon {get; private set;}
public static void LoadObjects()
{
if (alreadyLoaded)
return;
// Load the resource which is RELATIVE to the "Resources" path...
myHero = (GameObject)Resources.Load("Prefab/Hero");
// This OTHER appears to load at a SPECIFIC Path allowing it to go to the root level ASSETS
myWeapon = (GameObject)Resources.LoadAssetAtPath("Assets/Resources/Prefab/Weapon", typeof(GameObject));
alreadyLoaded = true;
}
}
public class GameMgr2 : MonoBehaviour
{
public static GameObject GetHero()
{
MyGameObjManager.LoadObjects();
return (GameObject)Instantiate(MyGameObjManager.myHero, new Vector3(0, 0, 0), new Quaternion());
}
public static GameObject GetWeapon()
{
MyGameObjManager.LoadObjects();
return (GameObject)Instantiate(MyGameObjManager.myWeapon, new Vector3(0, 0, 0), new Quaternion());
}
}
}
So, the STATIC class CAN NOT derive from MonoBehavior which allows the "Instantiate" call to create the clone of the object and return it. So, I created a SECONDARY non-static class that IS derived from MonoBehavior and put static methods that call the static game object manager to get the prefabs I need.
AGAIN, I too am still learning, but hope this helps you some with your design considerations... As for the calling to get the hero or weapon, you could obviously parameterize it by passing in its Vector3 coordinate, or Quaternion value, but you can run with it.
STATIC vs NOT
Per your code and making it a STATIC means a single instance no matter how many of the class are put anywhere within the system. So if you have 5 prefabs on a screen and try to put each one to a different "thing", it will overwrite with whatever one was assigned last. Having the property as just "public" will allow you to have 5 prefabs on a screen and then drag/drop different "things" on each respectively and each will retain their own "thing" instance.
Sorry I can't advise more without knowing what you are trying to implement.
non-static should help within the editor by drag/drop. However, STATIC

Categories