145 lines
4.0 KiB
C#
145 lines
4.0 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class Tower : MonoBehaviour
|
|
{
|
|
|
|
[Header("Assigned on start")]
|
|
[SerializeField] EnemyHandler enemyHandler;
|
|
[SerializeField] ScoreHandler scoreHandler;
|
|
|
|
[Header("Prefabs")]
|
|
[SerializeField] ParticleSystem _projectile;
|
|
[SerializeField] Transform weapon;
|
|
|
|
[Header("WeaponParameters")]
|
|
[SerializeField] float weaponRange = 40f;
|
|
[SerializeField] int damage = 1;
|
|
[SerializeField] float fireRate = 1;
|
|
[SerializeField] float projectileSpeed = 5;
|
|
[SerializeField] TargetStrategy targetStrategy = TargetStrategy.LowestHealth;
|
|
|
|
[Header("BuildParameters")]
|
|
[SerializeField] int cost = 30;
|
|
[SerializeField] float buildTimer = 1;
|
|
|
|
|
|
[Header("Stats")]
|
|
[SerializeField] float score = 0f;
|
|
|
|
#region Privates
|
|
[SerializeField] enum TargetStrategy { ClosestEnemy, LowestHealth };
|
|
private GameObject targetEnemy;
|
|
[SerializeField] private Transform[] buildingParts;
|
|
#endregion
|
|
|
|
#region Publics
|
|
public float MaxDistance { get; set; }
|
|
public int Damage { get => damage; set => damage = value; }
|
|
public int FireRate { get; set; }
|
|
public int Cost { get => cost; set => cost = value; }
|
|
|
|
#endregion
|
|
|
|
private void Awake()
|
|
{
|
|
buildingParts = GetComponentsInChildren<Transform>();
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
enemyHandler = FindObjectOfType<EnemyHandler>();
|
|
scoreHandler = FindObjectOfType<ScoreHandler>();
|
|
UpdateWeaponParameters(fireRate, projectileSpeed);
|
|
|
|
for (int i = 1; i < buildingParts.Length; i++)
|
|
{
|
|
buildingParts[i].gameObject.SetActive(false);
|
|
}
|
|
StartCoroutine(Build());
|
|
}
|
|
|
|
IEnumerator Build()
|
|
{
|
|
for (int i = 1; i < buildingParts.Length; i++)
|
|
{
|
|
buildingParts[i].gameObject.SetActive(true);
|
|
yield return new WaitForSeconds(buildTimer);
|
|
}
|
|
}
|
|
|
|
private void UpdateWeaponParameters(float _fireRate, float _projectileSpeed)
|
|
{
|
|
var main = _projectile.main;
|
|
main.startSpeed = _projectileSpeed;
|
|
|
|
var emission = _projectile.emission;
|
|
emission.rateOverTime = _fireRate;
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
ShootProjectile(false);
|
|
FindAndShootEnemy();
|
|
}
|
|
|
|
private void FindAndShootEnemy()
|
|
{
|
|
float bestValue = Mathf.Infinity;
|
|
bool targetFound = false;
|
|
List<GameObject> enemies = enemyHandler.ReturnAllEnemies();
|
|
|
|
foreach (GameObject enemy in enemies)
|
|
{
|
|
float distanceToTarget = Vector3.Magnitude(enemy.transform.position - transform.position);
|
|
|
|
bool withinRange = distanceToTarget < weaponRange;
|
|
if (withinRange)
|
|
{
|
|
if (targetStrategy == TargetStrategy.ClosestEnemy)
|
|
{
|
|
bool isClosest = distanceToTarget < bestValue;
|
|
if (isClosest)
|
|
{
|
|
targetFound = true;
|
|
bestValue = distanceToTarget;
|
|
targetEnemy = enemy;
|
|
}
|
|
}
|
|
if (targetStrategy == TargetStrategy.LowestHealth)
|
|
{
|
|
float enemyHealth = enemy.GetComponent<EnemyHealth>().Health;
|
|
|
|
bool isLowestHealth = enemyHealth < bestValue;
|
|
if (isLowestHealth)
|
|
{
|
|
targetFound = true;
|
|
bestValue = enemyHealth;
|
|
targetEnemy = enemy;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (targetFound)
|
|
{
|
|
weapon.transform.LookAt(targetEnemy.transform.position);
|
|
ShootProjectile(true);
|
|
}
|
|
}
|
|
|
|
void ShootProjectile(bool _state)
|
|
{
|
|
var emissionModule = _projectile.emission;
|
|
emissionModule.enabled = _state;
|
|
}
|
|
|
|
public void UpdateScore(float _score)
|
|
{
|
|
score += _score;
|
|
}
|
|
}
|