はじめに
前回はプレイヤー用のオブジェクトを作成して、移動を作成しました。
今回はプレイヤーが取れるコインを作っていきましょう。
今回の最終形はこんな感じになります!
コインが生成されて、プレイヤーが当たるとコインが消えるようになっています。
コインのプレハブを作成
コイン用のプレハブを作ります。
Cylinderを使い良い感じにコインの形にし、BoxColliderを付けます。
そして黄色のマテリアルに変えましょう。
コインを同期するためのコンポーネントを追加します。
- NetworkObject
- NetworkTransform
ついでにコインとプレイヤーの当たり判定用にTagを設定しておきましょう。
Coinという名前のTagを作成し、設定しておいてください。
コインを回転させる
コインをくるくる回したいのでCoinスクリプトを作成します。
public class Coin : NetworkBehaviour
{
private void Update()
{
if(IsServer)
{
transform.Rotate(Vector3.up, Space.World);
}
}
}
Updateでサーバーの場合のみ回転させています。
このスクリプトをプレハブにアタッチしたらコインの完成です。
アタッチするオブジェクトがネットワークオブジェクトなのでNetworkBehaviourを継承していることに注意してください。
プレハブをNetworkManagerに登録
前回も説明しましたがNetworkObjectのプレハブはNetworkManagerに登録する必要があります。
タイトルシーンを開き、NetworkManagerのNetworkPrefabsにプレハブを登録します。
コインをステージに生成
ステージにコインを生成するために、コイン管理用のクラスを作ります。
CoinManagerという名前のスクリプトを作成して、以下のコードを記述します。
public class CoinManager : NetworkBehaviour
{
//コインのプレハブ
[SerializeField] private NetworkObject m_coinPrefab;
//生成したコインのリスト
private List<GameObject> m_coinObjects = new List<GameObject>();
//スポーンされたとき
public override void OnNetworkSpawn()
{
//ホストの場合
if (IsHost)
{
GenerateCoin();
}
}
// コイン生成
public void GenerateCoin()
{
//コイン生成
for (int x = 0; x < 10; x++)
{
NetworkObject coin = Instantiate(m_coinPrefab);
int posX = UnityEngine.Random.Range(0, 10) - 5;
int posZ = UnityEngine.Random.Range(0, 10) - 5;
coin.transform.position = new Vector3(posX, 0, posZ);
coin.Spawn();
m_coinObjects.Add(coin.gameObject);
}
}
//簡易的なシングルトン
private static CoinManager instance;
public static CoinManager Instance
{
get
{
if (instance == null)
{
instance = (CoinManager)FindObjectOfType(typeof(CoinManager));
}
return instance;
}
}
}
スクリプトを作成出来たら、GameシーンにCoinManagerというオブジェクトを作成します。
そしてNetworkObjectと作成したスクリプトを追加します。
CoinPrefabには先ほど作成したプレハブをアタッチしてください。
CoinManager.csの大事な部分を解説します。
OnNetworkSpawn
OnNetworkSpawnはネットワークオブジェクトの準備が完了し生成された時に呼ばれるコールバックです。
今回はOnNetworkSpawnでホストのみコインの生成をしています。
public override void OnNetworkSpawn()
{
//ホストの場合
if (IsHost)
{
GenerateCoin();
}
}
ネットワークオブジェクトの動的生成
今回のコインは動的に生成しますが、ネットワークオブジェクトなので生成方法が少し異なります。
NetworkObject coin = Instantiate(m_coinPrefab);
int posX = UnityEngine.Random.Range(0, 10) - 5;
int posZ = UnityEngine.Random.Range(0, 10) - 5;
coin.transform.position = new Vector3(posX, 0, posZ);
coin.Spawn();
Instantiateしてオブジェクトのインスタンスを作成します。
GameObjectを生成する時と同じ関数ですが、引数がNetworkObjectのプレハブになっています。
そして、NetworkObjectのSpawn関数を呼び出します。
この関数を呼び出すとすべてのクライアントでオブジェクトがスポーンされます。
Spawn関数を呼び出さないとクライアントにオブジェクトが生成されないので注意が必要がです。
途中経過を見てみよう
スタート時にコインが生成されているはずなので、一度テストしてみましょう!
プレイヤーが当たっても取ることはできませんが、コインが生成されるようになりました!
プレイヤーが当たったらコインを消そう
CoinManagerクラスの下部に以下のコードを追加します。
// コイン削除(ホストから呼び出される)
public void DeleteCoin(GameObject coinObj)
{
var network = coinObj.GetComponent<NetworkObject>();
network.Despawn();
m_coinObjects.Remove(coinObj);
//全部消えたらコイン再生成
if (m_coinObjects.Count == 0)
{
GenerateCoin();
}
}
そしてPlayerクラスからDeleteCoin関数を呼び出すようにしましょう。
Playerクラスの下部に以下を追加します。
//コインと当たった場合コイン削除
void OnTriggerEnter(Collider other)
{
//クライアントの場合は無視
if (IsServer == false) { return; }
if (other.gameObject.CompareTag("Coin"))
{
//コイン削除処理(CoinManagerの処理を呼ぶ)
CoinManager.Instance.DeleteCoin(other.gameObject);
}
}
ネットワークオブジェクトの破棄
ネットワークオブジェクトはNetworkObject型のDespawn関数を呼び出すことで破棄できます。
network.Despawn();
ビルドして確認しよう
ここまで出来たらビルドして確認してみましょう。
コインが生成されて、プレイヤーが当たるとコインが消えるようになりました。
まとめ
今回でコインを生成と削除が出来るようになりました。
次回はコインを取った枚数を表示できるようにしていきます。
👇あなたにお勧めの書籍
次回↓
コメント