Skip to content

Latest commit

ย 

History

History
143 lines (99 loc) ยท 9.4 KB

File metadata and controls

143 lines (99 loc) ยท 9.4 KB

UniRx๋ฅผ ์ด์šฉํ•œ ์Šคํƒœ๋ฏธ๋‚˜ ์‹œ์Šคํ…œ์˜ ๊ตฌํ˜„

์ด ์˜ˆ์ œ๋Š” ๋‹คํฌ์†Œ์šธ์˜ ์Šคํƒœ๋ฏธ๋‚˜ ์‹œ์Šคํ…œ๊ณผ ์œ ์‚ฌํ•œ ์‹œ์Šคํ…œ ๊ตฌํ˜„์„ ์œ„ํ•ด ํ•„์š”ํ•œ RX์˜ ์—ฐ์‚ฐ๋“ค์˜ ์กฐํ•ฉ ๋ฐฉ๋ฒ•๊ณผ ์‚ฌ์šฉ์ž ์ •์˜ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ• ๋Œ€ํ•ด์„œ ์†Œ๊ฐœํ•˜๋Š” ๊ธ€๋กœ์จ ์•„๋ž˜์˜ ๋‚ด์šฉ๋“ค์„ ํฌํ•จํ•œ๋‹ค.

  • uGUI ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
  • Subject๋ฅผ ์ด์šฉํ•œ ๋ฉ”์‹œ์ง€ ํ†ต์ง€
  • ํ•˜๋‚˜ ์ด์ƒ์˜ Rx ์—ฐ์‚ฐ๋“ค์˜ ์กฐํ•ฉ(SkipUntil + TakeUntil + Repeat)

๊ตฌํ˜„ํ•œ ์‹œ์Šคํ…œ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘๋™ํ•œ๋‹ค.

  1. Action ๋ฒ„ํŠผ(๋‹คํฌ์†Œ์šธ์—์„œ์˜ ๊ณต๊ฒฉ, ๊ตฌ๋ฅด๊ธฐ ๋“ฑ)์„ ํด๋ฆญํ•˜๋ฉด ๋ฏธ๋ฆฌ ์ •ํ•œ ์–‘(amount)๋งŒํผ์˜ ์Šคํƒœ๋ฏธ๋‚˜๊ฐ€ ๊ฐ์†Œํ•œ๋‹ค.
  2. ์ผ์ • ์‹œ๊ฐ„(delay)์ด ์ง€๋‚œ ํ›„ ์Šคํƒœ๋ฏธ๋‚˜๋Š” ์ž๋™์œผ๋กœ ํšŒ๋ณต๋œ๋‹ค.
  3. ์Šคํƒœ๋ฏธ๋‚˜๊ฐ€ ํšŒ๋ณต์ค‘์— ๋‹ค์‹œ ์•ก์…˜์„ ์‹คํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ 2.๋ฅผ ๋ฐ˜๋ณตํ•œ๋‹ค.

Stamina-System

์ด๋ฅผ RX์—์„œ์˜ ์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆผ์˜ ๊ด€์ ์œผ๋กœ ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. ์•ก์…˜ ์ด๋ฒคํŠธ(์˜ˆ์ œ์—์„œ๋Š” Action ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ ๊ฒฝ์šฐ)๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ์Šคํƒœ๋ฏธ๋‚˜๋ฅผ ๊ฐ์†Œํ•œ ํ›„
  2. delay๋งŒํผ ๋Œ€๊ธฐ ํ›„์— ๊ฐ์†Œ ์ด๋ฒคํŠธ(= ์Šคํƒœ๋ฏธ๋‚˜ ํšŒ๋ณต ์‹œ์ž‘)๋ฅผ ํ†ต์ง€ํ•œ๋‹ค.
  3. ๊ฐ์†Œ ์ด๋ฒคํŠธ๋ฅผ ํ†ต์ง€ํ•˜๋ฉด ์Šคํƒœ๋ฏธ๋‚˜๋ฅผ ์ฑ„์šฐ๋Š” ์ŠคํŠธ๋ฆผ(ํšŒ๋ณต)์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
  4. ์Šคํƒœ๋ฏธ๋‚˜๋ฅผ ํšŒ๋ณตํ•˜๋Š” ๋„์ค‘์— ๋‹ค์‹œ ์•ก์…˜ ์ด๋ฒคํŠธ๊ฐ€ ํ†ต์ง€๋˜๋ฉด ๊ธฐ์กด์˜ ๋ฐ˜๋ณต์„ ์ค‘์ง€(์ค‘์š”!)ํ•œ ํ›„ 2. 3.์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
  5. ์Šคํƒœ๋ฏธ๋‚˜๋ฅผ ๋ชจ๋‘ ํšŒ๋ณตํ•˜๋ฉด (slider.value == 1) ์Šคํƒœ๋ฏธ๋‚˜ ๊ฐ์†Œ ์ด๋ฒคํŠธ๊ฐ€ ํ†ต์ง€๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•œ๋‹ค.

