Turn Based Strategy - Executing the turns

So I have some code that creates a list of GameObjects:

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

public class GoList : MonoBehaviour {
    public GameObject[] enemyList;
    public int enemyListLength;

    public List<GameObject> GObj = new List<GameObject> ();

    // Use this for initialization
    void Awake () {
        enemyList = GameObject.FindGameObjectsWithTag ("Character");
        enemyListLength = enemyList.Length;

        for (int i = 0; i < enemyListLength; i++){
            GObj.Add (enemyList[i]);
        }

        GObj.Sort (SortMethod);

        foreach (GameObject go in GObj) {
            print (go.name);       
        }

        GObj[0].GetComponent<PlayerTurn>().turnActive = true;

    }

    private int SortMethod (GameObject A, GameObject B){
        if (!A && !B) return 0;
        else if (!A) return -1;
        else if (!B) return 1;
        else if (A.GetComponent<Attributes>().speed > B.GetComponent<Attributes>().speed) return 1;
        else return -1;
    }

The GameObjects are ordered by a variable speed located on another script. I’m having trouble with coming up with a way to execute each characters turn. Every way that I attempted has either not worked, or wasn’t flexible enough to support varying numbers of characters. Right now I have a script on each character that has a bool turnActive set to false:

using UnityEngine;
using System.Collections;

public class PlayerTurn : MonoBehaviour {
    public bool turnActive = false;

    public GameObject battleBrain;

    // Use this for initialization
    void Start () {

    }
   
    // Update is called once per frame
    void Update () {

        if(turnActive) {
            Turn();
        }
    }

    public void Turn() {
        Debug.Log ("taking turn");

        turnActive = false;
    }
}

When turnActive is true, the character executes his/her turn. The problem I’m having is telling the next character that they can now go, while being flexible enough to support different numbers of characters. A nudge in the right direction and maybe some help along the way would be great.

As a general design decision, I believe actions and delegates may be the direction you need to go in order to communicate with the objects you’ve created. (For a nudge in the right direction.)

I’d recommend coroutines; that makes it very easy to schedule a sequence of events.

–Eric

@JollyJenkins I’ve never used actions and delegations before, do you have any tips or some article(s) I should read? Meanwhile I’ll see of corourtines will do what I want like @Eric5h5 suggested.

Delegates and events (not actions, my mistake) is one way to get communication going between objects, if you combine this with Eric’s suggestion about the coroutines, it may be a solution to getting your objects to take the actions you want exactly when you want it.

An example, would be setting up a delegate that covers when each character should go, if you fire off the event, any of the characters setup to listen to it will do so, and if you setup internal conditions within the individual object (such as object A is has isGo set to false, and object B has isGO set to true), you can have them react as needed according to the event that was fired.

1 Like

@JollyJenkins awesome thank you! I’ll report back when I’ve made some progress.

I wrote some sudo code today, I’ll need to actually write it out to make sure it works, but it looks good to me.

int i = 0;

if(gobj[i].turnActive == true){

coroutine //delay adding to i
i++;
    if(i <= gobj.length){
        gobj[i].turnActive = true;
    }

    if(i > gobj.length){
        i=0;
        gobj[i].turnActive = true;
    }
}

coroutine {
    yeild unitl gobj[i].turnActive == false;
}

The only thing I’m not sure about it my corountine. Can the yield in the coroutine yield until a bool equals true/false, if it can how would I write that?

edit: typed out all the code excluding the coroutine

    if(GObj[i]GetComponent<PlayerTurn>().turnActive == true){

            //coroutine
            i++;

            if(i <= GObj.Count){
                GObj[i].GetComponent<PlayerTurn>().turnActive = true;
            }
            else if(i > GObj.Count){
                i = 0;
                GObj[i].GetComponent<PlayerTurn>().turnActive = true;
            }
        }