UnityEngine擬似コードから考える transform.position
transform.position.x = 5.0f
としたところ、エラーが発生して代入できない経験はありませんか?
その場合、
float posX = 5.0f;
float posY = transform.position.y;
float posZ = transform.position.z;
transform.position = new Vector3(posX, posY, posZ);
という書き方をすれば、大丈夫なのですが、なぜ?と思いますよね。
理解を深めるために簡単なコードとUnityEngineのシミュレーションコードから、
内部の動作を確認してみましょう。C#のコードから追ってみてください。
C#の確認コード
正常終了(フィールドへのアクセス)
using UnityEngine;
public class PositionSetSample : MonoBehaviour
{
void Start()
{
MyPosition myPos = new MyPosition();
// 直接フィールド値を変更します
myPos.pos.x = 4;
}
}
public class MyPosition
{
public Vector3 pos;
}
public struct Vector3
{
public int x;
}
エラー(プロパティへのアクセス)
using UnityEngine;
public class PositionSetSample : MonoBehaviour
{
void Start()
{
MyPosition myPos = new MyPosition();
// 値型のコピーが渡されるため、変更してもPosプロパティの値は変わらない
myPos.Pos.x = 4;
// 次のコードと同じです。元のプロパティは変更されません
Vector3 temp = myPos.Pos;
temp.x = 4;
}
}
public class MyPosition
{
private Vector3 pos;
public Vector3 Pos
{
get
{
return pos;
}
set
{
pos = value;
}
}
}
public struct Vector3
{
public int x;
}
さらに理解を深めるためにUnityEngineのシミュレーションコードから、
内部の動作を確認してみましょう。C#のコードから追ってみてください。
Unityエンジンのシミュレーションサンプル
using System;
namespace SimulationUnityEngine
{
// 3次元ベクター情報の構造体
public struct Vector3
{
// フィールド
public float x;
public float y;
public float z;
// コンストラクタ
public Vector3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
// 静的プロパティ
public static Vector3 forward
{
get
{
return new Vector3(0f, 0f, 1f);
}
}
// 演算子オーバーロード
public static Vector3 operator +(Vector3 a, Vector3 b)
{
return new Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
}
}
// トランスフォーム情報のクラス
public class Transform
{
private Vector3 internalPos;
public Vector3 position
{
get
{
return internalPos;
}
set
{
internalPos = value;
}
}
}
class Program
{
static void Main(string[] args)
{
Transform transform = new Transform();
float posX = transform.position.x;
float posY = transform.position.y;
float posZ = transform.position.z;
Console.WriteLine($" position x = {posX}, y = {posY}, z = {posZ}”);
// これはダメ。transform.position の設定値は、プロパティのため。
// .xのfloat型までの代入はできない。
// transform.position.x = posX;
posX += 10.0f;
posY += 3.0f;
posZ += 5.0f;
// これはOK。コンストラクタを使って代入をしているため。
transform.position = new Vector3(posX, posY, posZ);
Console.WriteLine($" position x = {posX}, y = {posY}, z = {posZ}");
}
}
}
/*
// 実際のプログラムで x,y,z = (10,10,10)の地点にゲームオブジェクトがある設定。
transform.position = new Vector3(10f, 10f, 10f);
Console.WriteLine($" position x = {transform.position.x},
y = {transform.position.y},
z = {transform.position.z}”);
// 一歩前に進む。
// forwardプロパティは、staticなのでインスタンスを作る必要はない(newしない)
// z軸の座標が+1される。つまり3Dオブジェクトの場合、前進することになる。
transform.position += Vector3.forward;
Console.WriteLine($" position x = {transform.position.x},
y = {transform.position.y},
z = {transform.position.z}");
*/
表示
position x = 0, y = 0, z = 0
position x = 10, y = 3, z = 5
/*
position x = 10, y = 10, z = 10
position x = 10, y = 10, z = 11
*/
Unityのpositionは、値型のプロパティになります。次のリンクにあるように呼び出すとコピーされた値が返ってくるため、この値を変更しても実際のposition値は変更されません。
ディスカッション
コメント一覧
まだ、コメントがありません