What have I done with the Enemy?
So, as you can see, I did various upgrades.
First of all Enemy Pathing script was upgraded.
New variables:
[SerializeField] float rotSpeed = 360f;
[SerializeField] bool rotateTowardsPath = true;
Upgraded move method:
private void Move()
{
if (waypointIndex <= waypoints.Count - 1)
{
nextWaypoint = waypoints[waypointIndex].transform.position;
var movementThisFrame = waveConfig.GetMoveSpeed() * Time.deltaTime;
transform.position = Vector2.MoveTowards
(transform.position, nextWaypoint, movementThisFrame);
if (rotateTowardsPath)
{
RotationTowardsPathMethod();
}
if (transform.position == nextWaypoint)
{
waypointIndex++;
}
}
else
{
Destroy(gameObject);
}
}
Tough RotationTowardsPath method:
private void RotationTowardsPathMethod()
{
Vector3 dir = waypoints[waypointIndex].transform.position - transform.position;
dir.Normalize();
float zAngle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg - 90;
Quaternion desiredRot = Quaternion.Euler(0, 0, zAngle);
transform.rotation = Quaternion.RotateTowards(transform.rotation, desiredRot, rotSpeed * Time.deltaTime);
}
It was not easy to make Rotation work properly, so I explored YouTube, Google and finally found a solution. If you want - take it to your projects. Here some informative links:
Enemy aiming system variables:
[Header("Aiming on the player")]
[SerializeField] bool isSearchingForPlayer = false;
Transform playerCoordinates;
[SerializeField] float rotationSpeed = 360f;
GameObject playerCaptured;
At Start Enemy searches for player:
void Start()
{
shotCounter = Random.Range(minTimeBetweenShots, maxTimeBetweenShots);
playerCaptured = GameObject.Find("Player");
lootManager = GetComponent<LootManager>();
}
Update method in the Enemy.cs:
void Update()
{
if(isSearchingForPlayer)
{
SearchForPlayer();
TurnTowardsPlayer();
}
CountDownAndShoot();
}
Two methods which make the aiming possible:
private void TurnTowardsPlayer()
{
Vector3 dir = playerCoordinates.position - transform.position;
dir.Normalize();
float zAngle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg - 90;
Quaternion desiredRotation = Quaternion.Euler(0, 0, zAngle);
transform.rotation = Quaternion.RotateTowards(transform.rotation, desiredRotation, rotationSpeed * Time.deltaTime);
}
private void SearchForPlayer()
{
if (playerCaptured == null)
{
playerCaptured = GameObject.Find("Player");
}
else
{
playerCoordinates = playerCaptured.transform;
}
}
LootManager script connected in Enemy.cs:
LootManager lootManager;
// Start is called before the first frame update
void Start()
{
shotCounter = Random.Range(minTimeBetweenShots, maxTimeBetweenShots);
playerCaptured = GameObject.Find("Player");
lootManager = GetComponent<LootManager>();
}
And called when the enemy dies:
private void Die()
{
FindObjectOfType<GameSession>().AddToScore(scoreValue);
lootManager.LootSpawn();
//Debug.Log("After LootSpawn line activated");
Destroy(gameObject);
GameObject explosion = Instantiate(deathVFX, transform.position, transform.rotation);
Destroy(explosion, durationOfExplosion);
AudioSource.PlayClipAtPoint(deathSound, Camera.main.transform.position, deathSoundVolume);
}
The LootManager.cs itself:
public class LootManager : MonoBehaviour
{
[SerializeField] GameObject lootPrefab;
[SerializeField] float minProbability = 0.3f;
[SerializeField] AudioClip spawnSound;
[SerializeField] [Range(0, 1)] float spawnSoundVolume = 0.7f;
float spawnProbability;
public void LootSpawn()
{
spawnProbability = Random.Range(0f, 1f);
//Debug.Log("Spawn Probability is: ");
//Debug.Log(spawnProbability);
if (spawnProbability > minProbability)
{
GameObject loot = Instantiate(lootPrefab, transform.position, transform.rotation);
AudioSource.PlayClipAtPoint(spawnSound, Camera.main.transform.position, spawnSoundVolume);
}
else
{
return;
}
}
}