기본 콘텐츠로 건너뛰기

연구중.....

R3는 나중에 ...


UniTask


ReactiveProperty


예제 참고 : https://github.com/neuecc/UniRx?tab=readme-ov-file#reactiveproperty-reactivecollection 또는 Sample12_ReactiveProperty 코드 예제


Sample12_ReactiveProperty.cs


using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
 
namespace UniRx
{
    public class Sample12_ReactiveProperty : MonoBehaviour
    {
        public Button MyButton;
        public Toggle MyToggle;
        public TMP_InputField MyInput;
        public TextMeshProUGUI MyText;
        public Slider MySlider;
 
        // You can monitor/modifie in inspector by SpecializedReactiveProperty
        public IntReactiveProperty IntRxProp = new IntReactiveProperty();
 
        Enemy enemy = new Enemy(1000);
 
        // On Start, you can write reactive rules for declaretive/reactive ui programming
        void Start()
        {
            // UnityEvent as Observable
            // (shortcut, MyButton.OnClickAsObservable())
            MyButton.OnClickAsObservable().Subscribe(_ => enemy.CurrentHp.Value -= 99);
 
            // Toggle, Input etc as Observable (OnValueChangedAsObservable is a helper providing isOn value on subscribe)
            // SubscribeToInteractable is an Extension Method, same as .interactable = x)
            MyToggle.OnValueChangedAsObservable().SubscribeToInteractable(MyButton);
 
            // Input is displayed after a 1 second delay
            MyInput.OnValueChangedAsObservable()
                .Where(x => x != null)
                .Delay(TimeSpan.FromSeconds(1))
                .SubscribeToText(MyText); // SubscribeToText is helper for subscribe to text
 
            // Converting for human readability
            MySlider.OnValueChangedAsObservable()
                .SubscribeToText(MyText, x => Math.Round(x, 2).ToString());
 
            // from RxProp, CurrentHp changing(Button Click) is observable
            enemy.CurrentHp.SubscribeToText(MyText);
            enemy.IsDead.Where(isDead => isDead == true)
                .Subscribe(_ => { MyToggle.interactable = MyButton.interactable = false; });
 
            // initial text:)
            IntRxProp.SubscribeToText(MyText);
        }
    }
 
    // Reactive Notification Model
    public class Enemy
    {
        public IReactiveProperty<long> CurrentHp { get; private set; }
 
        public IReadOnlyReactiveProperty<bool> IsDead { get; private set; }
 
        public Enemy(int initialHp)
        {
            // Declarative Property
            CurrentHp = new ReactiveProperty<long>(initialHp);
            IsDead = CurrentHp.Select(x => x <= 0).ToReactiveProperty();
        }
    }
}
 
cs


원본 코드의 경우 TextMeshPro를 사용하지 않기 때문에 아래와 같이 TextMeshPro용 코드를 별도로 추가해야한다. 
코드 원본 : UnityUIComponentExtensions.cs


using System;
using TMPro;
 
namespace UniRx
{
    /// <summary>
    /// 
    /// </summary>
    /// <see cref="UnityUIComponentExtensions"/>
    public static class UnityUIExtensions
    {
        public static IDisposable SubscribeToText(this IObservable<string> source, TextMeshProUGUI text)
        {
            return source.SubscribeWithState(text, (x, t) => t.text = x);
        }
 
        public static IDisposable SubscribeToText<T>(this IObservable<T> source, TextMeshProUGUI text)
        {
            return source.SubscribeWithState(text, (x, t) => t.text = x.ToString());
        }
 
        public static IDisposable SubscribeToText<T>(this IObservable<T> source, TextMeshProUGUI text,
            Func<T, string> selector)
        {
            return source.SubscribeWithState2(text, selector, (x, t, s) => t.text = s(x));
        }
 
        /// <summary>Observe onEndEdit(Submit) event.</summary>
        public static IObservable<string> OnEndEditAsObservable(this TMP_InputField inputField)
        {
            return inputField.onEndEdit.AsObservable();
        }
 
        public static IObservable<string> OnValueChangedAsObservable(this TMP_InputField inputField)
        {
            return Observable.CreateWithState<string, TMP_InputField>(inputField, (i, observer) =>
            {
                observer.OnNext(i.text);
                return i.onValueChanged.AsObservable().Subscribe(observer);
            });
        }
    }
}
cs


코드 내용

  • 버튼
    • MyToggle의 On/Off → MyButton.interactable true/false
    • Enemy의 HP 값은 MyText에 표시
    • 1000으로 초기화된 Enemy의 HP값은 MyButton 클릭마다 -99 만큼 차감
    • Enemy의 HP 값이 0 보다 같거나 작아지면, MyToggle 및 MyButton interactable 값을 false처리
  • MySlider의 값을 MyText에 표시
  • MyInput이 입력 값을 1초 후에 MyText에 표시
 



WaitUntil, WaitWhile

WaitUntil

  • 사용 방법: yield return new WaitUntil(predicate); 
  • 동작 원리: predicate 람다 표현식이 true를 반환할 때까지 코루틴의 실행을 일시 중지합니다.
  • 사용 예시: 어떤 변수가 특정 값을 가질 때까지 기다릴 때 사용합니다. 
    • 예: yield return new WaitUntil(() => myVariable == true);
    • 적용 사례: 조건이 true가 될 때까지 기다림 (예: 로딩이 완료되거나, 플레이어가 특정 지점에 도달할 때까지 기다림).

WaitWhile

  • 사용 방법: yield return new WaitWhile(predicate);
  • 동작 원리: predicate 람다 표현식이 false를 반환할 때까지 코루틴의 실행을 일시 중지합니다.
  • 사용 예시: 어떤 조건이 더 이상 참이 아닐 때까지 기다릴 때 사용합니다.
    • 예: yield return new WaitWhile(() => myVariable == true);
    • 적용 사례: 조건이 false가 될 때까지 기다림 (예: 특정 상태가 더 이상 유효하지 않을 때까지 기다림).
 

결론

WaitUntil은 조건이 true가 되기를 기다립니다. WaitWhile은 조건이 false가 되기를 기다립니다. 두 명령 모두 매 프레임마다 조건을 평가하며, 해당 조건이 충족되면 코루틴의 실행을 계속합니다. 사용하는 시나리오와 조건에 따라 적절한 명령을 선택하여 사용하면 됩니다.














댓글