๋จผ์ € ์Šคํƒœ๋ฏธ๋‚˜์˜ ๊ฐ์†Œ์™€ ํšŒ๋ณต ์™„๋ฃŒ์— ๋Œ€ํ•œ ๋‘ ๊ฐ€์ง€ ์ด๋ฒคํŠธ ํ†ต์ง€๋ฅผ ์œ„ํ•œ ๋ฉ”์‹œ์ง€๊ฐ€ ํ•„์š”ํ•˜๋‹ค. RX์—์„œ ์ด์™€ ๊ฐ™์€ ์‚ฌ์šฉ์ž ์ •์˜ํ˜• ์ด๋ฒคํŠธ๋Š” Subject๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

    Subject<Slider> spStartSubject = new Subject<Slider>();
    Subject<Slider> spEndSubject = new Subject<Slider>();

๋‹ค์Œ์œผ๋กœ๋Š” ๋‘ Subject ๊ฐ์ฒด์— ๋Œ€ํ•œ Observable ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

    var spStartStream = spStartSubject.AsObservable();
    var spEndStream = spEndSubject.AsObservable();

์Šคํƒœ๋ฏธ๋‚˜์˜ ํšŒ๋ณต์€ spStartStream์ด ๋„์ฐฉํ•˜๋ฉด ํšŒ๋ณต์„ ์‹œ์ž‘ํ•œ๋‹ค. ํšŒ๋ณต ์ค‘์— spEndStream์ด ๋„์ฐฉํ•˜๋ฉด ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๋ฅผ ์™„๋ฃŒํ•œ๋‹ค. ์ด๋ฒคํŠธ A๊ฐ€ ์˜ฌ ๋•Œ๋ถ€ํ„ฐ ์ด๋ฒคํŠธ B๊ฐ€ ์˜ฌ ๋•Œ๊นŒ์ง€์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋Š” ์•„๋ž˜ RX ์—ฐ์‚ฐ ์กฐํ•ฉ์„ ์ด์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

SkipUntil + TakeUntil + Repeat

๊ฐ๊ฐ์˜ ์—ฐ์‚ฐ์— ๋Œ€ํ•ด์„œ๋Š” ์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ์กฐํ•˜์ž.

์Šคํƒœ๋ฏธ๋‚˜์˜ ํšŒ๋ณต์„ ์œ„ํ•œ recorveryStream ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

    var recoveryStream = Observable.EveryUpdate()
        .SkipUntil(spStartStream) // spStartStream ์ด๋ฒคํŠธ ํ†ต์ง€์‹œ๊นŒ์ง€ ๋Œ€๊ธฐ
        .Select( _ => slider.value )
        .TakeUntil(spEndStream)   // spEndStream ์ด๋ฒคํŠธ๊ฐ€ ํ†ต์ง€๋  ๋•Œ๊นŒ์ง€,
        .RepeatUntilDisable(this) // ๋ฐ˜๋ณต
        .Subscribe(v =>
            {
                // ์Šคํƒœ๋ฏธ๋‚˜๋ฅผ delta๋งŒํผ ํšŒ๋ณต
                slider.value += this.delta;

                // ์Šคํƒœ๋ฏธ๋‚˜ ํšŒ๋ณต์ด ์™„๋ฃŒ๋˜๋ฉด spEndSubject ์ด๋ฒคํŠธ ํ†ต์ง€๋กœ ์ŠคํŠธ๋ฆผ ์™„๋ฃŒ.
                // -> ๋‹ค์‹œ spStartStream ํ†ต์ง€๋ฅผ ๋Œ€๊ธฐํ•˜๋Š” ์ƒํƒœ๋กœ ์ „์ด.
                if (slider.value >= 1f)
                    spEndSubject.OnNext(slider); 
            });

MonoBehaviour์˜ Update ์‹œ๋งˆ๋‹ค ์ด๋ฒคํŠธ ํ†ต์ง€๋ฅผ ๊ฒ€์‚ฌํ•˜๊ธฐ ์œ„ํ•ด์„œ Observable.EveryUpdate()๋กœ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑํ•œ๋‹ค.

