• 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
0
Question by LeftyTwoGuns · Jun 26, 2014 at 05:43 AM · c#javascriptclasspublicprivate

Field is never assigned to, and will always have its default value

With the help of the smart people here, I have an object pooling script converted from JS to C#. There are some final warnings though preventing the important fields from showing up in the inspector.

Here is the script:

 public class EasyObjectPool : MonoBehaviour {
     private class PoolInfo{
         
         public string poolName;
         public GameObject prefab;
         public int poolSize;
         public bool canGrowPoolSize = true;
         
     }
     
     private class Pool{
         
         private List<PoolObject> list = new List<PoolObject>();
         public bool  canGrowPoolSize;
         
         public void  Add (PoolObject poolObject){
             list.Add(poolObject);
         }
         
         public int Count (){
             return list.Count;
         }
         
         
         public PoolObject ObjectAt ( int index  ){
 
             PoolObject result = null;
             if(index < list.Count) {
                 result = list[index];
             }
             
             return result;
             
         }
     }
     static public EasyObjectPool instance ;
     PoolInfo[] poolInfo;
     
     private Dictionary<string, Pool> poolDictionary  = new Dictionary<string, Pool>();
 
     
     void Start () {
         
         instance = this;
         
         CheckForDuplicatePoolNames();
         
         CreatePools();
         
     }
     
     private void CheckForDuplicatePoolNames() {
         
         for (int index = 0; index < poolInfo.Length; index++) {
             string poolName= poolInfo[index].poolName;
             if(poolName.Length == 0) {
                 Debug.LogError(string.Format("Pool {0} does not have a name!",index));
             }
             for (int internalIndex = index + 1; internalIndex < poolInfo.Length; internalIndex++) {
                 if(poolName == poolInfo[internalIndex].poolName) {
                     Debug.LogError(string.Format("Pool {0} & {1} have the same name. Assign different names.", index, internalIndex));
                 }
             }
         }
     }
     
     private void CreatePools() {
         
         foreach(PoolInfo currentPoolInfo in poolInfo){
             
             Pool pool = new Pool();
             pool.canGrowPoolSize = currentPoolInfo.canGrowPoolSize;
             
             for(int index = 0; index < currentPoolInfo.poolSize; index++) {
                 //instantiate
                 GameObject go = Instantiate(currentPoolInfo.prefab) as GameObject;
                 PoolObject poolObject = go.GetComponent<PoolObject>();
                 if(poolObject == null) {
                     Debug.LogError("Prefab must have PoolObject script attached!: " + currentPoolInfo.poolName);
                 } else {
                     //set state
                     poolObject.ReturnToPool();
                     //add to pool
                     pool.Add(poolObject);
                 }
             }
             
             Debug.Log("Adding pool for: " + currentPoolInfo.poolName);
             poolDictionary[currentPoolInfo.poolName] = pool;
             
         }
     }
     
     public PoolObject GetObjectFromPool ( string poolName  ){
         PoolObject poolObject = null;
         
         if(poolDictionary.ContainsKey(poolName)) {
             Pool pool = poolDictionary[poolName];
             
             //get the available object
             for (int index = 0; index < pool.Count(); index++) {
                 PoolObject currentObject = pool.ObjectAt(index);
                 
                 if(currentObject.AvailableForReuse()) {
                     //found an available object in pool
                     poolObject = currentObject;
                     break;
                 }
             }
             
             
             if(poolObject == null) {
                 if(pool.canGrowPoolSize) {
                     Debug.Log("Increasing pool size by 1: " + poolName);
                     
                     foreach (PoolInfo currentPoolInfo in poolInfo) {    
                         
                         if(poolName == currentPoolInfo.poolName) {
                             
                             GameObject go = Instantiate(currentPoolInfo.prefab) as GameObject;
                             poolObject = go.GetComponent<PoolObject>();
                             //set state
                             poolObject.ReturnToPool();
                             //add to pool
                             pool.Add(poolObject);
                             
                             break;
                             
                         }
                     }
                 } else {
                     Debug.LogWarning("No object available in pool. Consider setting canGrowPoolSize to true.: " + poolName);
                 }
             }
             
         } else {
             Debug.LogError("Invalid pool name specified: " + poolName);
         }
         
         return poolObject;
     }
     
 }

