Files
dungeons/Assets/Plugins/Zenject/OptionalExtras/SampleGame2 (Advanced)/Scripts/Enemy/States/EnemyStateFollow.cs

111 lines
3.1 KiB
C#

using System;
using UnityEngine;
using Random = UnityEngine.Random;
namespace Zenject.SpaceFighter
{
public class EnemyStateFollow : IEnemyState
{
readonly EnemyRotationHandler _rotationHandler;
readonly EnemyCommonSettings _commonSettings;
readonly Settings _settings;
readonly EnemyTunables _tunables;
readonly EnemyStateManager _stateManager;
readonly EnemyView _view;
readonly PlayerFacade _player;
bool _strafeRight;
float _lastStrafeChangeTime;
public EnemyStateFollow(
PlayerFacade player,
EnemyView view,
EnemyStateManager stateManager,
EnemyTunables tunables,
Settings settings,
EnemyCommonSettings commonSettings,
EnemyRotationHandler rotationHandler)
{
_rotationHandler = rotationHandler;
_commonSettings = commonSettings;
_settings = settings;
_tunables = tunables;
_stateManager = stateManager;
_view = view;
_player = player;
}
public void EnterState()
{
_strafeRight = Random.Range(0, 1) == 0;
_lastStrafeChangeTime = Time.realtimeSinceStartup;
}
public void ExitState()
{
}
public void Update()
{
if (_player.IsDead)
{
_stateManager.ChangeState(EnemyStates.Idle);
return;
}
var distanceToPlayer = (_player.Position - _view.Position).magnitude;
// Always look towards the player
_rotationHandler.DesiredLookDir = (_player.Position - _view.Position).normalized;
// Strafe back and forth over the given interval
// This helps avoiding being too easy a target
if (Time.realtimeSinceStartup - _lastStrafeChangeTime > _settings.StrafeChangeInterval)
{
_lastStrafeChangeTime = Time.realtimeSinceStartup;
_strafeRight = !_strafeRight;
}
if (distanceToPlayer < _commonSettings.AttackDistance)
{
_stateManager.ChangeState(EnemyStates.Attack);
}
}
public void FixedUpdate()
{
MoveTowardsPlayer();
Strafe();
}
void Strafe()
{
// Strafe to avoid getting hit too easily
if (_strafeRight)
{
_view.AddForce(_view.RightDir * _settings.StrafeMultiplier * _tunables.Speed);
}
else
{
_view.AddForce(-_view.RightDir * _settings.StrafeMultiplier * _tunables.Speed);
}
}
void MoveTowardsPlayer()
{
var playerDir = (_player.Position - _view.Position).normalized;
_view.AddForce(playerDir * _tunables.Speed);
}
[Serializable]
public class Settings
{
public float StrafeMultiplier;
public float StrafeChangeInterval;
public float TeleportNewDistance;
}
}
}