๋ฐ˜๋ณต์€ Repeat ์—ฐ์‚ฐ์œผ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•œ๋ฐ, ๋ฌดํ•œ๋ฃจํ”„์— ๋น ์ง€์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค. UniRx์—์„œ๋Š” ์ด๋ฅผ ์œ„ํ•ด์„œ RepeatSafe์™€ RepeatUntilDestroy(gameObject/component), RepeatUntilDisable(gameObject/component)์™€ ๊ฐ™์€ ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.(UniRx ReadMe ๋ฌธ์„œ ์ฐธ๊ณ ) ์—ฌ๊ธฐ์—์„œ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ disable ์ƒํƒœ์ผ ๋•Œ์—๋Š” ๋ฐ˜๋ณตํ•˜์ง€ ์•Š๋„๋ก RepeatUntilDisable ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ๋Š” uGUI์˜ UI ๊ฐ์ฒด๋“ค์˜ ์ด๋ฒคํŠธ๋ฅผ UniRx๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์‚ดํŽด ๋ณด์ž.

UniRx์—์„œ๋Š” UnityEvent.AsObservable๋ฅผ ํ†ตํ•ด์„œ uGUI์˜ UnityEvent๋“ค์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ์— ํ•  ์ˆ˜ ์žˆ๋‹ค.

Button์˜ ๊ฒฝ์šฐ Button ๊ฐ์ฒด์˜ OnClickAsObservable() ์„ ์‚ฌ์šฉํ•ด์„œ ํ•ด๋‹น ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ ๊ฒฝ์šฐ์— ๋Œ€ํ•œ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค.

    public Button actionButton;
    ...
        IDisposable cancel = null;

        var buttonStream = actionButton.OnClickAsObservable()
            .Subscribe(_ =>
            {
                Debug.Log("button click.");

                // ํšŒ๋ณต ๊ด€๋ จํ•ด์„œ ์ด๋ฏธ ์‹คํ–‰์ค‘์ธ ์ฝ”๋ฃจํ‹ด์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์‹คํ–‰์„ ์ข…๋ฃŒ.
                if (cancel != null)
                    cancel.Dispose(); 

                cancel = Observable.FromCoroutine(StartStaminaRecovery)
                                       .Subscribe();
            });

์Šคํƒœ๋ฏธ๋‚˜ ์†Œ๋ชจ์˜ ์‹œ์ž‘์„ Observable.FromCoroutine์„ ์‚ฌ์šฉํ•ด์„œ ์ฝ”๋ฃจํ‹ด ํ•จ์ˆ˜ StartStaminaRecovery๋ฅผ ํ†ตํ•ด์„œ ํ†ต์ง€ํ•œ ๊ฒƒ์€ ์Šคํƒœ๋ฏธ๋‚˜ ์†Œ๋ชจ๊ฐ€ ์ผ์–ด๋‚œ ์งํ›„ ๋ฐ”๋กœ recorveryStream์—์„œ ์Šคํƒœ๋ฏธ๋‚˜ ํšŒ๋ณต์„ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ delay๋งŒํผ ๋Œ€๊ธฐํ•œ ํ›„ spStartSubject๋กœ ์Šคํƒœ๋ฏธ๋‚˜ ํšŒ๋ณต ์‹œ์ž‘ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ํ†ต์ง€ ์ฒ˜๋ฆฌ๋ฅผ ์†์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.

    IEnumerator StartStaminaRecovery()
    {
        //  ์Šคํƒœ๋ฏธ๋‚˜๋ฅผ amount ๋งŒํผ ๊ฐ์†Œ.
        slider.value -= this.amount;

        // ํ˜„์žฌ ์Šคํƒœ๋ฏธ๋‚˜๊ฐ€ ํšŒ๋ณต์ค‘์ธ ๊ฒฝ์šฐ spEndSubject์˜ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด์„œ ํ˜„์žฌ ํšŒ๋ณต์ค‘(repeat)์ธ ์ƒํƒœ๋ฅผ ์ค‘์ง€ํ•˜๋„๋ก ํ•œ๋‹ค.
        spEndSubject.OnNext(slider);

        // delay ์‹œ๊ฐ„๋งŒํผ ๋Œ€๊ธฐ.
        yield return new WaitForSeconds(this.delay);

        // ์Šคํƒœ๋ฏธ๋„ˆ ํšŒ๋ณต ์ด๋ฒคํŠธ ํ†ต์ง€
        spStartSubject.OnNext(slider);
    }    

๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์„œ StartStaminaRecovery ์ฝ”๋ฃจํ‹ด ํ•จ์ˆ˜๊ฐ€ ์ด๋ฏธ ํ•˜๋‚˜ ์‹คํ–‰ ์ค‘์ธ ๊ฒฝ์šฐ๋ฅผ ์ƒ๊ฐํ•ด ๋ณด์ž. ์ฝ”๋ฃจํ‹ด ํ•จ์ˆ˜๋Š” ์ฃผ์–ด์ง„ delay๋งŒํผ ๋Œ€๊ธฐ ์ค‘์ธ ์ƒํƒœ๋กœ ์•„์ง spStartSubject.OnNext(slider)๋กœ ํšŒ๋ณต ์ด๋ฒคํŠธ๋Š” ํ†ต์ง€ํ•˜๊ธฐ ์ „์ด๋‹ค. ์ด ๋•Œ ๋‹ค์‹œ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ์„œ StartStaminaRecovery ์ฝ”๋ฃจํ‹ด ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ ๊ฒฝ์šฐ๋ฅผ ๊ฐ€์ •ํ•ด ๋ณด์ž. ์ฒซ ๋ฒˆ์งธ ์‹คํ–‰ํ•œ ์ฝ”๋ฃจํ‹ด ํ•จ์ˆ˜์—์„œ delay๋งŒํผ ๋Œ€๊ธฐ ํ›„์— ํšŒ๋ณต ์ด๋ฒคํŠธ๋ฅผ ํ†ต์ง€ํ•˜๊ณ  ๊ทธ ๋’ค์— ์‹คํ–‰ํ•œ ์ฝ”๋ฃจํ‹ด ํ•จ์ˆ˜์—์„œ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ delay๋งŒํผ ๋Œ€๊ธฐ ํ›„ ํšŒ๋ณต ์ด๋ฒคํŠธ๋ฅผ ํ†ต์ง€ํ•  ๊ฒƒ์ด๋‹ค. ๋‘ ๋ฒˆ์งธ ํšŒ๋ณต ์ด๋ฒคํŠธ๋ฅผ ํ†ต์ง€ํ•  ๋•Œ์—๋Š” ์ด๋ฏธ ์Šคํƒœ๋ฏธ๋‚˜๋ฅผ ํšŒ๋ณต ์ค‘์ธ ์ƒํƒœ์ด๊ณ  ๋‘ ๋ฒˆ์งธ ์ด๋ฒคํŠธ๋„ recoveryStream์— ํ†ต์ง€ํ•˜๋ฉด ํšŒ๋ณต์„ ์‹œ์ž‘ํ•˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋ฒ„ํŠผ์„ ์—ฐํƒ€ํ•ด์„œ ์—ฐ์†ํ•œ ํšŒ๋ณต ์ด๋ฒคํŠธ๋ฅผ ํ†ต์ง€ํ•˜๋Š” ๊ฒฝ์šฐ recoveryStream ์ŠคํŠธ๋ฆผ์— ํšŒ๋ณต ์ด๋ฒคํŠธ๊ฐ€ ์Œ“์—ฌ์„œ ์˜๋„ํ•œ๋Œ€๋กœ ํšŒ๋ณต ์‹œ์Šคํ…œ์ด ์ž‘๋™ํ•˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค. ์›๋ž˜ ์˜๋„ํ•œ ํšŒ๋ณต ์‹œ์Šคํ…œ์˜ ์ž‘๋™์€ ์•ก์…˜์ด ๋ฐœ์ƒํ•˜๋ฉด ์ •ํ•ด์ง„ ์Šคํƒœ๋ฏธ๋‚˜๋งŒํผ ๊ฐ์†Œํ•˜๊ณ  delay๋งŒํผ ๊ธฐ๋‹ค๋ฆฐํ›„ ์ž๋™์œผ๋กœ ํšŒ๋ณต์„ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ recoveryStream์— ์ด๋ฒคํŠธ๊ฐ€ ์•ƒ์ด๋ฉด delay๋งŒํผ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ํšŒ๋ณต๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ๋œ๋‹ค. ์ด๋Ÿฐ ์˜ค๋™์ž‘์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ฝ”๋ฃจํ‹ด ํ•จ์ˆ˜์˜ Observable์ด ์ด๋ฏธ ์žˆ๋Š”์ง€๋ฅผ ๊ฒ€์‚ฌํ•ด์„œ ์‹คํ–‰์ค‘์ธ ์ฝ”๋ฃจํ‹ด ํ•จ์ˆ˜๊ฐ€ ์žˆ์œผ๋ฉด Dispose๋กœ ํ•ด์ œํ•˜๋„๋ก ํ–ˆ๋‹ค.

    IDisposable cancel = null;
    ...
        // ๋ฐ”๋กœ ์ฝ”๋ฃจํ‹ด ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฒ€์‚ฌํ•ด์„œ Dispose๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ด์œ 
        if (cancel != null)
            cancel.Dispose(); 

            cancel = Observable.FromCoroutine(StartStaminaRecovery)
                               .Subscribe();

