ํฌ์ŠคํŠธ

๐Ÿ” Unity ์–ด์…ˆ๋ธ”๋ฆฌ ์ˆœํ™˜ ์ฐธ์กฐ, ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ• ๊นŒ?

EventBus ๊ธฐ๋ฐ˜ ๊ตฌ์กฐ๋กœ ์™„์ „ํžˆ ๋””์ปคํ”Œ๋งํ•˜๋Š” ๋ฐฉ๋ฒ•


๐Ÿงฉ ๋ฌธ์ œ ๋ฐฐ๊ฒฝ Unity ํ”„๋กœ์ ํŠธ์—์„œ .asmdef(Assembly Definition) ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋ฉด, ๋ชจ๋“ˆ ๊ฐ„ ์˜์กด์„ฑ์„ ๋ช…ํ™•ํžˆ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๊ณ  ๋ชจ๋“ˆ์ด ๋‚˜๋‰˜๋‹ค ๋ณด๋ฉด ํ•„์—ฐ์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค:

โœ… A ๋ชจ๋“ˆ์—์„œ B๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์‹ถ์€๋ฐ, โŒ B๋„ A๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์–ด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ƒํ™ฉ

๋Œ€ํ‘œ์ ์ธ ์˜ˆ๊ฐ€ **Core์™€ Services ๊ฐ„์˜ ์ˆœํ™˜ ์ฐธ์กฐ ๋ฌธ์ œ**์ž…๋‹ˆ๋‹ค.


  • Core ์–ด์…ˆ๋ธ”๋ฆฌ: ์ „์ฒด ์‹œ์Šคํ…œ์˜ ์ค‘์‹ฌ ๋กœ์ง, ๊ด€๋ฆฌ ํด๋ž˜์Šค
  • Services ์–ด์…ˆ๋ธ”๋ฆฌ: ๊ฐœ๋ณ„ ๊ธฐ๋Šฅ ๋ชจ๋“ˆ (์˜ˆ: UserService, GameLogicService)
  • App ์–ด์…ˆ๋ธ”๋ฆฌ: ์ดˆ๊ธฐ ์‹คํ–‰, UI, ์”ฌ ์ œ์–ด ๋“ฑ
1
2
CS0234: The type or namespace name 'Services' does not exist in the namespace 'MyProject'


๐ŸŽฏ ํ•ด๊ฒฐ ์ „๋žต: EventBus๋ฅผ ํ†ตํ•œ ์™„์ „ํ•œ ๋””์ปคํ”Œ๋ง ์„œ๋น„์Šค๋“ค์„ ์ง์ ‘ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ , ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ ๋ฐฉ์‹(EventBus)** ์„ ์‚ฌ์šฉํ•ด** ๋ชจ๋“ˆ ๊ฐ„์˜ ์ง์ ‘์ ์ธ ์˜์กด์„ฑ์„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.


๐Ÿงฑ ๊ตฌ์กฐ ์ „ํ™˜ ์ „/ํ›„ ๋น„๊ต

๊ตฌ์กฐBeforeAfter (EventBus ๋ฐฉ์‹)
์˜์กด์„ฑCore โ†’ Services ์ง์ ‘ ์ฐธ์กฐCore โ†’ EventBus, Services โ†’ EventBus
ํ˜ธ์ถœ ๋ฐฉ์‹์ง์ ‘ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์ด๋ฒคํŠธ ๋ฐœํ–‰ ๋ฐ ๊ตฌ๋…
ํ…Œ์ŠคํŠธ์„ฑ์–ด๋ ค์›€์‰ฌ์›€ (๋ชจ๋“ˆ ๋…๋ฆฝ)
ํ™•์žฅ์„ฑ๋‚ฎ์Œ (์˜์กด์„ฑ ์ฆ๊ฐ€)๋†’์Œ (๊ตฌ๋…๋งŒ ํ•˜๋ฉด ๋จ)

๐Ÿ”ง ํ•ต์‹ฌ ๊ตฌํ˜„ ์š”์†Œ โœ… 1. EventBus ์‹œ์Šคํ…œ

1
2
3
4
5
6
7
8
public static class EventBus {
    private static Dictionary _handlers = new();

    public static void Subscribe(Action listener) { ... }
    public static void Unsubscribe(Action listener) { ... }
    public static void Publish(T evt) { ... }
}

โœ… 2. ์„œ๋น„์Šค ๊ด€๋ จ ์ด๋ฒคํŠธ ์ •์˜

1
2
3
4
public struct ServiceInitializeRequestEvent {}
public struct ServiceInitializedEvent {}
public struct ServiceQueryRequestEvent { public Action callback; }


๐Ÿงฉ ๊ตฌ์กฐ ํ๋ฆ„ ์˜ˆ์‹œ โ–ถ ์„œ๋น„์Šค ์ดˆ๊ธฐํ™” ์š”์ฒญ

1
2
3
// Core์—์„œ ๋ฐœํ–‰
EventBus.Publish(new ServiceInitializeRequestEvent());

1
2
3
4
5
6
// ๊ฐ ์„œ๋น„์Šค์—์„œ ๊ตฌ๋…
EventBus.Subscribe(() => {
    InitializeSelf();
    EventBus.Publish(new ServiceInitializedEvent());
});


โ–ถ ํŠน์ • ์„œ๋น„์Šค ์กฐํšŒ ์š”์ฒญ

1
2
3
4
5
// App์—์„œ ์„œ๋น„์Šค ์š”์ฒญ
EventBus.Publish(new ServiceQueryRequestEvent {
    callback = service => { _userService = service; }
});

