読者です 読者をやめる 読者になる 読者になる

(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

スクリプトからテンプレを自動作成【Unity】【エディタ拡張】


このエントリーをはてなブックマークに追加


この記事でのバージョン
Unity 4.6.3f1


はじめに

前回、複数のテンプレを使えるようにはなったけど、そもそもテンプレ作るのめんどくね?

って所で終わりました。



なので今回は既存のスクリプトからテンプレを作るエディタ拡張のご紹介!


プログラム

何はなくともプログラムから!


CustomScriptCreator前回のScriptCreatorを修正した、テンプレから新たにスクリプトを作るクラス

TemplateScriptCreatorが今回作成した、既存スクリプトから新たにテンプレを作るクラス

ScriptCreatorが上記二つの親クラスで共通項目をまとめているクラスです。



選択されているスクリプトを読み込み、クラス名などのタグにしたい部分を判定し置換後、

テキストファイルを書き出す事でテンプレを作成しています。

テンプレからスクリプトを作る時より面倒だったり……


使い方

まず上記三つのスクリプトをEditorディレクトリに入れます


次にAssets/Scripts/Templatesという階層でディレクトリを作り、

テンプレートである下記のBasic.txt、Singleton.txt、Static.txtを入れます。



この状態でProjectのCreateを見てみると、新しくCustom Script(前回のTemplate Script)とその先の項目、

さらにTemplate Script(前回とは別機能)という項目がが出来ているはずです。


f:id:kan_kikuchi:20150526084936p:plain


Custom Scriptは前回と同じ使い方なので説明省略します。


テンプレートの元にしたいスクリプトを選択した状態で、

Template Scriptを選ぶと、以下のようなウィンドウが開きます


f:id:kan_kikuchi:20150526085804p:plain


テンプレート名を入力してCreateボタンを押すと、

Assets/Scripts/Templates以下に新しいテンプレートファイルが生成されます。


f:id:kan_kikuchi:20150526090026p:plain


この時点ではまだCreateのメニューには表示されないので、

CustomScriptCreatorに以下のようなコードを追加すると、

private const string TEMPLATE_SCRIPT_HERO_NAME = "Hero";

[MenuItem(MENU_PATH + TEMPLATE_SCRIPT_HERO_NAME)]
private static void CreateHeroScript(){
  ShowWindow (TEMPLATE_SCRIPT_HERO_NAME);
}


Createのメニューに新たな候補が表示されるようになります。


f:id:kan_kikuchi:20150526090454p:plain


ちなみにHero.csが以下のようなコードが書かれていると、

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

public class Hero : MonoBehaviour {


}


出力されるテンプレート、Hero.txtは以下のようになります

//  #SCRIPTNAME#.cs
//  ProductName #PRODUCTNAME#
//
//  Created by #AUTHOR# on #DATA#

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// #SUMMARY#
/// </summary>
public class #SCRIPTNAME# : MonoBehaviour {


}


一瞬でテンプレートが!これは楽!


コード説明

ではでは項目ごとにTemplateScriptCreatorのコード説明です!

CustomScriptCreatorのコードやウィンドウ作成周りの説明は前回記事を参照のこと。


クラス名をタグ置換

クラス名をタグに置換、今回でいうとHeroを#SCRIPTNAME#に変換するメソッドは以下の通りで、

//クラス名をタグ置換
private static string ReplaceClassNameToTag(string scriptText){

  //全置換すると関係ない所も置換するので、一旦クラス名を削除した後にタグを差し込む
  //クラス名で検索すると他の所が引っかかるかもしれないので"class "を使って検索する
  string classText = "class ";
  int classNameStartPoint = scriptText.IndexOf (classText) + classText.Length;
  string classname = System.IO.Path.GetFileNameWithoutExtension (_originalScriptPath);

  scriptText = scriptText.Remove (classNameStartPoint, classname.Length);
  scriptText = scriptText.Insert (classNameStartPoint, SCRIPT_NAME_TAG);

  return scriptText;
}


単純にReplaceで変換してしまうと、HeroPowerみたいな変数があった時にこれも変換してしまうので、

"class "という文字列を探し、そのあとから元のクラス名の文字数分、文字を削除し、

さらに同じ場所にタグを追加しています。


クラス説明のSummaryを置換

クラス説明のSummaryを置換しているのは以下のメソッドです。

//クラス説明のSummaryを置換
private static string ReplaceClassSummaryToTag(string scriptText){

  int summaryFirstPoint       = scriptText.IndexOf ("summary");
  int scriptNameTagFirstPoint = scriptText.IndexOf (SCRIPT_NAME_TAG);

  //クラス説明のSummaryが無い場合は、Summaryの定型を差し込む
  if(summaryFirstPoint == -1 || summaryFirstPoint > scriptNameTagFirstPoint){省略}

  //クラス説明のSummaryがある場合は最初の<summary>の後から</summary>の前の改行まで全て削除し、Summaryの定型の間だけ差し込む
  else{省略}

  return scriptText;
}


長いので途中省略していますが、やっている事は

そもそもSummaryが無ければ定型文を挿入

Summaryがある時は、summaryから/summaryの間を削除し、定型文を追加

といった具合です。


usingより上を削除し、定型テキスト差し込み

テンプレートから作った場合など、一番上にコメントで作成日時が載っている可能性があるので、

最初に出てくるusingという文字列より前の文字を全て削除してから、作成日時などの上部の定型文を追加しています。

//元スクリプトがテンプレートから作った時などに上部定型テキストがあるかもしれないので、最初のusingより上を削除
int usingFirstPoint = scriptText.IndexOf ("using");
if(usingFirstPoint > 0){
  scriptText = scriptText.Remove (0, usingFirstPoint - 1);
}
else{
  scriptText = "\n" + scriptText;
}

//上部定型テキスト差し込み
scriptText = TOP_TEXT + scriptText;


なお、usingより上に何もない場合、上部の定型文と空きが出来なくなってしまうため、

見栄えの問題で改行を追加しています。


おわりに

既存のスクリプトからテンプレを作るという目標は達成できましたが、

テンプレを作った分だけ、CustomScriptCreatorにコードを追加するのが、地味に面倒ですね……


( ゚ Д゚)ハッ!


という事で次回は、テンプレメニューを自動で更新するエディタ拡張です!