Comparing a buttons text to a gameobject name! help!

I want to take the text of a button, and when you clicked, it compares it against a list of current targets names on the field, and if the strings matched, the target gameobject gets added to an “attack list”.

Most everything works, except for what I’m assuming is this onclick function I cant get right. I keep trying things along the lines of:

  if (lists.combatants.Count > 0)
        {
            for (int i = 0; i < lists.combatants.Count; i++)
            {
                Debug.Log("I looped!");
                if (attackChoice.GetComponentInChildren<Text>().text == lists.combatants[i].name)
                {
                    attackTargetList.Add(lists.combatants[i]);
                    Debug.Log("If statment checked!");
                }

and

            foreach (GameObject target in lists.combatants)
            {
                if (attackChoice.GetComponentInChildren<Text>().text == target.name)
                {
                    attackTargetList.Add(target);
                    Debug.Log("If statment checked!");
                }

I get no errors, but nothing is getting added to the attract list.

lists is a reference to a spawner script I have, that keeps the list of enemies on the field (sorry if its not the smartest system, I am a student!) but I know its getting referenced fine, because many other things on the script use it just fine, and I don’t get any errors when I run the code. it just doesn’t work.

It is for a turn based RPG for school.
I hope I have made it clear enough, but can provide any pictures or additional info you need. I am very stuck. thanks!

I don’t see where you’re trying to handle the onClick anywhere. Could you show us that portion of the code?

I added the function to the button via the onclick thing in the inspector. maybe Im misunderstanding how that works?

7107835--847807--Screenshot (6)_LI.jpg

The default version of the function I keep going back to looking like :

    public void SelectTarget()
    {
        Debug.Log("it ran at all!");
        foreach (GameObject target in lists.combatants)
        {
            if (attackChoice.GetComponentInChildren<Text>().text == target.name)
            {
                attackTargetList.Add(target);
            }
        }
    }

the “it ran at all” debug log runs. but I can never get it to reach the if statement.

Now you’re working in the right direction. Since line 3 in that snippet runs, but line 6 doesn’t, and you don’t get any errors, the only logical explanation is that lists.combatants is empty. If that’s not what you’re expecting to happen, take a look at (and feel free to share) the code that populates that list.

1 Like

So it doesn’t display as empty, here’s a couple pictures during runtime, and Ill try and find some relative code snippets, since it’s like 300 lines of code total for both the scripts involved.

7108087--847855--Screenshot (8)_LI.jpg
7108087--847858--Screenshot (9)_LI.jpg

Here is the code that spawns the combatants list:

    private void Start()
    {
        combatants = new List<GameObject>();


        //Spawn Enemies
        for (int i = 0; i < enemySpawnPoints.Length; i++)
        {
            if (combatants.Count == 0 || (combatants.Count > 0 && CheckSpawnState() == true))
            {
                GameObject enemyObject = Instantiate(enemyPrefab);

                int randomIndex = UnityEngine.Random.Range(0, enemyGroups.enemyGroups.Length);
                var enemy = enemyObject.GetComponent<EnemyMain>();
               
                enemy.SetData(enemyGroups.enemyGroups[randomIndex]);
                enemy.SetTurnBasedSystem(turnBasedSystem);

                enemyObject.transform.position = enemySpawnPoints[i].transform.position;
                enemyObject.name = enemyGroups.enemyGroups[randomIndex].name;

                combatants.Add(enemyObject);
            }

        }
      
        //Spawn players
        for (int i = 0; i < party.partyMembers.Length; i++)
        {
            GameObject playerObject = Instantiate(playerPrefab);
            var player = playerObject.GetComponent<PlayerMain>();

            player.SetData(party.partyMembers[i]);
            player.SetTurnBasedSystem(turnBasedSystem);

            playerObject.transform.position = playerSpawnPoints[i].transform.position;
            playerObject.name = party.partyMembers[i].name;
          
            combatants.Add(playerObject);
        }

      
    }
    bool CheckSpawnState()
    {
        float picker = Random.Range(-1, 1);
        if (picker < 0)
            return false;
        else
            return true;
    }

The most obvious thing is to print the two things you are comparing before you compare them.

If nothing gets printed from within your for loop then, despite your assertions to the contrary, that particular list really is empty.

IF something does get printed, you’ll see why it fails to match.

Alrighty! I will move forward assuming it is empty, and trying to figure out why its empty. and like wise print the two things.

Not to question your obviously more educated opinion, but I am just very confused as to why it displays as full during runtime.

Not at all, I’m wrong sometimes too, and I love being corrected. How else could I learn?

Let me expand my thinking in my post #10 above.

  1. you assert and show screenshots of a list that is full.

  2. you run code that searches that list for items

  3. that code finds nothing matching

so how could that be?

a. it’s a different object that you’re showing the list for
b. it’s a different list entirely (either different variable or in another script)
c. there are more than one instance of this script in the scene: one has items, one does not
d. the items contain the word “Sword” but your button contains the word “sword”. Those are NOT equal

etc. etc. etc.

I’m just saying, in reference to post #5 above, you already have a debug log at line 3… the most obvious place is to put one at line 6 and display the 2 actual things you think you might be comparing, one after the other.

Either you’re not comparing them (list is empty)

Or they’re not what you think they are

Or … or something.

But the important point is that you WILL GET MORE INFO by printing stuff out. It really works.

Thank you for your replies! I really do appreciate it. I was just about to comment back saying that I tried to print the first spot in the list, and I got an error basically saying it was empty. so thank you for solving that! now I know the inspector is not always a literal representation of whats happening with the data, and to figure out why my list is empty.

1 Like

What also confuses me , is that the function that instantiates the attack choice buttons is on the same script and, and it uses the same combatants list as ref. so what would make the button function read the list as full, then 2 seconds later the on click function reads it as empty?
this is the button function, right above the target function, working just fine while referencing the same list.

public List <Button> DisplayTargets()
    {
        attackChoiceListOn = true;
        ColorBlock green = attackChoice.colors;
        green.normalColor = Color.green;

        ColorBlock red = attackChoice.colors;
        red.normalColor = Color.red;

        attackOrderPanel.SetActive(true);
        attackAlert.enabled = false;

        for (int i = 0; i < lists.combatants.Count;i++)
        {

            Button attackButton  = Instantiate(attackChoice);

            attackButton.transform.SetParent(verticalList);
            attackButton.GetComponentInChildren<Text>().text = lists.combatants[i].name;
            if (lists.combatants[i].tag == "Player")
            {
                attackButton.colors = green;
            }
            else
            {
                attackButton.colors = red;
            }
            Debug.Log(lists.combatants[i].tag);
            attackChoiceList.Add(attackButton);
        }
        return attackChoiceList;

    }

An excellent question! My first idea would be:

  1. this isn’t the same object:
    1a. you changed scenes when you clicked
    1b. you destroyed the previous object
    1c. something in the code emptied the list
    1d. etc.

Again, I still stand by : your answer is only just a few lines of code away from you, if you only print out and question the name of every gameobject going into and out of those lists.

1 Like

I will try that now. I’m gonna go print happy

1 Like

I am VERY close! so it turns out, the onclick function was referencing a prefab of the gameobject with the lists, and in the prefab version that’s not in the scene, the lists were of course empty. that’s one problem solved. So, now its reading the list. BUT. in the code

 foreach (GameObject target in lists.combatants)
        {
            //Debug.Log(target.name);
            if (attackChoice.GetComponentInChildren<Text>().text == target.name)
            {
                Debug.Log("if ran");
                attackTargetList.Add(target);
                Debug.Log("Added!");
            }
        }

it is returning the Text.text from the original button, not the clone I click on. so its saying “Button vs. Black Mass? NOPE, don’t add it to the target list.”

does anyone know how Id get the Text.text of the instantiated clone that’s clicked?

I hope that was clear enough.

Let’s just go ahead and see your whole script file at this point. It’ll be easier seeing the actual properties than us having to guess or ask you for each specific thing. I, for one, am having a lot of trouble following the logic without being able to see the whole system together.

In general, though, you maintain a reference to instances by storing the value returned by Instantiate.

public GameObject objectPrefab; // Assigned in inspector, probably

void Awake() {
    GameObject objectInstance = Instantiate(objectPrefab, Vector3.Zero);    // Reference to instance of prefab
}

Heres the turnbasedsystem script (Thus far)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using BattleSystem;
using System;
using System.Linq;


public class TurnBasedSystem : MonoBehaviour
{

    public int turnCoutner;
    public Spawner lists;
    public List<GameObject> attackOrder = new List<GameObject>();

    public GameObject attackOrderPanel;

    public Button attackChoice;
    public Text combatantNames;

    public List<Button> attackChoiceList = new List<Button>();
    public List<GameObject> attackTargetList = new List<GameObject>();
    public Text attackAlert;

    public Transform buttonPosition;
    public Transform verticalList;
 

    public bool attackChoiceListOn = false;

    public enum State
    {
        Initialize,
        PlayerPhase,
        EnemyPhase
    }

    public enum FinishState
    {
        InProgress,
        Won,
        Lost
    }
    public State CurrentState = State.Initialize;
    public FinishState BattleStatus = FinishState.InProgress;



    void Start()
      
    {
      
      
        switch (CurrentState)
        {
            case State.Initialize:
                break;

            case State.PlayerPhase:

                Debug.Log("You got here!");
                break;

            case State.EnemyPhase:
                Debug.Log("You got here!");
                break;
        }
    }

    void Update()
    {
      
        switch (CurrentState)
        {
            case State.Initialize:
             
                if (attackOrder.Count > 0)
                {
                    GetNextTurn();
                }

            
                break;

            case State.PlayerPhase:

                if (Input.GetButtonDown("Jump") && attackChoiceListOn == false)
                {
                    DisplayTargets();
                    //BasicAttack(target);
                }
                else if (Input.GetButtonDown("Jump") && attackChoiceListOn == true)
                {
                    cancelSelection();
                }

             

                break;
        }
    }
    State GetNextTurn()
    {
        var firstElement = attackOrder.FirstOrDefault();

        if (firstElement.gameObject.tag == "Player")
        {
            CurrentState = State.PlayerPhase;
        }

        else if (firstElement.gameObject.tag == "Enemy")
        {
            CurrentState = State.EnemyPhase;
        }
            return CurrentState;

    }

    public List <Button> DisplayTargets()
    {
        Debug.Log(lists.combatants.Count.ToString());
        attackChoiceListOn = true;
        ColorBlock green = attackChoice.colors;
        green.normalColor = Color.green;

        ColorBlock red = attackChoice.colors;
        red.normalColor = Color.red;

        attackOrderPanel.SetActive(true);
        attackAlert.enabled = false;

        for (int i = 0; i < lists.combatants.Count;i++)
        {
         
            Button attackButton  = Instantiate(attackChoice);
          
            attackButton.transform.SetParent(verticalList);
            attackButton.GetComponentInChildren<Text>().text = lists.combatants[i].name;
            if (lists.combatants[i].tag == "Player")
            {
                attackButton.colors = green;
            }
            else
            {
                attackButton.colors = red;
            }
            Debug.Log(lists.combatants[i].tag);
            attackChoiceList.Add(attackButton);
        }
        return attackChoiceList;

    }

    public List <Button> cancelSelection()
    {
        foreach (Transform buttonChoice in verticalList)
        {
            Destroy(buttonChoice.gameObject);
        }
        attackChoiceList.Clear();
        attackOrderPanel.SetActive(false);
        attackAlert.enabled = true;
        attackChoiceListOn = false;
        return attackChoiceList;
    }

    public void SelectTarget()
    {
        Debug.Log(lists.combatants.Count.ToString());
        Debug.Log("it ran at all!");

        foreach (GameObject target in lists.combatants)
        {
            //Debug.Log(target.name);

            if (attackChoice.GetComponentInChildren<Text>().text == target.name)
            {
                Debug.Log("if ran");
                attackTargetList.Add(target);
                Debug.Log("Added!");
            }

        }
    }
  
}