1
2
3
4
5
// ์„œ๋น„์Šค์—์„œ ๊ตฌ๋… ํ›„ ์‘๋‹ต
EventBus.Subscribe>(evt => {
    evt.callback?.Invoke(this);
});


โœ… ์ตœ์ข… ๊ตฌ์กฐ

1
2
3
4
5
6
7
Assets/
โ”œโ”€โ”€ Core/                 โ† Core.asmdef
โ”œโ”€โ”€ Services/             โ† Services.asmdef
โ”œโ”€โ”€ UI/                   โ† UI.asmdef
โ”œโ”€โ”€ EventBus/             โ† EventBus.asmdef
โ”œโ”€โ”€ App/                  โ† App.asmdef

์–ด์…ˆ๋ธ”๋ฆฌ์ฐธ์กฐ ๋Œ€์ƒ
Coreโœ… EventBus
Servicesโœ… EventBus
UIโœ… EventBus
Appโœ… EventBus
EventBusโŒ ์•„๋ฌด ๊ฒƒ๋„ ์ฐธ์กฐ ์•ˆ ํ•จ

  • Core โ†” Services โ†” UI ์‚ฌ์ด ๋ณต์žกํ•œ ํ˜ธ์ถœ์ด ์–ฝํžˆ๊ธฐ ์‹œ์ž‘ํ•  ๋•Œ
  • ์—ฌ๋Ÿฌ ์„œ๋น„์Šค๊ฐ€ ํ•œ ๊ด€๋ฆฌ์ž์˜ ํ˜ธ์ถœ์„ ๋ฐ›์•„์•ผ ํ•  ๋•Œ
  • ์„œ๋น„์Šค ๊ฐ„ ์ง์ ‘ ํ˜ธ์ถœ ์—†์ด ์œ ์—ฐํ•œ ์—ฐ๊ฒฐ์ด ํ•„์š”ํ•  ๋•Œ
  • ๊ตฌ์กฐ์ ์œผ๋กœ ํ™•์žฅ์„ฑ๊ณผ ํ…Œ์ŠคํŠธ์„ฑ์„ ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•  ๋•Œ

  • Uber์˜ RIBs ์•„ํ‚คํ…์ฒ˜: ์ดˆ๊ธฐ์—๋Š” ๋ชจ๋“  ํ†ต์‹ ์„ ์ด๋ฒคํŠธ๋กœ ํ•˜๋ ค๊ณ  ํ–ˆ์œผ๋‚˜, ๊ฒฐ๊ตญ ์ง์ ‘ ์ฐธ์กฐ๋„ ํ—ˆ์šฉํ•จ.
  • FaceBook์˜ Flux: โ€œ๋ชจ๋“  ๊ฒƒ์ด ์ด๋ฒคํŠธโ€์—์„œ ์‹œ์ž‘ํ–ˆ์ง€๋งŒ, Redux์—์„œ๋Š” ์ง์ ‘ ์ ‘๊ทผ๋„ ์ง€์›ํ•˜๊ธฐ ์‹œ์ž‘ํ•จ.
  • Unity์˜ ECS: ์ˆœ์ˆ˜ ์ด๋ฒคํŠธ ์‹œ์Šคํ…œ์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ, ComponentSystem์—์„œ ์ง์ ‘ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•จ.
  • ํ˜ผํ•ฉ ์ ‘๊ทผ๋ฒ•(Hybrid Approach)ํƒ€์ž…์ด ๋ช…ํ™•ํ•˜๊ณ  ๊ฐ•๊ฒฐํ•ฉ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ.
  • ๋А์Šจํ•œ ๊ฒฐํ•ฉ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ด๋ฒคํŠธ๋ฒ„์Šค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋А์Šจํ•˜๊ฒŒ ๊ฒฐํ•ฉ.
1
2
3
4
5
6
7
8
// ์ง์ ‘ ์ฐธ์กฐ: ํƒ€์ž…์ด ๋ช…ํ™•ํ•˜๊ณ  ๊ฐ•๊ฒฐํ•ฉ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ
public class GameManager : IGameService
{
    public GameState CurrentState { get; set; }
}

// EventBus: ๋А์Šจํ•œ ๊ฒฐํ•ฉ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ  
EventBus.Publish(new PlayerDiedEvent(player));

2. ๊ณ„์ธต๋ณ„ ์—ญํ•  ๋ถ„๋‹ด(Hierarchical Approach)

๊ณ„์ธต๋ชจ๋“ˆ์„ค๋ช…์ฐธ์กฐ ๋Œ€์ƒ
โ‘ EventBus์ด๋ฒคํŠธ ๋ฉ”์‹œ์ง€ ํ†ต์‹  ํ—ˆ๋ธŒ์—†์Œ โŒ
โ‘กCore๊ณตํ†ต ์œ ํ‹ธ, ์ธํ„ฐํŽ˜์ด์Šค, ๋ชจ๋ธโœ… EventBus
โ‘ขServices๊ฒŒ์ž„ ์‹œ์Šคํ…œ (ํ”Œ๋ ˆ์ด์–ด, ๋งค์น˜ ๋“ฑ)โœ… Core, EventBus
โ‘ฃUIํ™”๋ฉด ์ปดํฌ๋„ŒํŠธ, ์ธํ’‹ ์ฒ˜๋ฆฌโœ… Services, Core, EventBus
โ‘คAppBootstrap, EntryPointโœ… ๋ชจ๋“  ๊ฒƒ


์ด ๊ธฐ์‚ฌ๋Š” ์ €์ž‘๊ถŒ์ž์˜ CC BY 4.0 ๋ผ์ด์„ผ์Šค๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

ยฉ SouthGlory. ์ผ๋ถ€ ๊ถŒ๋ฆฌ ๋ณด์œ 

Powered by Jekyll with Chirpy theme