Skip to content

Instantly share code, notes, and snippets.

@hacha
Last active August 29, 2015 14:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hacha/bc6791e7bfa7aaf20a11 to your computer and use it in GitHub Desktop.
Save hacha/bc6791e7bfa7aaf20a11 to your computer and use it in GitHub Desktop.
生成されて10秒後に消滅するボール、みたいなものをUniRxで記述したもの
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) );
}
}
@neuecc
Copy link

neuecc commented Mar 12, 2015

Observable.Timer(TimeSpan.FromSeconds(10)).Subscribe(_ => Destroy(gameObject));

でどうでしょー。
キャンセルする必要がないなら、subscriptionのDisposeは特に要りません。

@hacha
Copy link
Author

hacha commented Mar 12, 2015

始めはそうかな、と思ってそれで動かしてみたら、なんかログに参照エラーっぽいのが出たので、ちゃんとDisPoseしないとダメかな、と思って。
でも再度確認したら大丈夫でした。
なんだったんだろ。

@hacha
Copy link
Author

hacha commented Mar 12, 2015

いや、やっぱりダメかも。
使い方が悪いのかもしれないけど、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)

@neuecc
Copy link

neuecc commented Mar 13, 2015

なるほー。

_ => Destroy(gameObject) の部分は一回しか呼ばれない&この辞典でgameObjectはDestoryされている。
ということになると思います。
別の何かが、そのBallを破壊してるのではかなー、と思うのですがどうでしょう?
もしそうなら単純な対策は

_ =>
{
    if(gameObject != null) Destroy(gameObject)
}

ですが、 Timerのライフサイクルを考えると、例えばシーン変更とか(Ballは破壊される!)の時とかも、このTimerは残り続けちゃうんですよね。
というわけで、どっかで集中的に CompositeDisposableで管理していて、Subscribe().AddTo(composite); して、
comositeをまとめてDispose(かClear)っていうのも手法としてよくあります。

@hacha
Copy link
Author

hacha commented Mar 20, 2015

なるほど、Timerそのものが残ってたってことなんですね!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment