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!
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);
}
}
}
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.
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.
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.
you assert and show screenshots of a list that is full.
you run code that searches that list for items
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.
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;
}
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.
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?
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
}
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!");
}
}
}
}