For my public variables, I get the warning posted in the question topic: Field is never assigned to and will always have its default value. Changing the PoolInfo class from private to public fixes those warnings but the JS script has this class as private class PoolInfo extends System.Object {. Does JS treat private and public classes differently than C#?

For line 37 I get the warning: "Field 'EasyObjectPool.poolInfo' is never assigned to, and will always have its default value 'null'" and I don't know how to fix that. Any advice?

Here is the JS version if it will help:

 #pragma strict
 import System.Collections.Generic;
 
 ///Private classes
 private class PoolInfo extends System.Object {
     public var poolName : String;
     public var prefab : GameObject;
     public var poolSize : int;
     public var canGrowPoolSize : boolean = true;
 }
 
 private class Pool extends System.Object {
     private var list : List.<PoolObject> = new List.<PoolObject>();
     public var canGrowPoolSize : boolean;
     
     public function Add(poolObject : PoolObject) {
         list.Add(poolObject);
     }
     
     public function Count() : int {
         return list.Count;
     }
     
     public function ObjectAt(index : int) : PoolObject {
         var result : PoolObject;
         if(index < list.Count) {
             result = list[index];
         }
         
         return result;
     }
 }
 //end of private classes
 
 /// Object pooling implementation
 static var instance : EasyObjectPool;
 var poolInfo : PoolInfo[];
 
 //mapping of pool name vs list
 private var poolDictionary : Dictionary.<String, Pool> = new Dictionary.<String, Pool>();
 
 function Start () {
     //set instance
     instance = this;
     //check for duplicate names
     CheckForDuplicatePoolNames();
     //create pools
     CreatePools();
 }
 
 private function CheckForDuplicatePoolNames() {
     for (var index : int = 0; index < poolInfo.Length; index++) {
         var poolName = poolInfo[index].poolName;
         if(poolName.Length == 0) {
             Debug.LogError(String.Format("Pool {0} does not have a name!",index));
         }
         for (var internalIndex : int = index + 1; internalIndex < poolInfo.Length; internalIndex++) {
             if(poolName == poolInfo[internalIndex].poolName) {
                 Debug.LogError(String.Format("Pool {0} & {1} have the same name. Assign different names.", index, internalIndex));
             }
         }
     }
 }
 
 private function CreatePools() {
     for (var currentPoolInfo in poolInfo) {
         
         var pool : Pool = new Pool();
         pool.canGrowPoolSize = currentPoolInfo.canGrowPoolSize;
         
         for(var index : int = 0; index < currentPoolInfo.poolSize; index++) {
             //instantiate
             var go : GameObject = Instantiate(currentPoolInfo.prefab);
             var poolObject : PoolObject = go.GetComponent(PoolObject);
             if(poolObject == null) {
                 Debug.LogError("Prefab must have PoolObject script attached!: " + currentPoolInfo.poolName);
             } else {
                 //set state
                 poolObject.ReturnToPool();
                 //add to pool
                 pool.Add(poolObject);
             }
         }
         
         Debug.Log("Adding pool for: " + currentPoolInfo.poolName);
         //add to mapping dict
         poolDictionary[currentPoolInfo.poolName] = pool;
     }
 }
 
 
 /* Returns an available object from the pool 
 OR 
 null in case the pool does not have any object available & can grow size is false.
 NOTE: The caller must activate this object by calling the Activate() method before 
 attempting to get another object from same pool.
 */
 function GetObjectFromPool(poolName : String) : PoolObject {
     var poolObject : PoolObject;
     
     if(poolDictionary.ContainsKey(poolName)) {
         var pool : Pool = poolDictionary[poolName];
         
         //get the available object
         for (var index : int = 0; index < pool.Count(); index++) {
             var currentObject : PoolObject = pool.ObjectAt(index);
             
             if(currentObject.IsAvailableForReuse()) {
                 //found an available object in pool
                 poolObject = currentObject;
                 break;
             }
         }
         
         //scenario when no available object is found in pool
         if(poolObject == null) {
             if(pool.canGrowPoolSize) {
                 Debug.Log("Increasing pool size by 1: " + poolName);
                 
                 //find the prefab for this poolname
                 for (var currentPoolInfo in poolInfo) {    
                     if(poolName == currentPoolInfo.poolName) {
                         var go : GameObject = Instantiate(currentPoolInfo.prefab);
                         poolObject = go.GetComponent(PoolObject);
                         //set state
                         poolObject.ReturnToPool();
                         //add to pool
                         pool.Add(poolObject);
                         
                         break;
                     }
                 }
             } else {
                 Debug.LogWarning("No object available in pool. Consider setting canGrowPoolSize to true.: " + poolName);
             }
         }
         
     } else {
         Debug.LogError("Invalid pool name specified: " + poolName);
     }
     
     return poolObject;
 }
Comment
Add comment · Show 4
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 rohitanshu · Jun 26, 2014 at 06:02 AM 0
Share

Note that if you're having some errors, the inspector won't update. If that's the case, fix them first and then assign the poolInfo variable in the inspector.

avatar image NoseKills · Jun 26, 2014 at 08:52 AM 1
Share

So are you assigning a value for EasyObjectPool.poolInfo anywhere ? That's what the warning is telling you to check.

You can get rid of the warning by simply changing PoolInfo[] poolInfo; to PoolInfo[] poolInfo = null;, but i doubt that's what's causing the variables not to show in the inspector.

It's just a warning so it's not anything you did "wrong". If you'r code is still work in progress it's completely normal to get warnings. Warnings don't prevent you from compiling or working normally with your code in Unity/$$anonymous$$onodevelop.

There at least was a bug in earlier versions of Unity where certain problems in your code could cause all warnings to turn into errors, which would cause your problem. In this case though the warnings should show as errors in the console (red circle ins$$anonymous$$d of yellow triangle)

avatar image gjf · Jun 26, 2014 at 11:19 AM 0
Share

maybe post the original js code - there's no definition for PoolObject

it'll help people here (and StackOverflow where you've also posted) to help you

