-
-
Save hacha/bc6791e7bfa7aaf20a11 to your computer and use it in GitHub Desktop.
using UnityEngine; | |
using System; | |
using UniRx; | |
public class Ball : MonoBehaviour | |
{ | |
void Awake () | |
{ | |
// var stream = Observable | |
// .EveryUpdate () | |
// .Delay(TimeSpan.FromSeconds(10)) | |
// .Take (1) | |
// ; | |
// var subscription = stream.Subscribe( _ => Destroy(gameObject) ); | |
// stream.Subscribe(_ => subscription.Dispose() ); | |
// 削除しちゃうなら別に明示的にDispose()しなくてよかったみたい。 | |
// なので下記になった。シンプル | |
Observable.Timer(TimeSpan.FromSeconds(10)).Subscribe( _ => Destroy(gameObject) ); | |
} | |
} |
始めはそうかな、と思ってそれで動かしてみたら、なんかログに参照エラーっぽいのが出たので、ちゃんとDisPoseしないとダメかな、と思って。
でも再度確認したら大丈夫でした。
なんだったんだろ。
いや、やっぱりダメかも。
使い方が悪いのかもしれないけど、GameObjectがDestroyされた後に処理が走ることがある。
MissingReferenceException: The object of type 'Ball' 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.
Ball.m__0 (Int64 _) (at Assets/Ball/Ball.cs:11)
UniRx.Observer+AnonymousObserver`1[System.Int64].OnNext (Int64 value) (at Assets/UniRx/Scripts/Observer.cs:55)
UnityEngine.Debug:LogException(Exception)
UniRx.MainThreadDispatcher:m__16B(Exception) (at Assets/UniRx/Scripts/UnityEngineBridge/MainThreadDispatcher.cs:265)
UniRx.MainThreadDispatcher:UnsafeSend(Action) (at Assets/UniRx/Scripts/UnityEngineBridge/MainThreadDispatcher.cs:220)
UniRx.c__IteratorF:MoveNext() (at Assets/UniRx/Scripts/UnityEngineBridge/MainThreadScheduler.cs:77)
なるほー。
_ => Destroy(gameObject)
の部分は一回しか呼ばれない&この辞典でgameObjectはDestoryされている。
ということになると思います。
別の何かが、そのBallを破壊してるのではかなー、と思うのですがどうでしょう?
もしそうなら単純な対策は
_ =>
{
if(gameObject != null) Destroy(gameObject)
}
ですが、 Timerのライフサイクルを考えると、例えばシーン変更とか(Ballは破壊される!)の時とかも、このTimerは残り続けちゃうんですよね。
というわけで、どっかで集中的に CompositeDisposable
で管理していて、Subscribe().AddTo(composite); して、
comositeをまとめてDispose(かClear)っていうのも手法としてよくあります。
なるほど、Timerそのものが残ってたってことなんですね!
でどうでしょー。
キャンセルする必要がないなら、subscriptionのDisposeは特に要りません。