Skip to main content
tutorial

Create Your First Unity Package: From GitHub to Package Manager

Angry Shark Studio
14 min
Unity Unity Package Manager UPM Git Tutorial Open Source Tools GitHub

Difficulty Level: Intermediate

What You’ll Learn

  • Unity Package Manager architecture and how it simplifies code distribution
  • Required package folder structure with Runtime, Editor, and Samples folders
  • Creating a package.json manifest with all essential fields and configuration
  • Setting up assembly definitions for proper code isolation and compilation control
  • Git version control best practices including .meta file handling
  • Testing packages locally before publishing to catch issues early
  • Publishing packages to GitHub with semantic versioning and release tags
  • Installing packages via Git URLs for one-click distribution
  • Adding optional samples and documentation for a better user experience
  • Converting existing Unity projects into professional packages

Quick Answer: Create a com.company.package folder with package.json, Runtime.asmdef, and Editor.asmdef files. Commit everything including .meta files to Git. Publish to GitHub and users install via Git URL in Package Manager. Takes 30-45 minutes for the first package.

You built an amazing debug visualizer for your Unity game. Your team loves it. Your Discord community wants it. Other developers keep asking, “Can you share the code?”

Sharing Unity code usually means messy zip files, manual imports, and outdated copies scattered across projects. When you fix bugs, users still run old versions. When they update Unity, your tool breaks, and they can’t get help.

Unity Package Manager solves this elegantly. Your tool becomes a proper package with a one-click installation via a Git URL. Users get automatic updates. Everything stays synchronized. The process is simpler than you think.

This guide walks through converting a real Unity project into a professional UPM package. We’ll use the Unity AI NPC Debugging Toolkit as a concrete example, but you can follow along with any Unity tool.

Unity Package Manager window showing Git URL installation dialog

Critical Development Environment Note: You ALWAYS develop Unity packages inside a Unity project with Unity Editor open. Your package folder (whether in Assets/ or Packages/) must be part of a Unity project for code compilation, testing, and .meta file generation. You cannot develop packages in isolation outside Unity. This guide will show you two valid approaches for where to place your package folder during development.

Unity Package Manager Overview

Unity Package Manager (UPM) is Unity’s official system for distributing reusable code and assets. Think of it like npm for JavaScript or pip for Python.

Why Create Packages?

Traditional asset distribution requires manual file copying, version tracking, and dependency management. Package Manager eliminates these problems.

Benefits over manual distribution:

  • Easy Installation: One Git URL vs. copying dozens of files
  • Version Control: Users update with one click, no manual downloads
  • Dependency Management: Automatically handles required packages
  • Code Isolation: Runs in separate assembly, preventing naming conflicts
  • Professional Standard: Industry-standard distribution method for Unity tools

Distribution Methods

UPM supports four distribution methods:

  1. Git URL (This Tutorial) - Free hosting on GitHub/GitLab/Bitbucket, no approval process
  2. Embedded Package - Copied into Packages folder, good for private internal tools
  3. Asset Store - Official Unity store, requires approval and revenue sharing
  4. Custom Registry - Advanced option for enterprise environments with private servers

Git URL distribution offers the best balance of simplicity and functionality. Users install packages directly from your repository. No fees, no approval process, no hosting costs. Updates happen through standard Git workflows.

Package Types

Packages fall into three categories based on their code:

  • Tool Packages: Editor utilities, build tools, debug visualizers, custom inspectors
  • Runtime Packages: Gameplay systems, AI behaviors, networking code, utility libraries
  • Hybrid Packages: Both runtime and editor code (most common)

Most packages are hybrid. Your runtime code implements functionality. Your editor code provides custom inspectors, scene view visualizations, or Unity Editor windows. The package structure accommodates both seamlessly.

Unity’s own packages use this same system. TextMeshPro, Cinemachine, and Input System, all distributed as UPM packages. Your package works identically to these professional tools.

Package Folder Structure

Unity packages follow strict folder conventions. Understanding this structure is critical because Unity won’t recognize packages that don’t match the expected format.

Required Structure

com.yourcompany.packagename/
├── package.json                    # REQUIRED: Package manifest
├── README.md                       # REQUIRED: User documentation
├── CHANGELOG.md                    # REQUIRED: Version history
├── LICENSE.md                      # REQUIRED: Usage terms
├── Runtime/                        # Runtime code (gameplay, utilities)
│   ├── Scripts/                   # Your C# scripts
│   │   ├── DebugVisualizer.cs
│   │   └── DebugLogger.cs
│   └── Runtime.asmdef             # REQUIRED: Assembly definition
├── Editor/                         # Editor-only code (inspectors, windows)
│   ├── Scripts/
│   │   └── DebugVisualizerEditor.cs
│   └── Editor.asmdef              # REQUIRED: Editor assembly definition
├── Tests/                          # Optional: Unit tests
│   ├── Runtime/
│   │   └── RuntimeTests.asmdef
│   └── Editor/
│       └── EditorTests.asmdef
├── Samples~/                       # Optional: Example scenes/prefabs
│   └── BasicDebugExample/
│       ├── Scenes/
│       └── Scripts/
└── Documentation~/                 # Optional: Extended docs
    └── TableOfContents.md

Naming Convention

The package folder name must follow this exact format: com.yourcompany.packagename

