概要
前回の続きです。
今回は、複数敵が出現するように実装します。
ObjectPoolerを使います。
2Wave以降 最終地点に直行してますが次回改善します。
次へ
開発環境
IDE:Rider
Unity:2020.3.42(LTS)
OS:Windows10
UnityEditorの画像
Enemyプレハブの設定
Spawnerオブジェクト
実装のポイント
Enemyクラス上でWaypointをSpawnerクラスから参照できるようにします。
理由としては、Enemyクラスがアタッチされているオブジェクトをプレファブ化するとWaypointに参照できなくなるからです。
対処方法としてはSpawnerクラスで、Enemyのプレファブを生成する際にWaypointクラスを渡すようにします。
コード部分
Enemy.cs
using System;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public static Action OnEndReached;
[SerializeField] private float moveSpeed = 3f;
- [SerializeField] private Waypoint waypoint;
+ public Waypoint Waypoint { get; set; }
- public Vector3 CurrentPointPosition => waypoint.GetWaypointPosition(_currentWaypointIndex);
+ public Vector3 CurrentPointPosition => Waypoint.GetWaypointPosition(_currentWaypointIndex);
private int _currentWaypointIndex;
private void Start()
{
_currentWaypointIndex = 0;
}
private void Update()
{
Move();
if (CurrentPointPositionReached())
{
UpdateCurrentPointIndex();
}
}
private void Move()
{
- Vector3 currentPosition = waypoint.GetWaypointPosition(_currentWaypointIndex);
+ Vector3 currentPosition = Waypoint.GetWaypointPosition(_currentWaypointIndex);
transform.position = Vector3.MoveTowards(transform.position, currentPosition, moveSpeed * Time.deltaTime);
}
private bool CurrentPointPositionReached()
{
return Vector3.Distance(transform.position, CurrentPointPosition) < 0.1f;
}
private void UpdateCurrentPointIndex()
{
- int lastWaypointIndex = waypoint.Points.Length - 1;
+ int lastWaypointIndex = Waypoint.Points.Length - 1;
if (_currentWaypointIndex < lastWaypointIndex)
{
_currentWaypointIndex++;
}
else
{
ReturnEnemyToPool();
}
}
private void ReturnEnemyToPool()
{
OnEndReached?.Invoke();
ObjectPooler.ReturnToPool(gameObject);
}
}
Spawner.cs
using System;
+ using System.Collections;
using UnityEngine;
public class Spawner : MonoBehaviour
{
[SerializeField] private int enemyCount = 10;
// Btw = Between
[SerializeField] private float delayBtwSpawns;
+ [SerializeField] private float delayBtwWaves = 1f;
+ private int _enemiesRemaining;
private int _enemiesSpawned;
private float _spawnTimer;
private ObjectPooler _objectPooler;
+ private Waypoint _waypoint;
private void Start()
{
_objectPooler = GetComponent<ObjectPooler>();
+ _waypoint = GetComponent<Waypoint>();
+ _enemiesRemaining = enemyCount;
}
private void Update()
{
_spawnTimer -= Time.deltaTime;
if (_spawnTimer < 0)
{
_spawnTimer = delayBtwSpawns;
if (_enemiesSpawned < enemyCount)
{
SpawnEnemy();
_enemiesSpawned++;
}
}
}
// ReSharper disable Unity.PerformanceAnalysis
private void SpawnEnemy()
{
GameObject newInstance = _objectPooler.GetInstanceFromPool();
+ Enemy enemy = newInstance.GetComponent<Enemy>();
+ enemy.Waypoint = _waypoint;
+ enemy.transform.localPosition = transform.position;
newInstance.SetActive(true);
}
private IEnumerator NextWave()
{
yield return new WaitForSeconds(delayBtwWaves);
_enemiesRemaining = enemyCount;
_spawnTimer = 0f;
_enemiesSpawned = 0;
}
private void RecordEnemyEndReached()
{
_enemiesRemaining--;
if (_enemiesRemaining <= 0)
{
StartCoroutine(NextWave());
}
}
private void OnEnable()
{
Enemy.OnEndReached += RecordEnemyEndReached;
}
private void OnDisable()
{
Enemy.OnEndReached -= RecordEnemyEndReached;
}
}
参考
Section4 15
github コミット分
章まとめ