nccgs 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/nccgs-accessibility-specialist.md +26 -0
- package/.claude/agents/nccgs-adversarial-reviewer.md +26 -0
- package/.claude/agents/nccgs-ai-programmer.md +26 -0
- package/.claude/agents/nccgs-analytics-engineer.md +26 -0
- package/.claude/agents/nccgs-art-direction-lead.md +26 -0
- package/.claude/agents/nccgs-audio-direction-lead.md +26 -0
- package/.claude/agents/nccgs-creative-director.md +26 -0
- package/.claude/agents/nccgs-documentation-manager.md +26 -0
- package/.claude/agents/nccgs-economy-designer.md +26 -0
- package/.claude/agents/nccgs-engine-programmer.md +26 -0
- package/.claude/agents/nccgs-game-design-lead.md +26 -0
- package/.claude/agents/nccgs-game-designer.md +26 -0
- package/.claude/agents/nccgs-gameplay-programmer.md +26 -0
- package/.claude/agents/nccgs-level-designer.md +26 -0
- package/.claude/agents/nccgs-live-ops-designer.md +26 -0
- package/.claude/agents/nccgs-localization-lead.md +26 -0
- package/.claude/agents/nccgs-narrative-lead.md +26 -0
- package/.claude/agents/nccgs-network-programmer.md +26 -0
- package/.claude/agents/nccgs-performance-analyst.md +26 -0
- package/.claude/agents/nccgs-producer.md +26 -0
- package/.claude/agents/nccgs-production-coordinator.md +23 -0
- package/.claude/agents/nccgs-programming-lead.md +26 -0
- package/.claude/agents/nccgs-prototyper.md +26 -0
- package/.claude/agents/nccgs-qa-engineer.md +26 -0
- package/.claude/agents/nccgs-qa-lead.md +26 -0
- package/.claude/agents/nccgs-release-engineer.md +26 -0
- package/.claude/agents/nccgs-release-lead.md +26 -0
- package/.claude/agents/nccgs-security-engineer.md +26 -0
- package/.claude/agents/nccgs-sound-designer.md +26 -0
- package/.claude/agents/nccgs-systems-designer.md +26 -0
- package/.claude/agents/nccgs-technical-architect.md +26 -0
- package/.claude/agents/nccgs-technical-artist.md +26 -0
- package/.claude/agents/nccgs-technical-director.md +26 -0
- package/.claude/agents/nccgs-tools-programmer.md +26 -0
- package/.claude/agents/nccgs-ui-programmer.md +26 -0
- package/.claude/agents/nccgs-unity-build-specialist.md +26 -0
- package/.claude/agents/nccgs-unity-content-specialist.md +26 -0
- package/.claude/agents/nccgs-unity-implementer.md +26 -0
- package/.claude/agents/nccgs-unity-rendering-specialist.md +26 -0
- package/.claude/agents/nccgs-unity-systems-specialist.md +26 -0
- package/.claude/agents/nccgs-unity-ui-specialist.md +26 -0
- package/.claude/agents/nccgs-ux-designer.md +26 -0
- package/.claude/agents/nccgs-verification-engineer.md +26 -0
- package/.claude/agents/nccgs-world-builder.md +26 -0
- package/.claude/agents/nccgs-writer.md +26 -0
- package/.claude/nccgs/THIRD_PARTY_NOTICES.md +13 -0
- package/.claude/nccgs/VERSION +1 -0
- package/.claude/nccgs/constitution.md +131 -0
- package/.claude/nccgs/hooks/agent-audit.mjs +10 -0
- package/.claude/nccgs/hooks/common.mjs +41 -0
- package/.claude/nccgs/hooks/post-compact.mjs +1 -0
- package/.claude/nccgs/hooks/pre-compact.mjs +8 -0
- package/.claude/nccgs/hooks/protect-git.mjs +22 -0
- package/.claude/nccgs/hooks/protect-write.mjs +17 -0
- package/.claude/nccgs/hooks/session-start.mjs +15 -0
- package/.claude/nccgs/hooks/session-stop.mjs +7 -0
- package/.claude/nccgs/protocols/agent-contract.md +34 -0
- package/.claude/nccgs/protocols/context-packets.md +13 -0
- package/.claude/nccgs/protocols/evidence.md +15 -0
- package/.claude/nccgs/protocols/model-routing.md +22 -0
- package/.claude/nccgs/protocols/orchestration.md +26 -0
- package/.claude/nccgs/protocols/unity-boundary.md +11 -0
- package/.claude/nccgs/settings.fragment.json +77 -0
- package/.claude/nccgs/studio.json +347 -0
- package/.claude/nccgs/tools/configure-models.mjs +39 -0
- package/.claude/nccgs/unity-skills-manifest.json +727 -0
- package/.claude/nccgs/workflow-catalog.json +317 -0
- package/.claude/rules/nccgs-canonical-docs.md +19 -0
- package/.claude/rules/nccgs-editor-tools.md +12 -0
- package/.claude/rules/nccgs-localization.md +12 -0
- package/.claude/rules/nccgs-networking.md +13 -0
- package/.claude/rules/nccgs-performance.md +14 -0
- package/.claude/rules/nccgs-rendering.md +16 -0
- package/.claude/rules/nccgs-security.md +13 -0
- package/.claude/rules/nccgs-tests.md +18 -0
- package/.claude/rules/nccgs-ui.md +14 -0
- package/.claude/rules/nccgs-unity-assets.md +21 -0
- package/.claude/rules/nccgs-unity-code.md +22 -0
- package/.claude/skills/accessibility-review/SKILL.md +14 -0
- package/.claude/skills/architecture-decision/SKILL.md +14 -0
- package/.claude/skills/asset-audit/SKILL.md +14 -0
- package/.claude/skills/audit/SKILL.md +16 -0
- package/.claude/skills/audit/references/dimensions.md +46 -0
- package/.claude/skills/balance-review/SKILL.md +14 -0
- package/.claude/skills/bug-triage/SKILL.md +14 -0
- package/.claude/skills/build-live-game/SKILL.md +317 -0
- package/.claude/skills/build-live-game/references/achievements.md +779 -0
- package/.claude/skills/build-live-game/references/apis.md +280 -0
- package/.claude/skills/build-live-game/references/authentication.md +437 -0
- package/.claude/skills/build-live-game/references/battlepass.md +860 -0
- package/.claude/skills/build-live-game/references/cloud-code.md +563 -0
- package/.claude/skills/build-live-game/references/cloud-save.md +474 -0
- package/.claude/skills/build-live-game/references/deployment.md +216 -0
- package/.claude/skills/build-live-game/references/player-account.md +813 -0
- package/.claude/skills/build-live-game/references/remote-config.md +96 -0
- package/.claude/skills/build-live-game/references/tooling.md +431 -0
- package/.claude/skills/closure/SKILL.md +14 -0
- package/.claude/skills/code-review/SKILL.md +14 -0
- package/.claude/skills/compatibility-review/SKILL.md +14 -0
- package/.claude/skills/context-pack/SKILL.md +14 -0
- package/.claude/skills/dependency-review/SKILL.md +14 -0
- package/.claude/skills/design/SKILL.md +20 -0
- package/.claude/skills/design-review/SKILL.md +14 -0
- package/.claude/skills/evidence-review/SKILL.md +14 -0
- package/.claude/skills/hotfix/SKILL.md +14 -0
- package/.claude/skills/implement-in-app-purchases/README.md +233 -0
- package/.claude/skills/implement-in-app-purchases/SKILL.md +158 -0
- package/.claude/skills/implement-in-app-purchases/references/api-notes.md +562 -0
- package/.claude/skills/implement-in-app-purchases/references/codeless-catalog.md +331 -0
- package/.claude/skills/implement-in-app-purchases/references/convert-adapty.md +268 -0
- package/.claude/skills/implement-in-app-purchases/references/convert-essentialkit.md +239 -0
- package/.claude/skills/implement-in-app-purchases/references/convert-revenuecat.md +275 -0
- package/.claude/skills/implement-in-app-purchases/references/convert-unipay.md +145 -0
- package/.claude/skills/implement-in-app-purchases/references/migration-v4-to-v5.md +204 -0
- package/.claude/skills/implement-in-app-purchases/references/path-add-iap-to-new-project.md +198 -0
- package/.claude/skills/implement-in-app-purchases/references/path-convert-native-google-billing.md +356 -0
- package/.claude/skills/implement-in-app-purchases/references/path-convert-native-storekit.md +446 -0
- package/.claude/skills/implement-in-app-purchases/references/path-implement-iap-d2c.md +680 -0
- package/.claude/skills/implement-in-app-purchases/references/platform-notes.md +204 -0
- package/.claude/skills/implement-in-app-purchases/references/pre-check.md +205 -0
- package/.claude/skills/incident-recovery/SKILL.md +14 -0
- package/.claude/skills/initialize-ai-navigation/SKILL.md +95 -0
- package/.claude/skills/initialize-ai-navigation/references/navigation-system.md +794 -0
- package/.claude/skills/levelplay-unity-integration/CHANGELOG.md +57 -0
- package/.claude/skills/levelplay-unity-integration/README.md +74 -0
- package/.claude/skills/levelplay-unity-integration/SKILL.md +1126 -0
- package/.claude/skills/levelplay-unity-integration/references/banner-api.md +920 -0
- package/.claude/skills/levelplay-unity-integration/references/best-practices.md +536 -0
- package/.claude/skills/levelplay-unity-integration/references/ilrd-api.md +337 -0
- package/.claude/skills/levelplay-unity-integration/references/initialization-api.md +630 -0
- package/.claude/skills/levelplay-unity-integration/references/interstitial-api.md +899 -0
- package/.claude/skills/levelplay-unity-integration/references/ios-setup.md +491 -0
- package/.claude/skills/levelplay-unity-integration/references/migration-sdk-9.md +666 -0
- package/.claude/skills/levelplay-unity-integration/references/privacy-settings.md +608 -0
- package/.claude/skills/levelplay-unity-integration/references/rewarded-api.md +902 -0
- package/.claude/skills/localization/SKILL.md +135 -0
- package/.claude/skills/localization/references/api-notes.md +76 -0
- package/.claude/skills/localization/resources/L10nBatchProcessor.cs +69 -0
- package/.claude/skills/localization/resources/LocalizedFontAsset.cs +18 -0
- package/.claude/skills/localize-game/SKILL.md +14 -0
- package/.claude/skills/migrate-project/SKILL.md +21 -0
- package/.claude/skills/migrate-project/references/procedure.md +63 -0
- package/.claude/skills/milestone-review/SKILL.md +14 -0
- package/.claude/skills/new-unity-project/SKILL.md +179 -0
- package/.claude/skills/optimize-audio/SKILL.md +199 -0
- package/.claude/skills/optimize-audio/resources/audio-import-api.md +146 -0
- package/.claude/skills/optimize-audio/resources/platform-settings.md +48 -0
- package/.claude/skills/optimize-text-mesh-pro/SKILL.md +182 -0
- package/.claude/skills/optimize-web/SKILL.md +393 -0
- package/.claude/skills/optimize-web/resources/WebOptimizer.cs +21 -0
- package/.claude/skills/optimize-web/resources/toktx-examples.sh +11 -0
- package/.claude/skills/performance-audit/SKILL.md +14 -0
- package/.claude/skills/physics-3d-collision/SKILL.md +442 -0
- package/.claude/skills/physics-3d-collision/references/troubleshooting.md +41 -0
- package/.claude/skills/physics-3d-collision/resources/CollisionDebugger.cs +33 -0
- package/.claude/skills/plan-feature/SKILL.md +14 -0
- package/.claude/skills/playtest/SKILL.md +14 -0
- package/.claude/skills/project-stage/SKILL.md +14 -0
- package/.claude/skills/prototype-feature/SKILL.md +14 -0
- package/.claude/skills/qa-plan/SKILL.md +14 -0
- package/.claude/skills/release/SKILL.md +18 -0
- package/.claude/skills/release-readiness/SKILL.md +14 -0
- package/.claude/skills/retrospective/SKILL.md +14 -0
- package/.claude/skills/review/SKILL.md +16 -0
- package/.claude/skills/security-audit/SKILL.md +14 -0
- package/.claude/skills/setup-multiplayer-services/SKILL.md +39 -0
- package/.claude/skills/setup-multiplayer-services/references/dgs-entrypoint.md +79 -0
- package/.claude/skills/setup-multiplayer-services/references/entrypoints.md +213 -0
- package/.claude/skills/setup-multiplayer-services/references/examples.md +33 -0
- package/.claude/skills/setup-multiplayer-services/references/implementation-fit.md +30 -0
- package/.claude/skills/setup-multiplayer-services/references/underlying-services.md +11 -0
- package/.claude/skills/setup-multiplayer-services/references/workflows-prerequisites.md +17 -0
- package/.claude/skills/setup-vivox-voice-chat/SKILL.md +118 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/.env.example +6 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/README.md +101 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/promptfooconfig.yaml +32 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/tests/init-and-login.yaml +76 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/tests/text-chat.yaml +65 -0
- package/.claude/skills/setup-vivox-voice-chat/evals/tests/voice-channels.yaml +74 -0
- package/.claude/skills/setup-vivox-voice-chat/references/events-and-participants.md +79 -0
- package/.claude/skills/setup-vivox-voice-chat/references/init-and-login.md +92 -0
- package/.claude/skills/setup-vivox-voice-chat/references/text-chat.md +93 -0
- package/.claude/skills/setup-vivox-voice-chat/references/troubleshooting.md +47 -0
- package/.claude/skills/setup-vivox-voice-chat/references/voice-channels.md +90 -0
- package/.claude/skills/shader-graph-create-custom-node/SKILL.md +25 -0
- package/.claude/skills/shader-graph-create-custom-node/resources/all_hints.hlsl +182 -0
- package/.claude/skills/sprint-plan/SKILL.md +14 -0
- package/.claude/skills/sprite-editor/SKILL.md +66 -0
- package/.claude/skills/sprite-editor/references/api_reference.md +151 -0
- package/.claude/skills/sprite-editor/references/background.md +112 -0
- package/.claude/skills/sprite-editor/references/templates.md +72 -0
- package/.claude/skills/sprite-editor/scripts/AutomaticSliceTexture.cs +40 -0
- package/.claude/skills/sprite-editor/scripts/GenerateNewSpriteRects.cs +200 -0
- package/.claude/skills/sprite-editor/scripts/GetTextureSourceImageSize.cs +32 -0
- package/.claude/skills/sprite-editor/scripts/GetTextureToSlice.cs +55 -0
- package/.claude/skills/sprite-editor/scripts/GridSliceTexture.cs +40 -0
- package/.claude/skills/sprite-editor/scripts/IsometricSliceTexture.cs +141 -0
- package/.claude/skills/sprite-editor/scripts/README.md +134 -0
- package/.claude/skills/sprite-editor/scripts/SetPivotExample.cs +58 -0
- package/.claude/skills/sprite-editor/scripts/SpriteToPng.cs +88 -0
- package/.claude/skills/status/SKILL.md +16 -0
- package/.claude/skills/story-readiness/SKILL.md +14 -0
- package/.claude/skills/test/SKILL.md +16 -0
- package/.claude/skills/ui/SKILL.md +142 -0
- package/.claude/skills/ui-imgui/SKILL.md +186 -0
- package/.claude/skills/ui-imgui/references/gui-elements.md +156 -0
- package/.claude/skills/ui-imgui/references/templates.md +141 -0
- package/.claude/skills/ui-review/SKILL.md +14 -0
- package/.claude/skills/ui-ugui/SKILL.md +282 -0
- package/.claude/skills/ui-ugui/references/scrollview-setup.md +29 -0
- package/.claude/skills/ui-uitk/SKILL.md +235 -0
- package/.claude/skills/ui-uitk/references/common-issues.md +74 -0
- package/.claude/skills/ui-uitk/references/custom-elements.md +241 -0
- package/.claude/skills/ui-uitk/references/painter2d.md +282 -0
- package/.claude/skills/ui-uitk/references/pointermanipulator-guide.md +94 -0
- package/.claude/skills/ui-uitk/references/svg-icons.md +136 -0
- package/.claude/skills/ui-uitk/references/ui-runtime-binding.md +234 -0
- package/.claude/skills/ui-uitk/references/uss-guide.md +138 -0
- package/.claude/skills/unity-cli/CHANGELOG.md +233 -0
- package/.claude/skills/unity-cli/SECURITY.md +22 -0
- package/.claude/skills/unity-cli/SKILL.md +414 -0
- package/.claude/skills/unity-cli/references/auth-license-cloud.md +146 -0
- package/.claude/skills/unity-cli/references/build-run-test.md +349 -0
- package/.claude/skills/unity-cli/references/collaboration.md +472 -0
- package/.claude/skills/unity-cli/references/config-hub.md +103 -0
- package/.claude/skills/unity-cli/references/diagnostics-maintenance.md +326 -0
- package/.claude/skills/unity-cli/references/editors-install.md +327 -0
- package/.claude/skills/unity-cli/references/integration-advanced.md +472 -0
- package/.claude/skills/unity-cli/references/projects-templates.md +574 -0
- package/.claude/skills/unity-package-management/SKILL.md +304 -0
- package/.claude/skills/unity-package-management/references/select-packages.md +108 -0
- package/.claude/skills/urp-postprocessing/SKILL.md +188 -0
- package/.claude/skills/urp-postprocessing/references/code-templates.md +119 -0
- package/.claude/skills/urp-postprocessing/references/effect-reference.md +86 -0
- package/.claude/skills/validate-urp-render-graph-renderer-feature/SKILL.md +269 -0
- package/.claude/skills/work/SKILL.md +36 -0
- package/.claude/skills/work/references/classification.md +41 -0
- package/.claude/skills/work/references/closure.md +50 -0
- package/.claude/skills/work/references/feature-contracts.md +32 -0
- package/.claude/skills/work/references/verification.md +26 -0
- package/CLAUDE.md +6 -0
- package/LICENSE +21 -0
- package/README.md +162 -0
- package/THIRD_PARTY_NOTICES.md +23 -0
- package/UPGRADING.md +32 -0
- package/VERSION +1 -0
- package/docs/ARCHITECTURE.md +73 -0
- package/docs/HUONG-DAN-MIGRATE-VA-SU-DUNG.md +324 -0
- package/docs/MIGRATION-MATRIX.md +23 -0
- package/docs/PROJECT-POLICY.md +67 -0
- package/docs/WORKFLOWS.md +61 -0
- package/package-assets/setup-vivox-voice-chat-evals.gitignore +7 -0
- package/package.json +41 -0
- package/scaffold/.nccgs/bugs/.gitkeep +1 -0
- package/scaffold/.nccgs/closures/.gitkeep +1 -0
- package/scaffold/.nccgs/context/.gitkeep +1 -0
- package/scaffold/.nccgs/decisions/.gitkeep +1 -0
- package/scaffold/.nccgs/evidence/.gitkeep +1 -0
- package/scaffold/.nccgs/features/.gitkeep +1 -0
- package/scaffold/.nccgs/migrations/.gitkeep +1 -0
- package/scaffold/.nccgs/playtests/.gitkeep +1 -0
- package/scaffold/.nccgs/project.yaml +103 -0
- package/scaffold/.nccgs/requirements.yaml +10 -0
- package/scaffold/.nccgs/reviews/.gitkeep +1 -0
- package/scaffold/.nccgs/state.md +40 -0
- package/scaffold/.nccgs/templates/agent-handoff.md +25 -0
- package/scaffold/.nccgs/templates/architecture-decision.md +27 -0
- package/scaffold/.nccgs/templates/closure-record.md +51 -0
- package/scaffold/.nccgs/templates/context-packet.yaml +17 -0
- package/scaffold/.nccgs/templates/evidence-record.md +23 -0
- package/scaffold/.nccgs/templates/feature-contract.md +35 -0
- package/scaffold/.nccgs/templates/migration-plan.md +40 -0
- package/scaffold/.nccgs/templates/waiver.md +11 -0
- package/scripts/cli.mjs +56 -0
- package/scripts/install.mjs +267 -0
- package/scripts/sync-unity-skills.mjs +126 -0
- package/scripts/validate.mjs +205 -0
- package/tests/framework.test.mjs +121 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: unity-package-management
|
|
3
|
+
description: Use when adding, removing, upgrading, or discovering Unity (UPM) packages programmatically from outside the Editor — headless or CI package installs via the C# UnityEditor.PackageManager.Client API, verifying package ids/versions against the Unity registry, or choosing which packages a game needs by genre, platform, and monetization. The Unity CLI does not manage UPM packages, so this skill covers that gap. Triggers on "install a Unity package", "add com.unity.*", "set up packages headless/CI", "which packages for a <genre> game".
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash
|
|
6
|
+
- Read
|
|
7
|
+
- Write
|
|
8
|
+
- Edit
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Unity Package Management (headless, via the C# Client API)
|
|
12
|
+
|
|
13
|
+
Add, remove, upgrade, and discover UPM (Unity Package Manager) packages programmatically with
|
|
14
|
+
`UnityEditor.PackageManager.Client`, driven headless from the terminal or CI. Do **not**
|
|
15
|
+
hand-edit `Packages/manifest.json` — the Client API resolves dependencies and compatible
|
|
16
|
+
versions correctly, whereas manual edits routinely break resolution.
|
|
17
|
+
|
|
18
|
+
This complements the **`unity-cli`** skill (editor install, project creation, build/test): the
|
|
19
|
+
CLI has **no** package-management command, so all package work goes through the Editor's C# API.
|
|
20
|
+
|
|
21
|
+
## When to use
|
|
22
|
+
|
|
23
|
+
- Add / remove / upgrade one or more packages in an existing or freshly-created project.
|
|
24
|
+
- Set up a project's packages non-interactively in CI.
|
|
25
|
+
- Verify a package id exists, or find its available versions, before depending on it.
|
|
26
|
+
- Decide which packages a game actually needs — see
|
|
27
|
+
[references/select-packages.md](references/select-packages.md).
|
|
28
|
+
|
|
29
|
+
## Choosing what to install
|
|
30
|
+
|
|
31
|
+
Install what the project actually needs, not everything; prefer packages the chosen template
|
|
32
|
+
already provides (URP templates already include the render pipeline, Input System, etc.). The
|
|
33
|
+
genre / look / platform / monetization → package mapping, plus how to search the registry, is
|
|
34
|
+
in [references/select-packages.md](references/select-packages.md). Produce a **deduplicated
|
|
35
|
+
list of package ids** and read it back to the user before installing.
|
|
36
|
+
|
|
37
|
+
## The `-quit` problem — why NOT `unity run` for installs
|
|
38
|
+
|
|
39
|
+
`Client.Add` / `Client.AddAndRemove` are **asynchronous**: they return a `Request` that only
|
|
40
|
+
completes on later `EditorApplication.update` ticks (the UPM child process marshals its result
|
|
41
|
+
back on the Editor's main-loop pump, so a blocking `while (!req.IsCompleted)` busy-wait
|
|
42
|
+
deadlocks it). The Editor must **stay alive** after `-executeMethod` returns, until the request
|
|
43
|
+
finishes.
|
|
44
|
+
|
|
45
|
+
`unity run` **cannot** be used for the installer: its default path injects `-quit` (see the reserved
|
|
46
|
+
flags in the **`unity-cli`** skill). With `-quit`, the Editor quits the instant the method
|
|
47
|
+
returns — before UPM resolves — so packages never install and the callback never runs.
|
|
48
|
+
|
|
49
|
+
**Solution:** launch the **Editor binary directly** in `-batchmode` **without** `-quit`. The
|
|
50
|
+
Editor stays alive, `EditorApplication.update` keeps ticking, the poll callback runs, and it
|
|
51
|
+
calls `EditorApplication.Exit(code)` itself when done — which both quits and sets the process
|
|
52
|
+
exit code.
|
|
53
|
+
|
|
54
|
+
## The installer script
|
|
55
|
+
|
|
56
|
+
Write this to `Assets/Editor/ProjectBootstrap/PackageInstaller.cs`. It must live under an
|
|
57
|
+
`Editor/` folder (or an Editor-only assembly) because it uses `UnityEditor`.
|
|
58
|
+
|
|
59
|
+
```csharp
|
|
60
|
+
using System.Linq;
|
|
61
|
+
using UnityEditor;
|
|
62
|
+
using UnityEditor.PackageManager;
|
|
63
|
+
using UnityEditor.PackageManager.Requests;
|
|
64
|
+
using UnityEngine;
|
|
65
|
+
|
|
66
|
+
namespace ProjectBootstrap
|
|
67
|
+
{
|
|
68
|
+
// Installs (and optionally removes) a fixed set of packages via the PackageManager
|
|
69
|
+
// Client API, headless-safe.
|
|
70
|
+
public static class PackageInstaller
|
|
71
|
+
{
|
|
72
|
+
// EDIT this list to match the package selection (see references/select-packages.md).
|
|
73
|
+
static readonly string[] PackagesToAdd =
|
|
74
|
+
{
|
|
75
|
+
"com.unity.inputsystem",
|
|
76
|
+
"com.unity.cinemachine",
|
|
77
|
+
"com.unity.render-pipelines.universal",
|
|
78
|
+
// "com.unity.package@1.2.3" // pin a version with @ when a minimum is required
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Optionally drop packages in the same resolution pass (e.g. a template default you don't want).
|
|
82
|
+
static readonly string[] PackagesToRemove = { };
|
|
83
|
+
|
|
84
|
+
const double TimeoutSeconds = 600; // UPM resolution + downloads can be slow
|
|
85
|
+
|
|
86
|
+
static AddAndRemoveRequest _request;
|
|
87
|
+
static double _deadline;
|
|
88
|
+
|
|
89
|
+
// Invoke with: -executeMethod ProjectBootstrap.PackageInstaller.Install (NO -quit)
|
|
90
|
+
public static void Install()
|
|
91
|
+
{
|
|
92
|
+
if (PackagesToAdd.Length == 0 && PackagesToRemove.Length == 0)
|
|
93
|
+
{
|
|
94
|
+
Debug.Log("[PackageInstaller] Nothing to do.");
|
|
95
|
+
EditorApplication.Exit(0);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
Debug.Log($"[PackageInstaller] Adding: {string.Join(", ", PackagesToAdd)}");
|
|
100
|
+
_request = Client.AddAndRemove(packagesToAdd: PackagesToAdd, packagesToRemove: PackagesToRemove);
|
|
101
|
+
_deadline = EditorApplication.timeSinceStartup + TimeoutSeconds;
|
|
102
|
+
EditorApplication.update += Poll;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static void Poll()
|
|
106
|
+
{
|
|
107
|
+
if (_request == null) return;
|
|
108
|
+
|
|
109
|
+
if (!_request.IsCompleted)
|
|
110
|
+
{
|
|
111
|
+
if (EditorApplication.timeSinceStartup > _deadline)
|
|
112
|
+
{
|
|
113
|
+
EditorApplication.update -= Poll;
|
|
114
|
+
Debug.LogError("[PackageInstaller] Timed out waiting for UPM.");
|
|
115
|
+
EditorApplication.Exit(2);
|
|
116
|
+
}
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
EditorApplication.update -= Poll;
|
|
121
|
+
|
|
122
|
+
if (_request.Status == StatusCode.Success)
|
|
123
|
+
{
|
|
124
|
+
var names = _request.Result.Select(p => $"{p.name}@{p.version}");
|
|
125
|
+
Debug.Log($"[PackageInstaller] Resolved: {string.Join(", ", names)}");
|
|
126
|
+
EditorApplication.Exit(0);
|
|
127
|
+
}
|
|
128
|
+
else
|
|
129
|
+
{
|
|
130
|
+
Debug.LogError($"[PackageInstaller] Failed: {_request.Error?.message}");
|
|
131
|
+
EditorApplication.Exit(1);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`AddAndRemove` installs the whole set in a single UPM resolution pass — faster and less
|
|
139
|
+
error-prone than one `Client.Add` per package.
|
|
140
|
+
|
|
141
|
+
**Add / remove / upgrade with one script:**
|
|
142
|
+
- **Add**: list the id in `PackagesToAdd`.
|
|
143
|
+
- **Remove**: list the id in `PackagesToRemove`.
|
|
144
|
+
- **Upgrade / pin**: add the id with `@<version>` (e.g. `com.unity.cinemachine@2.9.7`). Without
|
|
145
|
+
a version, resolution picks the latest compatible release.
|
|
146
|
+
|
|
147
|
+
## Discovering / verifying packages
|
|
148
|
+
|
|
149
|
+
To confirm an id exists or list its versions before adding it, search the registry. The
|
|
150
|
+
in-Editor `Client.SearchAll()` / `Client.Search("<id>")` calls are also async, so they use the
|
|
151
|
+
**same poll-and-`Exit` pattern and the same headless run** as the installer. Write
|
|
152
|
+
`Assets/Editor/ProjectBootstrap/PackageSearch.cs`:
|
|
153
|
+
|
|
154
|
+
```csharp
|
|
155
|
+
using System.Linq;
|
|
156
|
+
using UnityEditor;
|
|
157
|
+
using UnityEditor.PackageManager;
|
|
158
|
+
using UnityEditor.PackageManager.Requests;
|
|
159
|
+
using UnityEngine;
|
|
160
|
+
|
|
161
|
+
namespace ProjectBootstrap
|
|
162
|
+
{
|
|
163
|
+
public static class PackageSearch
|
|
164
|
+
{
|
|
165
|
+
const double TimeoutSeconds = 120;
|
|
166
|
+
static SearchRequest _request;
|
|
167
|
+
static double _deadline;
|
|
168
|
+
|
|
169
|
+
// Invoke with: -executeMethod ProjectBootstrap.PackageSearch.SearchAll (NO -quit)
|
|
170
|
+
public static void SearchAll()
|
|
171
|
+
{
|
|
172
|
+
_request = Client.SearchAll(); // or Client.Search("com.unity.cinemachine")
|
|
173
|
+
_deadline = EditorApplication.timeSinceStartup + TimeoutSeconds;
|
|
174
|
+
EditorApplication.update += Poll;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
static void Poll()
|
|
178
|
+
{
|
|
179
|
+
if (_request == null) return;
|
|
180
|
+
if (!_request.IsCompleted)
|
|
181
|
+
{
|
|
182
|
+
if (EditorApplication.timeSinceStartup > _deadline)
|
|
183
|
+
{
|
|
184
|
+
EditorApplication.update -= Poll;
|
|
185
|
+
Debug.LogError("[PackageSearch] Timed out.");
|
|
186
|
+
EditorApplication.Exit(2);
|
|
187
|
+
}
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
EditorApplication.update -= Poll;
|
|
191
|
+
|
|
192
|
+
if (_request.Status == StatusCode.Success)
|
|
193
|
+
{
|
|
194
|
+
foreach (var p in _request.Result.OrderBy(p => p.name))
|
|
195
|
+
Debug.Log($"[PackageSearch] {p.name}@{p.versions.latestCompatible} {p.displayName}");
|
|
196
|
+
Debug.Log($"[PackageSearch] {_request.Result.Length} packages found.");
|
|
197
|
+
EditorApplication.Exit(0);
|
|
198
|
+
}
|
|
199
|
+
else
|
|
200
|
+
{
|
|
201
|
+
Debug.LogError($"[PackageSearch] Failed: {_request.Error?.message}");
|
|
202
|
+
EditorApplication.Exit(1);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
`_request.Result` is a `PackageInfo[]`; each entry exposes `name`, `displayName`, `description`,
|
|
210
|
+
and `versions` (`.latest`, `.latestCompatible`, `.all`). For a terminal-only check without the
|
|
211
|
+
Editor (a **known** id, not free-text search), query the registry directly — see
|
|
212
|
+
[references/select-packages.md](references/select-packages.md#discovering-and-verifying-packages).
|
|
213
|
+
|
|
214
|
+
## Run it headless (direct Editor invocation, no `-quit`)
|
|
215
|
+
|
|
216
|
+
Resolve the Editor binary from the version, then run it in batch mode. The script owns quitting
|
|
217
|
+
via `EditorApplication.Exit`, so do **not** pass `-quit`:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
VERSION="<version>" # e.g. 6000.0.47f1 (or an installed version)
|
|
221
|
+
PROJECT="<project-path>"
|
|
222
|
+
METHOD="ProjectBootstrap.PackageInstaller.Install" # or ...PackageSearch.SearchAll
|
|
223
|
+
|
|
224
|
+
# Install directory of that editor (Hub layout), via the unity CLI
|
|
225
|
+
ED=$(unity editors path "$VERSION" --format json | python3 -c "import sys,json;print(json.load(sys.stdin)['data']['path'])")
|
|
226
|
+
|
|
227
|
+
# Resolve the executable per-OS (handles both "dir containing Unity.app" and the ".app" itself)
|
|
228
|
+
case "$(uname)" in
|
|
229
|
+
Darwin) if [ -d "$ED/Unity.app" ]; then UNITY_BIN="$ED/Unity.app/Contents/MacOS/Unity";
|
|
230
|
+
elif [[ "$ED" == *.app ]]; then UNITY_BIN="$ED/Contents/MacOS/Unity";
|
|
231
|
+
else UNITY_BIN="$ED/Unity"; fi ;;
|
|
232
|
+
Linux) UNITY_BIN="$ED/Editor/Unity" ;;
|
|
233
|
+
*) UNITY_BIN="$ED/Editor/Unity.exe" ;; # Windows (Git Bash / MSYS); use Editor\Unity.exe in PowerShell
|
|
234
|
+
esac
|
|
235
|
+
|
|
236
|
+
"$UNITY_BIN" -batchmode -projectPath "$PROJECT" -executeMethod "$METHOD" -logFile -
|
|
237
|
+
echo "Exit code: $?" # 0 = success, 1 = UPM error, 2 = timeout
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
`-logFile -` streams the Editor log (including the `[PackageInstaller]` / `[PackageSearch]`
|
|
241
|
+
lines) to stdout so you can watch resolution progress and read any UPM error. If
|
|
242
|
+
`unity editors path` output shape differs on your build, get the directory from
|
|
243
|
+
`unity editors --installed --format json` instead.
|
|
244
|
+
|
|
245
|
+
## Verify
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
# Every requested id should appear as a dependency
|
|
249
|
+
cat "<project-path>/Packages/manifest.json"
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Confirm the run exited `0` and each package from the list is present in `manifest.json`. If a
|
|
253
|
+
package fails to resolve, `_request.Error.message` is logged; read it and check the id/version
|
|
254
|
+
against the registry. The Editor's own log (including the `[PackageInstaller]` lines) is the
|
|
255
|
+
stdout you streamed with `-logFile -` above — read it there, not via `unity logs` (which shows
|
|
256
|
+
the CLI's own log, not the Editor's).
|
|
257
|
+
|
|
258
|
+
## Import & save headlessly (generate `.meta` files)
|
|
259
|
+
|
|
260
|
+
After a script or tool writes new `.cs`/asset files, Unity must **import** them so it generates
|
|
261
|
+
the `.meta` file each asset needs — and every `.cs`/asset MUST be committed together with its
|
|
262
|
+
`.meta`. Merely opening the project once (`unity open "<project-path>"`) imports and generates
|
|
263
|
+
them; use this method when you need it **headless** (in a script or CI).
|
|
264
|
+
|
|
265
|
+
Unlike the package installer, this is **synchronous** — it finishes before returning — so it's
|
|
266
|
+
safe to run via `unity run` (its injected `-quit` is harmless; the method also calls
|
|
267
|
+
`EditorApplication.Exit` for a clean exit code). Write
|
|
268
|
+
`Assets/Editor/ProjectBootstrap/ProjectSaver.cs`:
|
|
269
|
+
|
|
270
|
+
```csharp
|
|
271
|
+
using UnityEditor;
|
|
272
|
+
using UnityEngine;
|
|
273
|
+
|
|
274
|
+
namespace ProjectBootstrap
|
|
275
|
+
{
|
|
276
|
+
public static class ProjectSaver
|
|
277
|
+
{
|
|
278
|
+
// Invoke with: -executeMethod ProjectBootstrap.ProjectSaver.SaveAll
|
|
279
|
+
public static void SaveAll()
|
|
280
|
+
{
|
|
281
|
+
AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
|
|
282
|
+
AssetDatabase.SaveAssets();
|
|
283
|
+
Debug.Log("[ProjectSaver] Assets imported and saved.");
|
|
284
|
+
EditorApplication.Exit(0);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
unity run "<project-path>" --editor-version <version> \
|
|
292
|
+
-- -executeMethod ProjectBootstrap.ProjectSaver.SaveAll
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Notes
|
|
296
|
+
|
|
297
|
+
- These editor scripts are a bootstrap convenience. Leave them in
|
|
298
|
+
`Assets/Editor/ProjectBootstrap/` (they do nothing unless invoked) or delete them after
|
|
299
|
+
setup — your call; mention it to the user.
|
|
300
|
+
- All scripts live under `Editor/` because they use `UnityEditor`; they never ship in a build.
|
|
301
|
+
- Monetization / backend packages (`com.unity.purchasing`, `com.unity.services.levelplay`, the
|
|
302
|
+
UGS packages) install through this same mechanism, but do the actual **integration** via the
|
|
303
|
+
dedicated skills: **implement-in-app-purchases**, **levelplay-unity-integration**,
|
|
304
|
+
**build-live-game**.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Selecting packages
|
|
2
|
+
|
|
3
|
+
Turn a game concept — genre, look, target platforms, monetization — into a concrete package
|
|
4
|
+
list, then install it via the C# PackageManager Client API (see the main `SKILL.md`).
|
|
5
|
+
|
|
6
|
+
**Principle:** install what the concept actually needs, not everything. A hyper-casual 2D
|
|
7
|
+
prototype needs far less than a 3D multiplayer RPG. Prefer packages already provided by the
|
|
8
|
+
chosen template (URP templates already include the render pipeline, Input System, etc.) — only
|
|
9
|
+
add what's missing. Don't pin exact versions unless a minimum is required; `Client.Add` without
|
|
10
|
+
a version resolves the latest compatible release.
|
|
11
|
+
|
|
12
|
+
The tables below are a starting point, not the whole registry. **Search the registry** to
|
|
13
|
+
discover packages beyond this list, confirm an id exists, or check available versions before
|
|
14
|
+
installing — see [Discovering and verifying packages](#discovering-and-verifying-packages).
|
|
15
|
+
|
|
16
|
+
## Discovering and verifying packages
|
|
17
|
+
|
|
18
|
+
Two ways to search, depending on whether the Editor is involved:
|
|
19
|
+
|
|
20
|
+
**In-Editor — the PackageManager Client API (preferred).** `Client.SearchAll()` returns every
|
|
21
|
+
package available in the project's configured registries (the Unity registry plus any scoped
|
|
22
|
+
registries), each with all its versions and metadata — this is what the Package Manager
|
|
23
|
+
window's search filters over. `Client.Search("<id>")` inspects a single package. Use the
|
|
24
|
+
ready-to-run `PackageSearch` script in the main `SKILL.md` to discover candidates and verify
|
|
25
|
+
ids/versions before building the install list.
|
|
26
|
+
|
|
27
|
+
**Terminal — query the npm-compatible registry directly** (no Editor needed) to confirm a
|
|
28
|
+
**known** id exists and list its versions:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Full metadata for one package: versions{}, dist-tags.latest, description, dependencies.
|
|
32
|
+
# -f makes curl fail (non-zero) on HTTP errors — e.g. a 404 for a bad id — instead of piping
|
|
33
|
+
# an error page into python; -L follows redirects.
|
|
34
|
+
curl -fsSL https://packages.unity.com/com.unity.cinemachine | python3 -m json.tool | head -40
|
|
35
|
+
|
|
36
|
+
# Just the latest published version
|
|
37
|
+
curl -fsSL https://packages.unity.com/com.unity.cinemachine \
|
|
38
|
+
| python3 -c "import sys,json;print(json.load(sys.stdin)['dist-tags']['latest'])"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Note: the registry supports fetching a **known** package id, but **not** free-text search over
|
|
42
|
+
HTTP (the npm `-/v1/search` endpoint is not available — it 404s). For keyword discovery, use
|
|
43
|
+
`Client.SearchAll()` in-Editor, the Package Manager window, or the
|
|
44
|
+
[Unity package documentation](https://docs.unity3d.com/Manual/pack-keys.html).
|
|
45
|
+
|
|
46
|
+
## Foundation (almost every project)
|
|
47
|
+
|
|
48
|
+
| Need | Package | Notes |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| Modern input | `com.unity.inputsystem` | Preferred over the legacy Input Manager. |
|
|
51
|
+
| Text / UI | `com.unity.ugui` | uGUI + TextMeshPro (bundled). UI Toolkit ships with the Editor. |
|
|
52
|
+
| Camera framing | `com.unity.cinemachine` | Great for almost any 3D and many 2D games. |
|
|
53
|
+
| Testing | `com.unity.test-framework` | Enables `unity test`; usually already present. |
|
|
54
|
+
| Large/streamed assets | `com.unity.addressables` | Add when the game has many assets or needs content updates. |
|
|
55
|
+
|
|
56
|
+
## Render pipeline (pick one; usually set by the template)
|
|
57
|
+
|
|
58
|
+
| Choice | Package | Use when |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| **URP** (Universal) | `com.unity.render-pipelines.universal` | Default for most 2D/3D, mobile, and WebGL. Broadest platform reach. |
|
|
61
|
+
| **HDRP** (High-Definition) | `com.unity.render-pipelines.high-definition` | High-fidelity PC/console only. Not for mobile/WebGL. |
|
|
62
|
+
| **Built-in** | (none) | Simplest/legacy; fine for tiny prototypes. |
|
|
63
|
+
|
|
64
|
+
## By dimension & look
|
|
65
|
+
|
|
66
|
+
| Look | Packages |
|
|
67
|
+
|---|---|
|
|
68
|
+
| **2D** (any) | `com.unity.2d.feature` (sprites, tilemap, animation, pixel-perfect bundle) |
|
|
69
|
+
| **2D pixel-perfect** | `com.unity.2d.pixel-perfect` (included in the 2D feature set) |
|
|
70
|
+
| **3D navigation** | `com.unity.ai.navigation` (NavMesh for AI/pathfinding) |
|
|
71
|
+
| **Cutscenes / sequencing** | `com.unity.timeline` |
|
|
72
|
+
| **No-code logic** | `com.unity.visualscripting` |
|
|
73
|
+
|
|
74
|
+
## By genre (starting points, combine with the above)
|
|
75
|
+
|
|
76
|
+
| Genre | Typical additions |
|
|
77
|
+
|---|---|
|
|
78
|
+
| Platformer / action | URP, Input System, Cinemachine, 2D feature (if 2D), AI Navigation (if 3D) |
|
|
79
|
+
| Puzzle / match / card | URP or 2D feature, Input System, uGUI/TextMeshPro, Timeline (juice) |
|
|
80
|
+
| Top-down / twin-stick | URP, Input System, Cinemachine, AI Navigation |
|
|
81
|
+
| RPG / adventure | URP, Input System, Cinemachine, AI Navigation, Addressables, Timeline |
|
|
82
|
+
| Racing / physics | URP, Input System, Cinemachine; Physics is built in |
|
|
83
|
+
| Idle / hyper-casual | 2D feature or URP, Input System, uGUI/TextMeshPro (keep it lean) |
|
|
84
|
+
| Multiplayer (any) | `com.unity.netcode.gameobjects` + Multiplayer Services → see **build-live-game** |
|
|
85
|
+
|
|
86
|
+
## By target platform
|
|
87
|
+
|
|
88
|
+
Platform support is mostly Editor **modules** (installed with `unity install --module …`, see
|
|
89
|
+
the **`unity-cli`** skill), not packages. Package-wise:
|
|
90
|
+
|
|
91
|
+
| Platform | Consider |
|
|
92
|
+
|---|---|
|
|
93
|
+
| Mobile (iOS/Android) | Keep dependencies lean; URP over HDRP; Addressables for download size; monetization below |
|
|
94
|
+
| WebGL | URP (not HDRP); small footprint; avoid heavy packages |
|
|
95
|
+
| Desktop / Console | URP or HDRP depending on fidelity target |
|
|
96
|
+
|
|
97
|
+
## By monetization — install now, integrate via the dedicated skill
|
|
98
|
+
|
|
99
|
+
| Goal | Package | Integration skill |
|
|
100
|
+
|---|---|---|
|
|
101
|
+
| In-app purchases | `com.unity.purchasing` | **implement-in-app-purchases** |
|
|
102
|
+
| Ads / mediation | `com.unity.services.levelplay` | **levelplay-unity-integration** |
|
|
103
|
+
| Accounts, cloud save, economy, remote config, leaderboards, analytics | see the UGS package table | **build-live-game** |
|
|
104
|
+
|
|
105
|
+
Install the package(s) here so the manifest is complete, but do the actual wiring by invoking
|
|
106
|
+
the matching skill. For the full UGS package/version matrix (`com.unity.services.core`,
|
|
107
|
+
`authentication`, `cloudsave`, `cloudcode`, `economy`, `remote-config`, `analytics`, etc.),
|
|
108
|
+
read the **build-live-game** skill.
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: urp-postprocessing
|
|
3
|
+
description: Sets up, configures, and debugs URP post-processing effects using the Volume framework. Use when the user asks about bloom, tonemapping, color adjustments, depth of field, vignette, motion blur, or other Volume overrides in a URP project.
|
|
4
|
+
required_packages:
|
|
5
|
+
com.unity.render-pipelines.universal: ">=14.0.0"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Help the user set up, configure, and debug post-processing effects using URP's Volume framework.
|
|
9
|
+
|
|
10
|
+
**Goal: The user should have a working visual result with zero console errors after setup.**
|
|
11
|
+
|
|
12
|
+
## 0. Prerequisite: an Editor you can run C# in
|
|
13
|
+
|
|
14
|
+
Volume profiles, `VolumeParameter.overrideState`, and the camera's post-processing flags are
|
|
15
|
+
Editor/runtime object state — the checks and edits below all run C# inside a live Editor.
|
|
16
|
+
|
|
17
|
+
**The `unity-cli` skill owns getting you there** — installing the CLI, confirming a connected
|
|
18
|
+
Editor, adding the project's `com.unity.pipeline` package, telling a genuinely absent Editor
|
|
19
|
+
apart from one stuck in Safe Mode, and discovering the Editor's command catalog. Follow it
|
|
20
|
+
first; don't re-derive any of it here. You need `eval` in particular, not just a reachable
|
|
21
|
+
Editor: its presence depends on the Pipeline package version, not on the CLI. If it's
|
|
22
|
+
missing, say so and stop.
|
|
23
|
+
|
|
24
|
+
Run C# through the connected Editor with the `eval` command. Discover its parameter shape
|
|
25
|
+
from `unity command --format json` rather than assuming one — the inline form is
|
|
26
|
+
`unity command eval --code '<snippet>'`, and some Pipeline versions also register
|
|
27
|
+
`eval_file` for running a snippet from a file. **Check the catalog before reaching for
|
|
28
|
+
`eval_file`; it is frequently absent.** `unity command` defaults to a 30 second timeout.
|
|
29
|
+
|
|
30
|
+
### Passing C# to `eval`
|
|
31
|
+
|
|
32
|
+
`eval` compiles a **statement block, not a file**. Two consequences, both of which cause a
|
|
33
|
+
compile error rather than a warning:
|
|
34
|
+
|
|
35
|
+
- **No `using` directives.** The compiler reads `using UnityEngine;` as a resource-disposal
|
|
36
|
+
statement and rejects it (`CS0210`).
|
|
37
|
+
- **Types must be fully qualified.** A bare `AssetDatabase` or `Volume` does not resolve
|
|
38
|
+
(`CS0246` / `CS0103`), and a bare `Object` is ambiguous with `object` (`CS0104`).
|
|
39
|
+
|
|
40
|
+
Where a snippet below is written as a file — with usings, for readability, or because it is
|
|
41
|
+
meant to be saved into the project — qualify the types before passing it to `eval`.
|
|
42
|
+
|
|
43
|
+
## 0. Pre-Flight Checks
|
|
44
|
+
|
|
45
|
+
Before configuring any effect, **verify all checks**. Fix failures first.
|
|
46
|
+
|
|
47
|
+
1. **URP is the active render pipeline** — If not, inform the user and stop.
|
|
48
|
+
2. **HDR is enabled on the URP Asset** — Required for Tonemapping. Bloom works best with HDR; in SDR it still works but `threshold` must be < 1.
|
|
49
|
+
3. **Camera has post-processing enabled** — `renderPostProcessing` must be `true` (defaults to `false`). Camera Stacking: only a `CameraRenderType.Base` camera (or the last `Overlay` in the stack) should enable post-processing. Also verify the Renderer's PostProcessData asset is not null — if it is, the post-process pass won't exist.
|
|
50
|
+
4. **The Volume's GameObject layer is in the Camera's Volume Layer Mask** — `volumeLayerMask` defaults to layer 0 "Default" only. The Volume's `GameObject.layer` must be included, otherwise the camera ignores it.
|
|
51
|
+
5. **Volume exists with `enabled = true`, a valid Profile, and at least one override** — The `Volume` component must be enabled, have a non-null `profile` (or `sharedProfile`), and at least one `VolumeComponent` with `overrideState = true` on its properties.
|
|
52
|
+
|
|
53
|
+
### Pre-Flight Check Snippet
|
|
54
|
+
|
|
55
|
+
Run this to verify the setup programmatically:
|
|
56
|
+
|
|
57
|
+
```csharp
|
|
58
|
+
// `eval` compiles a statement block, not a file: no `using` directives are
|
|
59
|
+
// allowed, so every type is fully qualified.
|
|
60
|
+
var report = new System.Text.StringBuilder();
|
|
61
|
+
|
|
62
|
+
// 1. Check URP is active — a hard stop, so throw: it fails the eval loudly
|
|
63
|
+
var urpAsset = UnityEngine.Rendering.Universal.UniversalRenderPipeline.asset;
|
|
64
|
+
if (urpAsset == null)
|
|
65
|
+
throw new System.Exception("URP is not the active render pipeline.");
|
|
66
|
+
|
|
67
|
+
// 2. Check HDR
|
|
68
|
+
if (!urpAsset.supportsHDR)
|
|
69
|
+
report.AppendLine("Warning: HDR is disabled on the URP Asset. Tonemapping won't work; Bloom requires threshold < 1.");
|
|
70
|
+
|
|
71
|
+
// 3. Check camera post-processing
|
|
72
|
+
var cam = UnityEngine.Camera.main;
|
|
73
|
+
if (cam == null)
|
|
74
|
+
throw new System.Exception("No Main Camera found.");
|
|
75
|
+
if (!cam.TryGetComponent<UnityEngine.Rendering.Universal.UniversalAdditionalCameraData>(out var camData))
|
|
76
|
+
throw new System.Exception("Missing UniversalAdditionalCameraData on camera. Is URP active?");
|
|
77
|
+
if (!camData.renderPostProcessing)
|
|
78
|
+
report.AppendLine("Warning: Post-processing is disabled on the camera. Enable via camData.renderPostProcessing = true.");
|
|
79
|
+
|
|
80
|
+
// 4. Check volume layer mask
|
|
81
|
+
var volumes = UnityEngine.Object.FindObjectsByType<UnityEngine.Rendering.Volume>(UnityEngine.FindObjectsSortMode.None);
|
|
82
|
+
foreach (var vol in volumes)
|
|
83
|
+
{
|
|
84
|
+
if (!vol.enabled) { report.AppendLine($"Warning: Volume '{vol.name}' is disabled."); continue; }
|
|
85
|
+
if ((camData.volumeLayerMask & (1 << vol.gameObject.layer)) == 0)
|
|
86
|
+
report.AppendLine($"Warning: Volume '{vol.name}' on layer {vol.gameObject.layer} is not in camera's volumeLayerMask.");
|
|
87
|
+
// 5. Check profile and overrides
|
|
88
|
+
var profile = vol.sharedProfile;
|
|
89
|
+
if (profile == null) { report.AppendLine($"Warning: Volume '{vol.name}' has no profile assigned."); continue; }
|
|
90
|
+
if (profile.components.Count == 0)
|
|
91
|
+
report.AppendLine($"Warning: Volume '{vol.name}' profile has no overrides.");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Return the findings: logs land in the Editor console, the returned value comes back to you
|
|
95
|
+
return report.Length == 0 ? "Post-processing setup looks correct." : report.ToString();
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 1. Volume Setup
|
|
99
|
+
|
|
100
|
+
Effects are added as **VolumeComponent overrides** on a **VolumeProfile** (a `ScriptableObject`).
|
|
101
|
+
|
|
102
|
+
**Global Volume** (most common): GameObject with `Volume` component, `isGlobal = true`, `profile` assigned. Affects every camera whose `volumeLayerMask` includes the Volume's layer.
|
|
103
|
+
|
|
104
|
+
**Local Volume (optional, but takes precedence)**: GameObject with trigger `Collider` + `Volume` component, `isGlobal = false`. Properties:
|
|
105
|
+
- `priority` (float) — higher values override lower when volumes overlap.
|
|
106
|
+
- `blendDistance` (float) — outer distance in world units to start blending from (0 = no blend, instant transition at collider boundary).
|
|
107
|
+
- `weight` (float, 0–1) — scales the volume's overall influence.
|
|
108
|
+
|
|
109
|
+
## 2. Post-Processing Effects
|
|
110
|
+
|
|
111
|
+
All effects are `VolumeComponent` subclasses added as overrides on a `VolumeProfile` via `profile.Add<T>()`. Check existence with `profile.Has<T>()` or `profile.TryGet<T>(out var t)`. Remove with `profile.Remove<T>()`.
|
|
112
|
+
|
|
113
|
+
Every property is a `VolumeParameter`. You **must** set `overrideState = true` before setting `value`, otherwise the Volume system ignores it.
|
|
114
|
+
|
|
115
|
+
When configuring a specific effect, load the full API reference:
|
|
116
|
+
- [references/effect-reference.md](references/effect-reference.md) — All VolumeComponent properties by effect (Bloom, Tonemapping, ColorAdjustments, DepthOfField, Vignette, MotionBlur, FilmGrain, ChromaticAberration, SplitToning, LensDistortion, WhiteBalance, PaniniProjection, LiftGammaGain, ShadowsMidtonesHighlights, ColorCurves, ChannelMixer)
|
|
117
|
+
|
|
118
|
+
For code templates:
|
|
119
|
+
- [references/code-templates.md](references/code-templates.md) — Global Volume setup, camera post-processing, and profile modification templates
|
|
120
|
+
|
|
121
|
+
## 3. Anti-Hallucination Rules
|
|
122
|
+
|
|
123
|
+
### Required Usings
|
|
124
|
+
|
|
125
|
+
These apply when you write a `.cs` file into the project. **A snippet passed to `eval` cannot
|
|
126
|
+
carry them** — qualify the types instead (see "Passing C# to `eval`" above).
|
|
127
|
+
|
|
128
|
+
```csharp
|
|
129
|
+
using UnityEngine.Rendering; // Volume, VolumeProfile, VolumeComponent, VolumeParameter
|
|
130
|
+
using UnityEngine.Rendering.Universal; // Bloom, Tonemapping, ColorAdjustments, UniversalRenderPipeline, etc.
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Wrong → Correct API Mapping
|
|
134
|
+
|
|
135
|
+
| WRONG | CORRECT |
|
|
136
|
+
|-------|---------|
|
|
137
|
+
| `PostProcessVolume` | `Volume` (from `UnityEngine.Rendering`) |
|
|
138
|
+
| `PostProcessLayer` | `UniversalAdditionalCameraData.renderPostProcessing` (bool) |
|
|
139
|
+
| `UnityEngine.Rendering.PostProcessing` | `UnityEngine.Rendering.Universal` |
|
|
140
|
+
| `profile.GetSetting<T>()` | `profile.TryGet<T>(out var t)` (returns bool) |
|
|
141
|
+
| `profile.AddSettings<T>()` | `profile.Add<T>()` (returns T; throws if already exists — check `profile.Has<T>()` first) |
|
|
142
|
+
| `volume.sharedProfile` (to modify at runtime) | `volume.profile` (auto-clones the asset into an instance) |
|
|
143
|
+
| `VolumeManager.instance.stack.GetComponent<T>()` | `volume.profile.TryGet<T>(out var t)` |
|
|
144
|
+
|
|
145
|
+
### Key Facts
|
|
146
|
+
- **`overrideState = true`** is required on every `VolumeParameter` you set. The volume system skips parameters where `overrideState` is `false`. This is the #1 scripting mistake.
|
|
147
|
+
- **`sharedProfile`** = returns the asset directly (edits persist to disk). **`profile`** = auto-clones into an instance if needed (safe for runtime edits). Check with `volume.HasInstantiatedProfile()`.
|
|
148
|
+
- **`profile.Add<T>(bool overrides = false)`** — pass `true` to auto-enable `overrideState` on all parameters of the added component.
|
|
149
|
+
|
|
150
|
+
## 4. Debugging Checklist
|
|
151
|
+
|
|
152
|
+
When post-processing isn't working, check in order:
|
|
153
|
+
|
|
154
|
+
1. `cam.TryGetComponent<UniversalAdditionalCameraData>(out var data)` succeeds and `data.renderPostProcessing` is `true`?
|
|
155
|
+
2. Volume exists in scene with a non-null `profile` (or `sharedProfile`) assigned?
|
|
156
|
+
3. Overrides added via `profile.Add<T>()` AND `overrideState = true` on each property you set?
|
|
157
|
+
4. Volume's `GameObject.layer` is included in camera's `data.volumeLayerMask`? (Default mask is layer 0 "Default" only.)
|
|
158
|
+
5. `volume.isGlobal = true` (for global), or camera is inside the Volume's trigger `Collider` (for local)?
|
|
159
|
+
6. Camera `data.renderType` is `CameraRenderType.Base`, not `Overlay`? (Overlay cameras composite onto the Base camera's output.)
|
|
160
|
+
7. `UniversalRenderPipeline.asset.supportsHDR` is `true`? Required for Bloom and Tonemapping.
|
|
161
|
+
8. Viewing in **Game view**? Scene view has a separate post-processing toggle in its toolbar.
|
|
162
|
+
|
|
163
|
+
## 5. Common Recipes
|
|
164
|
+
|
|
165
|
+
Format: Effect property=value. Bloom values are threshold/intensity/scatter.
|
|
166
|
+
|
|
167
|
+
**Cinematic (Film):** Tonemapping mode=ACES, ColorAdjustments contrast=15 saturation=-10, Bloom threshold=0.9 intensity=0.5 scatter=0.7, Vignette intensity=0.3 smoothness=0.4, FilmGrain type=Medium1 intensity=0.2
|
|
168
|
+
|
|
169
|
+
**Stylized/Vibrant:** Tonemapping mode=Neutral, ColorAdjustments saturation=20 contrast=10, Bloom threshold=0.8 intensity=1.5 scatter=0.6, SplitToning highlights=warm shadows=cool
|
|
170
|
+
|
|
171
|
+
**Horror/Dark:** ColorAdjustments postExposure=-0.5 saturation=-30 contrast=20, Vignette intensity=0.5 smoothness=0.3 color=dark-red, FilmGrain type=Large01 intensity=0.4, ChromaticAberration intensity=0.15
|
|
172
|
+
|
|
173
|
+
**Clean/Mobile:** Tonemapping mode=Neutral, ColorAdjustments postExposure=0.2, Bloom threshold=1.0 intensity=0.3 (subtle). Avoid FilmGrain, MotionBlur, DepthOfField on mobile.
|
|
174
|
+
|
|
175
|
+
## 6. Final Confirmation
|
|
176
|
+
|
|
177
|
+
After setup, report to user:
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
Post-Processing Setup Complete
|
|
181
|
+
- Volume: [Global/Local] on "[GameObject Name]"
|
|
182
|
+
- Profile: [Asset Path]
|
|
183
|
+
- Effects: [List with key property=value pairs]
|
|
184
|
+
- Camera: [Name] — renderPostProcessing=true, volumeLayerMask includes layer [N]
|
|
185
|
+
|
|
186
|
+
View results in Game view (not Scene view).
|
|
187
|
+
Undo all changes with Edit > Undo (Ctrl+Z).
|
|
188
|
+
```
|