0
\$\begingroup\$

I have variables in my script but I can access these variables from other script but I want see them in other script without define again. I know about [System.Serializable] but I don't know how can I use for MonoBehaviour classes

like this:

enter image description here

using UnityEngine;
using System.Collections;

public class variables : MonoBehaviour {
    public static variables instance;
    public int health;
    public int bullets;


    void Awake(){
        instance = this;
    }
}

I want show variables class in below class's inspector

using UnityEngine;
using System.Collections;

public class access : MonoBehaviour {
// I have to define again variable for showing in inspector
public int bulletsAccess;
public int healthAccess;

void Update () {
    variables.instance.bullets = healthAccess;
    variables.instance.health = bulletsAccess;
  }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ I'm not quite sure what you're trying to achieve here. Do you want the properties in variables to always be the same value (i.e. if I change the value for bullets then all access values will change) or do you want to be able to edit them in the inspector for each instance of access? Or, do you want variables to be assigned to a game object only once, and then the changes of that to affect access? \$\endgroup\$ – hobnob Aug 25 '16 at 8:18
  • \$\begingroup\$ if I change the value for variables then all access values will change and if I change the value for access then all variables values will change \$\endgroup\$ – Seyed Morteza Kamali Aug 25 '16 at 8:34
3
\$\begingroup\$

Do it like this :

using UnityEngine;
using System.Collections;
[System.Serializable]
public class Variables {

    public int health;
    public int bullets;

}

Then in your second class you simple define a field of type Variables

using UnityEngine;
using System.Collections;
    public class Access : MonoBehaviour 
    {
         public Variables my_vars;// Now you will see a my_vars property in the inspector window of the Access component
    }

Friendly tip always name your classes with a capital letter.

\$\endgroup\$
1
\$\begingroup\$

As @Uri-Popov says, you can use the System.Serialize attibute to create an object that appears in the Inpector whenever it's included in your MonoBehaviour.

Depending on what you're actually storing in variables (i.e. if that class represents a player, actor, or gun) you may want to consider just extending the access object.

For example, if you have a Player class, but players and enemies share common properties and methods, you can extend them so that a common Actor class holds that informateion.

For example, your Actor may look like this:

using UnityEngine;

public class Actor : MonoBehaviour {
    public int Health;
    public int Bullets;
}

And then a player would look like this:

public class Player : Actor {
    void Update() {
        // Do player specific update tasks
    }
}

When you add the Player script to a GameObject the Health and Bullets properties will both be pulled through as if they belong to that class.

I realise your question was specific to Serialisation, but this may be a better solution to your problem, depending on what your ultimate aim is

\$\endgroup\$
0
\$\begingroup\$

The answer to the question is: ScriptableObject. That's what they're for.

Put your variables in a ScriptableObject and Unity will handle the serialisation and give you a custom editor and other nice features. Recommended.

\$\endgroup\$
-1
\$\begingroup\$

I'm pretty sure what you're looking for are static variables.

Do this: public static bool isDead;

For example.

Then to call it in another script you simply use your script's name and the variable.

Apologies for any errors, I'm on mobile.

\$\endgroup\$
  • \$\begingroup\$ In the question itself, the asker points out that they are already using statics, as an alternative to what they want. \$\endgroup\$ – Gnemlock Aug 25 '16 at 14:54
  • \$\begingroup\$ Not sure what they exactly want then, as statics sound like exactly what they want to accomplish, and it wouldn't require any hacky work arounds, as it looks like that's what it's shaping up to be. Not sure though. \$\endgroup\$ – GMR516 Aug 25 '16 at 18:22
  • \$\begingroup\$ And sorry if I missed this as well, but I re-read the question and I don't see anything about static variables in there. \$\endgroup\$ – GMR516 Aug 25 '16 at 18:24
  • \$\begingroup\$ They want to show a set of values from classA in classB. They are currently using a static self reference to link the two scripts in their code. \$\endgroup\$ – Gnemlock Aug 25 '16 at 23:21
-1
\$\begingroup\$

TL;DR: Uri has a good answer if you want to share functions, as well. If its just variables, follow the answer but with struct replacing class. If variables are shared because the other classes are similar in nature, it might be a good idea to inherit, more advantages listed below. If your still having trouble, you might be having problems with your keyword and/or attribute usage.

Above all else, you describe changing the values so that all instances change, including changes made directly to the "variables" script. You will most likely want to set each variable in "variables" to static to set up this behavior.

struct is better if you only store variables to share.

If you only intend to share variables, you may want to consider using struct instead of a class. What is the difference, you may ask? Well, a struct is designed to hold a set of variables. A class is designed to also store functions. Generally, if you do not intend to hold any functions in your "variables" script, you would use a struct instead of a class. They pretty much work the same way, for the purpose of implementation.

[System.Serializable]
public struct Variables
{
    public int health;
    public int bullets;
}

public class MainScript
{
    public Variables variables;
}

Inheritance is better if you want to share common functionality

Hobnob addresses this in their answer, but I felt I should provide greater insight to help you determine if this is the right solution. Either way, inheritance is a powerful tool at your disposal. Sooner or later, it will make your life a lot easier, so take five minutes and watch the Unity tutorial video on it, if you are unfamiliar with the concept.

Basically, any class that inherits from another automatically passes in the variables and functions of the base class. For reference sake, the original class is referred to as the "parent", with the 'inheriting' class referred to as the "child".

public class Variables
{
    public int health;
    public int bullets;
}

public class MainScript : Variables
{
    // I can already see health and bullets;
    // They will also show under me in the Inspector.
}

There are other advantages you want to consider, that might provide greater functionality for you. Some of these advantages include:

