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

Unity / VRゲーム開発日記@長崎

Unityを使ったVRのゲーム開発をやってます。

クラスのメソッドを拡張するExtensionの使い方

C#には、既存のクラスに機能を追加することができる
Extensionという機能があります。


例えば、
transform.position
は、
transform.position.x = 10;
など、座標のx値を直接変更することができませんが、


ExtensionでTransformクラスを拡張して、
tranform.SetPosX(10)
等として、x値だけを変更するというメソッドを
追加することができます。


例としてあげたpositionのx値だけを
書き換える拡張のコードは以下のようになります。

public static class Extensions
{

	public static void SetPosX (this Transform me, float val)
	{

		var newPos = me.transform.position;
		newPos.x = val;
		me.transform.position = newPos;
		
	}

}


まず、Extensionsというstaticクラスを作っておきます。
その中に更にstaticの関数でSetPosXを作りました。


この関数の引数に「this」という修飾子がついています。
これが、Transformクラスにメソッドを追加するよ!
の意味になります。


そして、meは引数名ですが、これがこのSetPosXを呼び出している
Transformへの参照という意味です。


で、関数の中身は、
一度transform.postionから既存のVector3の値をとって
そのx値だけ書き換えて
それをもう一度transform.positionに再設定するという、
普段positionの値を設定する通りの手続きになってます。


つまり、positionのXだけを変えるのに毎回関数内の記述を書いてた場合は、
それが
transform.SetPosX(val)
だけですむようになるので、かなり手続きが楽になるかと思います。


後は、同様にSetPosYやSetPosZも追加しておけば汎用性が高まるかと思います。


2D用にx,yだけ設定したい場合は、
Set2D(this Transform me, Vector2 val)
みたいな形にして、x,y値だけを変更できるようにすると便利かもです。


自分は他に、Get2Dとしてx,yの座標を取得したり
AddPosX等として、現在位置に値を足す物、
あとは、サイズ、角度にたいしてもx,y,zだけ変更できるような
拡張をつけています。


コードを共有して開発してる時は、勝手に拡張をつけすぎると
他の人にとっては煩わしくなる可能性もありますが、
個人開発の場合は、自分で使いやすい機能をどんどん追加していって
なるべくコードを書く手間を減らしていっても良いかと思います。



最後に、SetPos、xyzの拡張とSet2Dの例を上げておきます。

public static class Extensions
{

	public static void SetPosX (this Transform me, float val)
	{

		var newPos = me.transform.position;
		newPos.x = val;
		me.transform.position = newPos;
		
	}
		
	public static void SetPosY (this Transform me, float val)
	{
	
		var newPos = me.transform.position;
		newPos.y = val;
		me.transform.position = newPos;
		
	}
	
	public static void SetPosZ (this Transform me, float val)
	{
	
		var newPos = me.transform.position;
		newPos.z = val;
		me.transform.position = newPos;
		
	}

	public static void Set2D (this Transform me, float x, float y)
	{
		var newPos = me.transform.position;
		newPos.x = x;
		newPos.y = y;
		me.transform.position = newPos;

	}

	public static void Set2D(this Transform me, Vector2 pos){
		me.Set2D(pos.x, pos.y);
	}

}