けいごのなんとか

Unityユーザーとしてのブログ。ギリギリ路線走ってます。

テンプレートファイルにカスタムキーワード追加

Unity.app/Contents/Resources/ScriptTemplatesにあるテンプレートファイルに自由にReplaceできるキーワードを追加する

デフォルトでサポートされているのは

key 説明
#NAME# 拡張子なしのファイル名に変換
#SCRIPTNAME# 半角スペース無しで拡張子無しのファイル名に変換
#SCRIPTNAME_LOWER# 半角スペース無しで拡張子無しの全て小文字のファイル名に変換。ただし最初の文字をhogeのように小文字にするとmyHogeとなる。

こんな風にライセンスを追加(YEARとOWNER)

/*
Copyright (C) #YEAR# #OWNER#

This software is provided 'as-is', without any express or implied
warranty.  In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
   claim that you wrote the original software. If you use this software
   in a product, an acknowledgment in the product documentation would be
   appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
using UnityEngine;
using System.Collections;


public class #SCRIPTNAME# : MonoBehaviour {

    // Use this for initialization
    void Start () {
    
    }

    // Update is called once per frame
    void Update () {

    }
}

文字を入れ替える方法はなんでもいいんだけど、必須なのはOnPostprocessAllAssets内でAssetDatabase.ImportAsset (path, ImportAssetOptions.ForceUpdate);を呼び出すこと。 インポート処理を強制的に実行します。(今回はコンパイル処理をキャンセルしたみたいに受け取ってもらえればOK)

そうしないと入れ替えた後のインポート処理がコンパイル後まで待たされてしまうのでコンパイルエラーになる。

using System;
using System.IO;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

public class NamespaceGenerator : UnityEditor.AssetPostprocessor
{

        // ここをいじる
        static string[] keys = new []{
        "YEAR","OWNER",
        };

        static void OnPostprocessAllAssets (string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromPath)
        {
                foreach (var path in importedAssets) {
                        if (path.Contains (".cs") 
                                || path.Contains (".js") 
                                || path.Contains (".boo") 
                                || path.Contains (".shader") 
                                || path.Contains (".compute")) {
                                for (int i = 0; i < keys.Length; i++) {
                                        var key = keys [i];
                                
                                        var text = File.ReadAllText (path);
                                        if (text.Contains ("#" + key + "#")) {
                                                text = ReplaceText (key, text);

                                                StreamWriter writer = new StreamWriter (path, false, new System.Text.UTF8Encoding (true, false));
                                                writer.Write (text);
                                                writer.Close ();

                                                AssetDatabase.ImportAsset (path, ImportAssetOptions.ForceUpdate);
                                        }
                                }
                        }
                }
        }
        
        // ここをいじる
        static string ReplaceText (string key, string text)
        {
                
                switch (key) {
                case "YEAR":
                        // こんな感じでReplace
                        text = Regex.Replace (text, "#" + key + "#", DateTime.Now.Year.ToString());
                        break;
                case "OWNER":
                        text = Regex.Replace (text, "#" + key + "#", "Keigo Ando");
                        break;
                default:
                        break;
                }

                return text;
        }
}

ゲームオブジェクトのスクリプトが「Missing」になった時のリカバリー

このような時に出来るだけ素早く元に戻す。

f:id:anchan828:20140104011644p:plain

まずこのような事になる場合

  • Unityの管理外でスクリプト名の変更をした
  • Unityの管理外でスクリプトファイルの階層構成を変更した

が挙げられます。つまり、Unityが把握してない所で変更したら「誰だお前!?」となる。

Missingになった時でもデータは保持されている

Missingになっていてもシリアライズされたデータは保持されている。

なのでシリアライズされたプロパティのデータの型やプロパティ名を、既存の(MonoBehaviourを継承した)クラスのプロパティと照らし合わせ、一致しているものが多い順に表示してみた。

f:id:anchan828:20140104012411p:plain

一番一致しているプロパティが多いものはGoogleみたいに「もしかして」を付けてみた。

f:id:anchan828:20140104012427p:plain

現在の問題点としては

Missingとなった時のプロパティの照らし合わせで配列(Generic、Array)とUnityEngine.ObjectとEnumは照らし合わせを行っていない。ちょっと面倒なので...

MonoBehaviourのCustomEditorを作成しているので、他でMonoBehaviourのCustomEditorを作成していたらどっちかが動作しなくなる。

EditorMonoBehaviour作ってみた

MonoBehaviourと同じような使い方すると理解されやすいんじゃないかと思って。

EditorMonoBehaviourを継承して使用します。

最初はEditorApplicationのラッパーになりそう。 便利で実装ややこしいと思ったものは追加していきます。

AssetPostprocessor

この情報はUnity Documentation Tabsでも閲覧することが出来ます

Unity Documentation Tabsで閲覧する場合のURLはこちら(EN)またはこちら(JP)です


スクリプトファイルを生成した時に呼び出されるOnGeneratedCSProjectFiles

ドキュメント化されてないけど知っておくと便利

using UnityEngine;
using UnityEditor;

public class NewBehaviourScript : AssetPostprocessor
{
        static void OnGeneratedCSProjectFiles ()
        {
                Debug.Log ("call");
        }
}

TextureImporterSettings.spriteExtrude

この情報はUnity Documentation Tabsでも閲覧することが出来ます

Unity Documentation Tabsで閲覧する場合のURLはこちら(EN)またはこちら(JP)です


spriteExtrudeが1の時

spriteExtrudeが16の時

Hierarchyをカスタマイズ(新しくHierarchyを作る)

虫眼鏡のところに「お気に入り」を選択できるようにしてみました。

お気に入り機能は本来はUnityプロジェクト内のアセット検索に使用されますが、特に使ってない問題ないのでHierarchyの検索でも使用します。

使い方

まずお気に入り登録しましょう

そうすると「NewHierarchyウィンドウ」の虫眼鏡の所に追加されます。

「NewHierarchyウィンドウ」はNewHierarchyWindow.csを追加した時に自動的に「Hierarchyウィンドウ」の横に追加されます。

※注意・・・「Hierarchyウィンドウ」を消してはいけません。バグる。

以下ソースコード