Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by farmvillehd · Jun 16, 2020 at 01:44 AM · referenceinstanceinstancesstatic variable

Reference a static variable from an instance

Hello, fairly new to Unity and C#, I have a Character script I'm using to make instances of characters, and a PlayerStats script storing static variables, trying to give each instance it's own variable they can modify in PlayerStats by either referencing it in Unity or possibly by using an ID number (e.g. char1 - var1, char2 - var2, etc.), thought about just storing this variable in the Character script, but trying to use these variables as a currency might become troublesome if too many characters are added, anyway of doing something like this? Or am I going about this completely wrong? Couldn't really find anything like this scenario online, so help would be much appreciated.

Thanks for reading :)

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by farmvillehd · Jun 23, 2020 at 11:16 AM

Spent sometime searching how to use lists and made a super simple system that does what I want that I'm very happy with

         public List<float> matValueList = new List<float>();
     
         public float Material0;
         public float Material1;
         public float Material2;
     
         void Start()
         {
             matValueList.Add(Material0);
             matValueList.Add(Material1);
             matValueList.Add(Material2);

Make a list in your playerStats

 public PlayerStats playerStats;
 public int Id = 0;
 
 public void Increase();
 {
    playerStats.matValueList[Id] += 1
 }

Then all you gotta do is get some kind of reference to it, and give an iD, now the Character with ID 0 increases Material0. This is probably pretty trivial to more experienced programmers. But this newbie is proud to of figured it out, hopefully this helps anyone with the same issue I was in :)

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Jun 23, 2020 at 12:32 PM 1
Share

While this does probably what you want, I don't quite see the reason for your $$anonymous$$aterial0, $$anonymous$$aterial1 and $$anonymous$$aterial2 fields. The list itself is also serialized in the inspetor and the user (you) can change / add / remove values there. This is also quite dangerous in your case. Since you create the list in the field initializer which is then overwritten by the deserializer with the list shown in the inspector, you could have already values in that list when Start is called. In that case your $$anonymous$$aterial0 / 1 / 2 is just appended at the end of that list.


Also keep in $$anonymous$$d that float variables can not be "referenced". So all your "$$anonymous$$aterial" fields do is providing initial values. When you do

 playerStats.matValueList[0] += 1;

You do change the first element in the List, but you do NOT change the value of $$anonymous$$aterial0. That field has no relation to the values in the list.


I would recommend that you either:

  • Get rid of those "$$anonymous$$aterial" fields and just setup your initial values in the inspector directly by setting the size of the List to 3 and then input your 3 initial values there.

  • If you want to keep those "$$anonymous$$aterial" initializer variables, you should put a [System.NonSerialized] attribute before your List so it does not get serialized in the inspector. It is still public, but not serialized anymore so it won't show up in the inspector.


If this is about creating a list of different materials, I would strongly recommend to create a seperate "$$anonymous$$aterial" class (NOTE: do not call it $$anonymous$$aterial ^^ find a more suitable name to avoid issues with Unity's $$anonymous$$aterial class) which contains all the information needed, create an instance of that class for every material you want have and put those in a list. This is commonly done with ScriptableObject assets. So you can simply create as many of your materials in Unity as standalone assets. You can give them a name, maybe an initial value, a $$anonymous$$ and max value and whatever you might need.

avatar image farmvillehd Bunny83 · Jun 23, 2020 at 11:58 PM 0
Share

I actually am using ScriptableObjects to store names, sprites, and max values (and they're a life saver). the reason I'd prefer the $$anonymous$$aterial list over a class for them is just for easier access, and that seems to me currently the best thing for what I'm going for, from what I understand, if I wanted to use a value from a "$$anonymous$$aterial Class" I'd have to get the component for that particular class, and that might get complicated after a bit for someone of my skill level lol. I appreciate the feedback a lot on my previous code and currently applying changes to it. Thanks for the help :)

avatar image
2

Answer by ShadyProductions · Jun 16, 2020 at 05:17 AM

If the PlayerStats script is also on the same object as the character script you can do:

 public class Character : MonoBehaviour
 {
     public PlayerStats PlayerStats { get; private set; }
 
     private void Start
     {
         PlayerStats = GetComponent<PlayerStats>();
     }
 }
 
 public class PlayerStats : MonoBehaviour
 {
     public int Health;
     public int Shield;
 }
Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image farmvillehd · Jun 16, 2020 at 06:22 AM 0
Share

This is close to what I need, anyway to reference a particular variable when getting a component?Something like "If character ID = 0, Var = Health, or If character ID = 1, Var = Shield"? The end result is doing something like "Var++" and having Character 1 increase health, and Character 2 increase shield

Will update if I find out on my own, thanks a bunch for the info :)

