tldr; If you have a top-level custom asmdef in your Assets folder, you need an Editor asmdef in the Editor folder that only targets the Editor and references any assemblies you use in it.
I’ve solved this during writing this up, so adding it in full for others.
Detail
I want to set the product version number on the command line build (aka batchmode) so that the number can be easily reused by git tag and Steam upload.
In both my attempts, the custom code cannot use the required Editor classes.
Failed Attempt 1 - executeMethod
I attempted to pass in command line parameters using a static Build method in the Assets/Editor folder.
namespace Lang.Clomper.EditorExtensions
{
public static class Build
{
public static void SetBundleVersionNumber()
{
string[] args = System.Environment.GetCommandLineArgs();
for (var i = 0; i < args.Length; i++)
{
var arg = args[i];
if (arg.Contains("build"))
{
UnityEditor.PlayerSettings.bundleVersion = args[i + 1];
}
}
}
}
}
The powershell command line is:
Start-Process -FilePath $unityExe -ArgumentList "-batchmode", "-quit", "-projectPath", $projectPath, "-buildWindows64Player", "$outputPath\Clomper.exe", "-logFile", $logFile, "build", $versionNumber -Wait
The code fails on UnityEditor.PlayerSettings.bundleVersion the log reads:
Assets\Editor\Build.cs(16,21): error CS0234: The type or namespace name 'PlayerSettings' does not exist in the namespace 'UnityEditor' (are you missing an assembly reference?)
Failed Attempt 2 - IPreprocessBuildWithReport
Also located in Assets/Editor. This takes the command line arguments, finds “build” and sets bundle version to the argument that follows.
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;
namespace Lang.Clomper
{
public class BuildPreprocessor : IPreprocessBuildWithReport
{
public int callbackOrder => 0;
public void OnPreprocessBuild(BuildReport report)
{
string[] args = System.Environment.GetCommandLineArgs();
for (var i = 0; i < args.Length; i++)
{
var arg = args[i];
if (arg.Contains("build"))
{
Debug.Log($"Setting build version to {args[i + 1]}");
UnityEditor.PlayerSettings.bundleVersion = args[i + 1];
}
}
}
}
}
The powershell command to build this (similar to above without -executeMethod):
Start-Process -FilePath $unityExe -ArgumentList "-batchmode", "-quit", "-projectPath", "$projectPath", "-buildWindows64Player", "$outputPath\Clomper.exe", "-logFile", "$logFile", "build", "$versionNumber" -Wait
The code fails on UnityEditor.PlayerSettings.bundleVersion the error is:
Assets\Editor\BuildPreprocessor.cs(1,19): error CS0234: The type or namespace name 'Build' does not exist in the namespace 'UnityEditor' (are you missing an assembly reference?)
Custom asmdef info
I suspected this was the problem, I had a single custom asmdef in the root folder.
Lang.Clomperfound in the root folder, targeting Win64 only with the majority of my project/asset references.
Solution
You need a custom asmdef in the Editor folder that only targets the Editor and references any assemblies you use in your code.
Lang.Clomper.Editorfound inAssets/Editortargeting only the Editor platform.- It references
Lang.Clomperand Netcode for GameObjects. These are the only libraries that get used by my Editor scripts. If you are just setting version number, you won’t need any other references.
Be really careful with the checkboxes when you untick “Target All” because the list below becomes and include rather than exclude. I think that’s what I missed at first.
I hope that helps others!