Save values inside Unity using automated scripts

I begin to create an automated script to make easier to use Unity.

I use the script below to change my app name

using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.IO;

public static class AutoBuilder {

    [MenuItem("File/AutoBuilder/Change")]
    static void ChangeAppAll ()
    {
        PlayerSettings.productName = "myAppName" ;

    }

}

I run it using the command line on Mac and it works perfectly, I run the script using the command below

/Volumes/data/Applications/Unity5.4.3/Unity.app/Contents/MacOS/Unity -batchmode -executeMethod AutoBuilder.ChangeAppAll -quit

When I open Unity the app name is already changed (that means the name is changed and saved in disk )

But now I want to change values inside another scripts like the script below.

public class Values : MonoBehaviour{

public int number=0;
}

See the image below

The value of number is set to 25, but I want to change this value using the command line, but I don’t know how I can access the variable number inside the Values script using the static class AutoBuilder.

Any help?

For a component you should be able to do something like:

  1. Open up the scene containing the object with the component (using EditorSceneManager.OpenScene).
  2. Get a reference to the object in some way (Object.FindObjectOfType, GameObject.Find, etc).
  3. Modify the value (making sure you use Undo.RecordObject so the editor knows the scene needs saving).
  4. Save the scene back out (again using EditorSceneManager).

It works, thank you @NickAtUnity

This is the code that I use:

[MenuItem("File/AutoBuilder/Change")]
staticvoidChangeAppAll()
{
//ChangeAppTitle
PlayerSettings.productName="myAppName";
UnityEngine.SceneManagement.Scenes s =EditorSceneManager.OpenScene("Assets/Game/Scenes/init.unity");
GameObject[] gms = s.GetRootGameObjects();

//usingthefourthitem,istheobjectthatI want
NewValuenv2=(NewValue)gms[4].GetComponent("NewValue");

nv2.myNewValue="x99";
nv2.number=99;
Undo.RecordObject(nv2,"save");

EditorSceneManager.SaveScene(s);
}

ps: For some reason the " Undo.RecordObject(nv2,“save”);" didn’ make any difference in the code, I remove it and the code still works.

My automation process is becoming ever better.

1 Like

Undo.RecordObject won’t make a difference to the code, but as @NickAtUnity said, it tells the Editor that the scene has changed and marks it as dirty, so that when you save the scene, it knows that something has changed.
I would imagine that you would find your changes are lost after closing and re-opening the scene.

@Gizmoi I close an re-open Unity, the changes are not lost.

I made another test, with Unity closed, I run a command line script

/Volumes/data/Applications/Unity5.4.3/Unity.app/Contents/MacOS/Unity -batchmode -executeMethod AutoBuilder.ChangeAppAll -quit

After that I open Unity and check the values, the values changed.

Fair enough. In my experience I’ve always have to do EditorUtility.SetDirty or more recently Undo.RecordObject to have the Editor save my scene correctly. It seems this is no longer the case.

I believe when using SaveScene(Scene) it currently always saves the scene but other methods (such as SaveOpenScenes) will only save dirty scenes (as will the normal editor workflow). For that reason it is recommended best practice to always use Undo.RecordObject to ensure the editor always knows what needs to be saved for all cases.

Also you should call Undo.RecordObject before you change the object. The point of that method is to give the editor a chance to snapshot the current property values so they can be restored if the user hits undo. Calling it after you change the properties obviously isn’t going to snapshot at the right time.

1 Like

@NickAtUnity I understand now how the Undo.RecordObject works. Thanks for the explanation.
I will use the Undo.RecordObject before change the object, like this:

Undo.RecordObject(nv2,"save");
nv2.myNewValue="x99";
nv2.number=99;