Работает как скрипт на emptyGameObject, через сериалайзы задаётся радиус спавна/деспавна и тип моба на спавн
84 lines
2.4 KiB
C#
84 lines
2.4 KiB
C#
using Code.Gameplay.Player;
|
|
using Cysharp.Threading.Tasks;
|
|
using Reflex.Attributes;
|
|
using Reflex.Core;
|
|
using Reflex.Injectors;
|
|
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;
|
|
|
|
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 Despawn()
|
|
{
|
|
if (_spawnedEnemy == null) 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);
|
|
}
|
|
}
|
|
} |