MLAPI その9
非推奨となった UNet のやつを参考に、オブジェクトプールをやってみる。
docs.unity3d.com
mlapi.network
mlapi.network
シーン内に SpawnManager オブジェクトを作ってスクリプトをアタッチ。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SpawnManager : MonoBehaviour { public GameObject bullet; private GameObject[] bulletPool; private int poolSize = 5; void Start() { bulletPool = new GameObject[poolSize]; for (int i = 0; i < poolSize; i++) { bulletPool[i] = (GameObject)Instantiate(bullet, Vector3.zero, Quaternion.identity); bulletPool[i].name = "PoolObject" + i; bulletPool[i].SetActive(false); } MLAPI.Spawning.SpawnManager.RegisterSpawnHandler(MLAPI.Spawning.SpawnManager.GetPrefabHashFromIndex(1), SpawnObject); MLAPI.Spawning.SpawnManager.RegisterCustomDestroyHandler(MLAPI.Spawning.SpawnManager.GetPrefabHashFromIndex(1), UnSpawnObject); } public GameObject GetFromPool(Vector3 position, Quaternion rotation) { for (int i = 0; i < poolSize; i++) { if (!bulletPool[i].activeSelf) { Debug.Log("Activating GameObject " + bulletPool[i].name + " at " + position); bulletPool[i].transform.position = position; bulletPool[i].transform.rotation = rotation; bulletPool[i].SetActive(true); return bulletPool[i]; } } Debug.LogError("Could not grab GameObject from pool, nothing available"); return null; } public MLAPI.NetworkedObject SpawnObject(Vector3 position, Quaternion rotation) { return GetFromPool(position, rotation).GetComponent<MLAPI.NetworkedObject>(); } public void UnSpawnObject(MLAPI.NetworkedObject networkedObject) { Debug.Log("Re-pooling GameObject " + networkedObject.gameObject.name); networkedObject.gameObject.SetActive(false); } }
PlayerCubeController の方で、SpawnManager 経由で弾を呼び出すように変更。
public class PlayerCubeController : MLAPI.NetworkedBehaviour { private SpawnManager spawnManager; private void Start() { spawnManager = GameObject.Find("SpawnManager").GetComponent<SpawnManager>(); } [MLAPI.Messaging.ServerRPC] private void Shoot() { GameObject bullet = spawnManager.GetFromPool(new Vector3(Random.Range(-9, 9), 1.0f, Random.Range(-9, 9)), Quaternion.Euler(0, 0, 90)); bullet.GetComponent<MLAPI.NetworkedObject>().Spawn(); StartCoroutine(BackToPool(bullet, 2.0f)); } private IEnumerator BackToPool(GameObject bullet, float timer) { yield return new WaitForSeconds(timer); MLAPI.NetworkedObject no = bullet.GetComponent<MLAPI.NetworkedObject>(); spawnManager.UnSpawnObject(no); no.UnSpawn(); } }
弾が自動的に消えないようにコメントアウト。
public class Bullet : MonoBehaviour { void Update() { //restTime -= Time.deltaTime; //if (restTime < 0) //{ // Destroy(this.gameObject); //} } }
いまひとつ理解ができていない……。
これだとクライアントが複数つながっても、シーン内に弾が 5 発しか存在できない。
なかなか難しかった。