88 lines
2.5 KiB
C#
88 lines
2.5 KiB
C#
using Code.Gameplay.Player;
|
|
using Cysharp.Threading.Tasks;
|
|
using Reflex.Attributes;
|
|
using UnityEngine;
|
|
|
|
namespace Code.Gameplay.Enemies
|
|
{
|
|
public class EnemySpawner : MonoBehaviour
|
|
{
|
|
[SerializeField] private EnemyType spawnerType;
|
|
[SerializeField] private float spawnRadius = 40f;
|
|
[SerializeField] private float despawnRadius = 50f;
|
|
|
|
[Inject] private IPlayerProvider _playerProvider;
|
|
[Inject] private IEnemyFactory _enemyFactory;
|
|
|
|
private BaseEnemy _spawnedEnemy;
|
|
private bool _isSpawning;
|
|
private bool _isPlayerInRange;
|
|
|
|
// GameObjectSelfInjector существует
|
|
// private void Awake()
|
|
// {
|
|
// if (_playerProvider == null || _enemyFactory == null)
|
|
// {
|
|
// AttributeInjector.Inject(this, Container.ProjectContainer);
|
|
// }
|
|
// }
|
|
|
|
private void Update()
|
|
{
|
|
if (!_playerProvider?.Character)
|
|
return;
|
|
|
|
var distanceToPlayer = Vector3.Distance(transform.position, _playerProvider.Character.transform.position);
|
|
|
|
var wasInRange = _isPlayerInRange;
|
|
_isPlayerInRange = distanceToPlayer <= spawnRadius;
|
|
|
|
switch (_isPlayerInRange)
|
|
{
|
|
case true when !_spawnedEnemy && !_isSpawning && !wasInRange:
|
|
Spawn().Forget();
|
|
break;
|
|
case false when _spawnedEnemy && distanceToPlayer > despawnRadius:
|
|
Despawn();
|
|
break;
|
|
}
|
|
}
|
|
|
|
private async UniTask Spawn()
|
|
{
|
|
if (_spawnedEnemy || _isSpawning) return;
|
|
|
|
_isSpawning = true;
|
|
var enemy = await _enemyFactory.CreateEnemy(
|
|
spawnerType,
|
|
transform.position,
|
|
transform.rotation
|
|
);
|
|
|
|
_spawnedEnemy = enemy;
|
|
_isSpawning = false;
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
Despawn();
|
|
}
|
|
|
|
private void Despawn()
|
|
{
|
|
if (!_spawnedEnemy) return;
|
|
|
|
_enemyFactory.ReleaseEnemy(_spawnedEnemy);
|
|
_spawnedEnemy = null;
|
|
}
|
|
|
|
private void OnDrawGizmosSelected()
|
|
{
|
|
Gizmos.color = new Color(0, 1, 0, 0.5f);
|
|
Gizmos.DrawSphere(transform.position, spawnRadius);
|
|
|
|
Gizmos.color = new Color(1, 0, 0, 0.2f);
|
|
Gizmos.DrawSphere(transform.position, despawnRadius);
|
|
}
|
|
}
|
|
} |