【Unity】UniRxで.Subscribeしているオブジェクトがシーン遷移でエラーになるときのエラー解決方法[MissingReferenceException: The object of type XXX has been destroyed but you are still trying to access it.]
概要
UniRxで.Subscribe
したオブジェクトがシーン遷移してから戻って呼び出したときに以下のエラーを出していて何のことか分からないので解決方法と原因をまとめました
MissingReferenceException: The object of type 'PlayerIcon' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
UnityEngine.Component.GetComponent[T] () (at <127e81e1cb3441cc97d26b1910daae77>:0)
PlayerIcon.<Start>b__2_1 (System.String playerIcon) (at Assets/Scripts/UI/PlayerIcon.cs:17)
UniRx.Observer+Subscribe`1[T].OnNext (T value) (at Assets/Plugins/UniRx/Scripts/Observer.cs:165)
解決方法
.Subscribe
しているところに購読終了の.AddTo(gameObject)
を付与し、そのオブジェクトが破棄されたときに自動で購読終了させる
public static ReactiveProperty<string> rpPlayerIcon = new ReactiveProperty<string>("");
void Start()
{
// .Subscribeしたオブジェクトに.Add(gameObject)を付与すれば解決
rpPlayerIcon.ObserveEveryValueChanged(_ => _.Value)
.Subscribe(playerIcon => GetComponent<Image>().sprite = GetPlayerIcon(playerIcon));
.AddTo(gameObject); //指定のgameObjectが破棄されたらDisposeする
}
原因
別シーンに遷移したときにこれが付与されているオブジェクトが破棄されているのに、.Subscribe
しているためエラーになっていたようです。
こちらの記事を参考にさせていただきました! → AddToが必要な理由
このスクリプトをプレイヤーのアイコンを取得するために使用していたのですが、別シーンに遷移してから元のシーンに戻り、画像を変更したときにエラーになりました。
using UnityEngine;
using UnityEngine.UI;
using UniRx;
using System.Linq;
// プレイヤーが自分のアイコンを変更したときに使用
[RequireComponent(typeof(Image))]
public class PlayerIcon : MonoBehaviour
{
public static ReactiveProperty<string> rpPlayerIcon = new ReactiveProperty<string>("");
private Sprite[] icons;
void Start()
{
icons = Resources.LoadAll<Sprite>("PlayerIcons/");
rpPlayerIcon.ObserveEveryValueChanged(_ => _.Value)
.Subscribe(playerIcon => GetComponent<Image>().sprite = GetPlayerIcon(playerIcon));
// ↑この.Subscribeがオブジェクトが破棄された後も続いていた
}
private Sprite GetPlayerIcon(string playerIcon)
{
if (icons.Any(icon => icon.name == playerIcon))
{
return Resources.Load<Sprite>("PlayerIcons/" + playerIcon);
}
else
{
return Resources.Load<Sprite>("PlayerIcons/icon_0");
}
}
}
なので解決方法でも記載しましたが、.AddTo(gameObject)
そのオブジェクトが破棄されたときに購読停止すればエラーが無くなりました!
破棄されているのに購読していたらエラーになりますよねw
エラー文のままでしたが気づきませんでした。。。
MissingReferenceException: The object of type 'PlayerIcon' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
UnityEngine.Component.GetComponent[T] () (at <127e81e1cb3441cc97d26b1910daae77>:0)
PlayerIcon.<Start>b__2_1 (System.String playerIcon) (at Assets/Scripts/UI/PlayerIcon.cs:17)
UniRx.Observer+Subscribe`1[T].OnNext (T value) (at Assets/Plugins/UniRx/Scripts/Observer.cs:165)
まとめ
.Subscribe
した後のオブジェクトの挙動を忘れていたことが原因でした。でも.Add(gameObject)
で解決できたので被害は少なかったです。
UniRxはやっぱり難しいですね。エラーにたくさん出会いますが解決して習得していきたいですね。
Author And Source
この問題について(【Unity】UniRxで.Subscribeしているオブジェクトがシーン遷移でエラーになるときのエラー解決方法[MissingReferenceException: The object of type XXX has been destroyed but you are still trying to access it.]), 我々は、より多くの情報をここで見つけました https://qiita.com/nodokamome/items/0acc78fe8efee18c74be著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .