I’ve discovered the Queue class and thought it would be useful for the RTS Engine I’ve been working on. One problem though is that you can’t make it queue a function. I would want it to call a function when I call the Dequeue command.
public static void Task(RaycastHit hit)
{
string Tag = hit.transform.tag;
Selectable selCheck = hit.transform.gameObject.GetComponent<Selectable>();
if (Tag == "Terrain")
{
//What I might have to do
selCheck.entity.taskQueue.Enqueue("MoveTo");
//What I want to do
//selCheck.entity.taskQueue.Enqueue(MoveTo(hit.point));
//This is how it's originally being done
//MoveTo(hit.point);
}
public static void MoveTo(Vector3 position)...
I couldn’t use the string method because I wouldn’t be able to include parameters.
public class Entity : MonoBehaviour
public class Building : Entity
public class GatherUnit : Entity //An object like a tree, gold mine, etc.
public class Unit : Entity
The “MoveTo” command that is in the first post loops through the selected objects and calls Entity.MoveTo.
What do you mean when you said
Do you mean a separate GameObject or a new Class?
Edit: I’m taking a look at the Delegates and I’m “trying” to understand how they are supposed to be used.
Re: Commmand objects, read this. These solutions are all non-trivial programming questions to beginners, but hopefully some of the links from the Wikipedia page can get you started on that.
As for delegates, a delegate is essentially a function that adheres to a predetermined contract regarding what arguments it takes and what it returns. You define the contract by saying
public delegate void MyDelegateType (int someArgument);
public delegate void MyDelegateType2 ()
or so on. What you’re saying is that any function that wants to adhere to that signature (return nothing, take an int argument or no argument) can be called without the caller knowing or caring what the function does internally.
So if you have a Queue, you can declare a delegate like public delegate void UnitCommand () make that Queue be a queue of UnitCommands (Generics would help). As you dequeue things, they can be called without knowing what’s actually being done. An example:
public class Barracks
{
private Queue<UnitCommand> = new Queue<UnitCommand> ();
private void BuildSoldier ()
{
//Build a soldier
}
private void BuildMedic ()
{
//Build a medic
}
public void OnGUI ()
{
If (GUILayout.Button ("Soldier"))
{
buildQueue.Enqueue (BuildSoldier);
}
if (GUILayout.Button ("Medic"))
{
buildQueue.Enqueue (BuildMedic);
}
}
}
Even though the functions in Barracks are private, if you give them to something else to call (for example, if there were a global build queue or something in another class), they’ll be able to call them because they adhere to the UnitCommand delegate signature.
And when you actually move it, the taskQueue has a queue of “tasks” or “commands”:
foreach (Command cmd in this.TaskQueue)
{
cmd.Execute();
}
(all pseudo-code)
So similarly, you could create RotateCommands, AttackCommands, etc that take different arguments for their constructors and invoke different methods/behaviours when their “Execute” function is called.
The solution FizixMan posted works and it was easy to implement, thanks! I can now shift-click to task my units to walk to multiple places and gather from multiple resources. I don’t have any form of attacking or repairing yet. But one thing I don’t know how to do is make the unit automatically find a resource after it’s done gathering from its current resource. I want to use a trigger collider and loop through the objects inside the collider but that only works for collision colliders.
Can you explain exactly how this phase will work? Do you want to get all resources within a certain distance of the current position, find the nearest resource… ?
I want to find the nearest resource. I could do it by looping through every Entity and find the GatherUnits(resources) but that seems like a bit much. I could add a Trigger to the Unit and when the GatherUnit “enters” or “stays” in the trigger, I keep it in an ArrayList. The only problem with that is in this case…
If a GatherUnit is spawned inside the Trigger, it will not “trigger” the Trigger unless either the Unit or the GatherUnit moves.
Edit:
This would somewhat different than the average Find-Nearest-Object trigger. In a Tower Defense game, the enemies are moving and the Towers are constantly checking for them. But I only want to check once for more GatherUnits/Enemy Units/Enemy Buildings the instant my Unit/Building is Idle.