Reactive Programming for Game Developers: An Introduction

Hello, Habr. We invite future students of the "Unity Game Developer. Professional" course to take part in an open webinar on the topic "Advanced artificial intelligence of enemies in shooters" .



We also offer translation of an interesting article for reading.










If you are a game developer and haven’t heard of reactive programming yet, drop your business and read this article. I am not kidding.





Don't be distracted by kittens. Read about reactive programming!





So I got your attention?





Excellent! I will do my best not to lose him.





What is Reactive Programming?

, , . .





, Unity, β€” . , β€” . , .





?





, Player!





, ?





Rocket!





, ?





. Level.





? , , . , , .





Glue Code ( ) β€” …





, , , . , , , (UI). ?





, ? , Player (label) UI UI , ?





. , ?





? Level UI , .





, , .





, Player, ?





, ? , , , .





, … …





…





!

, . , .





, Unity C# . , . .





: , - , , .





, C# β€” . , , . , , , .





β€” , Unity C# (Reactive Extensions) Unity (UniRx).





!





. !





Player



, :





 using UnityEngine;
 using UnityEngine.UI;
 
 public class Player : MonoBehaviour {
   public int health = 100;
   public Text scoreLabel;
 
   public void ApplyDamage(int damage) {
     health -= damage;
     scoreLabel.text = health.ToString();
   }
 }
      
      



- , , «» (glue) , (  β€œsticky”).





using UnityEngine;
 using UnityEngine.UI;
 
 public class Player : MonoBehaviour {
   public int health = 100;
   public Text scoreLabel;
 
   public void ApplyDamage(int damage) {
     health -= damage;
     scoreLabel.text = health.ToString();
   }
 }
      
      



! .





, :





 using UnityEngine;
 using UnityEngine.UI;
 using UniRx;
 
 public class Player : MonoBehaviour {
   public ReactiveProperty<int> health 
     = new ReactiveProperty<int>(100);
 
   public void ApplyDamage(int damage) {
     health.Value -= damage;
   }
 }
      
      



? - . ReactiveProperty



.





, , , ( , ). , , , .





ReactiveProperty

, UiPresenter



:





using UnityEngine;
 using UnityEngine.UI;
 using UniRx;
 
 public class UiPresenter : MonoBehaviour {
   public Player player;
 
   public Text scoreLabel;
 
   void Start() {
     player.health.SubscribeToText(scoreLabel);
   }
 }
      
      



scoreLabel



. -, ?





, .





, , - , , ? ?





! , , , . , .





, , , ( ). ReactiveProperty



. , , ( , β€” , ?).





? ReactiveProperty? , .





ReactiveProperty β€” Observable



( β€œ), , Reactive Properties



. Observable



.





This looks amazing, but unfortunately we are not talking about such a stream of values.
, , ,

β€” , ? , , , - .





, , , - , :





? !





, ?





, , Observable



!





6 Observable



!





, , Observable



, . , , β€” -Observable



«» (emit) . . X :





, observable



β€” . ?





, , observable



, , .





: , , . β€” β€” , . - :





, , , :





all_balls_in_order = Observable.Merge(h1, h2, h3, h4, h5, h6);
      
      



, . . , - . , , , . .





: .





!

, . , .





. , , , , .





all_balls_delayed = Observable.Merge(
  h1.Delay(
    TimeSpan.FromSeconds(1)
  ), 
  h2.Delay(
    TimeSpan.FromSeconds(2)
  ), 
  h3.Delay(
    TimeSpan.FromSeconds(3)
  ), 
  h4.Delay(
    TimeSpan.FromSeconds(3)
  ), 
  h5.Delay(
    TimeSpan.FromSeconds(2)
  ), 
  h6.Delay(
    TimeSpan.FromSeconds(1)
  )
);
      
      



, ?





?





rxmarbles.com , .





UI

, UI, - ? !





. , observable



, , . , UiPresenter



:





using UnityEngine;
 using UnityEngine.UI;
 using UniRx;
 
 public class UiPresenter : MonoBehaviour {
   public Player player;
 
   public Text scoreLabel;
 
   void Start() {
     player.health
       .Select(health => string.Format("Health: {0}", health))
       .Subscribe(text => scoreLabel.text = text);
   }
 }
      
      



Select



( rxmarbles



map



). . ( ) .





, , β€” . , , ?





Subscribe



, . , . SubscribeToText



, , β€” , .





, , . :





using UnityEngine;
 using UnityEngine.UI;
 using UniRx;
 
 public class UiPresenter : MonoBehaviour {
   public Player player;
 
   public Text scoreLabel;
   public Animator animator;
 
   void Start() {
     player.health
       .Select(health => string.Format("Health: {0}", health))
       .Do(x => animator.Play("Flash"))
       .Subscribe(text => scoreLabel.text = text);
   }
 }
      
      



, ? , , , Do



, .





, , β€” () :





using UnityEngine;
 using UnityEngine.UI;
 using UniRx;
 
 public class UiPresenter : MonoBehaviour {
   public ReactiveProperty<Player> player 
     = new ReactiveProperty<Player>();
 
   public Text scoreLabel;
   public Animator animator;
 
   void Start() {
     var playerHealth = this.player
       .Where(player => player != null)
       .Select(player => player.health);
 
     playerHealth
       .Select(health => string.Format("Health: {0}", health))
       .Do(x => animator.Play("Flash"))
       .Subscribe(text => scoreLabel.text = text);
   }
 }
      
      



? ReactiveProperty



, . , , .





, , , .





,





, , , . , , , . Unity UniRx.





rxmarbles.com, , . , UniRx (map



, , Select



UniRx).





Β« , Β» β€” .





!






"Unity Game Developer. Professional".



" ".












All Articles