Rules:

  • All lowercase, no exceptions
  • No spaces or special characters (hyphens and periods only)
  • Use your reverse domain or GitHub username
  • Examples: com.angryshark.aidebugger, com.github.yourusername.toolname

The folder name must exactly match the name field in package.json. Unity uses this for package identification.

Runtime vs. Editor Folders

The separation between Runtime and Editor folders is fundamental:

Runtime Folder: Code that runs in builds. MonoBehaviours, gameplay systems, utility classes, and any code needed at runtime. This code compiles into game builds and runs on target platforms.

Editor Folder: Code that only runs in Unity Editor. Custom inspectors, editor windows, scene view tools, build processors. This code never appears in builds, keeping the build size smaller.

Both folders require separate assembly definitions. Unity treats them as distinct compilation units with different capabilities and restrictions.

Assembly Definitions

Assembly definition (.asmdef) files are required for package code isolation. They prevent naming conflicts and reduce compilation times by creating separate compilation units.

Without assembly definitions, Unity compiles all project code together. Your package code sees everything, and everything sees your package code. This creates conflicts when multiple packages define similar classes or when projects have naming collisions.

Tests Folder

The Tests folder is optional but recommended for professional packages. Unity’s Test Runner automatically discovers tests in this folder. The structure mirrors Runtime and Editor, with separate assembly definitions for each.

Tests improve package quality and give users confidence. They’re particularly valuable for complex logic or when supporting multiple Unity versions.

Samples~ Folder

Note the tilde (~) after “Samples”. Unity ignores folders with tildes during normal operations but exposes them through Package Manager’s “Samples” section.

This separation is intentional. Package code stays read-only in the Packages folder. Samples get imported to the Assets folder where users can modify them. This prevents users from accidentally editing package code while allowing experimentation with examples.

Package Development Workflows: Where to Create Your Package

One of the most confusing aspects of Unity package development is understanding WHERE to actually create and work on your package code. Unity supports two valid approaches, and choosing the right one depends on your distribution goals and workflow preferences.

The Critical Rule: Regardless of which approach you choose, you MUST develop your package inside a Unity project with Unity Editor open. Your package code needs Unity for compilation, testing, and .meta file generation.

Approach 1: Assets-Based Development

This approach places your package folder inside the Assets/ directory of your Unity project.

Unity Project Structure:

YourUnityProject/
├── Assets/
│   ├── Scenes/                          ← Your test scenes
│   ├── YourGameCode/                    ← Other project code
│   └── com.yourcompany.package/         ← DEVELOP YOUR PACKAGE HERE
│       ├── package.json
│       ├── Runtime/
│       ├── Editor/
│       └── README.md
├── Packages/
│   └── manifest.json
├── ProjectSettings/
└── Library/

Git Repository Structure: The entire Unity project becomes your Git repository, or just the Assets folder:

your-repo/
└── Assets/
    └── com.yourcompany.package/         ← Package folder with package.json

Users Install Via:

https://github.com/user/repo.git?path=Assets/com.yourcompany.package#v1.0.0

Real-World Examples:

  • VContainer (Assets/VContainer/)
  • UniRx
  • Many popular Asset Store packages

Benefits:

  • Traditional Unity workflow (everything in Assets)
  • Can ALSO export as .unitypackage for Asset Store distribution
  • Familiar for developers used to Assets folder
  • Single Unity project serves as both development and test environment
  • Easier mental model for beginners

Drawbacks:

  • Requires ?path= parameter in Git URL (slightly more complex)
  • Package mixed with development project files
  • Can’t easily separate package from development project

When to Use:

  • You plan to sell on Asset Store (.unitypackage required)
  • You’re converting existing Assets folder code to a package
  • You prefer working in the traditional Unity Assets structure
  • You want hybrid distribution (both UPM and .unitypackage)

Approach 2: Packages-Based Development

This approach places your package folder inside the Packages/ directory (or develops it as a standalone folder that gets embedded).

Unity Project Structure:

YourUnityProject/
├── Assets/                              ← Test scenes only
│   └── TestScenes/
├── Packages/
│   ├── manifest.json
│   └── com.yourcompany.package/         ← DEVELOP YOUR PACKAGE HERE
│       ├── package.json
│       ├── Runtime/
│       ├── Editor/
│       └── README.md
├── ProjectSettings/
└── Library/

Git Repository Structure: Option A - Package folder IS the repository root:

your-package-repo/                       ← Root directory
├── package.json
├── Runtime/
├── Editor/
├── README.md
└── CHANGELOG.md

Option B - Monorepo with separate package folder:

your-mono-repo/
├── PackageDevProject/                   ← Unity project for development
│   ├── Assets/
│   ├── Packages/
│   └── ProjectSettings/
└── com.yourcompany.package/             ← Package folder
    ├── package.json
    └── Runtime/

Users Install Via:

https://github.com/user/package.git#v1.0.0

(No ?path= needed if package is at root)

Real-World Examples:

  • Many official Unity packages
  • StansAssets packages structure
  • Professional package templates

Benefits:

  • Clean separation between package and development project
  • Simpler Git URL (no ?path parameter needed)
  • Package folder can be its own standalone repository
  • Recommended by Unity official documentation
  • Assets folder stays clean for test scenes only

