前回でアイテム管理プログラムが完成しました。
今回はフィールドにアイテムを生成します。
設計
生成するときに必要なものは以下の3つです。
- アイテム名
- 生成するか決める指標
- 生成座標
1. アイテム名
今回はアイテム名をKeyにしてプレハブを生成するため必須です。
他の方法として、新たにアイテムIDを作成してIDをKeyにすることもできますが、面倒なのでアイテム名を使用します。
2. 生成するか決める指標
登録された座標にアイテムが存在するか確認できるようにします。
プレイヤーが既にアイテムを拾っていて、アイテムが無くなっている場合のみ生成します。
3. 生成座標
空中とか海中にアイテムを生成されても困るので生成される場所を指定しておきます。
実装
アイテム名は既にあるので、「生成するか決める指標」と「生成座標」を要素にしたオブジェクトを最初に作成します。
なお、Flagが 0 の場合にアイテムプレハブを生成することにします。

次に、作成したオブジェクトをアイテムデータベースに登録します。
これで生成データを一括管理できるようになります。

必要なものが全て揃ったのでアイテム生成スクリプトを作成します。
ゲームオブジェクトにはアイテムプレハブを設定して動的にインスタンス化できるようにしておきます。
Coconut. Kiwi は無料プレハブが無かったため Peanut, Peach で仕方なく代用してます。

動作確認
動的にアイテムを生成できました。
ゲームでは1時間ごとにアイテム生成されるようにしてます。
ココナッツの無料プレハブが無くてピーナッツで代用しましたが、意外と違和感ないですね(笑)

アイテムのアセットは以下をダウンロードしました。
最後に使用プログラムを掲載します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
[Serializable]
[CreateAssetMenu(fileName = "Position", menuName = "CreatePosition")]
/* アイテム生成データを作成するクラス */
public class GeneratePosition : ScriptableObject {
// アイテム名
[SerializeField]
private string itemName;
// x座標
[SerializeField]
private int x;
// y座標
[SerializeField]
private int y;
// z座標
[SerializeField]
public int z;
// 判定値
[SerializeField]
private int flag;
/*-------------------関数----------------------------*/
// アイテム名
public string GetItemName(){
return itemName;
}
// x座標
public int GetX(){
return x;
}
// y座標
public int GetY(){
return y;
}
// z座標
public int GetZ(){
return z;
}
// 判定値
public int GetFlag(){
return flag;
}
public void SetFlag(){
flag = 1;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "GenerateDataBase", menuName="CreateGenerateDataBase")]
/* アイテム生成データベース */
public class GenerateDataBase : ScriptableObject {
[SerializeField]
private List<GeneratePosition> posLists = new List<GeneratePosition>();
// 座標リストを返す
public List<GeneratePosition> GetPosLists() {
return posLists;
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
/* フィールドにアイテムを生成するクラス */
public class ItemGenerater : MonoBehaviour {
// 生成座標
public GenerateDataBase GenerateDataBase;
// インスタンス化
private GameObject Instance;
// アイテム名
private string item_name;
// 生成間隔
private float interval;
// 経過時間
private float time = 0f;
// 生成リスト
private List<GeneratePosition> posLists = new List<GeneratePosition>();
private int l_size;
// 生成座標
private int x;
private int y;
private int z;
// アイテムプレハブ
public GameObject Prefab1;
public GameObject Prefab2;
public GameObject Prefab3;
public GameObject Prefab4;
public GameObject Prefab5;
public GameObject Prefab6;
public GameObject Prefab7;
void Start()
{
interval = 0f;
posLists = GenerateDataBase.GetPosLists();
l_size = posLists.Count;
Debug.Log(posLists[0].GetItemName());
}
void Update()
{
// 時間計測
time += Time.deltaTime;
// 経過時間が生成時間になったとき(生成時間より大きくなったとき)
if(time > interval)
{
for(int i=0; i<l_size; i++)
{
// アイテム生成
GenerateItem(posLists[i], posLists[i].GetFlag(), i);
}
// 経過時間を初期化
time = 0f;
interval = 3600f;
}
}
public void GenerateItem(GeneratePosition posData, int flag, int index)
{
// アイテムが残ってる場合は何もしない
if(flag == 1)
return;
// アイテム名を取得
item_name = posData.GetItemName();
// 生成座標を取得
x = posData.GetX();
y = posData.GetY();
z = posData.GetZ();
// インスタンス化する
switch(item_name)
{
case "Apple":
Instance = Instantiate(Prefab1);
break;
case "Cherry":
Instance = Instantiate(Prefab2);
break;
case "Kiwi":
Instance = Instantiate(Prefab3);
break;
case "Lemon":
Instance = Instantiate(Prefab4);
break;
case "Coconut":
Instance = Instantiate(Prefab5);
break;
case "Pear":
Instance = Instantiate(Prefab6);
break;
case "Strawberry":
Instance = Instantiate(Prefab7);
break;
default:
return;
}
// 指定した座標にアイテムを生成
Instance.transform.position = new Vector3(x,y,z);
// アイテムを生成したので flag を 1 にする
GenerateDataBase.GetPosLists()[index].SetFlag();
}
}
フィールドにアイテムがある状態にできました。
次回はアイテムを拾う処理を考えます。