構造体とは
構造体は、複数の変数を1つにまとめて管理することが出来ます。
一つの構造体に、int型やstirng型のような、型の違うものでも1つにまとめることが出来ます。クラスと似ていますが、シンプルに値だけを持たせたい時や、軽量なオブジェクトとして使いたい時に使うことが多いです。
構造体を使わない場合
using UnityEngine;
//スライムクラス
public class Slime : MonoBehaviour
{
private string name;
private int hp;
private int strength;
private int defence;
private int speed;
//名前を取得
public string GetName()
{
return name;
}
//体力を取得
public int GetHp()
{
return hp;
}
//攻撃力を取得
public int GetStrength()
{
return strength;
}
//防御力を取得
public int GetDefence()
{
return defence;
}
//素早さを取得
public int GetSpeed()
{
return speed;
}
}
このプログラムは、構造体を使わないで、Slimeクラスにステータス情報を持たせています。
5つ変数があるだけでもまあまあな長さのプログラムになってしまいました。
では、構造体を使った場合のプログラムを見てみましょう!
構造体を使った場合
using UnityEngine;
//構造体
[System.Serializable] //インスペクターに値を表示できるようにする
public struct Status
{
public string name;
public int hp;
public int strength;
public int defence;
public int speed;
}
using UnityEngine;
//スライムクラス
public class Slime : MonoBehaviour
{
private Status status = new Status(); //ステータス構造体を定義
//ステータスを取得する
public Status GetStatus()
{
return status;
}
}
各ステータスを構造体(struct)にまとめたことで、Slimeクラスがすっきりしました。一度、構造体を定義しておけば、他のクラスでもStatus構造体を使いまわすことが出来るので、スライムの他に新しくクラスを作る際にも、ステータスを1つずつ定義する必要がなくなります。
構造体の初期化
コンストラクタを使う
using UnityEngine;
[System.Serializable] //インスペクターに値を表示できるようにする
public struct Status
{
public string name;
public int hp;
public int strength;
public int defence;
public int speed;
//コンストラクタ
public Status(string name, int hp, int strength, int defence, int speed)
{
this.name = name;
this.hp = hp;
this.strength = strength;
this.defence = defence;
this.speed = speed;
}
}
using UnityEngine;
//スライムクラス
public class Slime : MonoBehaviour
{
private Status status = new Status("スライム",10, 20, 30, 400); //ステータス構造体を定義
}
構造体には、コンストラクタを定義することが出来ます。コンストラクタとは、変数として構造体を使う時に、初期値を入れておきたい場合に、使うことが出来る初期化用の関数のことを言います。
Vector3 pos = new Vector3(0,10,0); //Vector3(0,10,0)の部分がコンストラクタ
Unityでよく使う、Vector3の初期化を行う時に、new Vector3(値,値,値);を使って初期化すると思います。この(値,値,値)の部分がコンストラクタに渡す値になります。ここに入れた値で、構造体の値が初期化されます。
※構造体に、コンストラクタを定義していない場合は、new 構造体(値)では、初期化できませんので、コンストラクタを利用したい場合は、構造体の中にきちんとコンストラクタを実装する必要があります。
[System.Serializable] //インスペクターに値を表示できるようにする
public struct Status
{
public string name;
public int hp;
public int strength;
public int defence;
public int speed;
//コンストラクタ
public Status(string name, int hp, int strength, int defence)
{
this.name = name;
this.hp = hp;
this.strength = strength;
this.defence = defence;
//speedを初期化していないので、エラーとなる
}
}
さらに、コンストラクタを定義すると、構造体に定義した変数をすべて初期化しなくてはいけません。
初期化しない場合、エラーとなります。
インスタンス化と同時に初期化する
using UnityEngine;
[System.Serializable] //インスペクターに値を表示できるようにする
public struct Status
{
public string name;
public int hp;
public int strength;
public int defence;
public int speed;
}
using UnityEngine;
//スライムクラス
public class Slime : MonoBehaviour
{
private Status status = new Status() { name = "スライム", hp = 10, strength = 20, defence = 30, speed = 40 }; //ステータス構造体を定義
}
変数をインスタンス化(コンピューターのメモリ上に値を確保)したとき、new Status()の後ろに
{ hp = 10 }と書くことで、値を指定して初期化することが出来ます。
newを使わずに初期化する
using UnityEngine;
[System.Serializable] //インスペクターに値を表示できるようにする
public struct Status
{
public string name;
public int hp;
public int strength;
public int defence;
public int speed;
}
//スライムクラス
public class Slime : MonoBehaviour
{
private Status status; //ステータス構造体を定義
private void Start()
{
status.name = "スライム";
status.hp = 10;
status.strength = 20;
status.defence = 30;
status.speed = 40;
}
}
newを使わない場合は、関数などの中で構造体の各変数に値を入れることで初期化できます。