Drawbacks:

  • Cannot export as .unitypackage for Asset Store
  • Slightly less intuitive for Unity beginners
  • Need to understand Packages folder purpose

When to Use:

  • Pure UPM distribution only (no Asset Store plans)
  • You want cleaner project structure
  • You’re starting from scratch
  • You prefer Unity’s official recommended approach

Development Workflow Comparison

Assets Approach:

  1. Open Unity Editor with your project
  2. Work on code in Assets/com.company.package/
  3. Test immediately in same project
  4. Commit changes, push to GitHub
  5. Users install via Git URL with ?path=Assets/com.company.package

Packages Approach:

  1. Open Unity Editor with your project
  2. Work on code in Packages/com.company.package/
  3. Test immediately in same project
  4. Initialize Git inside package folder (or whole repo)
  5. Push package folder as standalone repo
  6. Users install via simple Git URL

Which Approach Should You Choose?

Choose Assets-Based if:

  • You want Asset Store distribution (.unitypackage support)
  • You’re converting existing Assets folder code
  • You prefer traditional Unity workflows
  • You want a simpler mental model

Choose Packages-Based if:

  • Pure UPM distribution (GitHub/OpenUPM only)
  • You want cleaner project organization
  • You’re starting from scratch
  • You prefer Unity’s official approach

Both approaches are equally valid. Popular, professional packages use both methods. Choose based on your distribution goals and personal preference.

The rest of this tutorial applies to BOTH approaches. The core concepts (package.json, assembly definitions, Git workflow) are identical. The only difference is WHERE you place the package folder during development and the Git URL format users use for installation.

Documentation~ Folder

The Documentation~ folder also uses a tilde. It contains extended documentation, tutorials, API references, or integration guides.

Package Manager shows a “View Documentation” button linking to your documentationUrl. This can point to GitHub README, a dedicated documentation site, or HTML files in this folder.

Creating package.json Manifest

The package.json file is the most important file in your package. Unity reads this file to determine package identity, version, dependencies, and compatibility.

Complete Example

{
  "name": "com.angryshark.aidebugger",
  "version": "1.0.0",
  "displayName": "AI NPC Debug Toolkit",
  "description": "Debug tools for Unity AI NPCs. Visualize responses, validate character consistency, and catch API errors for ChatGPT, Claude, and Gemini integrations.",
  "unity": "2020.3",
  "unityRelease": "0f1",
  "documentationUrl": "https://github.com/angrysharkstudio/unity-ai-npc-debugging#readme",
  "changelogUrl": "https://github.com/angrysharkstudio/unity-ai-npc-debugging/blob/main/CHANGELOG.md",
  "licensesUrl": "https://github.com/angrysharkstudio/unity-ai-npc-debugging/blob/main/LICENSE.md",
  "dependencies": {},
  "keywords": [
    "ai",
    "debug",
    "npc",
    "chatgpt",
    "claude",
    "gemini",
    "tools"
  ],
  "author": {
    "name": "Angry Shark Studio",
    "email": "studio.angry.shark@gmail.com",
    "url": "https://www.angry-shark-studio.com"
  },
  "samples": [
    {
      "displayName": "Basic Debug Example",
      "description": "Simple scene demonstrating AI debug visualizer setup",
      "path": "Samples~/BasicDebugExample"
    }
  ]
}

Field Breakdown

name (REQUIRED)

Must match the folder name exactly. Format: com.company.package. Lowercase only, no spaces. This becomes the package identifier Unity uses internally.

version (REQUIRED)

Semantic versioning: MAJOR.MINOR.PATCH. Example: 1.0.0 for the initial release, 1.0.1 for bug fix, 1.1.0 for a new feature, 2.0.0 for breaking change. Each version should correspond to a Git tag for version locking.

displayName (REQUIRED)

Human-readable name shown in Package Manager UI. Can use spaces and capitals. Keep under 40 characters for proper display in a Package Manager window.

description (REQUIRED)

Short summary (1-2 sentences) shown in Package Manager. Include main features and use case. Keep under 200 characters. This text appears before users install, so make it clear and specific.

unity (REQUIRED)

Minimum Unity version required. Format: “2020.3” or “2022.3”. Test your package on this version before publishing. Users on older versions can’t install the package.

unityRelease (Optional)

Specific Unity patch version. Format: “0f1” for final release. Usually omit this unless you need specific patch features. Most packages work across patch versions within a Unity release.

documentationUrl (Recommended)

Link to GitHub README or documentation site. Shows the “View Documentation” button in Package Manager. Users click this when they need help or want to understand features before installing.

changelogUrl (Recommended)

Link to the CHANGELOG.md file. Shows the “View Changelog” button in Package Manager. Users check this to see what changed between versions before updating.

licensesUrl (Recommended)

Link to the LICENSE.md file. Important for open source packages. Users need to know usage terms, especially for commercial projects.

dependencies (Optional)

Other packages this package requires. Format: {"com.unity.textmeshpro": "3.0.6"}. Unity automatically installs dependencies when users add your package. Use empty object {} if no dependencies.

keywords (Recommended)

Array of search terms. Helps users discover your package when searching. Limit to 5-10 relevant terms. Focus on functionality and use cases, not generic terms.

author (Recommended)

