- Home /
Queueing methods and calling them at specific times
So I'm trying to build a turn based battle system in which a player can take a specific number of actions per turn. Additionally a player can manipulate the times when these actions will be taken and at the end the actions will play out at the player-determined times.
I'm kind of at loss at how to approach this and would appreciate a hint at how to accomplish this. Right now I've tried queueing my actions / functions by storing them in a list, I've tried using delegates and queues but a problem I encounter is the use of different parameters for my functions, i.e. a Move function for a unit will take a Vector3 targetPosition but a SwapWeapon function for a unit will take a Int index parameter. Additionally right now I'm implementing my action functions by using Coroutines, so I can call them at various times and overlap each other but since these aren't working the way I want yet this is up for change as well. I imagine I could implement the timer by letting the player choose the starting times of his actions, then when it's time to execute just starting a timer and calling the function in my queue at the respective time but I haven't tried implementing this bit yet.
Thanks for any answer I might get.
Answer by YoungDeveloper · Aug 11, 2015 at 12:04 PM
Check out c# delegates, you can add - register and remove - unregister any methods of same param type. When you call the event all registered methods will be called, you can even loop and do picky stuff. As param will be any possible type really, create a container which will hold a dictionary that way you will be able to pass any data you want without creating override type of events.
Thank you for your answer. Could you please give an example of how to use any parameter by using dictionaries? I don't quite understand how I'd go about doing that.
//pseudo
public class DataObject{
private Dictionary<string, System.Object> _data = new ...
public void add(string key, System.Object value){
//add ..
}
public System.Object get(string key){
//get ..
}
}
//to add
int a = 5;
string b = "something";
dataObject.add("myNumber", a);
dataObject.add("myString", b);
//to get
int num = (int)dataObject.get("myNumber");
string text = (string)dataObject.get("myString");
of course this will work with any data types or objects
Thanks, I tried to implement your suggestion but encountered a few problems. $$anonymous$$y code looks something like this:
public class DataObject {
// like in your example above
}
...
public delegate void Action(DataObject param);
private Action actionQueue;
...
// here I want to call a move function of an object of custom type Unit which normally takes
// Vector3 as a parameter (I use DataObject.get in Unit.RotateAnd$$anonymous$$ove to get the Vector3)
DataObject param = new DataObject();
param.add("targetPosition", mousePosition);
actionQueue += selectedUnit.RotateAnd$$anonymous$$ove(param);
// then if I want to invoke all stored method calls I do something like this
if(actionQueue != null) {
actionQueue();
}
With this code I get the following error message: "Operator +=' cannot be applied to operands of type
TurnController.Action' and `void'"
It doesnt work like that, you register only the methods and then call the Action() passing the value.
public delegate void Action(DataObject param);
private Action actionQueue;
private void Test(DataObject data){
//unpack you data here
}
actionQueue += Test;
DataObject param = new DataObject();
param.add("targetPosition", mousePosition);
actionQueue(param);
Oh I see, that makes sense. But then this isn't the kind of flexibility I had hoped to achieve, is there no way to store the parameters of a function call WITH the function call? Because I wanted to collect all the calls including their parameters so I could later on easily rearrange and call them in the order I want with a simple loop. This way this seems really difficult; maybe I could store the DataObjects in a separate list but then it would be hard to associate the parameters with their respective function calls after rearranging the order of the calls.