スクリプト



編集文字の縮小、拡大


ctrl+マウススクロールで編集文字の拡大縮小できる


ネストの有効範囲を知る


マウスをネストのコンパクト化するアイコンにオーバーさせると視覚的にネスト範囲を知る事が出来る

mouseover1.jpg

デバックのブレークポイントに条件を設定


ブレークポイントに変数の条件を設定する事により例えばforループの中の変数がある数値になるとブレークするなどの設定が可能となります
下記の画像ではローカル変数iに12になると停止させる条件を設定しています

debugBreakPoint2.jpg
<手順>
  1. コードにブレークポイントを設定
  2. SourceパネルのBreakpointsタブを表示し該当するブレークポイントの上で右クリック
    メニューを表示してPropertiesを実行
  3. 画像の様に各設定を行いデバッガを走らせます


MonoDevelopエディタの各種機能


  • インテリセンス起動 ctrl+Space
  • unityAPIリファレンスヘルプの表示 Ctrl+'
  • ナビゲート next ctrl+alt+→   prev ctrl+alt+←
  • 行の移動 alt+↑↓
  • prop等のスニペットもvisualStudioと同様に利用可能
  • ctrl+shif+spaceでパラメータの候補表示

ctrl+shift+tab 編集ファイルの切り替え
tab (何気に気が付かないが)選択範囲に対してインデントする
shift+tab 選択範囲に対して逆方向にインデントする

tools => option -> keybinding の「Unity API Reference」がリファレンスヘルプ起動にあたる
「ShowCompletionWindow」がインテリセンス起動となっている
もしvisualStudioと同じ様にしたいならここをカスタマイズする(例えばF1キーや「Alt + → 」キーを割り当てる)

keyassign.jpg

MonoDevelopエディタのインテリセンス何ができる、できない?

  • あらかじめvirtual宣言した関数のoverrideは検出入力できる
  • ラムダ式周りに関しては非常に鈍い

Snippets スニペット

Win7以上のOSでのスニペットテンプレートファイルの場所
C:\Users\<ユーザー名>\AppData\Roaming\MonoDevelop-Unity-2.8\Snippets

■(改良版)unity用にMonoBehaviourのスニペットを拡張する
monodevelop-code-template-unity-csharpから拾ったデータではMonoDevelopのエディタを利用している限りインデント位置がズレるので個人的に修正したファイルを作成しました。以下のリンクSnippets.zipよりダウンロードできます(勝手に触ったけど大丈夫かな・・・kyusyukeigo anchan828氏オリジナルです。…GitHubに登録して活躍できるレベルに早くなりたいです)
C:\Users\<ユーザー名>\AppData\Roaming\MonoDevelop-Unity-2.8\Snippetsフォルダ内に解凍した内容をコピーすると使えます
(OSの設定によっては隠しフォルダになっている場合もありますので各自対処してコピーしてください)

snip.jpg

<使い方>
他のスニペット入力と同じです。試しに「ont」まで入力してみるとMonoBehaviourクラスの入力候補が出てくると思います

snip2.jpg

■(旧)unity用にMonoBehaviourのスニペットを拡張する
1.以下のuriのDownloadZipよりmonodevelop-code-template-unity-csharp-master.zipファイルをダウンロード
2.C:\Users\<ユーザー名>\AppData\Roaming\MonoDevelop-Unity-2.8\Snippetsフォルダ内に解凍した内容をコピーする


インテリセンスはVisualStudio程、万能ではない
例えばfor構文を入力中はパラメーターがイテレーター扱いとなり.NETのメンバーアクセスなどが出来ないなど気になる点がある

例1.
for (int i = 0; i < myPeices.Length; i++) {DoSomthing();}

myPeicesがIEnumratorのコレクションの場合Lengthをインテリセンス入力できない
この場合、ショートカットキーでの.NETのインテリセンス呼び出しは可能なのでそちらを利用する手がある
(正確に言うとスニペット入力中は自動のインテリセンス入力がフルに効かないという事らしい)

