Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Serialized variables not being recognized elsewhere in the class

Discussion in 'Scripting' started by Sajid, Mar 6, 2015.

  1. Sajid

    Sajid

    Joined:
    Mar 12, 2011
    Posts:
    199
    Hey all,

    I was reading through a list of good practices when working with Unity3D, and one of them was to use serialized methods to store variables so that they stay organized in the inspector. I tried doing this, but the variables inside the serialized method became unrecognized within the rest of the class. Here is the code in question:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System;
    4. using System.Collections;
    5. using System.Collections.Generic;
    6.  
    7. public class turretHandlerRevised : MonoBehaviour {
    8.     public List<GameObject> enemiesInScene = new List<GameObject>();
    9.  
    10.     public GameObject projectile;
    11.     public GameObject spawnOrigin;
    12.  
    13.     private GameObject[] taggedEnemies;
    14.     private GameObject target;
    15.     private GameObject currentBulletClone;
    16.  
    17.     [Serializable]
    18.     public class turretProperties
    19.     {
    20.         public float defaultFireRate;
    21.         public float fireSpeed;
    22.         public float range;
    23.         private float fireRate;
    24.     }
    25.  
    26.     void Awake()
    27.     {
    28.         target = findClosest();
    29.         fireSpeed = 5;
    30.         populateEnemyList();
    31.         fireRate = defaultFireRate;
    32.        
    33.     }
    34.  
    35.     void Update()
    36.     {
    37.         removeDeadEnemies();
    38.        
    39.         target = findClosest();
    40.    
    41.         if (fireRate > 0)
    42.         {
    43.             fireRate -= Time.deltaTime;
    44.         }
    45.         else
    46.         {
    47.             fireRate = 0;
    48.         }
    49.  
    50.         if(fireRate <= 0)
    51.         {
    52.             if(target != null)
    53.             {
    54.                 fire(projectile, fireRate);
    55.                 fireRate = defaultFireRate;
    56.             }
    57.  
    58.         }
    59.         if(target != null)
    60.         {
    61.             spawnOrigin.transform.LookAt(target.transform);
    62.         }
    63.      
    64.     }
    65.  
    66.     public void populateEnemyList()
    67.     {
    68.         taggedEnemies = GameObject.FindGameObjectsWithTag("Enemy");
    69.  
    70.         for (int i = 0; i < taggedEnemies.Length; i++)
    71.         {
    72.             enemiesInScene.Add(taggedEnemies[i]);
    73.         }
    74.     }
    75.  
    76.     public void refreshEnemyList(GameObject inEnemy)
    77.     {
    78.         if(enemiesInScene.Contains(inEnemy) == false)
    79.         {
    80.             enemiesInScene.Add(inEnemy);
    81.         }
    82.  
    83.     }
    84.  
    85.    public void removeDeadEnemies()
    86.    {
    87.        for(int i = 0; i <= enemiesInScene.Count-1; i++)
    88.        {
    89.            if(enemiesInScene[i] == null)
    90.            {
    91.                enemiesInScene.Remove(enemiesInScene[i]);
    92.            }
    93.        }
    94.    }
    95.  
    96.     public GameObject findClosest()
    97.     {
    98.         float tempDistance = 0;
    99.         for(int i = enemiesInScene.Count-1; i >= 0; i--)
    100.         {
    101.             if(enemiesInScene[i] != null)
    102.             {
    103.                 if(Vector3.Distance(transform.position,
    104.                                     enemiesInScene[i].transform.position) <
    105.                    Vector3.Distance(transform.position,
    106.                                     enemiesInScene[i - 1].transform.position))
    107.                 {
    108.                     tempDistance = Vector3.Distance(transform.position,
    109.                                                     enemiesInScene[i].transform.position);
    110.                 }
    111.             }
    112.             i--;
    113.         }
    114.  
    115.         for(int j = 0; j <= enemiesInScene.Count-1; j++)
    116.         {
    117.             if (Vector3.Distance(transform.position,
    118.                                  enemiesInScene[j].transform.position) <= range)
    119.             {
    120.                  if(Vector3.Distance(transform.position, enemiesInScene[j].transform.position) == tempDistance)
    121.                 {
    122.                     return enemiesInScene[j];
    123.                 }
    124.             }
    125.                
    126.          
    127.         }
    128.  
    129.         return null;
    130.     }
    131.  
    132.     public void fire(GameObject projectile, float fireRate)
    133.     {
    134.         GameObject projectileClone = Instantiate(projectile, spawnOrigin.transform.position, spawnOrigin.transform.rotation) as GameObject;
    135.         projectileClone.SendMessage("setTarget", target.transform.position);
    136.         projectileClone.SendMessage("setSpeed", fireSpeed);
    137.         fireRate = defaultFireRate;
    138.      
    139.     }  
    140. }

    Brand new to serialized methods, and I'm wondering what I'm doing wrong.

    Thanks!
     
  2. DanielQuick

    DanielQuick

    Joined:
    Dec 31, 2010
    Posts:
    3,137
    You're serializing a class, not a method. I don't understand your problem, your serialized class has no methods and you are not using the class anywhere in your code. What are you trying to do?
     
  3. Sajid

    Sajid

    Joined:
    Mar 12, 2011
    Posts:
    199
    I've only ever had education in java, but we reffered to "public void test(int a){}" as a method, and the "public class turretHandlerRevised : MonoBehaviour {}" as a class, so I don't understand how I could "use" the class anywhere else. my terminology is probably just messed up though.

    Also, this is what I'm trying to do but I realize I must not be on the same page as the person who wrote the instructions:
     
  4. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Your working in an OOP environment. You must have an instance of a class to actually access the variables. I would suggest simply deleting line 17, 18, 19 and 24.

    The alternative would be to add the following anywhere in your code

    Code (CSharp):
    1. public TerretProperties turretProperties;
    Then access the turret properties like this

    Code (CSharp):
    1. turretProperties.firerate
    Honestly this does not strike me as best practice. The best practice you should be aiming for first is encapsulation. You have far too many public members. Hide them from other classes by removing the public and tagging them with [SerialiseFeild]
     
  5. tswalk

    tswalk

    Joined:
    Jul 27, 2013
    Posts:
    1,109
    you don't serialize methods... you make the class serializable and it's members a serializefield.

    I've had troubles with null-coalescing them during initialization (seems mostly on generic list types though).. hope that helps,

    be sure to read: http://forum.unity3d.com/threads/serialization-best-practices-megapost.155352/

    (and make note of the deal about constructors... super important, especially for abstract classes)
     
  6. tswalk

    tswalk

    Joined:
    Jul 27, 2013
    Posts:
    1,109
    (adjusted your sample w/o all the using and other things...)
    you should probably externalize this to a file, having the class attribute as [Serializable] and extend it with ScriptableObject. You 'should' then make your members private with the [SerializeField] attribute, and create Accessors for them... using protected on setters "if" needed. Add the OnEnable() method to the class, and add that hideFlags field to it (like described in the link above I sent).

    Then in you can do something like:

    Code (CSharp):
    1.  
    2. public class TurretHandlerRevised : MonoBehaviour
    3. {
    4. public List<TurretProperties> turretLists;
    5. public TurretProperties aTurretProperty;
    6. .
    7. .
    8. .
    9. void OnEnable()
    10. {
    11. if(turretLists == null)
    12. {
    13. turretLists = new List<TurretProperties>();
    14. }
    15. if(aTurretProperty == null)
    16. {
    17. aTurretProperty = CreateInstance<TurretProperty>();
    18. }
    19. }
    20.  
    21.  
    22.