Unityでゲーム作るぞ

Unityでゲーム制作できるようになるまでのリアルドキュメント

Unity上でSpineオブジェクトをアニメさせつつ連番PNGを作成

果たして需用あるのか謎だが、spineのデータ(json)をunityに読み込み、各パーツのアニメフレームを再生しつつ、連番PNGを出力させる事に成功した。c#
(別にspineでも同じ事はできるが、パーツが多すぎるとON,OFFの切り替えが面倒そうだったので…)

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

public class Screenshot : MonoBehaviour {
	private Animator model_animator;
	void Awake(){
			model_animator = GameObject.Find("skeleton.json").GetComponent<Animator>();
			model_animator.speed = 0; // アニメ停止

			StartCoroutine(Test());
  }

	private IEnumerator Test()
	{
		// 全オブジェクトリストアップ。引っ掛けたくないものは非アクティブにする
		List<GameObject> ary = new List<GameObject>();
		foreach (GameObject obj in UnityEngine.Object.FindObjectsOfType(typeof(GameObject))){
			if(obj.transform.FindChild(obj.name))ary.Add(obj);
		}
		
		// 画像を変えていく
		System.IO.Directory.CreateDirectory(@"フォルダを作る場所");
		Texture2D tex = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false);
		for (int i = 0 ; i < ary.Count ; i++){
			yield return new WaitForEndOfFrame(); // 描画系には描画を待つだけのウェイトを
			// yield return new WaitForSeconds(1.5f);
			for (int j = 0 ; j < ary.Count ; j++){
				GameObject child = ary[j].transform.FindChild(ary[j].name).gameObject;
				var s_compo = child.GetComponent<SkinnedMeshRenderer>();
				s_compo.enabled = (i == j);
			}

			System.IO.Directory.CreateDirectory(@"フォルダを作る場所" + ary[i].name);				
			var anime_flame = 0.0f;
			var count = 0;
			while(model_animator.GetCurrentAnimatorStateInfo(0).normalizedTime < 1.0f){
				// アルファチャンネル・保存のために
				yield return new WaitForEndOfFrame();
				tex.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
				tex.Apply();	
				byte[] bytes = tex.EncodeToPNG();
				File.WriteAllBytes("フォルダを作る場所" + ary[i].name + "\\" + ary[i].name + count.ToString() + ".png", bytes);
				
        count++;
				
				anime_flame += (1.0f / 60.0f); 
				model_animator.ForceStateNormalizedTime(anime_flame); // アニメフレームコマ送り
			}
			model_animator.ForceStateNormalizedTime(0.0f);	
		}
		Destroy(tex);
		// エディタの再生、終了
		UnityEditor.EditorApplication.isPlaying = false;
	}
}

Unityに取り込んだspineのオブジェクト名は”skeleton.json”だと仮定している。
フォルダの生成箇所も手動で書き換えよう

要はアニメフレームを1つずつめくりながら画面のスクリーンショットを撮る、という荒業。
自分のPCでは20fpsくらいになってしまうという負荷だった…

画面スクショは再生ウィンドーに大きさが影響されるので、再生(GAME)ウィンドーの大きさを固定する為のクラスも作成。
この場合は横1000、縦800としている。
http://answers.unity3d.com/questions/267097/editor-programming-experts-regarding-layouts.html
このフォーラムを参考にしてコピペ。

これをEditorと名前を付けたフォルダに入れると、メニュー欄に"Caputer">"start"という項目が加わるので、それを押せば勝手に始まって勝手に終わる。

using System;
using UnityEditor;
using UnityEngine;
using System.Collections;

public class EditorGamePosition : EditorWindow
{
    [MenuItem ("Caputer/start")]
		static void Init () {
        WindowInfos windows = new WindowInfos();
        windows.game.position = new Rect(0, 0, 1000, 800 + 17); // titleバー分が17px?
        UnityEditor.EditorApplication.isPlaying = true;
    }

