๋ฐ˜์‘ํ˜•

๐Ÿงฉ Unity ๋””์ž์ธ ํŒจํ„ด - ์ค‘์žฌ์ž(Mediator) ํŒจํ„ด

1. ์ค‘์žฌ์ž ํŒจํ„ด์ด๋ž€?

์ค‘์žฌ์ž(Mediator) ํŒจํ„ด์€ ๊ฐ์ฒด ๊ฐ„์˜ ์ง์ ‘์ ์ธ ์†Œํ†ต์„ ํ”ผํ•˜๊ณ , ๋ชจ๋“  ํ†ต์‹ ์„ ์ค‘์•™ ๊ด€๋ฆฌ์ž(์ค‘์žฌ์ž)๋ฅผ ํ†ตํ•ด ์ง„ํ–‰ํ•˜๋„๋ก ์„ค๊ณ„ํ•˜๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

"A์™€ B๊ฐ€ ์„œ๋กœ๋ฅผ ๋ชฐ๋ผ๋„, ์ค‘์žฌ์ž์—๊ฒŒ๋งŒ ๋งํ•˜๋ฉด ํ•„์š”ํ•œ ์—ฐ๊ฒฐ์ด ์ž๋™์œผ๋กœ ์ด๋ค„์ง€๋Š” ๊ตฌ์กฐ"์ž…๋‹ˆ๋‹ค.


2. ์–ธ์ œ ์‚ฌ์šฉํ•˜๋‚˜์š”?

  • UI ์š”์†Œ๋‚˜ ์‹œ์Šคํ…œ ๊ฐ„ ์ƒํ˜ธ์ž‘์šฉ์ด ๋งŽ๊ณ  ๋ณต์žกํ•  ๋•Œ
  • ๊ฐ์ฒด ๊ฐ„ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๊ณ  ์‹ถ์„ ๋•Œ
  • Observer ํŒจํ„ด๋ณด๋‹ค ๋” ๋„“์€ ๋ฒ”์œ„์˜ ์ œ์–ด๊ฐ€ ํ•„์š”ํ•  ๋•Œ

3. ๊ตฌ์กฐ ๊ตฌ์„ฑ์š”์†Œ

์—ญํ•  ์„ค๋ช…
IMediator ์ค‘์žฌ์ž ์ธํ„ฐํŽ˜์ด์Šค
ConcreteMediator ์‹ค์ œ ์ด๋ฒคํŠธ๋ฅผ ์ค‘๊ณ„ํ•˜๋Š” ํด๋ž˜์Šค
Participant ์ค‘์žฌ์ž์—๊ฒŒ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋Š” ๊ตฌ์„ฑ์› ๊ฐ์ฒด

4. Unity ์˜ˆ์ œ: ๋ฒ„ํŠผ ๋ˆ„๋ฅด๋ฉด ์—ฌ๋Ÿฌ ์‹œ์Šคํ…œ์— ๋ช…๋ น ์ „ํŒŒ

๐Ÿ’ฌ Step 1: IMediator ์ธํ„ฐํŽ˜์ด์Šค

public interface IMediator
{
    void Notify(string eventKey, object data = null);
}

๐Ÿง  Step 2: ConcreteMediator ํด๋ž˜์Šค

using System;
using System.Collections.Generic;

public class GameMediator : IMediator
{
    private Dictionary<string, Action<object>> listeners = new();

    public void Register(string eventKey, Action<object> callback)
    {
        if (!listeners.ContainsKey(eventKey))
            listeners[eventKey] = delegate { };

        listeners[eventKey] += callback;
    }

    public void Unregister(string eventKey, Action<object> callback)
    {
        if (listeners.ContainsKey(eventKey))
            listeners[eventKey] -= callback;
    }

    public void Notify(string eventKey, object data = null)
    {
        if (listeners.TryGetValue(eventKey, out var callback))
            callback?.Invoke(data);
    }
}

๐Ÿ“ฆ Step 3: MediatorProvider (์‹ฑ๊ธ€ํ†ค ๋“ฑ๋ก์†Œ)

public static class MediatorProvider
{
    public static GameMediator Mediator = new();
}

๐Ÿงฑ Step 4: Button ํด๋ฆญ → ์ค‘์žฌ์ž์—๊ฒŒ ์•Œ๋ฆผ

using UnityEngine;

public class UIButton : MonoBehaviour
{
    public void OnClick()
    {
        MediatorProvider.Mediator.Notify("PlayClicked", "๊ฒŒ์ž„ ์‹œ์ž‘!");
    }
}

๐Ÿ–ฅ๏ธ Step 5: UIManager๊ฐ€ ์ด๋ฒคํŠธ ์ˆ˜์‹ 

using UnityEngine;

public class UIManager : MonoBehaviour
{
    private void OnEnable()
    {
        MediatorProvider.Mediator.Register("PlayClicked", OnPlayClicked);
    }

    private void OnDisable()
    {
        MediatorProvider.Mediator.Unregister("PlayClicked", OnPlayClicked);
    }

    private void OnPlayClicked(object data)
    {
        Debug.Log($"UIManager ์ˆ˜์‹ : {data}");
        // ์˜ˆ: ํƒ€์ดํ‹€ ํ™”๋ฉด ์ˆจ๊ธฐ๊ธฐ
    }
}

5. ์ •๋ฆฌ ๋ฐ ์žฅ๋‹จ์ 

โœ… ์žฅ์ 

  • ๊ฐ์ฒด ๊ฐ„ ์ง์ ‘ ์ฐธ์กฐ ์—†์ด ์ƒํ˜ธ์ž‘์šฉ ๊ฐ€๋Šฅ → ๊ฒฐํ•ฉ๋„ ↓
  • ๋™์ ์œผ๋กœ ๊ตฌ๋…/ํ•ด์ œ ๊ฐ€๋Šฅ
  • ๋ณต์žกํ•œ ์‹œ์Šคํ…œ ๊ฐ„ ํ†ต์‹  ๊ตฌ์กฐ ๋‹จ์ˆœํ™”

โŒ ๋‹จ์ 

  • ๋ชจ๋“  ํ†ต์‹ ์ด ์ค‘์žฌ์ž๋ฅผ ๊ฑฐ์น˜๊ธฐ ๋•Œ๋ฌธ์—, ์ค‘์žฌ์ž๊ฐ€ ๋น„๋Œ€ํ•ด์งˆ ์ˆ˜ ์žˆ์Œ
  • ๋””๋ฒ„๊น… ์‹œ ํ๋ฆ„ ์ถ”์ ์ด ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ์Œ

โœ… ๋งˆ๋ฌด๋ฆฌ ํ•œ ์ค„ ์š”์•ฝ

์ค‘์žฌ์ž ํŒจํ„ด์€ ๋ชจ๋“  ๊ฐ์ฒด๊ฐ€ ์„œ๋กœ๋ฅผ ๋ชฐ๋ผ๋„, ํ•˜๋‚˜์˜ ์ฐฝ๊ตฌ๋งŒ ์•Œ๋ฉด ํ˜‘๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” ์„ค๊ณ„๋กœ, ๋ณต์žกํ•œ ์‹œ์Šคํ…œ ๊ตฌ์กฐ๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•