Tech Journal - Develop Unity package INSIDE a Unity Project
Created on: 13 Mar 25 11:19 +0700 by Son Nguyen Hoang in English
A flow of development when you are doing Unity project and build custom framework at the same time
Motivation
I encountered a funny problem when coding a Unity Game. To increase the reusability while making game, I also develop a Framework. This framework would be an Unity Package. The thing is that the GAME itself also relies on the framework, which basically mean that I cannot modify and update the framework directly. So, what is the work arround?
Problem Statement
Foundation
- The game is refered as FAW (Codename)
- The framework is SysiphusFramework.
- I am NOT the only one working at the game. Because of the, SysiphusFramework exists as a UnityPackage that is added to Unity Project through
git url
- By doing so, the
framework
itself is part of the game (insideFAW Folder
). However, it now stays inLibrary
(notAssets
folder), thus we cannot modify it - So, as a developer who are making the framework, how to edit it?
Solution
Ideas
The logic is to create a DEFINITION
(in Unity Editor). In the Editor
, we now refer the DEFINITION
as USE_GIT_FRAMEWORK
. If USE_GIT_FRAMEWORK
existed, then the project would remove the package from the library. Developers of the package now would have to clone the actual git repository
of the framework into the project (into Assets
folder) to make update.
The skillful programmer then can use any git client
to set skip checking on that assets folder (to not be included in git
), then manually modify on that repo onced required. This framework repo although located inside Assets/
but it can still be opened by git
. Thus, for each modification, you can safely commit/push it to the framework remote origin.
But How to Remove the package from Library/
Using my script below, replace the RemovePackageSymbol
and your package url
#if UNITY_EDITOR
using System.IO;
using UnityEngine;
using UnityEditor;
using UnityEditor.PackageManager;
using Newtonsoft.Json.Linq;
[InitializeOnLoad]
public static class ConditionalPackageManager
{
private const string PackageUrl = "https://github.com/sonnguyen9800/Sisyphus-UniFramework.git";
private const string DefineSymbol = "USE_SISYPHUS_PACKAGE";
private const string RemovePackageSymbol = "USE_GIT_SISYPHUSFW";
static ConditionalPackageManager()
{
if (HasDefine(RemovePackageSymbol))
{
RemovePackage(PackageUrl);
}
else
{
AddPackage(PackageUrl);
}
}
private static bool HasDefine(string define)
{
string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
return defines.Contains(define);
}
private static void AddPackage(string packageUrl)
{
var manifestPath = Path.Combine(Application.dataPath, "../Packages/manifest.json");
var json = JObject.Parse(File.ReadAllText(manifestPath));
if (!json["dependencies"].ToObject<JObject>().ContainsKey(packageUrl))
{
Debug.Log($"Adding package: {packageUrl}");
Client.Add(packageUrl);
}
}
private static void RemovePackage(string packageUrl)
{
var manifestPath = Path.Combine(Application.dataPath, "../Packages/manifest.json");
var json = JObject.Parse(File.ReadAllText(manifestPath));
if (json["dependencies"].ToObject<JObject>().ContainsKey(packageUrl))
{
Debug.Log($"Removing package: {packageUrl}");
var request = Client.Remove(packageUrl);
EditorApplication.update += () =>
{
if (request.IsCompleted)
{
Debug.Log($"Package {packageUrl} removed.");
EditorApplication.update -= () => {};
}
};
}
}
}
#endif
The actual flow
So from the designers or thoses who do not work on the Framework. What they do is clone the project. The definition
is not there. Thus what they got is
If you want to start modifying the Framework, here are what you gonna do
Ending thoughts
I may consider build a custom tool with rich GUI to handle this more efficiency!