EDIT: I know I could use a switch to do something like this, but I'm pretty sure each character would have to run it every frame in order for it to work, and that'd get pretty messy with each new character being added, I'd much rather have a direct reference if it's possible

avatar image ShadyProductions farmvillehd · Jun 16, 2020 at 06:29 AM 1
Share

Sure imagine:

 public class Character : $$anonymous$$onoBehaviour 
 {
     public int Id;
     public PlayerStats PlayerStats { get; private set; }
  
     private void Start
     {
         PlayerStats = GetComponent<PlayerStats>();
     }
 }

Define this method somewhere:

 private Character[] _characters;
 public Character GetCharacterById(int id)
 {
     if (_characters == null) 
     {
         // Find all objects of type Character in scene
         _characters = FindObjectsOfType<Character>();
     }
     return _characters.FirstOrDefault(a => a.Id == id);
 }

Now you can do:

 var character = GetCharacterById(id);
 character.PlayerStats.Health++;
avatar image farmvillehd ShadyProductions · Jun 16, 2020 at 07:45 PM 0
Share

Been having issues getting this to work, trying working it out myself for a couple hours but couldn't find it out.

Set up a test to try and work it out

Character:

 using UnityEngine;
 
 public class Character : $$anonymous$$onoBehaviour
 {
     public int Id;
     public PlayerStats PlayerStats { get; private set; }
 
     private void Start()
     {
         PlayerStats = GetComponent<PlayerStats>();
     }
 }

PlayerStats:

 using UnityEngine;
 
 public class PlayerStats : $$anonymous$$onoBehaviour
 {
     public int material1;
     public int material2;
 }

Game$$anonymous$$aster:

 using UnityEngine;
 using System.Linq;
 
 public class $$anonymous$$aster : $$anonymous$$onoBehaviour
 {
     private Character[] _characters;
     public Character GetCharacterById(int id)
     {
         if (_characters == null)
         {
             // Find all Characters in scene
             _characters = FindObjectsOfType<Character>();
         }
         return _characters.FirstOrDefault(a => a.Id == id);
     }
 
     //Test if Char is found
     public void IncreaseVar()
     {
         var character = GetCharacterById(0);
         character.PlayerStats.material1++;
     }
 }

Running the code "character.PlayerStats.material1++;" is giving this error "NullReferenceException: Object reference not set to an instance of an object $$anonymous$$aster.IncreaseVar () (at Assets/$$anonymous$$aster.cs:23)"

It seems like it can't find the instance to reference, but I'm not really sure what to do about this, did I misplace something? Let me know if you get the chance Thanks for helping this helpless novice lol

Show more comments
avatar image Bunny83 · Jun 16, 2020 at 08:07 AM 1
Share

I would recommend to use Awake to setup connections between components since Start is usually used to do the first interactions. When you setup all necessary connections in Awake it's guaranteed to have them initialized for other scripts inside Start.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

133 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Static member cannot be accessed 0 Answers

NullReferenceException: Object reference not set to an instance of an object ? 1 Answer

Comparing PhysicMaterials at Runtime 3 Answers

object not set to instance? 1 Answer

It looks like another Unity instance is running with this project open. Multiple Unity instances cannot open the same project. 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges