Working on lession 29
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
using System.Linq;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AI;
|
||||
|
||||
public enum TargetType { Gate, Wall, Tower, Any }
|
||||
|
||||
public class EnemyController : MonoBehaviour
|
||||
{
|
||||
public float moveSpeed;
|
||||
@@ -8,8 +12,7 @@ public class EnemyController : MonoBehaviour
|
||||
public float attackRange;
|
||||
public float attackSpeed;
|
||||
public float attackDamage;
|
||||
public float health;
|
||||
public Transform defaultTarget;
|
||||
public TargetType targetType;
|
||||
public Transform target;
|
||||
private NavMeshAgent navMeshAgent;
|
||||
private Animator animator;
|
||||
@@ -27,18 +30,18 @@ public class EnemyController : MonoBehaviour
|
||||
|
||||
void Start()
|
||||
{
|
||||
MoveToDefault();
|
||||
GetTarget(targetType);
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if(target != null && !target.gameObject.activeInHierarchy)
|
||||
if (target != null && !target.gameObject.activeInHierarchy)
|
||||
{
|
||||
target = null;
|
||||
MoveToDefault();
|
||||
GetTarget(targetType);
|
||||
}
|
||||
|
||||
if(target != null)
|
||||
if (target != null)
|
||||
Attack();
|
||||
|
||||
animator.SetFloat("Speed", navMeshAgent.velocity.magnitude);
|
||||
@@ -46,11 +49,11 @@ public class EnemyController : MonoBehaviour
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if(target != null) return;
|
||||
if(!other.CompareTag("Gate")) return;
|
||||
if (target != null) return;
|
||||
if (!other.CompareTag("Gate")) return;
|
||||
|
||||
AttackPoint attackPoint = other.GetComponentInChildren<AttackPoint>();
|
||||
if(attackPoint != null)
|
||||
if (attackPoint != null && targetType == TargetType.Any)
|
||||
{
|
||||
target = attackPoint.transform;
|
||||
navMeshAgent.stoppingDistance = attackRange;
|
||||
@@ -58,17 +61,65 @@ public class EnemyController : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveToDefault()
|
||||
private void GetTarget(TargetType targetType)
|
||||
{
|
||||
navMeshAgent.stoppingDistance = 0f;
|
||||
if(defaultTarget != null)
|
||||
navMeshAgent.destination = defaultTarget.position;
|
||||
GameObject[] potentialTargets;
|
||||
GameObject closest = null;
|
||||
float minDistance = Mathf.Infinity;
|
||||
switch (targetType)
|
||||
{
|
||||
case TargetType.Gate:
|
||||
potentialTargets = GameObject.FindGameObjectsWithTag("Gate");
|
||||
foreach (GameObject go in potentialTargets)
|
||||
{
|
||||
float distance = Vector3.Distance(go.transform.position, transform.position);
|
||||
if (distance < minDistance) { minDistance = distance; closest = go; }
|
||||
}
|
||||
break;
|
||||
case TargetType.Wall:
|
||||
potentialTargets = GameObject.FindGameObjectsWithTag("Wall");
|
||||
foreach (GameObject go in potentialTargets)
|
||||
{
|
||||
float distance = Vector3.Distance(go.transform.position, transform.position);
|
||||
if (distance < minDistance) { minDistance = distance; closest = go; }
|
||||
}
|
||||
break;
|
||||
case TargetType.Tower:
|
||||
potentialTargets = GameObject.FindGameObjectsWithTag("Tower");
|
||||
foreach (GameObject go in potentialTargets)
|
||||
{
|
||||
float distance = Vector3.Distance(go.transform.position, transform.position);
|
||||
if (distance < minDistance) { minDistance = distance; closest = go; }
|
||||
}
|
||||
break;
|
||||
case TargetType.Any:
|
||||
potentialTargets = GameObject.FindGameObjectsWithTag("Gate")
|
||||
.Concat(GameObject.FindGameObjectsWithTag("Wall"))
|
||||
.Concat(GameObject.FindGameObjectsWithTag("Tower")).ToArray();
|
||||
foreach (GameObject go in potentialTargets)
|
||||
{
|
||||
float distance = Vector3.Distance(go.transform.position, transform.position);
|
||||
if (distance < minDistance) { minDistance = distance; closest = go; }
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (closest != null)
|
||||
{
|
||||
AttackPoint attackPoint = closest.GetComponentInChildren<AttackPoint>();
|
||||
if (attackPoint != null)
|
||||
{
|
||||
target = attackPoint.transform;
|
||||
navMeshAgent.stoppingDistance = attackRange;
|
||||
navMeshAgent.destination = target.position;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void Attack()
|
||||
{
|
||||
attackCooldown -= Time.deltaTime;
|
||||
if(Vector3.Distance(target.position, transform.position) < attackRange && attackCooldown <= 0f)
|
||||
if (Vector3.Distance(target.position, transform.position) < attackRange && attackCooldown <= 0f)
|
||||
{
|
||||
transform.LookAt(target.position);
|
||||
animator.SetTrigger("Attack");
|
||||
@@ -78,7 +129,7 @@ public class EnemyController : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDrawGizmosSelected()
|
||||
/*private void OnDrawGizmosSelected()
|
||||
{
|
||||
// Target range — green if priority target is assigned, red if not
|
||||
Gizmos.color = target != null ? Color.green : Color.red;
|
||||
@@ -88,5 +139,5 @@ public class EnemyController : MonoBehaviour
|
||||
bool inAttackRange = target != null && Vector3.Distance(target.position, transform.position) < attackRange;
|
||||
Gizmos.color = inAttackRange ? Color.green : Color.red;
|
||||
Gizmos.DrawWireSphere(transform.position, attackRange);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class EnemyDetector : MonoBehaviour
|
||||
{
|
||||
private EnemyController enemyController;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
enemyController = GetComponentInParent<EnemyController>();
|
||||
}
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
enemyController.OnDetectorTriggerEnter(other);
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 137b6d86a1dcfa94b84dee4c8c248fab
|
||||
23
Assets/Scripts/EnemyHealthController.cs
Normal file
23
Assets/Scripts/EnemyHealthController.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class EnemyHealthController : MonoBehaviour
|
||||
{
|
||||
[SerializeField] float totalHealth;
|
||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
public void TakeDamage(float damageToTake)
|
||||
{
|
||||
totalHealth -= damageToTake;
|
||||
if(totalHealth <= 0)
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/EnemyHealthController.cs.meta
Normal file
2
Assets/Scripts/EnemyHealthController.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 005e302fe21ff164985e65ea087d083c
|
||||
8
Assets/Scripts/Towers.meta
Normal file
8
Assets/Scripts/Towers.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 357db81f8fc0d2a40a68189df6a4d203
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
38
Assets/Scripts/Towers/Projectile.cs
Normal file
38
Assets/Scripts/Towers/Projectile.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public class Projectile : MonoBehaviour
|
||||
{
|
||||
private Rigidbody theRB;
|
||||
[SerializeField] private float moveSpeed;
|
||||
[SerializeField] private float damageAmount;
|
||||
[SerializeField] private GameObject impactEffect;
|
||||
void Awake()
|
||||
{
|
||||
theRB = GetComponent<Rigidbody>();
|
||||
}
|
||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||
void Start()
|
||||
{
|
||||
theRB.linearVelocity = transform.forward * moveSpeed;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
void OnTriggerEnter(Collider other)
|
||||
{
|
||||
if(other.tag == "Enemy")
|
||||
{
|
||||
other.GetComponent<EnemyHealthController>().TakeDamage(damageAmount);
|
||||
Instantiate(impactEffect, transform.position, transform.rotation);
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
void OnBecameVisible()
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Towers/Projectile.cs.meta
Normal file
2
Assets/Scripts/Towers/Projectile.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84b12942bc65a07418ae0012c4b99995
|
||||
70
Assets/Scripts/Towers/ProjectileTower.cs
Normal file
70
Assets/Scripts/Towers/ProjectileTower.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using Unity.Mathematics;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
public class ProjectileTower : MonoBehaviour
|
||||
{
|
||||
private Tower theTower;
|
||||
[SerializeField] GameObject projectile;
|
||||
[SerializeField] Transform firePoint;
|
||||
[SerializeField] float minTimeBetweenShot = 2f;
|
||||
[SerializeField] float maxTimeBetweenShot = 6f;
|
||||
private Transform target;
|
||||
[SerializeField] private Transform launcherModel;
|
||||
[SerializeField] private GameObject shotEffect;
|
||||
private float shotCounter;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
theTower = GetComponentInParent<Tower>();
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
shotCounter = UnityEngine.Random.Range(minTimeBetweenShot, maxTimeBetweenShot);
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
shotCounter -= Time.deltaTime;
|
||||
if (shotCounter <= 0f && target != null)
|
||||
{
|
||||
Vector3 directionToTarget = (target.position - firePoint.position).normalized;
|
||||
Quaternion aimRotation = Quaternion.LookRotation(directionToTarget);
|
||||
Instantiate(projectile, firePoint.position, aimRotation);
|
||||
shotCounter = UnityEngine.Random.Range(minTimeBetweenShot, maxTimeBetweenShot);
|
||||
}
|
||||
if (theTower.enemiesUpdated)
|
||||
{
|
||||
if (theTower.enemiesInRange.Count > 0)
|
||||
{
|
||||
float minDistance = theTower.range * 1f;
|
||||
foreach (EnemyController enemy in theTower.enemiesInRange)
|
||||
{
|
||||
if (enemy != null)
|
||||
{
|
||||
float distance = Vector3.Distance(enemy.transform.position, transform.position);
|
||||
if (distance < minDistance)
|
||||
{
|
||||
minDistance = distance;
|
||||
target = enemy.transform;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
target = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
void LateUpdate()
|
||||
{
|
||||
if (target != null)
|
||||
{
|
||||
launcherModel.rotation = Quaternion.Slerp(launcherModel.rotation, Quaternion.LookRotation(target.position - transform.position), 5f * Time.deltaTime);
|
||||
launcherModel.rotation = Quaternion.Euler(0f, launcherModel.rotation.eulerAngles.y, 0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Towers/ProjectileTower.cs.meta
Normal file
2
Assets/Scripts/Towers/ProjectileTower.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e4085db6b1775b4b8304ef40f7d802d
|
||||
43
Assets/Scripts/Towers/Tower.cs
Normal file
43
Assets/Scripts/Towers/Tower.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
public class Tower : MonoBehaviour
|
||||
{
|
||||
public float range;
|
||||
[SerializeField] private float attackSpeed;
|
||||
[SerializeField] private float attackDamage;
|
||||
[SerializeField] private LayerMask whatIsEnemy;
|
||||
private Collider[] collidersInRange;
|
||||
public List<EnemyController> enemiesInRange = new List<EnemyController>();
|
||||
private float checkCounter;
|
||||
[SerializeField] private float checkTime = .2f;
|
||||
[HideInInspector] public bool enemiesUpdated;
|
||||
|
||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||
void Start()
|
||||
{
|
||||
checkCounter = checkTime;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
enemiesUpdated = false;
|
||||
checkCounter -= Time.deltaTime;
|
||||
if (checkCounter <= 0f)
|
||||
{
|
||||
checkCounter = checkTime;
|
||||
collidersInRange = Physics.OverlapSphere(transform.position, range, whatIsEnemy);
|
||||
enemiesInRange.Clear();
|
||||
foreach (Collider collider in collidersInRange)
|
||||
{
|
||||
if (collider.gameObject.GetComponent<EnemyController>() != null)
|
||||
{
|
||||
enemiesInRange.Add(collider.GetComponent<EnemyController>());
|
||||
}
|
||||
}
|
||||
enemiesUpdated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Towers/Tower.cs.meta
Normal file
2
Assets/Scripts/Towers/Tower.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c877527d90d3a5b4d879a153b810fcfe
|
||||
Reference in New Issue
Block a user