Programação reativa para desenvolvedores de jogos: uma introdução

Oi, Habr. Convidamos futuros alunos do curso "Unity Game Developer. Professional" a participarem de um webinar aberto sobre o tema "Inteligência artificial avançada de inimigos em atiradores" .



Também oferecemos a tradução de um artigo interessante para leitura.










Se você é um desenvolvedor de jogos e ainda não ouviu falar em programação reativa, pare seu negócio e leia este artigo. Eu não estou brincando.





Não se distraia com gatinhos. Leia sobre a programação reativa!





Então eu chamei sua atenção?





Excelente! Vou fazer o meu melhor para não perdê-lo.





O que é programação reativa?

Não vou cansá-lo do nada com uma descrição de alto nível do que é a programação reativa, como ela surgiu e por que é tão importante para cada um de nós. Vou começar com coisas muito mais práticas.





, 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



.





Isso parece incrível, mas infelizmente não estamos falando sobre esse fluxo de valores.
, , ,

— , ? , , , - .





, , , - , :





? !





, ?





, , 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