    // 簡単な書き方で各エディターにアクセスしやすいようにしてくれてるクラス
    class WindowInfos
    {
        // note: some of this data might need to change a little between different versions of Unity
        public WindowInfo scene = new WindowInfo("UnityEditor.SceneView", "Scene", "Window/Scene");
        public WindowInfo game = new WindowInfo("UnityEditor.GameView", "Game", "Window/Game");
        public WindowInfo inspector = new WindowInfo("UnityEditor.InspectorWindow", "Inspector", "Window/Inspector");
        public WindowInfo hierarchy = new WindowInfo("UnityEditor.HierarchyWindow", "Hierarchy", "Window/Hierarchy");
        public WindowInfo project = new WindowInfo("UnityEditor.ProjectWindow", "Project", "Window/Project");
        public WindowInfo animation = new WindowInfo("UnityEditor.AnimationWindow", "Animation", "Window/Animation");
        public WindowInfo profiler = new WindowInfo("UnityEditor.ProfilerWindow", "Profiler", "Window/Profiler");
        public WindowInfo console = new WindowInfo("UnityEditor.ConsoleWindow", "Console", "Window/Console");
        public WindowInfo navigation = new WindowInfo("UnityEditor.NavMeshEditorWindow", "Navigation", "Window/Navigation");
        public WindowInfo occlusion = new WindowInfo("UnityEditor.OcclusionCullingWindow", "Occlusion", "Window/Occlusion Culling");
        public WindowInfo lightmapping = new WindowInfo("UnityEditor.LightmappingWindow", "Lightmapping", "Window/Lightmapping");
        public WindowInfo assetServer = new WindowInfo("UnityEditor.ASMainWindow", "Server", "Window/Asset Server");
        public WindowInfo assetStore = new WindowInfo("UnityEditor.AssetStoreWindow", "Asset Store", "Window/Asset Store");
        public WindowInfo particle = new WindowInfo("UnityEditor.ParticleSystemWindow", "Particle Effect", "Window/Particle Effect");
        public MainWindow main = new MainWindow();
    }

    class WindowInfo
    {
        string defaultTitle;
        string menuPath;
        Type type;

        public WindowInfo(string typeName, string defaultTitle = null, string menuPath = null, System.Reflection.Assembly assembly = null)
        {
            this.defaultTitle = defaultTitle;
            this.menuPath = menuPath;

            if (assembly == null)
                assembly = typeof(UnityEditor.EditorWindow).Assembly;
            type = assembly.GetType(typeName);
            if (type == null)
                Debug.LogWarning("Unable to find type \"" + typeName + "\" in assembly \"" + assembly.GetName().Name + "\".\nYou might want to update the data in WindowInfos.");
        }

        public EditorWindow[] FindAll()
        {
            if (type == null)
                return new EditorWindow[0];
            return (EditorWindow[])(Resources.FindObjectsOfTypeAll(type));
        }

        public EditorWindow FindFirst()
        {
            foreach (EditorWindow window in FindAll())
                return window;
            return null;
        }

        public EditorWindow FindFirstOrCreate()
        {
            EditorWindow window = FindFirst();
            if (window != null)
                return window;
            if (type == null)
                return null;
            if (menuPath != null && menuPath.Length != 0)
                EditorApplication.ExecuteMenuItem(menuPath);
            window = EditorWindow.GetWindow(type, false, defaultTitle);
            return window;
        }

        // shortcut for setting/getting the position and size of the first window of this type.
        // when setting the position, if the window doesn't exist it will also be created.
        public Rect position
        {
            get
            {
                EditorWindow window = FindFirst();
                if (window == null)
                    return new Rect(0, 0, 0, 0);
                return window.position;
            }
            set
            {
                EditorWindow window = FindFirstOrCreate();
                if (window != null)
                    window.position = value;
            }
        }

        // shortcut for deciding if any windows of this type are open,
        // or for opening/closing windows
        public bool isOpen
        {
            get
            {
                return FindAll().Length != 0;
            }
            set
            {
                if (value)
                    FindFirstOrCreate();
                else
                    foreach (EditorWindow window in FindAll())
                        window.Close();
            }
        }
    }

    // experimental support for getting at the main Unity window
    class MainWindow
    {
        Type type;
        UnityEngine.Object window;

        public MainWindow()
        {
            type = typeof(UnityEditor.EditorWindow).Assembly.GetType("UnityEditor.ContainerWindow");
            if (type != null)
            {
                foreach (UnityEngine.Object w in Resources.FindObjectsOfTypeAll(type))
                {
                    object parent = type.InvokeMember("get_mainView", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Instance, null, w, null);
                    if (parent != null && parent.GetType().Name.Contains("MainWindow"))
                    {
                        window = w;
                        break;
                    }
                }
            }
            if (window == null)
                Debug.LogWarning("Unable to find main window.\nMaybe you'll need to update the MainWindow constructor for your version of Unity.");
        }

        public Rect position
        {
            get
            {
                if (window == null)
                    return new Rect(0, 0, 0, 0);
                return (Rect)type.InvokeMember("get_position", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Instance, null, window, null);
            }
            set
            {
                if (window != null)
                    type.InvokeMember("set_position", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Instance, null, window, new object[] { value });
            }
        }

        public bool isOpen
        {
            get
            {
                return window != null;
            }
            set
            {
                if (!value)
                {
                    if (EditorApplication.SaveCurrentSceneIfUserWantsTo())
                        EditorApplication.Exit(0);
                }
            }
        }
    }
}