418 lines
14 KiB
C#
418 lines
14 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class DumbEnemyHoverMovement : HoverMovement
|
|
{
|
|
// Game object to track the player GO
|
|
private GameObject _player;
|
|
private GameObject _blackHole;
|
|
private EnemyColliderManager _enemyColliderManager;
|
|
|
|
// Residual Thrust variables to handle the "glide" after the gameObject has moved
|
|
public float residualThrustStep;
|
|
public float residualThrustMax;
|
|
public float residualThrustTimeTickMax;
|
|
public float residualThrustDecayRate;
|
|
public float residualThrustIdleDecayRate;
|
|
|
|
public float jumpForce;
|
|
public float jumpMaxTime;
|
|
|
|
private float _residualThrust;
|
|
private float _residualThrustCurrentTime;
|
|
|
|
private float _currentJumpTime;
|
|
private bool _isJumping;
|
|
|
|
// Variables for RNG movement
|
|
private float _aiVert;
|
|
private float _aiHorz;
|
|
private bool _aiJump;
|
|
|
|
public float maxRNGThrust;
|
|
public float movementDecayRate;
|
|
private List<TimerHelper> _movementMoveTimers = new List<TimerHelper>();
|
|
public float patternChangeInterval;
|
|
private TimerHelper _movementPatternTimer;
|
|
|
|
private float _currentHoldHeight;
|
|
private float _heightChangeTick;
|
|
public float heightChangeInterval;
|
|
|
|
private int _currentPattern;
|
|
private int _nextThrustDir;
|
|
private int _nextTurnDir;
|
|
|
|
protected override void DoAwakeTasks()
|
|
{
|
|
base.DoAwakeTasks();
|
|
}
|
|
|
|
// Start is called before the first frame update
|
|
private void Start()
|
|
{
|
|
// We have to find the player since setting it in the editor doesnt work correctly
|
|
_player = GameObject.Find("Player");
|
|
_blackHole = GameObject.Find("BlackHole");
|
|
_enemyColliderManager = gameObject.GetComponent<EnemyColliderManager>();
|
|
|
|
_residualThrust = 0.0f;
|
|
_residualThrustCurrentTime = 0.0f;
|
|
_currentJumpTime = 0.0f;
|
|
_isJumping = false;
|
|
|
|
_aiJump = false;
|
|
_aiHorz = 0.0f;
|
|
_aiVert = 0.0f;
|
|
|
|
_currentHoldHeight = GetCurrentHeight();
|
|
_heightChangeTick = 0.0f;
|
|
|
|
_movementPatternTimer = new TimerHelper(patternChangeInterval, false);
|
|
_movementPatternTimer.HasTicked(patternChangeInterval + 100.0f);
|
|
_currentPattern = Random.Range(0, 4);
|
|
|
|
BaseOnStart();
|
|
// Custom start stuff can go here
|
|
}
|
|
|
|
private void DoAIPhysics(float currentTimeStep)
|
|
{
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculates some RNG movement for the attached Enemy.
|
|
/// </summary>
|
|
/// <param name="currentTimeStep">The time unit currently used, typically deltatime or deltafixed time depending on if its the fixed update or not.</param>
|
|
private void DoAI(float currentTimeStep)
|
|
{
|
|
if (_enemyColliderManager.Magnetized)
|
|
{
|
|
_noMovement = true;
|
|
}
|
|
else
|
|
{
|
|
_noMovement = false;
|
|
}
|
|
|
|
// Get the Up vector of each gameObject so we can compare its X values rather than the Y
|
|
Vector3 playerDirection = _player.transform.position - transform.position;
|
|
Vector3 playerLocation = Vector3.ProjectOnPlane(_player.transform.position, Vector3.up);
|
|
Vector3 myLocation = Vector3.ProjectOnPlane(transform.position, Vector3.forward);
|
|
|
|
// Added a check to see if the difference is big enough to warrant a turn otherwise they just get stuck turning forever
|
|
float playerHeight = _player.GetComponent<PlayerHoverMovement>().GetCurrentHeight();
|
|
|
|
_aiVert = 1;
|
|
if (_movementPatternTimer.HasTicked(currentTimeStep))
|
|
{
|
|
_currentPattern = Random.Range(0, 4);
|
|
_movementMoveTimers.Clear();
|
|
|
|
switch (_currentPattern)
|
|
{
|
|
default:
|
|
case 0:
|
|
int dirRandom = Random.Range(0, 2);
|
|
if (dirRandom == 0)
|
|
{
|
|
_nextTurnDir = -1;
|
|
}
|
|
else
|
|
{
|
|
_nextTurnDir = 1;
|
|
}
|
|
_movementMoveTimers.Add(new TimerHelper(30.0f, false));
|
|
_movementMoveTimers.Add(new TimerHelper(3.0f, false));
|
|
break;
|
|
case 1:
|
|
_movementMoveTimers.Add(new TimerHelper(10.0f));
|
|
break;
|
|
case 2:
|
|
int zigRandom = Random.Range(0, 2);
|
|
if (zigRandom == 0)
|
|
{
|
|
_nextTurnDir = -1;
|
|
}
|
|
else
|
|
{
|
|
_nextTurnDir = 1;
|
|
}
|
|
_movementMoveTimers.Add(new TimerHelper(3.0f, false));
|
|
break;
|
|
case 3:
|
|
_movementMoveTimers.Add(new TimerHelper(5.0f, false));
|
|
break;
|
|
}
|
|
|
|
_movementPatternTimer.RestartTimer();
|
|
}
|
|
else
|
|
{
|
|
switch (_currentPattern)
|
|
{
|
|
default:
|
|
case 0:
|
|
_aiVert = 1.0f;
|
|
if (_movementMoveTimers[0].HasTicked(currentTimeStep))
|
|
{
|
|
if (_movementMoveTimers[1].HasTicked(currentTimeStep))
|
|
{
|
|
int dirRandom = Random.Range(0, 2);
|
|
if (dirRandom == 0)
|
|
{
|
|
_nextTurnDir = -1;
|
|
}
|
|
else
|
|
{
|
|
_nextTurnDir = 1;
|
|
}
|
|
|
|
_movementMoveTimers[0].RestartTimer();
|
|
_movementMoveTimers[1].RestartTimer();
|
|
}
|
|
else
|
|
{
|
|
_aiHorz = _nextTurnDir;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_aiHorz = 0.0f;
|
|
}
|
|
break;
|
|
case 1:
|
|
_aiVert = 1.0f;
|
|
if (_movementMoveTimers[0].HasTicked(currentTimeStep))
|
|
{
|
|
int dirTimesRan = _movementMoveTimers[0].TimesRun % 2;
|
|
if (dirTimesRan == 0)
|
|
{
|
|
_aiHorz = 1;
|
|
}
|
|
else
|
|
{
|
|
_aiHorz = -1;
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
_aiVert = 1.0f;
|
|
if (_movementMoveTimers[0].HasTicked(currentTimeStep))
|
|
{
|
|
_nextTurnDir *= -1;
|
|
|
|
_movementMoveTimers[0].RestartTimer();
|
|
}
|
|
else
|
|
{
|
|
_aiHorz = _nextTurnDir;
|
|
}
|
|
break;
|
|
case 3:
|
|
if (_movementMoveTimers[0].HasTicked(currentTimeStep))
|
|
{
|
|
_nextThrustDir = Random.Range(0, 2);
|
|
_nextTurnDir = Random.Range(-1, 2);
|
|
|
|
_movementMoveTimers[0].RestartTimer();
|
|
}
|
|
else
|
|
{
|
|
_aiVert = _nextThrustDir;
|
|
_aiHorz = _nextTurnDir;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (_currentHoldHeight >= GetCurrentHeight())
|
|
{
|
|
RaycastHit aboveCheck;
|
|
Physics.SphereCast(transform.position, 3.0f, transform.up, out aboveCheck, 5.0f, LayerMask.GetMask("Player"));
|
|
if (aboveCheck.rigidbody != null)
|
|
{
|
|
if ((GetCurrentHeight() < playerHeight))
|
|
{
|
|
_objectRigidbody.velocity = Vector3.zero;
|
|
_aiJump = false;
|
|
}
|
|
else
|
|
{
|
|
_aiJump = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_aiJump = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_aiJump = false;
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processes the inputs needed to move the gameObject, the turn direction, thrust direction and any residual thrust calculations so that we dont just stop in place.
|
|
/// Anything in this method can be removed, as long as the _turnDirection and _thrustDirection are set then the parent script with handle the orbit and positioning.
|
|
/// </summary>
|
|
/// <param name="currentTimeStep">The time unit currently used, typically deltatime or deltafixed time depending on if its the fixed update or not.</param>
|
|
protected override void ProcessPreMovement(float currentTimeStep)
|
|
{
|
|
// Check if movement has been frozen
|
|
if (!freezeMovement)
|
|
{
|
|
// Get the Horz and Vert axis from the RNG (or whatever vars you want)
|
|
float horzInput = _aiHorz;
|
|
float vertInput = _aiVert;
|
|
|
|
// Check horz direction value, pos = Right, neg = Left
|
|
if (horzInput > 0)
|
|
{
|
|
_turnDirection = 1;
|
|
}
|
|
else if (horzInput < 0)
|
|
{
|
|
_turnDirection = -1;
|
|
}
|
|
else
|
|
{
|
|
_turnDirection = 0;
|
|
}
|
|
|
|
// Check if the vert is pushed forwards or back, pos = forward, neg = back
|
|
if (vertInput > 0)
|
|
{
|
|
_thrusting = true;
|
|
_thrustDirection = 1.0f * _aiVert;
|
|
if (_residualThrust < residualThrustMax)
|
|
{
|
|
_residualThrust += residualThrustStep * currentTimeStep;
|
|
}
|
|
}
|
|
// If the Enemy is holding backwards
|
|
else if (vertInput < 0)
|
|
{
|
|
if (_residualThrust > 0.0f)
|
|
{
|
|
if (_residualThrustCurrentTime >= residualThrustTimeTickMax)
|
|
{
|
|
_residualThrust -= residualThrustDecayRate;
|
|
}
|
|
_thrustDirection = _residualThrust / residualThrustMax;
|
|
}
|
|
else
|
|
{
|
|
_thrusting = true;
|
|
_thrustDirection = -1.0f * _aiVert;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (_residualThrust > 0.0f)
|
|
{
|
|
if (_residualThrustCurrentTime >= residualThrustTimeTickMax)
|
|
{
|
|
_residualThrust -= residualThrustIdleDecayRate;
|
|
}
|
|
_thrustDirection = _residualThrust / residualThrustMax;
|
|
}
|
|
else
|
|
{
|
|
_thrusting = false;
|
|
_thrustDirection = 0.0f;
|
|
}
|
|
}
|
|
|
|
// Clamp the residual thrust so we cant fall below 0 or greater than the max value set
|
|
_residualThrust = Mathf.Clamp(_residualThrust, 0, residualThrustMax);
|
|
if (_residualThrustCurrentTime >= residualThrustTimeTickMax)
|
|
{
|
|
_residualThrustCurrentTime = 0.0f;
|
|
}
|
|
else
|
|
{
|
|
_residualThrustCurrentTime += currentTimeStep;
|
|
}
|
|
|
|
// Check if the jump button
|
|
if (_aiJump && !_isJumping)
|
|
{
|
|
_isJumping = true;
|
|
}
|
|
|
|
// Run any base class stuff
|
|
base.ProcessPreMovement(currentTimeStep);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Method for dealing with the jump physics, this should be in the fixed update since it uses rigidbody physics
|
|
/// </summary>
|
|
private void ProcessJump()
|
|
{
|
|
// If the enemy is jumping add the jump force
|
|
if (_isJumping)
|
|
{
|
|
_objectRigidbody.AddRelativeForce(Vector3.up * jumpForce * Time.fixedDeltaTime, ForceMode.Impulse);
|
|
if (_currentJumpTime >= jumpMaxTime)
|
|
{
|
|
_currentJumpTime = 0.0f;
|
|
_isJumping = false;
|
|
_aiJump = false;
|
|
|
|
}
|
|
else
|
|
{
|
|
_currentJumpTime += Time.fixedDeltaTime;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ProcessCooldowns(float currentTimeStep)
|
|
{
|
|
if (_heightChangeTick >= heightChangeInterval)
|
|
{
|
|
_currentHoldHeight = Random.Range(startHeight, startHeight + 5.0f);
|
|
_heightChangeTick = 0.0f;
|
|
}
|
|
else
|
|
{
|
|
_heightChangeTick += currentTimeStep;
|
|
}
|
|
}
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
if (!GameEngine.isPaused)
|
|
{
|
|
if (objectIsActive)
|
|
{
|
|
DoAIPhysics(Time.fixedDeltaTime);
|
|
ProcessJump();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
if (!GameEngine.isPaused)
|
|
{
|
|
if (objectIsActive)
|
|
{
|
|
ProcessWorkingStartValues(Time.deltaTime);
|
|
DoAI(Time.deltaTime);
|
|
ProcessPreMovement(Time.deltaTime);
|
|
ProcessCurrentMovement(Time.deltaTime);
|
|
ProcessPostMovement();
|
|
ProcessCooldowns(Time.deltaTime);
|
|
}
|
|
}
|
|
}
|
|
}
|