Crazy-ass behaviour from a C# Queue

Alrighty hello all :slight_smile:

I am busy with my first ever game in Unity and C#, but I hit a slight snag.
I am well versed in languages like C++ and Java and ActionScript3 and I have about 4+ years experience under the belt.

As the title suggests, I am struggling with a Queue of char using C# as my scripting language.

Basically (as far as I can tell), the queue is constructed right and I can start enqueueing into it. The problem comes when I start dequeuing out of it. It seems like the newest element in the queue is continuously returned by Queue.Dequeue() for as long as there are elements in the queue.

So if I have 250 elements in the queue, and the last one was something like {‘0’,‘1’,‘0’}, then it will return {‘0’,‘1’,‘0’} 250 times, ignoring all the other contents.

The queue is used to record keyboard commands, so that I can play them back at a later stage. Please see the following code. To reproduce my problem, attach the Testdirector class to an empty gameObject, and execute.


Testdirector Class:

using UnityEngine;
using System.Collections.Generic;
using System.Collections;

public class Testdirector : MonoBehaviour {

	private Queue<char[]> commandQueue;
	private InputReader inputReader;	
	private char[] currentCommand;	

	void Start () {		
		commandQueue = new Queue<char[]>();			
		inputReader = this.gameObject.AddComponent<InputReader>();	
	}
	
	void Update () { 		
		currentCommand = null;
		currentCommand = inputReader.GetCurrentCommand();
		commandQueue.Enqueue(currentCommand);
		
		if (Input.GetKeyDown("space")) {			
			Debug.Log("COUNT Before " + commandQueue.Count);			
			EmptyQueue();
			Debug.Log("COUNT After " + commandQueue.Count);
		}	
	}
	
	void EmptyQueue(){
		while (commandQueue.Count != 0){			
			char[] temp = commandQueue.Dequeue();			
			Debug.Log(temp[0] + "" + temp[1] + "" + temp[2]);									
		}		
		Debug.Log("EMPTY");
	}
	
}

And the InputReader Class:

using UnityEngine;
using System.Collections.Generic;

public class InputReader : MonoBehaviour {
	
	private char[] currentCommand;

	void Awake () {		
		//CurrentCommand: pos(0) = left, pos(1) = right, pos(2) = jump
		currentCommand = new char[] {'0','0','0'};	
	}

	void Update () {
		
		currentCommand[0] = 'z';
		currentCommand[1] = 'z';
		currentCommand[2] = 'z';
		
		if (Input.GetKey("a")){
			currentCommand[0] = '1';				
		}
		
		if (Input.GetKey("d")){
			currentCommand[1] = '1';				
		}
		
		if (Input.GetKey("w")){
			currentCommand[2] = '1';				
		}		
		
	}
	
	public char[] GetCurrentCommand(){
		return currentCommand;
	}	
}

Any help will be greatly appreciated.
I will try and send a bottle of good South African wine your way should my problem be solved :slight_smile:

IMO, the point here is that currenCommand is a reference too. So you only enqueue reference to the array which you change.

I’m new to C# as well (similar circumstances to You), but if C# supports copy constructor for char then this should help:

currentCommand = new char[](inputReader.GetCurrentCommand());

this way, you enforce a full copy of that char

Remeber, that unless it’s a primitive (and arrays aren’t so AFAIK) the default is a shallow copy - only the reference is copied, not the value itself.

Well it seems that Owen’s solution was the one that worked… Thanks!

I changed return currentCommand to return currentCommand.Clone() as char[];