Unityは
transform.position.x = 123f;
と書くと
エラーになるんですが
positionのxだけを変えるとなると
transform.position = new Vector3(123f, transform.position.y, transform.position.z);
こんな長ったらしくなるので
transform.position.x = 123f;
に近い書き方ができないかなと
ポケモンをしながら真剣に考えたら
一つの方法を思いついたので
共有したいと思います。
よく紹介されてる方法として
public static class TransformExtensions
{
public static void SetPositionX(this Transform self, float x)
{
self.position.x = x;
}
}
というクラスを用意すると
transform.SetPositionX(123f);
という風に書ける方法があります。
これでもいいんですがtransform.position.x += 123f;
のように
加算したいときは別にAddPositionXのような関数を書かなければいけないので
必要な関数の数が膨大になります。
ざっと挙げてみると
- SetPositionX
- SetPositionY
- SetPositionZ
- AddPositionX
- AddPositionY
- AddPositionZ
- SubPositionX
- SubPositionY
- SubPositionZ
- MulPositionX
- MulPositionY
- MulPositionZ
- DivPositionX
- DivPositionY
- DivPositionZ
- SetLocalPositionX
- SetLocalPositionY
- SetLocalPositionZ
- AddLocalPositionX
- AddLocalPositionY
- AddLocalPositionZ
- SubLocalPositionX
- SubLocalPositionY
- SubLocalPositionZ
- MulLocalPositionX
- MulLocalPositionY
- MulLocalPositionZ
- DivLocalPositionX
- DivLocalPositionY
- DivLocalPositionZ
- SetEulerAnglesX
- SetEulerAnglesY
- SetEulerAnglesZ
- AddEulerAnglesX
- AddEulerAnglesY
- AddEulerAnglesZ
- SubEulerAnglesX
- SubEulerAnglesY
- SubEulerAnglesZ
- MulEulerAnglesX
- MulEulerAnglesY
- MulEulerAnglesZ
- DivEulerAnglesX
- DivEulerAnglesY
- DivEulerAnglesZ
- SetLocalEulerAnglesX
- SetLocalEulerAnglesY
- SetLocalEulerAnglesZ
- AddLocalEulerAnglesX
- AddLocalEulerAnglesY
- AddLocalEulerAnglesZ
- SubLocalEulerAnglesX
- SubLocalEulerAnglesY
- SubLocalEulerAnglesZ
- MulLocalEulerAnglesX
- MulLocalEulerAnglesY
- MulLocalEulerAnglesZ
- DivLocalEulerAnglesX
- DivLocalEulerAnglesY
- DivLocalEulerAnglesZ
- SetLocalScaleX
- SetLocalScaleY
- SetLocalScaleZ
- AddLocalScaleX
- AddLocalScaleY
- AddLocalScaleZ
- SubLocalScaleX
- SubLocalScaleY
- SubLocalScaleZ
- MulLocalScaleX
- MulLocalScaleY
- MulLocalScaleZ
- DivLocalScaleX
- DivLocalScaleY
- DivLocalScaleZ
冗長ですよね。
でもこの記事の方法を使えば
transform.SetPosition(t => t.x = 123f);
transform.SetPosition(t => t.x += 456f);
transform.SetPosition(t => {
t.y *= 123f;
t.z /= 456f;
});
という風に自由に値をいじれます。
わかる人にはわかると思いますが、ラムダ式を使います。
下のように書けば使えるようになります。
using System;
public static class TransformExtensions
{
public class WrappedVector3
{
public Vector3 vector3;
public float x { get => vector3.x; set => vector3.x = value; }
public float y { get => vector3.y; set => vector3.y = value; }
public float z { get => vector3.z; set => vector3.z = value; }
}
public static void SetPosition(this Transform self, Action<WrappedVector3> setter)
{
WrappedVector3 temp = new WrappedVector3();
temp.vector3 = self.position;
setter(temp);
self.position = temp.vector3;
}
public static void SetLocalPosition(this Transform self, Action<WrappedVector3> setter)
{
WrappedVector3 temp = new WrappedVector3();
temp.vector3 = self.localPosition;
setter(temp);
self.localPosition = temp.vector3;
}
public static void SetEulerAngles(this Transform self, Action<WrappedVector3> setter)
{
WrappedVector3 temp = new WrappedVector3();
temp.vector3 = self.eulerAngles;
setter(temp);
self.eulerAngles = temp.vector3;
}
public static void SetLocalEulerAngles(this Transform self, Action<WrappedVector3> setter)
{
WrappedVector3 temp = new WrappedVector3();
temp.vector3 = self.localEulerAngles;
setter(temp);
self.localEulerAngles = temp.vector3;
}
public static void SetLocalScale(this Transform self, Action<WrappedVector3> setter)
{
WrappedVector3 temp = new WrappedVector3();
temp.vector3 = self.localScale;
setter(temp);
self.localScale = temp.vector3;
}
}
これで、positionもlocalPositionもeulerAnglesもlocalEulerAnglesもlocalScaleも
x、y、z、どの値も自由にいじることができます。
これが自分が考えうる限り
一番スマートだと思います。
もっといい方法があるならぜひ教えてください!