Unity Addressables加载Sprite返回None问题求助
问题:Addressables加载Sprite到Weather Struct后图标始终为Null
我尝试通过代码将Sprite加载到自定义的Weather struct中,但运行项目时weatherList中所有条目均报错“Failed to load weather icon for XXX”。已确认Addressables Group配置正确(修改图标名称会触发键错误),但weatherList中的Weather Icon始终显示为None(Sprite)。
WeatherManager代码实现
public class WeatherManager : MonoBehaviour { #region Variables private List<Weather> weatherList = new List<Weather>(); #endregion ... public void Start() { InitialiseWeatherList(); } ... private void InitialiseWeatherList() { if(weatherList.Count == 0) { weatherList.Add(new Weather(WeatherType.Cloudy, "Cloudy", "Weather_Cloudy")); weatherList.Add(new Weather(WeatherType.PartlyCloudy, "Partly Cloudy", "Weather_PartlyCloudy")); weatherList.Add(new Weather(WeatherType.Rainy, "Rainy", "Weather_Rainy")); weatherList.Add(new Weather(WeatherType.Snowing, "Snowing", "Weather_Snowing")); weatherList.Add(new Weather(WeatherType.Sunny, "Sunny", "Weather_Sunny")); weatherList.Add(new Weather(WeatherType.Thunderstorm, "Thunderstorm", "Weather_Thunderstorm")); StartCoroutine(LoadWeatherIcons()); } } private IEnumerator LoadWeatherIcons() { foreach(Weather weather in weatherList) { yield return weather.LoadWeatherIcon(); weather.SetWeatherIcon(weather.GetWeatherIcon()); } foreach (Weather weather in weatherList) { if(weather.GetWeatherIcon() == null) { Debug.LogError($"Failed to load weather icon for {weather.GetWeatherName()}"); } } } }
Weather Struct定义
public struct Weather { private WeatherType weatherType; private AssetReference weatherIconReference; private Sprite weatherIcon; private string weatherName; private string weatherIconName; public Weather(WeatherType weatherType, string weatherName, string weatherIconName) { this.weatherType = weatherType; this.weatherIconReference = null; this.weatherIcon = null; this.weatherName = weatherName; this.weatherIconName = weatherIconName; } public WeatherType GetWeatherType() { return weatherType; } public Sprite GetWeatherIcon() { return weatherIcon; } public string GetWeatherName() { return weatherName; } public string GetWeatherIconName() { return weatherIconName; } public void SetWeatherIcon(Sprite weatherIcon) { if(this.weatherIcon == null) { this.weatherIcon = weatherIcon; } else { Debug.LogError("Could not reassign weather icon."); } } public IEnumerator LoadWeatherIcon() { AsyncOperationHandle<Sprite> loadOperation = Addressables.LoadAssetAsync<Sprite>(weatherIconName); yield return loadOperation; if(loadOperation.Status == AsyncOperationStatus.Succeeded) { weatherIcon = loadOperation.Result; } else { Debug.LogError($"Failed to load weather icon for {weatherName}"); } } }
核心问题
Weather是值类型(struct),在LoadWeatherIcons的foreach循环中,Weather weather in weatherList会创建原结构体的副本。调用LoadWeatherIcon()和SetWeatherIcon()时,所有修改都只作用于这个副本,而非列表中的原结构体实例,导致原列表里的weatherIcon始终为null。
解决方案
方案1:将Weather从struct改为class(推荐)
将Weather改为引用类型(class),这样foreach循环中操作的是原实例的引用,修改会直接同步到列表中的元素:
public class Weather // 替换struct为class { private WeatherType weatherType; private AssetReference weatherIconReference; private Sprite weatherIcon; private string weatherName; private string weatherIconName; public Weather(WeatherType weatherType, string weatherName, string weatherIconName) { this.weatherType = weatherType; this.weatherIconReference = null; this.weatherIcon = null; this.weatherName = weatherName; this.weatherIconName = weatherIconName; } // 其余方法保持不变... }
同时可以去掉LoadWeatherIcons中多余的weather.SetWeatherIcon(weather.GetWeatherIcon())行,因为LoadWeatherIcon()已经直接给实例的weatherIcon赋值了。
方案2:保持struct,通过索引修改原元素
如果必须使用struct,遍历列表时通过索引访问元素,修改后重新赋值回列表:
private IEnumerator LoadWeatherIcons() { for (int i = 0; i < weatherList.Count; i++) { Weather weather = weatherList[i]; yield return weather.LoadWeatherIcon(); // 将修改后的副本重新赋值回列表 weatherList[i] = weather; } foreach (Weather weather in weatherList) { if(weather.GetWeatherIcon() == null) { Debug.LogError($"Failed to load weather icon for {weather.GetWeatherName()}"); } } }
同样可以去掉多余的SetWeatherIcon调用,避免无效操作。
内容的提问来源于stack exchange,提问作者JamieRhys
相关产品推荐
相关产品推荐