Your contact information. All fields are optional but recommended for user support. Shows in a Package Manager details panel. Include URL for a website or repository.

samples (Optional)

Defines importable examples in the Samples~ folder. Each sample has a displayName, description, and path. Users see these in Package Manager and import them to the Assets folder when needed.

Assembly Definitions: Code Isolation

Assembly definitions (.asmdef files) control how Unity compiles your package code. They’re required for proper package functionality.

Why Assembly Definitions Matter

Without assembly definitions, Unity compiles all code together in the default Assembly-CSharp assembly. This causes several problems:

  • Slow Compilation: Changing one line triggers recompilation of the entire project
  • Naming Conflicts: Your package classes conflict with project classes of the same name
  • No Dependency Control: Can’t specify which code depends on what
  • Large Assemblies: Everything compiles into one massive DLL

Assembly definitions create separate compilation units. Your package code compiles independently. Changes to your package don’t trigger project recompilation and vice versa.

Runtime Assembly Definition

File: Runtime/Runtime.asmdef

{
    "name": "AngryShark.AIDebugger.Runtime",
    "rootNamespace": "AngryShark.AIDebugger",
    "references": [],
    "includePlatforms": [],
    "excludePlatforms": [],
    "allowUnsafeCode": false,
    "overrideReferences": false,
    "precompiledReferences": [],
    "autoReferenced": true,
    "defineConstraints": [],
    "versionDefines": [],
    "noEngineReferences": false
}

Editor Assembly Definition

File: Editor/Editor.asmdef

{
    "name": "AngryShark.AIDebugger.Editor",
    "rootNamespace": "AngryShark.AIDebugger.Editor",
    "references": [
        "AngryShark.AIDebugger.Runtime"
    ],
    "includePlatforms": [
        "Editor"
    ],
    "excludePlatforms": [],
    "allowUnsafeCode": false,
    "overrideReferences": false,
    "precompiledReferences": [],
    "autoReferenced": true,
    "defineConstraints": [],
    "versionDefines": [],
    "noEngineReferences": false
}

Key Fields Explained

name: Unique assembly name. Use reverse domain notation matching your namespace. This becomes the compiled DLL name.

rootNamespace: Default namespace for new scripts created in this folder. Unity automatically adds this namespace to new files.

references: Other assemblies this assembly depends on. Editor assembly must reference Runtime assembly to access runtime classes. Runtime assembly typically has no references, making it independent.

includePlatforms: Restrict assembly to specific platforms. Editor assembly MUST include only “Editor” platform. Runtime assembly leaves this empty to include all platforms.

excludePlatforms: Platforms to exclude. Usually leave empty. Use when assembly should compile everywhere except specific platforms.

autoReferenced: Should other assemblies automatically see this assembly? Set true for packages so project code can use your classes without manual assembly references.

allowUnsafeCode: Enable C# unsafe code blocks. Only set true if your package needs pointer manipulation or unmanaged memory access.

Creating Assembly Definitions in Unity

Right-click the folder in Unity’s Project window, select Create > Assembly Definition. Unity creates an ‘.asmdef’ file you can edit in Inspector or text editor.

The Inspector shows all fields with descriptions. For packages, you’ll typically only modify: name, rootNamespace, references, and includePlatforms.

Common Assembly Definition Mistakes

Forgetting Runtime Reference in Editor Assembly: Editor scripts get “type not found” errors when trying to use runtime classes. Always add Runtime assembly to Editor assembly’s ‘references’ array.

Wrong Platform Settings: Editor assembly without “Editor” in includePlatforms tries to compile into builds, causing build failures. Runtime assembly with platform restrictions might not work on all targets.

Circular References: Assembly A references Assembly B which references Assembly A creates circular dependency. Keep Runtime assembly independent and only reference it from Editor.

Version Control Setup with Git

Git version control is essential for package distribution. Unity Package Manager installs directly from Git repositories, so proper Git setup is required.

Initializing Git Repository

# Navigate to package folder
cd com.angryshark.aidebugger

# Initialize Git
git init

# Create .gitignore
touch .gitignore

Essential .gitignore for Unity Packages

# Unity-generated meta files are REQUIRED for packages
# Do NOT ignore .meta files!

# OS files
.DS_Store
Thumbs.db

# IDE files
.vs/
.vscode/
.idea/
*.suo
*.user

# Unity temp files (outside package folder)
[Tt]emp/
[Oo]bj/
[Ll]ibrary/

# Documentation build output (if using DocFX or similar)
Documentation~/html/
Documentation~/api/

# Test results
TestResults/

Critical: DO NOT Ignore .meta Files

This is the most common mistake when creating Unity packages. Unity generates .meta files for every asset containing:

  • Unique GUIDs that Unity uses to track assets
  • Import settings for textures, models, and audio
  • Reference links between assets

Without .meta files in your repository:

  • Unity generates new random GUIDs when users install
  • All references break (missing script errors appear)
  • Prefabs lose connections to scripts
  • ScriptableObjects become empty shells

Your .gitignore should NOT contain .meta anywhere. Commit all .meta files. This is different from normal Unity projects where .meta files in the Library folder get ignored. For packages, every .meta file matters.

Creating Essential Documentation Files

README.md Template

# AI NPC Debug Toolkit