(2013/08/18追記)
インデクサー周辺のインテリセンスがvisualStudio程万能ではない感じらしい??
例えば string[] str で str[3].Split('\r') みたいな場合Splitが出てこない。その癖str.split なら出てくる。謎…
unityの関数までは出てくるが.NETの関数までは届いてない感じ

タスクリスト


コードの中に //TODO:~~ を含めるとタスクリストが作成できる
タスクリストは View -> Pads -> TaskList を実行するか、shift + alt + t のショートカットで呼び出せる

クラスに必要なusingの追加



利用したいクラスをコードで書いて、その上で右クリックすると必要なusingを追加できる
例えば「Convert」と書いてその上で操作するとusing System;が追加できる

usingCollect.jpg


すべてのunityエンジンの操作をスクリプトで出来ると思ってはいけない


例えば、ParticleSystem.renderer.materialにスクリプトからマテリアルがセットできない
なぜかメッシュの方に行ってしまう。またParticleSystemのシェイプ形状の変更等も現時点不可能(2014/04/26)

この辺りユニティエンジンの開発が何を考えているか判らないが、インスペクタの値にアクセスする為のAPIを用意してくれていない以上
できないものは出来ない。これはプロジェクトエディタ側の操作で回避できるがスクリプトだけで全部なんでもやってしまおうとすると変な苦労をするので注意

デバック機能



ResourcesフォルダからPrefabを読む


プロジェクトにResourcesフォルダを作成し、その中にプレハブなどのアセットを保管すれば

      Instantiate(Resources.Load("DrawGraphPrefab"));

等でコードから直接、プレハブ名を指定してインスタンスを作れます
ドラッグで指定するのが面倒な人にはとても良い方法です

資料URL:


<サンプル>

(Pythagoras.cs)

using UnityEngine;
using System.Collections;

public class Pythagoras : MonoBehaviour {

  DrawGraph dg;

  void Start () {
       dg = (Instantiate(Resources.Load("DrawGraph")) as GameObject).GetComponent<DrawGraph>();
       dg.TestMethod();
   }
}



(Resources/DrawGraph.cs)

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(MeshFilter),typeof(MeshRenderer))]
public class DrawGraph : MonoBehaviour {

  Mesh mesh;
   
   public float gridSize=1f;
   public int size=8;
   public Color color = Color.white;
   public bool back = true;
   
   void Start () {
       print("!");
   }

  public void TestMethod(){
       print("!!!");
   }
}

インスペクタにリアルタイムに値を表示


例えば独自のクラスを作成して各パラメーターをその中に内包している場合、クラスの宣言の上に
[System.Serializable] 属性をコードとして書くとインスペクタに内容が表示されるようになります
ジェネリックのパラメーターでも表示できるので非常に便利です

参考URL:

unity上のC#の特徴


<基本構造>
Unity内のスクリプトは、ビヘイビアと呼ばれるカスタムスクリプトをGameObjectにアタッチすることから成り立っています
スクリプトオブジェクトの中の関数は定期的なイベントで呼ばれます
C#のコード内では MonoBehaviour クラスが継承されることによりユニティのサービスを利用できる仕組み