avatar image LeftyTwoGuns · Jun 26, 2014 at 05:43 PM 0
Share

I updated my question with the JS version. PoolObject is another script but I didn't think it was related to the issue of my variables not showing up in the inspector. Here is the PoolObject script in C#:

 public class PoolObject : $$anonymous$$onoBehaviour {
 
     [HideInInspector]
     public bool availableForReuse = true;
 
 
     void Activate () {
 
         availableForReuse = false;
         gameObject.SetActive(true);
     
     }
     
 
     public void ReturnToPool () {
 
         gameObject.SetActive(false);
         availableForReuse = true;
 
     
     }
 
     public bool AvailableForReuse () {
         //true when isAvailableForReuse & inactive in hierarchy
 
         return availableForReuse && (gameObject.activeInHierarchy == false);
 
 
 
     }
 }


Here is the JS version of it:

 #pragma strict

     @HideInInspector var isAvailableForReuse : boolean = true;
 
 function Activate() {
     isAvailableForReuse = false;
     gameObject.SetActive(true);
 }
 function ReturnToPool() {
     gameObject.SetActive(false);
     isAvailableForReuse = true;
 }
 
 function IsAvailableForReuse() : boolean {
     //true when isAvailableForReuse & inactive in hierarchy
     return isAvailableForReuse && (gameObject.activeInHierarchy == false);
 }


3 Replies

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

Answer by AyAMrau · Jun 26, 2014 at 11:44 AM

just assign a default value (null in this case) to get rid of the warning. However this is just a warning and shouldn't break anything.

