- Home /
Arrays suddenly not serializing?
While working on one of my projects today I came across something very, very weird. I tried to declare a public array of 100 bools, but would for some reason get an array with a length of 0. I tested it further with a few other datatypes, but neither of them gave different results. I tried opening one of my other projects but nothing changed. I also tried setting the size from the inspector instead, but it would reset to 0 when starting the game. Finally, I started a new project and this time it went back to normal. I could declare arrays and I could change their size from the inspector. However, as soon as I go back to the other two projects the problem resurfaces.
It might be worth noting that all arrays that are already in the script act like normal, so as long as I don't try to change something my scripts work just fine.
I'm still very much a novice programmer, but from the little I know it seems like the arrays don't serialize. As soon as I select a new object the size is forgotten. But there's absolutely no reason for that to happen. I'm working on a custom inspector for one of the projects, but the other one is completely vanilla and very, very simple.
This is the piece of code I used for testing, by either setting the length from the inspector or by adding "= new bool[100]".
using UnityEngine;
using System.Collections;
public class Movement : MonoBehaviour {
public bool Jump = true;
protected Animator animator;
public float Speed;
public float JumpHeight;
public ParticleSystem Particles1;
public ParticleSystem Particles2;
public bool [] Test = new bool[100];
void Update () {
print(Test.Length);
}
// Use this for initialization
void Start () {
animator = gameObject.GetComponent<Animator>();
}
// Update is called once per frame
void FixedUpdate () {
rigidbody2D.AddForce(Vector2.right * Input.GetAxis("Horizontal") * Speed);
if (Input.GetAxis("Horizontal")>0)
{
Vector2 temp = new Vector2(-1, transform.localScale.y);
transform.localScale = temp;
Particles1.enableEmission = false;
Particles2.enableEmission = true;
animator.SetBool("Walk", true);
}
if (Input.GetAxis("Horizontal")<0)
{
Vector2 temp = new Vector2(1, transform.localScale.y);
transform.localScale = temp;
Particles1.enableEmission = true;
Particles2.enableEmission = false;
animator.SetBool("Walk", true);
}
if (Input.GetAxis("Horizontal") == 0)
{
animator.SetBool("Walk", false);
}
if (Input.GetAxis("Fire1") > 0 && Jump == true)
{
rigidbody2D.AddForce(Vector2.up*JumpHeight);
Jump = false;
}
}
void OnCollisionEnter2D (Collision2D collision)
{
Jump = true;
}
}
I have restarted both my computer and software. All my code is written in C# using MonoDevelop. I'm on a Macbook Pro running Mavericks.
Can you comment out //print(Test.Length); in Update() and type it in Start(). See what happens.
Still a zero, only difference is that it only prints it once.
Seems to have worked this time. I tried setting a few values from code earlier, but it would just tell me that it was out of range.
After trying with a few values in an array of 90, it started reverting back to 90 ins$$anonymous$$d of zero. If I set a few values it works like it's supposed to, but whenever the array is empty it goes back to 90.
Answer by Guts · Dec 08, 2013 at 04:23 AM
I ran some tests to see what happens in a few situations (Using Unity 4.3.1).
I used this simple script in the tests:
using UnityEngine;
using System.Collections;
public class Movement : MonoBehaviour
{
public bool[] Test = new bool[100];
void Start()
{
print(Test.Length);
}
}
Once you add that component to a GameObject, Unity serializes it and no longer cares if you change the size of the serialized array in the script (unless you click on the gear in the inspector and hit "Reset").
This behaviour is not exclusive to arrays. If you add another serialized field and initialize it as you do with the array, for example a public string field initialized to "Hello!", then once Unity serializes it it doesn't care if you change the string initialization to "Goodbye!", it's still going to have stored "Hello!" as the value. As this demonstrates if you attach it to an object and then play:
using UnityEngine;
using System.Collections;
public class Movement : MonoBehaviour
{
public bool[] Test = new bool[100];
public string word = "Hello!";
void Start ()
{
print(Test.Length);
print(word);
}
}
I would consider this good and expected behaviour, as it's what makes editing per-instance values in the inspector possible. I guess maybe the thing to remember about serialized members is that you're turning them over to be managed by Unity and whoever is poking values into them in the inspector. If you want something more controlled you'll have to look elsewhere.
Answer by Crazy Noa · Dec 11, 2013 at 09:51 AM
The problem isn't that all arrays work differently than I'd expect them to. I have a script with ten or so arrays that work just fine. The thing is, when I declare a new one it does not behave like the others. For example:
public string [] Dialogue = new string [100];
This one works just fine. It is one of the first arrays I declared in this script. I can get the length regardless of if I place the Print() in Update, OnGUI or Start. However, when I declare this one:
public string [] Test = new string[100];
print(Test.Length) prints out 0. This is the exact same way I print out Dialogue, the only difference being that I switch out the name. And all my other arrays work just like Dialogue, it's just the ones I've declared since last friday that don't behave this way.
Might be worth mentioning that trying to use the array gives me IndexOutOfRangeException: Array index is out of range, so it's not that it fails to print the length.
This is not an answer! Please don't post such things as answer. You can post it as comment or edit your question.
Also like Guts said serialized arrays shouldn't be created by you. Unity will create the array automatically and you can change it's size and content in the inspector.
If you don't want the array to be serialized at edit time, make the array private or put a NonSerialized attribute on your variable
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Trigger GUI with a key when colliding (C#)? 1 Answer
NullReferenceException problem 2 Answers
Pause Game When Function Is Enabled? 3 Answers