  • Children classes also inherit the parent functions, but can override them with their own logic. You can even call back to the parent logic with base., if you need to 'do the same thing, but do something else before or after'.
  • Children can all be classed as typeof(parent), which is especially useful if you are looking for a particular 'base class' of objects. For example, if you wanted to look for all enemy scripts, but many were "specialized" variants. In the above example, you could successfully store MainScript in a reference for Variables. This does limit your functionality1, but is still very useful.
  • It allows you to put all common function in one place, allowing you to reuse your code.

Keywords and Attributes will provide greater functionality

The above suggestions may not get you where you want on their own. The addition of several keywords and attributes may give you greater functionality, and can mostly be used along with the above examples.

  • static: You already know this one from your self-reference, but it sounds like this will definetly be using it. static means there will only ever be one instance. For example, if instance A of your script changes a static variable, it will also change in instance B of your script.
  • const: Likely unwanted, but this sets the variable as "finalised", so that you can not change it. Good if you just want to reference a hard-coded value. Bad if you want to modify it from another script.
  • protected: An access modifier, much like private and public. The difference is that, while protected variables will be as inaccessible as private fields to outside references, they will still be accessible to classes that inherit from that class. Likewise, private variables will not be accessible through inheritance.
  • virtual: A function keyword that effectively marks that function as "overload-able". If you wish to overwrite a function from a parent class, the function needs to be marked as virtual in the parent class.
  • overload: A function keyword that effectively marks that function as an "overwrite" of a parent class of the same name. You can only overload virtual functions, and you can still call back to the parent function with base.<function name>.
  • [System.Serializable]: An attribute that tells Unity to serialise the below class or struct, to display it in the Inspector. As mentioned in the above answers, you need to use this if you include that class as a reference in another class, where you want its values to be drawn to the inspector.
  • [Serialize]: An attribute that tells Unity to serialise the below variable, to display in the Inspector. You almost never need to use this, but this attribute will allow you to display private variables in the Inspector.

1 I have had experience before where you would store MainScript as a type of Variables, but only gain access to the functionality listed under Variables. I have previously assumed this to be a constraint of inheritance, but since have found bug reports where Unity will break inheritance with use of various serialisation-based attributes that I would commonly use in these situations. As such, I can neither confirm nor deny what limits are real, what were caused by bugs and what were caused by bugs but have since been fixed. Any comments to clarify would be very much appreciated.

\$\endgroup\$
-2
\$\begingroup\$

Maybe using [HideInInspector] behind each variable in your second class will be a good choice.

But I suggest to make something cleaner, like custom inspector!

EDIT: I was outside, and I posted this using my mobile phone.

You should use inheritance, as I read your question better, as other said, the best choice is use this.

Also, I add, if you want to make private your class properties, you can still use [SerializeField] to make them available from Inspector.

Maybe, you can make it a little bit more messy:

using UnityEngine;
using System.Collections;

public class Variables : MonoBehaviour 
{
    [SerializeField] private int health;
    [SerializeField] private int bullets;
}

You can import the following script only, and save a little bit more time:

using UnityEngine; using System.Collections;

public class Access : Variables 
{
   void Update () 
   {
      base.Update(); //You can call Variable's Update method from child. 
      //Do your work here!
   }
}

Good luck.

\$\endgroup\$
  • \$\begingroup\$ The question asks how to show variables. As asker describes, they have the second set as a current alternative to being able to show the first set. \$\endgroup\$ – Gnemlock Aug 25 '16 at 14:49
  • \$\begingroup\$ I wish I could downvote this more for simply trying to include the points I added with my answer, and for doing so in such a blatantly incorrect way. Two major points: You say "you can make it messy". I think you might be misinterpretting what that means, as you would ideally want to not be making it messy. You want it to be tidy. Also, private variables are not accessible from the child class. Even with [SerializeField], while they may (I'm honestly not sure) show in the inspector, *you will have no reference to these variables in the actuall code, rendering them useless. \$\endgroup\$ – Gnemlock Aug 25 '16 at 23:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.