2013年2月11日月曜日

[MonoDevelop]Snippetsを使って記述を楽にする方法

Snippetsをご存知だろうか。
端的に言えば、Snippetsとは、何度も同じことを入力する場合、その作業が面倒なので短い単語で呼び出せるようにしちゃおう!ということ。
HashKeyの概念でとらえると分かりやすいかもしれない(というかまんまHashです)。

だが、正直にいうと僕はSnippetsという言葉を知らなかった。
しかし、Snippetsという言葉を知らなくても恩恵に授かっていたことに気づく。
多くのプログラマーなら恩恵を授かったことが有るはず。
最も基本的なもので言えば、if文やfor文、while文やclass構文などでも使用されており、恩恵を授かったことの無いプログラマーなどは居ないはずだ。

と、どうでもいい言い訳がましいことはさておいて、早速使ってみた。

今回はUnityScript上での例で、タッチイベントの処理が毎度毎度記述するのが面倒なのでCode Snippets化した。

UnityScript上でタッチイベントを取得する際、下記のように記述するだろう。


foreach (Touch item in Input.touches) {
 switch( item.phase ) {
 case TouchPhase.Began:
  break;
 case TouchPhase.Canceled:
  break;
 case TouchPhase.Ended:
  break;
 case TouchPhase.Moved:
  break;
 case TouchPhase.Stationary:
  break;
 }
}


このようなコードを毎回記述するのは面倒だろう。
そこで、Snippetsの出番。
まずは「MonoDevelopEditor」上の[Preference]を開く。




◆[TextEditor] -> [Code Templates]を開くと、各言語毎に設定されているテンプレートコードがあるのが分かる。
今回は「Unity C#」なので、「C#」にSnippetsを追加する。




◆[Add]ボタンを押すと、テンプレート作成画面になる。



[Shoutcut] : TemplateTextを呼び出す際に記述するコード
[Group] : どのテンプレートグループなのかを判別
[Description] : snippetsの説明文
[Mime] : どの言語で使用されるものかを判別

[Shoutcut]に「TouchTemp」と記述し、[Group]は「C#」、
[Description]には「template for touch event」、[Mime]に「text/x-csharp」を入力し、大きい空欄の[Template Text]にコードを記述する。
今回はタッチイベント用のコードを記述しておく。

すると、コード上で「TouchTemp」と記述した後に「tab」キーを押すと、先ほど[Template Text]に記述しておいたコードが呼ばれるようになる。

※Descriptionの説明が記述もきちんとある



確かにこれは……いいものだ!


[Unity]Quaternionについて

UnityScriptでオブジェクトの回転に関する計算をするのが面倒な場合、Quaternionを使用すれば処理も高速になるし幸せになれるので実際に動かしながら実験したときのメモ。


◆概念

今回はUnity Script上のコードでどういう挙動になるかの調査なので、概念はwikiなどにお任し、割愛させていただく。



◆ソース
using UnityEngine;
using System.Collections;

/**
 * Quaternionを体系的に学ぶためのテストクラス
 * Quaternionは四元数と呼ばれ、回転をごくごく簡単に扱うことができる
 * なお、Quaternionは原点を中心に回転軸を考慮してしまうので、原点以外からの回転軸の計算を行いたい場合は事前に座標計算をしておく必要がある
 **/
public class QuaternionTest : MonoBehaviour {
 
 public Vector3 point;
 public Vector3 angle;
 
 public bool isAnimation;
 public int animationCounter;
 public int ANIMATION_FPS = 24;

 // Use this for initialization
 void Start () {
  // if target os is iPhone ~
  // change value from "#define kFPS 30 of AppController.mm"
  Application.targetFrameRate = 60;
 }
 
 // Update is called once per frame
 void LateUpdate () {
  if ( !isAnimation ) return;
  
  // カメラのQuaternionを取得
  // 今回の場合、カメラの座標 to 原点の向きが取得できる
  Quaternion targetQuaternion = Camera.mainCamera.transform.rotation;
  
  // 特定の座標点から座標点への向きを取得できる
  //targetQuaternion = Quaternion.FromToRotation( new Vector3(1,1,1), new Vector3(-1,-1,-1));
  
  // この例だと、カメラから物体の座標点
  //targetQuaternion = Quaternion.FromToRotation( transform.position, Camera.mainCamera.transform.position );
  
  // Quaternionを反転させる
  // 用途例としては、自分(敵)のQuaternionを敵(自分)に反転させて反映させることで向き合うことができる、など
  //targetQuaternion = Quaternion.Inverse(Camera.mainCamera.transform.rotation);
  
  // 原点 to 座標点の向きが取得できる
  //targetQuaternion = Quaternion.LookRotation( new Vector3(1,1,1) );
  
  // こちらの例だと、カメラの座標点 - 物体の座標点 を計算してから行っているので、
  // 物体の座標点 to 座標点の向きが取得できる
  Vector3 relativePos = Camera.mainCamera.transform.position - transform.position;
        targetQuaternion = Quaternion.LookRotation(relativePos);
  
  animationCounter++;
  if ( animationCounter >= ANIMATION_FPS ) {
   animationInit();
   return;
  }
  //transform.rotation = Quaternion.Slerp( transform.rotation, Camera.mainCamera.transform.rotation, Time.deltaTime );
  float mountTime = (float)animationCounter / ANIMATION_FPS;
  
  // Slerpは球面線形補間と呼ばれるアルゴリズムで、
  // QuaternionからQuaternionへの移動をスムーズに行うことができるヘルパー関数
  // 3つめの引数に、変化量を指定することで、なめらかな変化が実現できる( 0.0f 〜 1.0f )
  transform.rotation = Quaternion.Slerp( transform.rotation, targetQuaternion, mountTime );
 }
 
 public void animationStart() {
  animationInit ();
  isAnimation = true;
 }
 
 private void animationInit() {
  isAnimation = false;
  animationCounter = 0;
 }
}


◆参照
http://www015.upp.so-net.ne.jp/notgeld/quaternion.html http://ja.wikipedia.org/wiki/%E5%9B%9B%E5%85%83%E6%95%B0 http://marupeke296.com/DXG_No10_Quaternion.html http://docs.unity3d.com/Documentation/ScriptReference/Quaternion.html