Imagine I have this situation, I have multiple units in a strategy game and when I click on a unit the UI on the bottom updates the image to display their skills. There is only one instance of this UI but there are multiple units.
using UnityEngine;
public class Unit : MonoBehaviour
{
public Image SkillImage; // Only one instance of this exists, not per unit
AssetReference SkillIcon;
bool IsClicked;
void Update()
{
if(IsClicked)
{
SetSkillIcon();
}
}
async void SetSkillIcon()
{
SkillImage.sprite = await SkillIcon.LoadAssetAsync<Sprite>().Result;
}
}
Is it possible that a previously called ‘SetSkillIcon’ method finishes after another one which is called afterwards?
For instance we click Unit1 and 5 frames later Unit2 but async operation for Unit1 finishes later so we see Unit1’s skills on the UI even though we clicked Unit2 last?
Is this a common problem and if so, what’s the best way to go around this?
I’m not entirely sure cause I don’t use the async await but if it needs to be synchronous, you need to load it before hand.
So I’d call LoadAssetAsync in start or something
I think this is not really a problem with Addressables, but rather a race-condition situation in general. Your problem is essentially: whichever clicked unit loads in his icon the latest will get to display his result, regardless of whether he is selected or not. I think the way you’ve set up your code right now will not have an elegant solution to this problem.
Something to consider:
Don’t let the unit itself keep track of whether it is the currently selected unit. Rather: let it send out an event to let other scripts know he got clicked on. If he got clicked on, check whether the unit still needs to load his icon or not. I think you can do that with a simple null-check. Additionally, have the unit also send out an event when the icon is loaded and available to use.
Have some kind of a ‘Unit selection manager’: this one should keep track of which unit got click on the latest and pick up these ‘got clicked on’ events. When it receives such an event callback, check if the icon of that unit is available. If not, don’t do anything yet and wait for the unit to fire its ‘my icon got loaded’ event. When you do receive that ‘icon got loaded’ event callback, check whether that unit is still the selected one. If so, change the UI to let it show that new Icon. If another unit got selected in the meantime, don’t show the new icon.
The above also decouples the UI-part from the unit itself and gives that responsibility to this selection manager.