Unclaimed Package Is this your package? Claim it to unlock full analytics and manage your listing.
Claim This Package

Install via UPM

Add to Unity Package Manager using this URL

https://www.pkglnk.dev/jongseonpark-uimanager.git?path=Assets/UIManager

README Markdown

Copy this to your project's README.md

Style
Preview
pkglnk installs badge
## Installation

Add **UIManagerForMe** to your Unity project via Package Manager:

1. Open **Window > Package Manager**
2. Click **+** > **Add package from git URL**
3. Enter:
```
https://www.pkglnk.dev/jongseonpark-uimanager.git?path=Assets%2FUIManager
```

[![pkglnk](https://www.pkglnk.dev/badge/jongseonpark-uimanager.svg?style=pkglnk)](https://www.pkglnk.dev/pkg/jongseonpark-uimanager)

Dependencies (1)

README

UIManager

์ด ํ”„๋กœ์ ํŠธ๋Š” Task ๊ธฐ๋ฐ˜์˜ UIManager๋ฅผ ์ œ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. resource, server๋“ฑ์˜ ์—ฌ๋Ÿฌ ๋น„๋™๊ธฐ API์— ๋Œ€์‘ํ•˜๊ธฐ ์œ„ํ•ด ๋น„๋™๊ธฐ Task๋ฅผ ํ†ตํ•ฉ ๊ด€๋ฆฌํ•˜์—ฌ Page, Popup๋“ฑ์˜ UI๋ฅผ ๋„์šฐ๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Page ๊ด€๋ฆฌํ•˜๋Š” ๋ชจ์Šต

Honeycam 2022-12-19 18-25-07.gif

Popup ๊ด€๋ฆฌํ•˜๋Š” ๋ชจ์Šต

Honeycam 2022-12-19 18-24-04.gif

์•ž์„œ์„œ

  • ์œ ๋‹ˆํ‹ฐ์—์„œ ๋น„๋™๊ธฐ ์‚ฌ์šฉ์„ ํšจ์œจ์ ์œผ๋กœ ์ง„ํ–‰ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ UniTask๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•ด๋‹น ๋‚ด์šฉ์€ UniTask๋ฅผ ์ฐธ์กฐ.
  • ํ•ด๋‹นํ”„๋กœ์ ํŠธ๋Š” Unity 2021.3, UniTask Ver.2.3.3์—์„œ ํ…Œ์ŠคํŠธ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  • namespace ๋“ฑ์— ํฌํ•จ๋œ ํšŒ์‚ฌ๋ช… ChickenGames๋Š” ํ˜„์กดํ•˜๋Š” ํšŒ์‚ฌ๊ฐ€ ์•„๋‹ˆ๋ฉฐ, ๋งŒ์•ฝ ๋‹ค๋ฅธ ๊ณณ์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด ์ €์™€ ๋ฌด๊ด€ํ•ฉ๋‹ˆ๋‹ค.

Getting Start

Release์—์„œ ๊ด€๋ จ ์ฝ”๋“œ ์˜ˆ์ œ๋ฅผ ๋‹ค์šด ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

UIManager Instance ์ƒ์„ฑ

์‚ฌ์šฉํ•˜๊ธฐ ์ „์— Instance๋ฅผ ์ƒ์„ฑํ•ด์ฃผ์„ธ์š”. ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ๋Š” IResourceLoader, uiRoot๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. uiRoot๋Š” UI์˜ ๋ถ€๋ชจ๊ฐ€ ๋  transform์„ ๋„ฃ์–ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

public class UI_TestMain : MonoBehaviour
{
        [SerializeField]
        Transform uiRoot;

        void Start()
        {
            UIManager.CreateInstance(new UnityResourceLoader(), uiRoot);
        }
}

ResourceLoader

public interface IResourceLoader
    {
        UniTask<Object> LoadAsync(string path);
        UniTask<Object> InstantiateAsync(string path, Transform parent = null, bool instantiateInWorldSpace = false);
        bool ReleaseInstance(GameObject instance);
    }

IResourceLoader๋Š” ๋ฆฌ์†Œ์Šค ๋กœ๋“œ ๋ฐฉ๋ฒ•์„ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•œ ์ธํ„ฐํŽ˜์ด์Šค์ž…๋‹ˆ๋‹ค. ์œ ๋‹ˆํ‹ฐ๋Š” ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ๋ฆฌ์†Œ์Šค ๋กœ๋“œ ๋ฐฉ์‹์ด ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Resources
  • AssetBundle
  • Adressable

๋•Œ๋ฌธ์— UIManager์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑ๋•Œ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ์— ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌํ˜„ํ•ด ์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” Unity์˜ Resources๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ž‘์„ฑํ•œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. Example์—์„œ ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

public class UnityResourceLoader : IResourceLoader
    {
        public async UniTask<Object> InstantiateAsync(string path, Transform parent = null, bool instantiateInWorldSpace = false)
        {
            var objRes = await Resources.LoadAsync(path);

            if (objRes == null)
            {
                Debug.LogError($"{path} is not exist..");
                return null;
            }

            return Object.Instantiate(objRes, parent, instantiateInWorldSpace);
        }

        public async UniTask<Object> LoadAsync(string path)
        {
            return await Resources.LoadAsync(path);
        }

        public bool ReleaseInstance(GameObject instance)
        {
            Object.Destroy(instance);
            return true;
        }
    }

Page ์ƒ์„ฑ

PageBase๋ฅผ ์ƒ์†๋ฐ›์€ Component๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”. ๊ทธ๋ฆฌ๊ณ  ์•„๋ž˜์™€ ๊ฐ™์ด Init๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

LoadFuncAsyncs์—์„œ Task๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ํŽ˜์ด์ง€๋Š” LoadFuncAsyncs๊ฐ€ ์™„๋ฃŒ๋˜์ง€ ์•Š๋Š” ํ•œ ์—ด๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

public class TestMainPage : PageBase
    {
        [SerializeField]
        Button openSubPageButton;

        public override void Init()
        {
            base.Init();

            LoadFuncAsyncs.Add(async (p, ct) =>
            {
                ct.ThrowIfCancellationRequested();
                await UniTask.Delay(500);
                Debug.Log("Done1");
            });
            LoadFuncAsyncs.Add(async (p, ct) =>
            {
                ct.ThrowIfCancellationRequested();
                await UniTask.Delay(1000);
                Debug.Log("Done2");
            });
            
            openSubPageButton?.onClick.AddListener(() =>
            {
                UIManager.Instance.OpenPage("TestSubPage");
            });
        }
    }

์ตœ์ƒ๋‹จ์— ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํฌํ•จํ•œ Prefab์„ ์ œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

ํ™”๋ฉด ์บก์ฒ˜ 2022-12-19 183317.png

UIManager.Instance.OpenPage๋ฅผ ํ†ตํ•ด Page๋ฅผ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • path๋Š” ResourceLoader์—์„œ์˜ Load path์ž…๋‹ˆ๋‹ค. ResourceLoader์—์„œ ์ง€์ •ํ•œ ๋ฐฉ์‹์œผ๋กœ ๋ฆฌ์†Œ์Šค๋ฅผ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.
  • ํ•„์š”์‹œ IProgress progress๋ฅผ ํ†ตํ•ด ์ง„ํ–‰๋„๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • CancellationToken cancellationToken๋Š” ์ค‘๊ฐ„์— ์ƒ์„ฑ Task๋ฅผ ์ทจ์†Œํ•˜๊ธฐ ์œ„ํ•œ ํ† ํฐ์ž…๋‹ˆ๋‹ค.
  • int delay๋Š” ์—ฌ๋Š”๊ฒŒ ๋Š˜์–ด์กŒ์„ ๋•Œ ๋”œ๋ ˆ์ด ์ด๋ฒคํŠธ๋ฅผ ์‹คํ–‰ํ•  ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค. ๋”œ๋ ˆ์ด ์ด๋ฒคํŠธ๋Š” UIInstantiateRequest๋ฅผ ํ†ตํ•ด ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜์—์„œ ์–ธ๊ธ‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
public UIInstantiateRequest OpenPage(string path, IProgress<float> progress = null, CancellationToken cancellationToken = default, int delay = 1000)

์‚ฌ์šฉ ์˜ˆ์‹œ

UIManager.Instance.OpenPage("TestSubPage");

UIInstantiateRequest

UIManager๋ฅผ ํ†ตํ•ด UI๋ฅผ ์ƒ์„ฑ์‹œ์— UIInstantiateRequest๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. UIInstantiateRequest์—์„œ ํฌํ•จ๋œ ๋‚ด์šฉ์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • onLoadingDelay: ์ง€์ •ํ•œ ์‹œ๊ฐ„๋ณด๋‹ค ๋”œ๋ ˆ์ด ๋˜์—ˆ์„ ๋•Œ ๋ฐœ์ƒํ•  ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋ก
  • onLoadingDelayDone: ๋งŒ์•ฝ ๋”œ๋ ˆ์ด ๋˜์—ˆ์„ ๋•Œ, ๋”œ๋ ˆ์ด๊ฐ€ ๋๋‚  ๋•Œ ๋ฐœ์ƒํ•  ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋ก
  • Complete: ๋กœ๋“œ ์™„๋ฃŒ์‹œ์— ๋ฐœ์ƒํ•  ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋ก
async UniTask StartAsync(CancellationToken ct)
        {
            ct.ThrowIfCancellationRequested();

            openUICTS = new CancellationTokenSource();
            UIInstantiateRequest request = UIManager.Instance.OpenPopup("TestLoopPopup", cancellationToken: openUICTS.Token);
						
            // ๋”œ๋ ˆ์ด ๋˜์—ˆ์œผ๋‹ˆ ๋กœ๋”ฉ UI๋ฅผ ์ƒ์„ฑํ•จ.
            request.onLoadingDelay.AddListener(() =>
            {
                loadingCTS = new CancellationTokenSource();
                UniTask.Void(async () =>
                {
                    var obj = await Resources.LoadAsync<GameObject>("LoadingUI");
                    loadingCTS.Token.ThrowIfCancellationRequested();
                    loadingObject = Instantiate(obj as GameObject);
                    loadingObject.GetComponent<Transform>().SetParent(panelTransform, false);
                });
            });

            // ๋”œ๋ ˆ์ด๊ฐ€ ๋๋‚ฌ์œผ๋‹ˆ ์ƒ์„ฑ๋œ ๋กœ๋”ฉ UI๋ฅผ ์ œ๊ฑฐํ•จ.
            request.onLoadingDelayDone.AddListener(() =>
            {
                loadingCTS.Cancel();
                loadingCTS = null;
                Destroy(loadingObject);
                loadingObject = null;
            });

            // ์ƒ์„ฑ์ด ์™„๋ฃŒ ๋˜์—ˆ์„ ๋•Œ ์œ„์น˜๋ฅผ ์žก์Œ.
            request.Complete += (obj) =>
            {
                obj.GetComponent<Transform>().localPosition = transform.localPosition + new Vector3(10, 0);
            };
            await request;

            openUICTS?.Dispose();
            openUICTS = null;
        }

์„ค์น˜

์ด ํ”„๋กœ์ ํŠธ๋Š” UniTask๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์„ค์น˜๋ฅผ ์ง„ํ–‰ํ•˜๊ธฐ ์ „, ์œ ๋‹ˆํ‹ฐ ํ”„๋กœ์ ํŠธ์— UniTask๋ฅผ ์„ค์น˜ ํ›„ ์ง„ํ–‰ํ•ด์ฃผ์„ธ์š”.

git URL๋กœ ์„ค์น˜

Untitled

Untitled

Package Manager์—์„œ https://github.com/JongSeonPark/Unity_UIManager.git?path=Assets/UIManager๋ฅผ ๊ธฐ์ž…ํ•˜์—ฌ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

openUPM์œผ๋กœ ์„ค์น˜

openUPM์— ์ž‘์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. openupm-cli๋ฅผ ์ด์šฉํ•ด ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

openupm add com.chickengames.uimanager

Packages/manifest.json์— ์ถ”๊ฐ€ํ•˜์—ฌ ์„ค์น˜

Packages/manifest.json์—์„œ ์•„๋ž˜ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

"com.chickengames.uimanager": "https://github.com/JongSeonPark/Unity_UIManager.git?path=Assets/UIManager"

์ฝ”๋“œ๋ฅผ ํด๋ก  ํ›„ ์‚ฌ์šฉ

์ฝ”๋“œ ์ˆ˜์ • ๋ฐ ์ง์ ‘ ์ œ์–ด๋ฅผ ์›ํ•œ๋‹ค๋ฉด Git์„ ํด๋ก ํ•˜์—ฌ UIManagerํด๋” ๋ถ€๋ถ„์„ ์‚ฌ์šฉํ•ด๋„ ๋ฌด๋ฐฉํ•ฉ๋‹ˆ๋‹ค.

๐Ÿป License

์ด ํ”„๋กœ์ ํŠธ๋Š” Unity์™ธ์˜ ์™ธ๋ถ€์—์„œ ์ž‘์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์ง€ ์•Š์œผ๋ฉฐ, ์ œ๊ฐ€ ์ž‘์„ฑ๋œ ์ฝ”๋“œ์— ๋Œ€ํ•ด์„œ๋Š” Beer License๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ–‰๋ณตํ•˜์„ธ์š”. :)

Comments

No comments yet. Be the first!