<特徴>
unityの設計はオブジェクト指向ではなく一歩進んだ「コンポーネント指向」。C#によりオブジェクトを作成できるがMonoBehaviourを継承すればコンポーネントとなる。コンポーネントになればtransformが自動的に付与されGameObjectの子として扱える。
GameObjectの子として扱える=親のGameObejctにthis.gameobjectでアクセスできて他のシーンに存在するコンポーネントと連携できるサービスが得られる


  • propしなくてもpublicにすればプロパティとしてユニティ上のインスペクタに表示される
  • 注釈(//)に日本語文字の「ト」等の文字を使うと何故かコンパイルが正常に行われないので日本語注釈は基本しない方が良いらしい??
  • 基本コンポーネント Transform、Rigidbody、Renderer、Animation、Collider 等々はクラス内であれば直接アクセスできる。参考
  • すべてのGamObjectはTransformコンポーネントを必ず持ちます
  • ゲームオブジェクトのTransformコンポーネントによって既存のオブジェクトへの子どもおよび親オブジェクトを見つけることができる参考
  • unityはMonoBehaviourを継承したクラスがコンストラクタを実装する事を推奨していません。Awake/Startを利用する事

ユニティコンポーネントの特徴(Object.boolの利用)


using UnityEngine;
using System.Collections;

public class TransformTest : MonoBehaviour {
  
   public Transform tr;
   
   void Start () {
       if(tr){print("tr!");}
   }
   
}

この場合、Transformのなかに中身があればtrueを返す
これはコンポーネントの有無に対しても使え、スクリプトの有無などで種別を判別したり様々な応用が利く
(例えばプレーヤー特有のスクリプトがアタッチされているかでコリジョンから拾ったオブジェクトの正体を判別したり等)


gameObjectとGameObjectの違いとは?


「gameObject」は「this.gameObject」でありコンポーネントから見た場合、親のゲームオブジェクトです。
試しにスクリプトコンポーネントから「print(this.gameObject.name);」とすると親の名前が表示されます(print(gameObject.name);も同様)
つまりコンポーネントとゲームオブジェクト間のアクセスに使用します。

かわってGameObjectはクラスであり、ここからシーンの中のオブジェクトをタグや名前で検索し拾ったり、
新しいゲームオブジェクトのインスタンスを作成したりできます。

コンポーネントのキャッシュ


Transform を使用することを変数のアクセスと同様に捉えている人がいるかもしれないが、それは誤りだ。
transform.position と記述したときは GetComponent<Transform>().position を短く記述していることと同様だ。
繰り返しこの処理を行う場合はパフォーマンス上明らかなオーバーヘッドとなり、Transformおよびその他の同様の変数をキャッシュするのは良い習慣だ。

毎回
  float x = transform.position.x;
とするより
      
   var t = transform.position;
   t.x++;

一度、変数にキャッシュして取り出す方がオーバーヘッドが無い
何度もTransformにアクセスするなら尚更、これはした方が良い


unityが使用しているMONOのバージョンを調べる


using UnityEngine;
using System.Reflection;
using System;

void Start ()
{
print(Type.GetType("Mono.Runtime").GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null,null));
}

上記のコードによりMONOのバージョンが表示される

unityに関するベストプラクティス集


<参考資料>

スクリプトの起動させる順番を管理


<参考資料>

プロジェクト内の特別なフォルダー


C#とjavaを混在させて利用する場合、コンパイルの順番の都合上、C#からjavaへアクセスする形となるらしい。
複数メンバーでプログラムする際は留意

<参考資料>


メソッド抽出


抽出したいコードをブロック単位に選択して右クリック → Refactor →Extract Method
ウインドウが立ち上がるので関数の名前と必要な引数を入力してOKすると挿入位置を求められるので決定する

コードの複雑度をスコアリング


ソリューションロールアウトのルートを右クリックしてTools -> Code Metricsを実行すると複雑度のスコアを算出する
複雑度が30を超えると客観的に読みにくいコードと評価される。その場合リファクタリングを考えて良い段階に入っている


テンプレートの変更、改良


C#のテンプレートファイルの場所
<あなたがunityをインストールしたドライブ>:\Program Files (x86)\Unity\Editor\Data\Resources\ScriptTemplates

他言語のテンプレートもここにあります


MonoDevelopのエディタの「Unity API Reference」を実行すると404になってしまう


症状:MonoDevelopのエディタの「Unity API Reference」を実行するとネット側にリファレンスのドキュメントを探しに行き404になってしまう
unityのリファレンスドキュメントがCドライブに無いと起こるバグ(現時点2013/09/14にてunity4.2.1で確認されるバグ)

対策として他ドライブにインストールしたリファレンスのドキュメントファイル(html等)をCドライブにコピーする事で解決できる

