Build automation...

Originally, I thought this should be possible via editor scripting, and I still hope it is… if not, that might better go to Wish List, but I stay optimistic :wink:

I love the feature of Unity for creating different builds “on click”. However, my feeling is that when one really wants to build for different platforms, it can quickly become somewhat cumbersome. For instance, I’d like to change all the compression settings between Web player and standalone versions (Web players low quality but small filesize, standalone versions always nice quality). Also, it probably makes sense to change some of the textures (they can be made smaller in the import settings - that’s great, but I would like to have it “small” for Web, but “as it is” for standalone). In some cases, it might even be cool to be able to have lower-poly models for the Web player than for the standalone versions to reduce download times (not sure if that really makes sense, but it might be an interesting idea).

If before doing a build, I could somehow access all scenes, prefabs etc. via a script, I could write something up that suits my needs as I don’t believe this is something that can be solved “for all” in a general manner (it’s probably possible, but I think it would be a tremendous amount of work and require some serious UI changes in the Unity editor).

Another issue where I would need this is for building game servers. Right now, I have one setting “IsStandaloneServer” that I click to true, do one build, then click it to false and change some other things and do another build. Maybe I’m just spoiled by stuff like Ant, NAnt or MSBuild, but wouldn’t that flexibility also be cool for Unity?

Ideally, I would like to be able to create one “build script” that does all the builds for me in one “big step”, one after the other - and before each build, changes what needs to be customized. Then, with the post-build-processing, I could upload that whole bunch to the server to be ready for download.

Now… Is that possible, or am I just dreaming?

Jashan

Did you ever receive a good reply for this? I’m interested in doing something similar. Build automation as part of a general automated pipeline, nightly builds etc.

Cheers,

A.

This is from our pythonbased buildsoftware:

subprocess.call([str(GetUnity()),“-projectPath”,projectPath.abspath(),“-batchmode”,“-executemethod”,“Publisher.MakeBuild”,“-quit”])

with Publisher.MakeBuild being a static function that could do whatever you want. Including making a build.

Bye, Lucas

One year ago … ah … missed it by one day :wink:

Yeah, it’s possible and works nicely. Modified code from my bash-shell-script:

/Applications/Unity/Unity.app/Contents/MacOS/Unity -batchmode -projectPath "YourProjectPath" -executeMethod "YourClass.StaticMethodOfThatClass" -quit

Then, you need an Editor script in your project called “YourClass” (well, just for consistency, use whichever name you like :wink: ), which has a static public method “StaticMethodOfThatClass”.

And that could do something like:

    public static void StaticMethodOfThatClass() {
        BuildPipeline.BuildPlayer(scenes, filePath, buildTarget, buildOptions);
    }

See also: BuildPipeline.BuildPlayer

Works smooth for me (and I’m doing lots of builds from that script … 13 different players from the same project, to be exact … but it also does some other stuff like code replacements etc.)

Awesome! Thanks! :slight_smile:

Hi Jashan,
I’ve been trying “-executeMethod” out, as mentioned here also: http://unity3d.com/support/documentation/Manual/Command%20Line%20Arguments.html.

Anyway, I’m running a command line from another application that calls a method in a Unity project.

Have you been able to set the return value or either of the two standard streams from your own static Unity function using “-executeMethod”? I’d like to analyze how my function fared.

The code in my Unity project looks something like this (this function lives in a class called ‘MyClass’):

public static Int32 DoStuff()
{
   Console.Error.Write("Hello");
   return -2;
}

The code that calls this function in “-batchmode” looks something like this:

String sCommand = "\"C:\\Program Files\\Unity\\Editor\\Unity.exe\"";
ProcessStartInfo oPSI = new ProcessStartInfo(sCommand);
oPSI.Arguments = "-batchMode -quit -projectPath \"C:\\MyUnityProject\" -executeMethod MyClass.DoStuff";
oPSI.RedirectStandardError = true;
oPSI.WindowStyle = ProcessWindowStyle.Hidden;
oPSI.UseShellExecute = false;
Process oProcess = Process.Start(oPSI);
StreamReader oReaderStdError = oProcess.StandardError;
oProcess.WaitForExit(45000);
if (oProcess.HasExited)
{
    String sError = String.Format("Exit Code: {0}\nDetails: {1}", oProcess.ExitCode, oReaderStdError.ReadToEnd());
    MessageBox.Show(sError);
}

I am using WindowsUnity2.5. I’m somewhat expecting someone to tell me that it’s not possible since the “DoStuff” function is not a part of the engine, proper. In any case, thanks for any advice you might have.

Currently we don’t read the return value of the -executeMethod function as the return value.

You can use EditorApplication.Exit(2); to trigger specific return values.

Additionally you can throw an exception which will also output the full error to stdout and return -1.

Thanks for the info, Joachim.

I was able to get the Exit function to work as expected. However, throwing an exception is returning 0 for me and neither stderr or stdout have anything in their buffers.

Here’s my script…

public static void DoStuff()
{
   throw new Exception("Hi there");
}

The code that is kicking off the Unity process is still the same (I’ve tried redirecting and reading both StandardOutput and StandardError).

This is not a critical issue any longer. I find myself using Debug.Log as a pseudo-stderr. I then parse the log file written to my hard drive. The addition of EditorApplication.Exit is nice here. Yea, it’s a bit clunky; but, it appears to be working. :slight_smile:

Thanks!

Oops. You are right. Just use Exit for now.

Has anyone had luck building with plugins from the command line? Every time I do, it seems to hang in the middle of PostProcessBuildPlayer_. Actually at the point it calls UpdateXCode.scpt (which when opening it up in any editor seems to be non-human readable).

If this isn’t the right place to post this question please tell me what would be a better place.

We have multiple Unity projects that were developed on a Mac, by Clint. We need to be able to automate recompiling of these projects from the command line, from an Ant or NAnt script, on other computers. Clint has been able to do this from the command line on his Mac for one project, which we are using as a test case. I can’t figure out how to get it to work from Windows. Clint didn’t need to specify a project path, which doesn’t make any sense to me at all if we are going to be juggling multiple projects being recompiled. In any case, I either get dead silence or I get “Couldn’t set project path to…” On this page as well as posts in this thread, it is not clear to me how to determine the project path. Do I need the full path to the folder that the .unity file is in? Will a relative path work? Do I need to specify the name of the .unity file as well?

Any advice would be most appreciated. Perhaps I’m spoiled, but we have one huge automatically generated build script that recompiles dozens of AS3, Java, and generic C# clients, and I’d really like to be able to have it handle all the Unity ones too.

It appears that this is a Unity Pro feature that wasn’t listed on the feature comparison chart. So the reason I couldn’t get it to work was that I had the free version of Unity, not Unity Pro.

Anyone know

A. The best way to pass arguments from the python build wrapper into the static class doing the build
B. Why BuildOptions enumerator doesn’t have an option to do nothing, i.e I don’t want to open the player after it’s built or do anything and leaving the BuildOptions throws an error.

In answer to question A

Passing arguments

I see in v3.3 there is now a BuildOptions.None but that doesn’t work in 2.6 rather annoyingly. I wonder how this can be done in older versions.