Hello Unity community,
I’m currently building a custom Unity package hosted on GitHub that has dependencies on other GitHub-based packages. Since Unity doesn’t support adding direct GitHub package links as dependencies in the package.json
, I’ve been working on a solution to dynamically install these packages whenever the main package loads.
To avoid compilation errors due to missing namespaces from those dependencies, I’ve wrapped the dependent parts of my code in custom define symbols (like #if MY_PACKAGE_INSTALLED
). However, I’m running into an issue where these define symbols are not recognized during the initial compilation, causing Unity to throw namespace and assembly errors.
The issue:
- I can’t find a way to make Unity set these define symbols before the rest of the package compiles.
- When the package loads, Unity compiles everything at once, including the code inside
#if MY_PACKAGE_INSTALLED
blocks, even though the define symbols haven’t been set yet. This causes the compilation to fail because the package dependencies aren’t available, and the directives are unknown at compile time.
What I’ve Tried:
I’ve tried using a PackageDefineChecker
script to check if the necessary dependencies are installed (by inspecting the manifest.json
file) and then dynamically set the define symbols. Here’s an example of what I tried using a single package as an example:
using UnityEditor;
using UnityEngine;
using System.IO;
using System.Collections.Generic;
namespace MyPackage.Editor
{
[InitializeOnLoad]
public class PackageDefineChecker
{
static PackageDefineChecker()
{
CheckAndSetDefines();
}
private static void CheckAndSetDefines()
{
string manifestPath = Path.Combine(Application.dataPath, "../Packages/manifest.json");
if (!File.Exists(manifestPath))
{
Debug.LogError("Manifest file not found.");
return;
}
string manifest = File.ReadAllText(manifestPath);
bool hasMyDependency = manifest.Contains("com.mygithub.package");
SetDefineSymbol("MY_PACKAGE_INSTALLED", hasMyDependency);
}
private static void SetDefineSymbol(string symbol, bool shouldSet)
{
var currentDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
var definesList = new List<string>(currentDefines.Split(';'));
if (shouldSet && !definesList.Contains(symbol))
{
definesList.Add(symbol);
}
else if (!shouldSet && definesList.Contains(symbol))
{
definesList.Remove(symbol);
}
PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, string.Join(";", definesList.ToArray()));
}
}
}
In my package, I conditionally wrap the code with:
#if MY_PACKAGE_INSTALLED
using MyPackageNamespace;
namespace MyPackage.Editor
{
public class MyCustomEditor : Editor
{
// Code dependent on the package
}
}
#endif
The problem is that Unity tries to compile everything at once, including the code inside the #if MY_PACKAGE_INSTALLED
block, before the PackageDefineChecker
runs and sets the define symbol. As a result, Unity throws namespace errors because the dependent package hasn’t been loaded yet.
Question:
Is there a way to set custom define symbols before the rest of the package is compiled, or is there another way to handle package dependencies dynamically without running into these compilation errors?
Any advice or alternative approaches would be greatly appreciated. Thanks in advance!