Debug tools for Unity AI NPCs using ChatGPT, Claude, or Gemini.

## Installation

1. Open Unity Package Manager
2. Click + → Add package from git URL
3. Paste: `https://github.com/angrysharkstudio/unity-ai-npc-debugging.git`

## Features

- Real-time AI response visualization
- Character consistency validation
- API error detection and logging
- Performance monitoring

## Quick Start

[Brief usage instructions with code example]

## Documentation

Full documentation available at [link]

## Requirements

- Unity 2020.3 or newer
- TextMeshPro

## Support

Report issues at https://github.com/angrysharkstudio/unity-ai-npc-debugging/issues

## License

MIT License - see LICENSE.md

CHANGELOG.md Template

# Changelog

All notable changes to this package will be documented in this file.

## [1.0.0] - 2025-10-05

### Added
- Initial release
- AI response visualizer component
- Character consistency validator
- Debug a logging system with filtering
- Example scene with setup instructions

### Changed
- None

### Fixed
- None

LICENSE.md

Choose an appropriate open source license. MIT License is popular for Unity tools because it’s permissive and simple. Include the full license text in this file.

Testing Packages Locally

Before publishing to GitHub, test your package thoroughly in a clean Unity project. Local testing catches issues that are hard to fix after publishing.

Important: If you’re developing using either the Assets-Based or Packages-Based approach, your package is ALREADY in your development Unity project and automatically available for testing. You can test it immediately by creating test scenes in your Assets folder. The methods below are for testing in a SEPARATE clean Unity project to verify the package works correctly in isolation.

Method 1: Install from Disk

This method tests package structure and Unity recognition:

  1. Open Unity Package Manager (Window → Package Manager)
  2. Click + dropdown in the top-left corner
  3. Select “Add package from disk…”
  4. Navigate to your package folder
  5. Select the package.json file
  6. Unity installs the package from local files

Benefits: Instant feedback on package structure issues. No Git setup is required. Easy to iterate rapidly during development.

Limitations: Doesn’t test Git installation workflow. Changes require removing and reimporting. Doesn’t validate version tags or Git-specific features.

Method 2: Local Git Repository

This method tests the complete Git installation workflow:

# In your test Unity project
cd Packages

# Clone your package directly into Packages folder
git clone /path/to/your/package/folder com.angryshark.aidebugger

Benefits: Tests real installation environment. Validates Git structure. Can test branch switching and version tags.

Limitations: Requires Git setup. Changes need commit and Unity reimport. More complex than disk installation.

Testing Checklist

Work through this checklist systematically:

  • Package appears in Package Manager with the correct name and description
  • All scripts compile without errors or warnings
  • Runtime code functions correctly in Play mode
  • Editor code functions correctly in Edit mode (custom inspectors, windows)
  • Samples shown in the Package Manager “Samples” section
  • Samples import correctly and work without modification
  • Documentation links open to correct URLs
  • No console errors or warnings after installation
  • Package works in a completely fresh Unity project
  • Package works with a minimum Unity version specified in package.json

Common Issues During Testing

Package doesn’t appear in Package Manager: Validate package.json syntax at jsonlint.com. Check that the folder name matches the package.json name field exactly. Verify all required fields are present.

Missing script errors: Check that all .meta files are committed to the repository. Verify Runtime.asmdef exists in the Runtime folder and Editor.asmdef exists in the Editor folder.

Compilation errors: Verify Editor.asmdef references Runtime assembly in ‘references’ array. Check that the includePlatforms array contains “Editor” for Editor assembly.

Samples don’t show: Verify Samples~ folder uses tilde character. Check that the samples array in package.json has correct paths matching actual folders.

Publishing to GitHub

GitHub provides free hosting for Git repositories, making it the ideal platform for Unity package distribution.

Creating a GitHub Repository

# Create repository on GitHub.com first, then:
git remote add origin https://github.com/yourusername/your-package.git

# Add all files (including .meta files)
git add .

# First commit
git commit -m "Initial package release v1.0.0"

# Push to GitHub
git push -u origin main

Repository Setup Best Practices

Configure your GitHub repository for maximum discoverability:

  • Description: Use the same description from package.json
  • Topics/Tags: Add “unity”, “unity-package”, “upm”, “unity3d”
  • README: Make sure README.md is visible and well-formatted on repository home
  • License: Add a license file through GitHub’s license chooser or manually
  • Issues: Enable Issues for user support and bug reports

Creating Releases with Semantic Versioning

Git releases allow users to install specific versions of your package. Each release corresponds to a version tag.

# Tag version matching package.json version
git tag v1.0.0

# Push tag to GitHub
git push origin v1.0.0

Creating a Release on GitHub

  1. Go to your repository on GitHub
  2. Click “Releases” in the right sidebar
  3. Click “Create a new release”
  4. Choose your tag (v1.0.0) or create a new tag
  5. Release title: “Version 1.0.0”
  6. Description: Copy content from CHANGELOG.md for this version
  7. Click “Publish release”

Semantic Versioning Rules

Semantic versioning (SemVer) uses three numbers: MAJOR.MINOR.PATCH

MAJOR Version (1.0.0 → 2.0.0): Breaking changes that require users to update their code. Renamed methods, removed features, changed the behavior of existing features. Users must read release notes and modify their code.

