概要
前回の続きです
今回は2Wave以降敵が最終地点に行くバグを修正します。
改善前
改善後
次へ
開発環境
IDE:Rider
Unity:2020.3.42(LTS)
OS:Windows10
UnityEdtior上の設定
前回と変化なし
実装のポイント
バグの原因は、Enemyクラスの変数_currentWaypointIndexの値が初期化されていないことです。
対処方法としては、
Enemyクラス側で_currentWaypointIndexを初期化する関数を作り
SpawnerクラスでEnemyを生成する際に、_currentWaypointIndexを初期化する関数を実行しまう。
コード
Enemy.cs
using System;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public static Action OnEndReached;
[SerializeField] private float moveSpeed = 3f;
public Waypoint Waypoint { get; set; }
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);
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;
if (_currentWaypointIndex < lastWaypointIndex)
{
_currentWaypointIndex++;
}
else
{
ReturnEnemyToPool();
}
}
private void ReturnEnemyToPool()
{
OnEndReached?.Invoke();
ObjectPooler.ReturnToPool(gameObject);
}
+ public void ResetEnemy()
+ {
+ _currentWaypointIndex = 0;
+ }
}
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;
+ enemy.ResetEnemy();
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 16
githubコミット分
章まとめ