I have a class that stores all the data pertinent to a unit for an army. One of those pieces of data is an array that stores all the upgrades the unit has.
public class CustomAssembledUnit
{
public UnitData unitData;
//Array I'm having issues with
public UpgradeCard[] upgradeCards;
public int totalPoints;
public GameObject unitButton;
public GameObject categoryButton;
public GameObject activatedUnitButton;
public TextMeshProUGUI categoryText;
}
When the class is create and all the data is assigned, it’s stored in another script to be called at a later time.
If I run a Debug.Log on the unitData variable everything is fine and all the data is there. The problem is when I call that data at a later point.
public void OnPointerClick(PointerEventData eventData)
{
CustomAssembledUnit unit = cancelButton.ReturnUnitData();
Debug.Log(unit.unitData.unitName);
Debug.Log(unit.totalPoints);
Debug.Log(unit.upgradeCards.Length + " upgrade cards");
for (int i = 0; i < unit.upgradeCards.Length; i++)
{
Debug.Log(unit.upgradeCards[i]);
}
}
public CustomAssembledUnit ReturnUnitData()
{
return unitData;
}
When I run a Debug.Log on the upgrades after returning it, every index shows a null result. What would be the reason that specific piece of data isn’t being passed back?
Don’t think it’s possible for anyone to figure out the problem with these snippets of code, or at least I couldn’t. What is cancelButton? What did your other Debugs return? Where’s your code actually setting the upgradeCards in the first place?
A few things you could try:
Try right-clicking upgradeCards and clicking “Find All References” (might be called something else in other IDEs, but I use Visual Studio). This will show you every place that you reference the upgradeCards, be it setting or getting. You can print before and after every place you set the value, to make sure it’s actually getting set.
Attach a debugger to your code and run through it line by line, while watching the value. This will guarantee you find your problem, but I’ve had problems getting it to work consistently with Unity.
Just give more code so we can identify the problem area.
So I’ve tracked down the issue but now I can’t make sense of why the array is being cleared. I’ve removed a bunch of code because it’s all UI related and don’t want it cluttering the post.
public class ActivatedButton : MonoBehaviour, IPointerClickHandler
{
private CustomAssembledUnit unitData = new CustomAssembledUnit();
public void InitializeButton(CustomAssembledUnit storedUnit)
{
unitData = storedUnit;
UnitCustomization uc = GameObject.FindObjectOfType<UnitCustomization>();
uc.CancelButton();
}
}
So basically what happens, the player creates a unit for an army and that unit data is sent to this button script that stores it in case the player wants to edit it and then the script that was handling the customizing has its variables and ui elements cleared through the CancelButton and ResetButton functions.
private UpgradeCard[] upgrades;
public void CancelButton()
{
ResetButton();
}
public void ResetButton()
{
for (int x = 0; x < upgrades.Length; x++)
{
upgrades[x] = null;
}
}
This for loop is the problem. I’ve commented out the line that calls the CancelButton funtion and the data was stored as expected and then I commented out just the for loop and again worked as expected. So I know for sure that loop is the issue. It clears the upgrades in the customization script but when I do that it also clears the upgrades in the button script. This is what I don’t understand. If I basically copy the storedUnit data into the unitData variable and then clear the original storedUnit, why is it clearing the unitData variable. As I understand it, that shouldn’t be affected. If you need to see all the code I can upload it to a shared folder on google drive.
So almost all objects are “passed by reference by value”, which sounds confusing, but basically, you can just assume everything acts as if it is passed by reference. That means unitData is not a copy of storedUnit, it is storedUnit. What you’re going to want to do is initialize a new CustomAssembledUnit and copy the data over.
Confusing is right. I thought I did exactly that which obviously I didn’t because it isn’t working. But didn’t I initialize a new CustomAssembledUnit in line 3
private CustomAssembledUnit unitData = new CustomAssembledUnit();
It is assigned unless I’m not understanding what you’re saying. It’s like RedRedPanda stated being a reference issue. It’s not actually copying the data. Because if it changes on the original it also changes it on the new but if I don’t change anything and run a debug on the new unit all the data is there.
Oh I see what you’re saying. I shouldn’t have included that bottom portion. That’s for a something separate. The code is a mess right now. I need to clean it up