MINOR Version (1.0.0 → 1.1.0): New features that are backward compatible. Added methods, new components, additional functionality. Existing code continues working without changes.

PATCH Version (1.0.0 → 1.0.1): Bug fixes only. No new features, no breaking changes. Pure fixes for issues in existing functionality.

Example version history:

v1.0.0 - Initial release with core features
v1.0.1 - Fixed null reference in DebugVisualizer
v1.0.2 - Fixed performance issue with large logs
v1.1.0 - Added response caching feature
v1.1.1 - Fixed cache invalidation bug
v2.0.0 - Refactored API, renamed DebugLogger to ConsistencyLogger (breaking)

Updating Package Versions

When releasing a new version:

  1. Update version field in package.json
  2. Add an entry to CHANGELOG.md with date and changes
  3. Commit changes: git commit -m "Release v1.1.0"
  4. Create Git tag: git tag v1.1.0
  5. Push commits: git push
  6. Push tag: git push origin v1.1.0
  7. Create a GitHub release with a changelog entry

Branch Strategy

Use a simple branch strategy for package development:

  • main branch: Stable releases only. Every commit should be a release.
  • develop branch: Work-in-progress features and bug fixes.
  • Feature branches: Individual features or fixes branch from the ‘develop’ branch.

Merge to main only when ready to release. Tag main branch commits with version numbers. Users installing from main always get the latest stable release.

Installing from Git URLs

Users install your package through Unity Package Manager using the Git URL. The process is simple and works identically to official Unity packages.

Step-by-Step Installation

  1. Open Unity Package Manager (Window → Package Manager)
  2. Click the + dropdown in the top-left corner
  3. Select “Add package from git URL…”
  4. Paste the Git URL
  5. Click “Add”
  6. Unity downloads and installs the package automatically

The package appears in the Package Manager under “Packages - Custom”. Users can remove it, update it, or view documentation through the standard Package Manager interface.

URL Formats

Unity Package Manager supports several Git URL formats for different installation scenarios.

Latest Version (main branch)

https://github.com/angrysharkstudio/unity-ai-npc-debugging.git

Installs the latest commit from the main branch. Updates when users remove and reinstall.

Specific Version Tag

https://github.com/angrysharkstudio/unity-ai-npc-debugging.git#v1.0.0

Locks to a specific release version. Users won’t get updates automatically. Recommended for production projects requiring stability.

Specific Branch

https://github.com/angrysharkstudio/unity-ai-npc-debugging.git#develop

Installs from a specific branch. Useful for testing development versions or accessing features not yet in the main branch.

Specific Commit

https://github.com/angrysharkstudio/unity-ai-npc-debugging.git#a1b2c3d4e5f6

Locks to the exact commit hash. Maximum stability, completely immutable. Used when even patch updates must be controlled.

Subfolder in Repository (Assets-Based Approach)

https://github.com/yourusername/repo.git?path=/Assets/com.company.package#v1.0.0

Use this format for the Assets-Based Development approach where package.json is in a subfolder (like Assets/com.company.package/). The ?path= parameter tells Unity where to find the package within the repository.

Manual Installation via manifest.json

Advanced users can manually edit Packages/manifest.json to add packages:

{
  "dependencies": {
    "com.angryshark.aidebugger": "https://github.com/angrysharkstudio/unity-ai-npc-debugging.git#v1.0.0",
    "com.unity.textmeshpro": "3.0.6"
  }
}

Unity automatically installs packages when it detects manifest changes. This method allows scripted package installation or configuration management.

Version Locking Behavior

Without version tag in URL: Unity installs the latest commit from a specified branch. Unity doesn’t automatically update packages, but users can update by removing and reinstalling or updating through the Package Manager UI.

With version tag in URL: Unity locks to that specific release. Users must manually change the URL or tag to update. Recommended for production projects where unexpected changes would be problematic.

Private Repositories

Git URLs work with private repositories if users have access. Unity uses system Git credentials:

SSH URLs: git@github.com:username/private-repo.git - Requires SSH key configured in GitHub settings HTTPS with Token: https://token@github.com/username/private-repo.git - Use personal access token for authentication

Private packages work identically to public packages once authentication is configured. Useful for internal company tools or client-specific solutions.

Troubleshooting Installation

“Unable to find package”: Verify the repository URL is correct and the repository is public (or the user has access if private). Check that package.json exists in the repository root.

“Invalid package.json”: Validate JSON syntax at jsonlint.com. Ensure all required fields are present: name, version, displayName, description, unity.

“Package version not found”: Check that Git tag exists on GitHub. Verify the tag name matches the URL exactly (include ‘v’ prefix if used).

Long installation time: Large repositories with history take time to clone. Consider using Git LFS for large binary assets or keeping package repositories focused and small.

Real Example: AI Debugging Toolkit Conversion

Converting an existing Unity project into a package requires reorganizing files, creating a package structure, and setting up Git properly. Here’s the complete process using our AI debugging toolkit as a real example.

Note: This example shows the package structure and Git workflow that applies to BOTH development approaches (Assets-Based and Packages-Based). The steps are the same regardless of whether you place your package folder in Assets/ or Packages/ during development. See the “Package Development Workflows” section above to choose your preferred approach.

Original Project Structure