例えばDドライブにunityをインストールしていた場合・・・
D:\Program Files (x86)\Unity\Editor\Data の中身を
C:\Program Files (x86)\Unity\Editor\Data にコピーすると解決する
(unity本体をここに置かなくてもドキュメント部分だけあれば良い)


コーディングルール


  • スクリプトファイルの名前は一文字目は大文字で(クラスとして扱いたい為)
  • enum変数はすべて大文字
  • 固定変数はすべて大文字
  • デリゲートの型変数も大文字で統一
  • 「On~」関数はSendMessageから利用する関数

例.

const float THRESHOLD = 0.1f;

delegate void STATE_FUNC();

  public enum STATE {
       NORMAL,
       DEAD
   };

void OnStageStart(){}



スクリプトを組む前に最終確認


  1. タグ、レイヤーの目的、機能が頭の中で整理、設計、出来ているか?
  2. アセットやプレハブへのタグやレイヤー割り当ては作業済みか?

それからスクリプト作業に入る事!




スクリプト


C#でコードを書くことが可能

現在(2013/06/13において)「//」による日本語の注釈で場合によりコンパイルエラーが発生する。対策として注釈文の最期にスペース、もしくは「.」を入れるとエラーは回避できる

MONOdevelopエディタのswitch、caseのインデントがおかしい。これは明確なバグで治らない。エディタの設定で該当項目初期状態オフになっている。オンにしても次に見た時にはオフになっている。バグが治るまであきらめよう(2013/06/26において)

(2013/08/22追記)
switch~caseはエディットメニュー内にある「フォーマット整形」の実行により正常なインデント表示にできる
ある程度関連するコードを書いたら実行すると良い

チュートリアルや例題ではjavaScriptが最初表示されているがC#の項目もちゃんとあるのでそれを見ると良い

プロパティにあたる変数はunity上でも表示される。この時、変数名は頭文字が大文字になり適時スペースが挿入される
例。scrollSpeed → Scroll Speed

Unityエディタ上でプロパティの値を変更した場合、その変更はリアルタイムに内部で変更され状況により視覚的にも確認可能
この値はunityエディタ上で保持されるがスクリプト側のコードが変更されるわけではない事に注意
(必要であればresetする事でスクリプト側の値に戻せる)

これはレベル上で配置したプレハブでも同じでそれぞれが値を持つ。これはオリジナルを書き換えない
オリジナルを書き換えたい場合はインスペクタ内の「 prefab → Select 」をクリックしてプロジェクト内の
オリジナルを選択状態にして内容を書き換える。この場合、無変更状態のレベル上に配置されたプレハブの内容は
オリジナルに沿って更新されるが、変更を加えたプレハブは各々の値を保持する
必要であれば歯車アイコン内にある「Revert to Prehab」でオリジナルの値にすることも出来る

重要:ユニティエディタ上のローカルな値は太字(ボールド書体)で表示される

スクリプト内でprivate変数にした場合、この変数はユニティエディタ上からも見えなくなる


  • 新しいレベルのロード時、前のレベルの全オブジェクトが破棄されます。 これを防ぐには、破棄したくないオブジェクトで、 DontDestroyOnLoad() を使用します。 これは、レベルのロード時に音楽の再生を続ける場合や、ゲームの状態や進捗を維持するゲーム コントローラ スクリプトに通常使用されます。

  • 新しいレベルのロード終了後に、 OnLevelWasLoaded() というメッセージがすべてのアクティブなゲーム オブジェクトに送信されます。

インスペクタ


インスペクタ内の変数は配列をサポートする
例えば以下のようなスクリプトではユニティエディタ上でカラーピッカーが4要素、表示されるようになる

public class vector : MonoBehaviour {
  
   public    Color32[] col= new Color32[4];

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


メモ


(単純なメニュー等の日本語化。ちなみにunityをアップデートすると吹っ飛ぶのでツールに慣れてるなら、しない方が良いのでは?)

メニュー


  • 最終更新:2015-02-09 02:43:10

このWIKIを編集するにはパスワード入力が必要です

認証パスワード