{"id":16209923,"url":"https://github.com/annulusgames/navstack","last_synced_at":"2025-12-24T08:27:21.242Z","repository":{"id":231079983,"uuid":"780711856","full_name":"annulusgames/NavStack","owner":"annulusgames","description":"Asynchronous screen transition/navigation for Unity.","archived":false,"fork":false,"pushed_at":"2025-01-05T08:05:12.000Z","size":167,"stargazers_count":53,"open_issues_count":0,"forks_count":6,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-02T03:24:16.374Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/annulusgames.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-02T02:37:35.000Z","updated_at":"2025-02-01T15:13:57.000Z","dependencies_parsed_at":"2025-02-08T17:36:25.791Z","dependency_job_id":"2cf7ebe8-0d2e-40ab-9f50-0681aa8e8804","html_url":"https://github.com/annulusgames/NavStack","commit_stats":null,"previous_names":["annulusgames/navstack","yn01dev/navstack","yn01-dev/navstack"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/annulusgames%2FNavStack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/annulusgames%2FNavStack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/annulusgames%2FNavStack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/annulusgames%2FNavStack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/annulusgames","download_url":"https://codeload.github.com/annulusgames/NavStack/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241481969,"owners_count":19969833,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-10T10:34:10.023Z","updated_at":"2025-12-24T08:27:21.198Z","avatar_url":"https://github.com/annulusgames.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NavStack\n Asynchronous screen transition/navigation for Unity.\n\n[日本語版READMEはこちら](README_JA.md)\n\n## Overview\n\nNavStack is a library for managing screen transitions in Unity. It provides a foundation interface for asynchronous API-based screen transitions, as well as support for integration with uGUI and content management using Resources/Addressables.\n\n\u003e [!NOTE]\n\u003e NavStack is currently released as a preview version. Feedback through issues or pull requests would be appreciated.\n\n## Setup\n\n### Requirements\n\n* Unity 2021.3 or later\n* [UniTask](https://github.com/Cysharp/UniTask) 2.0.0 or later\n\n### Installation\n\n1. Open the Package Manager from Window \u003e Package Manager.\n2. Click the \"+\" button \u003e Add package from git URL.\n3. Enter the following URL:\n\n```\nhttps://github.com/AnnulusGames/NavStack.git?path=src/NavStack/Assets/NavStack\n```\n\nAlternatively, open Packages/manifest.json and add the following to the dependencies block:\n\n```json\n{\n    \"dependencies\": {\n        \"com.annulusgames.navstack\": \"https://github.com/AnnulusGames/NavStack.git?path=src/NavStack/Assets/NavStack\"\n    }\n}\n```\n\n## Basic Concepts\n\nIn NavStack, a screen is divided into units called \"Pages.\" The only requirement for a Page is the implementation of the `IPage` interface, allowing any object such as GameObjects, VisualElements, or Scenes to be represented as a Page.\n\nScreen transitions and lifecycle management are handled by \"Navigation.\" NavStack provides two types of Navigation: `INavigationStack`, which can stack Page transitions, and `INaviagtionSheet`, which switches between active Pages without keeping a history of transitions.\n\n## Page Lifecycle\n\nThe `IPage` interface defines the basic events for a Page's lifecycle. Each event is called from the Navigation side, allowing customization of screen transition processes.\n\n```cs\npublic interface IPage\n{\n    UniTask OnNavigatedFrom(NavigationContext context, CancellationToken cancellationToken = default);\n    UniTask OnNavigatedTo(NavigationContext context, CancellationToken cancellationToken = default);\n}\n```\n\n| Event           | Description                                |\n| --------------- | ------------------------------------------ |\n| OnNavigatedFrom | Called when navigating away from the Page. |\n| OnNavigatedTo   | Called when navigating to the Page.        |\n\nAdditionally, by implementing `IPageLifecycleEvent`, you can add additional lifecycle events for the Page.\n\n```cs\npublic interface IPageLifecycleEvent\n{\n    UniTask OnAttached(CancellationToken cancellationToken = default);\n    UniTask OnDetached(CancellationToken cancellationToken = default);\n}\n```\n\n## NavigationStack\n\nNavigationStack supports stacked screen transitions. Pages pushed onto the stack are stacked, and the last pushed Page becomes the active Page. You can push a Page using `PushAsync()` and pop using `PopAsync()`.\n\n```cs\nINavigationStack navigationStack;\nIPage page;\n\nawait navigationStack.PushAsync(page);\nawait navigationStack.PopAsync();\n```\n\nYou can also add NavigationStack-specific events to Pages by implementing `IPageStackEvent`.\n\n```cs\npublic interface IPageStackEvent\n{\n    UniTask OnPush(NavigationContext context, CancellationToken cancellationToken = default);\n    UniTask OnPop(NavigationContext context, CancellationToken cancellationToken = default);\n}\n```\n\n## NavigationSheet\n\nNavigationSheet supports switching between active Pages, similar to tabs. Unlike NavigationStack, it does not keep a history of Page transitions.\n\nYou need to use `AddAsync()` to add Pages to the NavigationSheet.\n\n```cs\nINavigationSheet navigationSheet;\nIPage page1;\nIPage page2;\nIPage page3;\n\nawait navigationSheet.AddAsync(page1);\nawait navigationSheet.AddAsync(page2);\nawait navigationSheet.AddAsync(page3);\n```\n\nTo switch the displayed Page, use `ShowAsync()`. To hide a Page, use `HideAsync()`.\n\n```cs\nint index = 0;\nawait navigationSheet.ShowAsync(index);\nawait navigationSheet.HideAsync();\n```\n\nYou can remove Pages using `RemoveAsync()` or `RemoveAllAsync()`.\n\n```cs\nawait navigationSheet.RemoveAsync(page3);\nawait navigationSheet.RemoveAllAsync();\n```\n\n## NavigationContext\n\nYou can pass `NavigationContext` during Page transitions to pass data between Pages and specify transition options.\n\n### Passing Data\n\nYou can pass data to the destination Page through `NavigationContext`.\n\n```cs\nvar page = new ExamplePage();\n\nvar context = new NavigationContext()\n{\n    Parameters = { { \"id\", \"123456\" } }\n};\n\nawait navigationStack.PushAsync(page, context, cancellationToken);\n\nclass ExamplePage : IPage\n{\n    public UniTask OnNavigatedTo(NavigationContext context, CancellationToken cancellationToken = default)\n    {\n        var id = (string)context.Parameters[\"id\"];\n\n        ...\n    }\n\n    ...\n}\n```\n\n### NavigationOptions\n\nYou can specify transition options using `NavigationOptions`.\n\n```cs\nvar context = new NavigationContext()\n{\n    Options = new NavigationOptions()\n    {\n        Animated = true,\n        AwaitOperation = NavigationAwaitOperation.Drop,\n    }\n};\n\nawait navigationStack.PushAsync(page, context, cancellationToken);\n```\n\n| Property       | Description                                                                                                                            |\n| -------------- | -------------------------------------------------------------------------------------------------------------------------------------- |\n| Animated       | Specifies whether to play transition animations (default is true).                                                                     |\n| AwaitOperation | Specifies the behavior when a transition operation is called again during Page transition (default is NavigationAwaitOperation.Error). |\n\n## Workflow for uGUI\n\nWhen using NavStack with uGUI, add the `Navigation Stack` / `Navigation Sheet` component to any object placed under the Canvas.\n\nNext, create Pages for displaying UI. Implement a component that inherits from `IPage`.\n\n```cs\npublic class SamplePage1 : MonoBehaviour, IPage\n{\n    [SerializeField] CanvasGroup canvasGroup;\n\n    public async UniTask OnNavigatedTo(NavigationContext context, CancellationToken cancellationToken = default)\n    {\n        if (!context.Options.Animated)\n        {\n            canvasGroup.alpha = 1f;\n            return;\n        }\n\n        // Example implementation using LitMotion for tween animations\n        await LMotion.Create(0f, 1f, 0.25f)\n            .WithEase(Ease.InQuad)\n            .BindToCanvasGroupAlpha(canvasGroup)\n            .ToUniTask(CancellationTokenSource.CreateLinkedTokenSource(destroyCancellationToken, cancellationToken).Token);\n    }\n\n    public async UniTask OnNavigatedFrom(NavigationContext context, CancellationToken cancellationToken = default)\n    {\n        if (!context.Options.Animated)\n        {\n            canvasGroup.alpha = 0f;\n            return;\n        }\n\n        await LMotion.Create(1f, 0f, 0.25f)\n            .WithEase(Ease.OutQuad)\n            .BindToCanvasGroupAlpha(canvasGroup)\n            .ToUniTask(CancellationTokenSource.CreateLinkedTokenSource(destroyCancellationToken, cancellationToken).Token);\n    }\n}\n```\n\nPrefab the created Page objects for convenience. By adding Prefabed Pages using `PushNewObjectAsync()` or `AddNewObjectAsync()`, you can manage object generation/destruction based on the Page lifecycle.\n\n```cs\nPage prefab;\nNavigationStack navigationStack;\nNavigationSheet navigationSheet;\n\nawait navigationStack.PushNewObjectAsync(prefab);\nawait navigationSheet.AddNewObjectAsync(prefab);\n```\n\n## Content Management\n\nTODO\n\n## R3\n\nTODO\n\n## VContainer\n\nTODO\n\n## License\n\n[MIT License](LICENSE)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fannulusgames%2Fnavstack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fannulusgames%2Fnavstack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fannulusgames%2Fnavstack/lists"}