Depending on what you are trying to show in the inspector you may need to add [System.Serializable] over the class definitions for your classes that don't inherit from any of the Unity stuff.

 [System.Serializable]
 private class PoolInfo
 {
 ...

Or use [SerializeField] over private variables that you want to see in editor.

Or the combination of both depending on the case.

Comment
Add comment · Show 4 · 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 LeftyTwoGuns · Jun 26, 2014 at 05:39 PM 0
Share

This might be part of the problem. The JS had private class PoolInfo extends System.Object which I now know is that language's way of doing System.Serializable. So I added [System.Serializable] above both the PoolInfo and Pool classes, as well as [SerializeField] over my variables, but they still don't show in the inspector. I posted the JS version in my question if this will help

avatar image AyAMrau · Jun 26, 2014 at 06:27 PM 1
Share

I copied your C# code and added System.Serializable over PoolInfo class ans SerializeField over PoolInfo[] poolInfo variable. This is what I get (you need to add elements to the array before being able to look into them): alt text

You can't show the EasyObjectPool instance because it's static or the poolDictionary dictionary because it's also not directly supported.

Or is there something else you wanted to show?

poolinfo.png (10.3 kB)
avatar image LeftyTwoGuns · Jun 26, 2014 at 07:33 PM 0
Share

That was it, thank you! Had to add SerializeField over PoolInfo[]

It all shows up now whether it works, dunno yet. I'll just start a new question if I have any more problems. Thanks again! And thank you to everyone else, too. I've learned a lot about UnityScript the past week lol

avatar image SOS PC · Aug 25, 2015 at 09:39 AM 0
Share

This method of adding [SerializeField] also worked for me whilst starting out with Unity's Roll-a-Ball Tutorial. need to add this into my code in order to be able to change the speed of the ball from the inspector rather than having to edit the script :) script attached below to show where i added this in for all the other googlers looking for a solution to this problem :D

 using UnityEngine;
 using System.Collections;
 
 public class PlayerController : $$anonymous$$onoBehaviour 
 {
     [SerializeField] //This is the line needed to fix the problem :D (For Private Variables)
     private float speed;  //To show this Variable in the inspector
 
     private Rigidbody rb;
 
     void Start ()
     {
         rb = GetComponent<Rigidbody> ();
     }
 
     void FixedUpdate ()
     {
         float moveHorizontal = Input.GetAxis ("Horizontal");
         float moveVertical = Input.GetAxis ("Vertical");
 
         Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
 
         rb.AddForce (movement * speed);
     }
 }



avatar image
1

Answer by NoseKills · Jun 26, 2014 at 09:03 AM

You can get rid of the warning by simply changing PoolInfo[] poolInfo; to PoolInfo[] poolInfo = null;, but i doubt that's what's causing the variables not to show in the inspector.

Comment
Add comment · 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
1

Answer by Bunny83 · Jun 26, 2014 at 06:46 PM

Your problem is that you declared poolInfo as a private variable and you didn't initialize it. Since it's private it can only be initialized by your script which you did not. In the UnityScript version it's declared as public. In UnityScript all variables are public by default in C# all variables are private by default.

As far as i know in UnityScript you don't need the Serializable attribute on custom classes to have them serialized. However in C# you have to mark them as serializable.

It's strange that UnityScript does allow this. To use a local private class in a public variable usually shouldn't work.

So my advise to fix your problems:

  • make your PoolInfo class public.

  • put the [System.Serializable] attribute on the PoolInfo class.

  • make poolInfo public as well.

Now you should see the poolInfo array in the inspector.

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 AyAMrau · Jun 26, 2014 at 06:53 PM 0
Share

There is no need to make the variable public, using [SerializeField] will expose it in the editor without breaking encapsulation.

avatar image Bunny83 · Jun 26, 2014 at 07:20 PM 0
Share

@AyA$$anonymous$$rau: Of course you can use SerializeField but it wouldn't make any sense.

  1. The variable was public in the UnityScript version

  2. The variable is an important interface which need to by accessed / set from outside, so making it private doesn't make any sense.

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

25 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

Related Questions

Field is never assigned to and will always have its default value. 0 Answers

javascript call a method from c sharp and vise versa 1 Answer

Multiple Cars not working 1 Answer

How do I access a static function in JS? 1 Answer

Creation of RPG Class Stat Presets? 1 Answer


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