์ด๋ ‡๊ฒŒ ๋ฒ„ํŠผ์ด ๋ˆŒ๋Ÿฌ์งˆ ๋•Œ๋งˆ๋‹ค ์‹คํ–‰ ์ค‘์ธ ์ฝ”๋ฃจํ‹ดํ•จ์ˆ˜๊ฐ€ ์žˆ์œผ๋ฉด ๊ฐ•์ œ๋กœ ์ข…๋ฃŒํ•œ ํ›„ ์ƒˆ๋กœ์šด ์ฝ”๋ฃจํ‹ด ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์˜๋„ํ•œ ๋Œ€๋กœ ํšŒ๋ณต ์‹œ์Šคํ…œ์ด ์ž‘๋™ํ•œ๋‹ค.

์‹ค์ œ ๊ฒŒ์ž„์— ์ ์šฉํ•  ๋•Œ์—๋Š” ์Šฌ๋ผ์ด๋“œ์˜ ๊ฐ’์„ ๋ฐ”๋กœ ๋ณ€๊ฒฝํ•˜์ง€ ๋ง๊ณ  ํ”Œ๋ ˆ์ด์–ด ์บ๋ฆญํ„ฐ์˜ ์Šคํƒœ๋ฏธ๋‚˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋„๋ก ํ•˜๊ณ  ์Šฌ๋ผ์ด๋“œ๋Š” ํ”Œ๋ ˆ์ด์–ด ์บ๋ฆญํ„ฐ์˜ ์Šคํƒœ๋ฏธ๋‚˜ ๊ฐ’๊ณผ Bindingํ•ด ๋‘์–ด์„œ ํ”Œ๋ ˆ์ด์–ด ์บ๋ฆญํ„ฐ์˜ ์Šคํƒœ๋ฏธ๋‚˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ๋•Œ๋งˆ๋‹ค ์Šฌ๋ผ์ด๋“œ์˜ ๊ฐ’์—๋„ ๋ณ€๊ฒฝ๋œ ๊ฐ’์ด ์ž๋™์œผ๋กœ ๋ฐ˜์˜๋˜๋„๋ก ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. UniRx์—์„œ๋Š” ์ด๋Ÿฌํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ReactiveProperty๋ฅผ ์ œ๊ณตํ•˜๊ณ  ์žˆ์œผ๋‹ˆ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋‹ค.

๋˜ํ•œ ์˜ˆ์ œ์—์„œ๋Š” Observable.EveryUpdate()์„ ์‚ฌ์šฉํ•ด์„œ ๋งคํ”„๋ ˆ์ž„๋งˆ๋‹ค ์ •ํ•ด์ง„ ์–‘๋งŒํผ ์Šคํƒœ๋ฏธ๋‚˜๋ฅผ ํšŒ๋ณตํ•˜๋„๋ก ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ์ง€๋งŒ ๋‹คํฌ์†Œ์šธ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด ๋ ˆ๋ฒจ์ด๋‚˜ ๊ด€๋ จ ์•„์ดํ…œ์˜ ์ฐฉ์šฉ ์œ ๋ฌด์— ๋”ฐ๋ผ ์ •ํ•ด์ง„ ์ดˆ๋‹น ์Šคํ…Œ๋ฏธ๋‚˜ ์ฆ๊ฐ€๋Ÿ‰์„ ์ด์šฉํ•ด์„œ ํšŒ๋ณตํ•˜๋„๋ก ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ํ”„๋ ˆ์ž„๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ ์ฃผ์–ด์ง„ ์‹œ๊ฐ„์— ์Šคํƒœ๋ฏธ๋‚˜๊ฐ€ ํšŒ๋ณตํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๋ณ€๊ฒฝํ•ด์•ผ ํ•  ๊ฒƒ์ด๋‹ค. ๋ฐ”๊พธ์–ด ๋งํ•˜๋ฉด ํ”„๋ ˆ์ž„์— ๋…๋ฆฝ์ ์ธ ๋ฐฉ๋ฒ•์„ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ด์•ผ๊ธฐ์ด๋‹ค.