Assets/
├── Scripts/
│   ├── DebugVisualizer.cs
│   ├── NpcCharacterConsistency.cs
│   └── ConsistencyLogger.cs
├── Editor/
│   └── DebugVisualizerEditor.cs
└── Examples/
    └── DebugExample.unity

Step 1: Create a Package Folder

# Create package folder with proper naming
mkdir com.angryshark.aidebugger
cd com.angryshark.aidebugger

Step 2: Organize Runtime Code

# Create Runtime folder structure
mkdir -p Runtime/Scripts

# Move runtime scripts from Assets to Runtime
# (Copy files from Unity project to package folder)
# DebugVisualizer.cs
# NpcCharacterConsistency.cs
# ConsistencyLogger.cs

All MonoBehaviours, ScriptableObjects, and utility classes go in Runtime. Anything that needs to exist at runtime or compile into builds goes here.

Step 3: Organize Editor Code

# Create Editor folder structure
mkdir -p Editor/Scripts

# Move editor scripts
# DebugVisualizerEditor.cs (custom inspector)

Custom inspectors, editor windows, menu items, and other Unity Editor extensions go in the Editor folder.

Step 4: Create Assembly Definitions

Create Runtime/Runtime.asmdef:

{
    "name": "AngryShark.AIDebugger.Runtime",
    "rootNamespace": "AngryShark.AIDebugger",
    "references": [],
    "includePlatforms": [],
    "excludePlatforms": [],
    "allowUnsafeCode": false,
    "autoReferenced": true
}

Create Editor/Editor.asmdef:

{
    "name": "AngryShark.AIDebugger.Editor",
    "rootNamespace": "AngryShark.AIDebugger.Editor",
    "references": ["AngryShark.AIDebugger.Runtime"],
    "includePlatforms": ["Editor"],
    "excludePlatforms": [],
    "allowUnsafeCode": false,
    "autoReferenced": true
}

Note that Editor assembly references Runtime assembly and restricts to an Editor platform.

Step 5: Move Examples to Samples

# Create Samples folder (with tilde)
mkdir -p Samples~/BasicExample/Scenes
mkdir -p Samples~/BasicExample/Scripts

# Move example scene and any example scripts
# DebugExample.unity

Examples become importable samples. Users choose whether to import them, keeping their Assets folder clean.

Step 6: Create package.json

{
  "name": "com.angryshark.aidebugger",
  "version": "1.0.0",
  "displayName": "AI NPC Debug Toolkit",
  "description": "Debug tools for Unity AI NPCs. Visualize responses, validate character consistency, and catch API errors for ChatGPT, Claude, and Gemini integrations.",
  "unity": "2020.3",
  "documentationUrl": "https://github.com/angrysharkstudio/unity-ai-npc-debugging#readme",
  "changelogUrl": "https://github.com/angrysharkstudio/unity-ai-npc-debugging/blob/main/CHANGELOG.md",
  "licensesUrl": "https://github.com/angrysharkstudio/unity-ai-npc-debugging/blob/main/LICENSE.md",
  "dependencies": {},
  "keywords": ["ai", "debug", "npc", "chatgpt", "claude", "gemini", "tools"],
  "author": {
    "name": "Angry Shark Studio",
    "email": "info@angry-shark-studio.com",
    "url": "https://angry-shark-studio.com"
  },
  "samples": [
    {
      "displayName": "Basic Debug Example",
      "description": "Simple scene demonstrating AI debug visualizer setup",
      "path": "Samples~/BasicExample"
    }
  ]
}

Step 7: Add Documentation

Create README.md with installation instructions, features, quick start guide, and support information.

Create CHANGELOG.md with the initial version entry.

Create LICENSE.md with a chosen open source license (MIT recommended).

Step 8: Initialize Git

# Initialize Git repository
git init

# Create .gitignore (do NOT ignore .meta files)
cat > .gitignore << EOF
.DS_Store
Thumbs.db
.vs/
.vscode/
.idea/
EOF

# Add all files including .meta
git add .

# First commit
git commit -m "Initial package release v1.0.0"

Step 9: Test Locally

Before publishing, test thoroughly:

  1. Create a fresh Unity project (File → New Project)
  2. Open Package Manager
  3. Add package from disk (select package.json)
  4. Verify package appears correctly
  5. Import BasicExample sample
  6. Test functionality in an example scene
  7. Check for console errors or warnings
  8. Verify custom inspector displays correctly

Step 10: Publish to GitHub

# Create repository on GitHub, then:
git remote add origin https://github.com/angrysharkstudio/unity-ai-npc-debugging.git
git push -u origin main

# Create first release tag
git tag v1.0.0
git push origin v1.0.0

Create a GitHub release through the web interface with changelog content.

Before/After Comparison

Before Package Conversion:

  • Distribution: Zip file uploaded to Google Drive or sent directly
  • Installation: Unzip, copy 15+ files manually into the Assets folder
  • Updates: Users manually delete old files, copy new files
  • Version tracking: Users don’t know which version they have
  • Setup time: 10-15 minutes per project

After Package Conversion:

  • Distribution: Single Git URL
  • Installation: Paste URL in Package Manager, click Add
  • Updates: Remove and reinstall the package (30 seconds)
  • Version tracking: Clear version number in Package Manager
  • Setup time: 30 seconds per project

