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; // 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; public float movementTickMax; private float _movementCurrentTick; private float _currentHoldHeight; private float _heightChangeTick; public float heightChangeInterval; public 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"); _residualThrust = 0.0f; _residualThrustCurrentTime = 0.0f; _currentJumpTime = 0.0f; _isJumping = false; _aiJump = false; _aiHorz = 0.0f; _aiVert = 0.0f; _currentHoldHeight = GetCurrentHeight(); _heightChangeTick = 0.0f; BaseOnStart(); // Custom start stuff can go here } void DoAIPhysics(float currentTimeStep) { } /// /// Calculates some RNG movement for the attached Enemy. /// /// The time unit currently used, typically deltatime or deltafixed time depending on if its the fixed update or not. void DoAI(float currentTimeStep) { // 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().GetCurrentHeight(); _aiVert = 1; if (_movementCurrentTick >= movementTickMax) { // Pick a random horz value if (_aiHorz == 0) { _aiHorz = Random.Range(0, maxRNGThrust); } // Pick a random vert value if (_aiVert == 0) { _aiVert = Random.Range(0, maxRNGThrust); } _movementCurrentTick = 0.0f; } else { // Reset the variables to stop it turning/moving if (_aiHorz > 0) { _aiHorz = Mathf.Clamp(_aiHorz - movementDecayRate, 0, maxRNGThrust); ; } if (_aiVert > 0) { _aiVert = Mathf.Clamp(_aiVert - movementDecayRate, 0, maxRNGThrust); } _movementCurrentTick += currentTimeStep; } 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; } } /// /// 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. /// /// The time unit currently used, typically deltatime or deltafixed time depending on if its the fixed update or not. public 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); } } /// /// Method for dealing with the jump physics, this should be in the fixed update since it uses rigidbody physics /// 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; } } } void ProcessCooldowns(float currentTimeStep) { if (_heightChangeTick >= heightChangeInterval) { _currentHoldHeight = Random.Range(startHeight, startHeight + 5.0f); _heightChangeTick = 0.0f; } else { _heightChangeTick += currentTimeStep; } } private void FixedUpdate() { if (objectIsActive) { DoAIPhysics(Time.fixedDeltaTime); ProcessJump(); } } // Update is called once per frame void Update() { if (objectIsActive) { DoAI(Time.deltaTime); ProcessPreMovement(Time.deltaTime); ProcessCurrentMovement(Time.deltaTime); ProcessPostMovement(); ProcessCooldowns(Time.deltaTime); } } }