Skip to content

Observable Examples

bleedingpixels edited this page Apr 20, 2015 · 11 revisions

Snippets, references, samples of UniRX Observables usage in uFrame.

Inspired by http://rxwiki.wikidot.com/101samples

Please feel free to add more!


General

Simple RX Time. Should be self explanatory.

this.UpdateAsObservable().Subscribe(_=>{ Debug.Log("THIS IS CALLED EVERY FRAME") });
this.UpdateAsObservable().Where(_=>Input.GetMouseButtonDown(0)).Subscribe(_=>{ Debug.Log("THIS IS CALLED when the mouse button is down") });
this.UpdateAsObservable().Where(_=>Input.GetMouseButtonDown(0)).Throttle(TimeSpan.FromSeconds(1)).Subscribe(_=>{ Debug.Log("This is only called once per second. This keeps many clicks from firing this to quickly") });

Once per second, execute command to damage player

Observable.Interval(TimeSpan.FromMilliseconds(1000))
	.Subscribe(_ => {
			ExecutedamagePerSecondTick(); 
	}).DisposeWhenChanged(Player.healthStateProperty);

Time based functionality without co-routines in controller to trigger waves.

if (state is Wave)
{
	// Wait for the alloted amount of time
	Observable.Interval(TimeSpan.FromSeconds(wavesFPSGame.SpawnWaitSeconds))
	.Where(_ => wavesFPSGame.WavesState is Wave)
	.Take(wavesFPSGame.KillsToNextWave)
	.Subscribe(l => {
		SpawnEnemy();
	});
}

GUI (Non Specific)

uGUI events as observables. A button as an event stream in your view.

Button poorButton;  // Our button.
 
poorButton.AsClickObservable()
	.Where(_ => YOUR FILTER )
	.Throttle(_ => PREVENT SPAMMING )
	.DelayFrame( FRAMES TO DELAY )
	.SkipWhile( SKIP FIRST TAPS IF CONDITION IS NOT MET )
	.Subscribe(_ =>
	{
		USE LIKE SIMPLE OBSERVABLE
	});

Flash sprites on and off rapidly.

	var sprites = GetComponentsInChildren<SpriteRenderer>().ToList ();

	if(value){
		Observable.Interval(TimeSpan.FromMilliseconds(100))
				.Subscribe(l => 
				{
					if (Character.isInvulnerable)
						sprites.ForEach(s => s.enabled = 1 % 2 == 0);
				}).DisposeWhenChanged(Character._isInvulnerableProperty);
		}
		else
		{
			sprites.ForEach(s => s.enabled = true);
		}

State Machines

Bind to state machines last state

{StateMachineProperty}Property.Subscribe(_=>{  {StateMachineProperty}Property.LastState });

Setting up a subscription for when a state changes

// Do something on state changes
myViewModel.myStateMachine.StateMachine
    .Subscribe(newState => {
       // Do something now that state has changed
    });

// Listen for a single state change then stop listening
myViewModel.myStateMachine.StateMachine
    .Single()
    .Subscribe(newState => {
       // Do something once
    });

Triggers (Collision, Physics etc)

Bind to various trigger and collision events.

Filter by the type of view specified.

Triggers.

this.BindViewTriggerWith<PlayerViewBase>(CollisionEventType.Enter, (_ )=> ExecutePlayerEntered() );

Collision events. Requires at least one non-kinematic rigidbody. http://docs.unity3d.com/ScriptReference/Collider.OnCollisionEnter.html

this.BindViewCollisionWith<PlayerViewBase>(CollisionEventType.Enter, (_ )=> ExecutePlayerEntered() );

Bind to various trigger and collision events, and subscribe to changes on the ViewModel of the object that entered your trigger.

On the view attached to your game object with the trigger:

this.BindViewTriggerWith<ThingyView>(CollisionEventType.Enter, _thingyView => ExecuteSubscribeToViewModel(_thingyView.ViewModelObject as ThingyViewModel));

this.BindViewTriggerWith<ThingyBarView>(CollisionEventType.Exit, _thingyView => ExecuteUnsubscribeFromThingy(_thingyView.ViewModelObject as ThingyViewModel));

In your element's controller:

public override void SubscribeToViewModel (ThisViewModel this, ThingyViewModel arg)
{
    base.SubscribeToThingy (this, arg);
		
    this.Thingy = arg;
    this.Thingy.StateProperty
    .Where(s => s == ThingyState.Dead)
    .Subscribe( _ => ExecuteCommand(this.Idle))
    .DisposeWhenChanged(this.ThingyProperty);
}
	
public override void UnsubscribeFromViewModel (ThisViewModel this, ThingyViewModel arg)
{
    base.UnsubscribeFromViewModel (this, arg);
		
    this.Thingy = null;
}