The user experience improvement is substantial. Package Manager makes your tools more accessible and maintainable.

Troubleshooting Common Issues

Package creation involves many moving parts. Here are solutions to common problems.

Package Doesn’t Appear in Package Manager

Symptoms: Added package from disk or Git URL, but nothing appears in Package Manager.

Causes and Fixes:

  1. Invalid package.json syntax: Validate JSON at jsonlint.com. Common mistakes include missing commas, trailing commas, or unquoted strings.

  2. Folder name mismatch: Folder name must exactly match name field in package.json. Check for typos, case differences, or extra characters.

  3. Missing required fields: Verify package.json contains name, version, displayName, description, and unity fields. All are required.

  4. Wrong Unity version: If package.json specifies unity: “2022.3” but you’re using Unity 2021.3, the package won’t appear. Lower the minimum version or upgrade Unity.

”Missing Script” Errors After Installation

Symptoms: Package installs but GameObjects show “Missing Script” components. Prefabs lose all references.

Cause: Missing .meta files in repository. Without .meta files, Unity generates new random GUIDs when users install, breaking all references.

Fix:

# Remove .meta from .gitignore if present
# Add all .meta files to repository
git add *.meta
git add Runtime/*.meta Runtime/Scripts/*.meta
git add Editor/*.meta Editor/Scripts/*.meta
git commit -m "Add meta files"

# Create new release
git tag v1.0.1
git push origin v1.0.1

Users must remove the package and reinstall it from a new version. Emphasize in the documentation that .meta files are critical.

Scripts Don’t Compile

Symptoms: Package installs but scripts show compilation errors.

Causes and Fixes:

  1. Missing assembly definition reference: Editor scripts can’t see Runtime types. Fix: Add Runtime assembly to Editor.asmdef references array.

  2. Wrong platform settings: Runtime code restricted to a specific platform causes issues. Fix: Leave Runtime.asmdef includePlatforms empty.

  3. Namespace conflicts: Package classes conflict with project classes. Fix: Use unique namespace matching your company/username.

Samples Don’t Show in Package Manager

Symptoms: Package installs but no samples appear in a Package Manager samples section.

Causes and Fixes:

  1. Missing tilde: Folder named “Samples” instead of “Samples~”. Fix: Rename folder to include tilde.

  2. Wrong paths in package.json: Paths in a ‘samples’ array don’t match actual folders. Fix: Verify paths match exactly, including a case.

  3. Invalid samples syntax: JSON syntax error in a samples array. Fix: Validate JSON, ensure each sample has a displayName, description, and path.

Git URL Installation Fails

Symptoms: Unity shows the “Unable to add package” error when installing from Git URL.

Causes and Fixes:

  1. Repository is private: User lacks access. Fix: Make the repository public or grant user access through GitHub collaborators.

  2. Invalid URL format: Typo in URL or wrong format. Fix: Copy URL directly from the GitHub repository page, ensure .git extension is included.

  3. Package not in root: package.json is in a subfolder. Fix: Add ?path=/subfolder/path to URL or restructure repository with package in root.

  4. Git isn’t installed: User doesn’t have Git installed. Fix: Install Git from git-scm.com.

Unity Package Manager Cache Problems

Symptoms: Package seems stuck on an old version, or Unity shows cached errors.

Fix: Clear Unity Package Manager cache:

# Close Unity first

# Windows:
del /s /q "%APPDATA%\Unity\Asset Store-5.x"

# macOS:
rm -rf ~/Library/Unity/Asset\ Store-5.x

# Linux:
rm -rf ~/.config/unity3d/Asset\ Store-5.x

Restart Unity and reinstall package.

Next Steps

You’ve created a professional Unity package. Here’s what to do next:

Improve Package Quality:

  • Add unit tests with Unity Test Framework
  • Create additional samples for common use cases
  • Write comprehensive API documentation
  • Add tooltips and help URLs to custom inspectors

Build Community:

  • Share on Unity Forums in the “Showcase” section
  • Post to r/Unity3D subreddit
  • Tweet with #unity3d and #gamedev hashtags
  • Add to Unity Discord server channels
  • Consider open source promotion sites

Expand Distribution:

  • Submit to OpenUPM registry for easier discovery
  • Create a video tutorial showing installation and usage
  • Write a blog post about a package creation process
  • Build portfolio showcasing your Unity tools

Maintain and Update:

  • Watch GitHub Issues for user problems
  • Release regular updates with bug fixes
  • Add requested features in minor version updates
  • Update for new Unity versions as they release

Package creation opens new opportunities. Your tools can reach thousands of developers. Good packages become portfolio pieces demonstrating professional Unity development skills. Start with one package. Learn the process. Then create more.

The Unity development community benefits when developers share tools. Your package might solve problems for developers worldwide. Package Manager makes this sharing professional and sustainable.

Angry Shark Studio Logo

About Angry Shark Studio

Angry Shark Studio is a professional Unity AR/VR development studio specializing in mobile multiplatform applications and AI solutions. Our team includes Unity Certified Expert Programmers with extensive experience in AR/VR development.

Related Articles

More Articles

Explore more insights on Unity AR/VR development, mobile apps, and emerging technologies.

View All Articles

Need Help?

Have questions about this article or need assistance with your project?

Get in Touch