Files
blackhole-escape/Assets/Scripts/AI/ChaserEnemyHoverMovement.cs
iDunnoDev fb3415c7b2 Added new sounds needed for game
Added blackhole swirl texture and materials
Added Magnet, Hunter and Drop core powerups and script overhaul for powerups in general
Added Scenes and Cinematic changes for the game, win and death screens
Added a score
Changed the way enemy spawns work
Removed unused scripts
2022-07-14 17:31:10 +01:00

333 lines
10 KiB
C#

using UnityEngine;
public class ChaserEnemyHoverMovement : 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 chargePower;
public float chargeCooldown;
public float chargeCooldownSpeed;
private bool _charged;
private float _currentChargeCooldownTick;
protected override void DoAwakeTasks()
{
base.DoAwakeTasks();
}
// Start is called before the first frame update
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;
_charged = false;
_currentChargeCooldownTick = 0.0f;
BaseOnStart();
// Custom start stuff can go here
}
void DoAIPhysics(float currentTimeStep)
{
RaycastHit belowCheck;
Physics.SphereCast(transform.position, 2.0f, -transform.up, out belowCheck, 5.0f, LayerMask.GetMask("Player"));
if (belowCheck.rigidbody != null)
{
if (!_charged)
{
float playerHeight = _player.GetComponent<PlayerHoverMovement>().GetCurrentHeight();
if (playerHeight + 1.0f < GetCurrentHeight())
{
_objectRigidbody.AddRelativeForce(Vector3.down * chargePower, ForceMode.Impulse);
_charged = true;
}
}
}
}
/// <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>
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.forward);
Vector3 myLocation = Vector3.ProjectOnPlane(transform.position, Vector3.forward);
Vector3 direction = playerLocation - myLocation;
float angleDiff = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
float facingPlayer = Vector3.Dot(playerDirection.normalized, transform.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 (facingPlayer > 0.8f)
{
_aiHorz = 0.0f;
if (playerDirection.magnitude <= 10.0f)
{
if (!_charged)
{
if (playerHeight + 1.5f > GetCurrentHeight())
{
_aiJump = false;
}
else
{
_aiJump = true;
}
}
}
else
{
if (playerHeight > GetCurrentHeight())
{
_aiJump = true;
}
}
}
else
{
_aiHorz = angleDiff;
if ((playerHeight - 0.5f) >= 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;
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;
}
}
else
{
if (_residualThrust > 0.0f)
{
if (_residualThrustCurrentTime >= residualThrustTimeTickMax)
{
_residualThrust -= residualThrustIdleDecayRate;
}
_thrustDirection = _residualThrust / residualThrustMax;
}
else
{
_thrusting = false;
_thrustDirection = 0;
}
}
// 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 (_charged)
{
if (_currentChargeCooldownTick >= chargeCooldown)
{
_charged = false;
_currentChargeCooldownTick = 0.0f;
}
else
{
_currentChargeCooldownTick += 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);
}
}
}
}