Completed course 2 adn 3, working on 4

This commit is contained in:
2026-03-20 17:34:22 +00:00
parent 623ad6f509
commit db966bab55
507 changed files with 67348 additions and 4667 deletions

View File

@@ -1,5 +1,4 @@
using System.Collections;
using Unity.VisualScripting;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
@@ -9,7 +8,9 @@ public enum UnitState
Idle,
Move,
MoveToResource,
Gather
Gather,
MoveToEnemy,
Attack
}
public class Unit : MonoBehaviour
@@ -23,16 +24,30 @@ public class Unit : MonoBehaviour
public int gatherAmount;
public float gatherRate;
private float lastGatherTime;
private ResourceSource resource;
public int curHp;
public int maxHp;
public int minAttackDamage;
public int maxAttackDamage;
public float attackRate;
private float lastAttackTime;
public float pathUpdateRate = 1.0f;
private float lastPathUpdateTime;
private Unit curEnemyTarget;
public float attackDistance;
public UnitHealthBar healthBar;
public ResourceSource curResourceSource;
//events
public class StateChangeEvent : UnitEvent<UnitState> { }
[System.Serializable]
public class StateChangeEvent : UnityEvent<UnitState> { }
public StateChangeEvent onStateChange;
public Player player;
[System.Obsolete]
void Awake()
{
//get the components
navAgent = GetComponent<NavMeshAgent>();
SetState(UnitState.Idle);
}
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
@@ -50,26 +65,37 @@ public class Unit : MonoBehaviour
}
switch(state)
{
case UnitState.Move
case UnitState.Move:
{
MoveUpdate();
break;
}
case UnitState.MoveToResource
case UnitState.MoveToResource:
{
MoveToResourceUpdate();
break;
}
case UnitState.Gather
case UnitState.Gather:
{
GatherUpdate();
break;
}
case UnitState.MoveToEnemy:
{
MoveToEnemyUpdate();
break;
}
case UnitState.Attack:
{
AttackUpdate();
break;
}
}
}
public void ToggleSelectionVisual(bool selected)
{
selectionVisual.SetActive(selected);
if(selectionVisual != null)
selectionVisual.SetActive(selected);
}
public void MoveToPosition(Vector3 pos, SelectionMarker marker = null)
{
@@ -81,11 +107,15 @@ public class Unit : MonoBehaviour
navAgent.isStopped = false;
navAgent.SetDestination(pos);
selectionMarker = marker;
SetState(UnitState.Move);
}
//move to a resource and begin to gather it
public void GatherResource(ResourceSource resource, Vector3 pos)
{
curResourceSource = resource;
SetState(UnitState.MoveToResource);
navAgent.isStopped = false;
navAgent.SetDestination(pos);
}
void SetState(UnitState toState)
{
@@ -101,14 +131,100 @@ public class Unit : MonoBehaviour
}
void MoveUpdate()
{
if(!navAgent.pathPending && navAgent.remainingDistance <= navAgent.stoppingDistance)
SetState(UnitState.Idle);
}
void MoveToResourceUpdate()
{
if(curResourceSource == null)
{
SetState(UnitState.Idle);
return;
}
if(!navAgent.pathPending && navAgent.remainingDistance <= navAgent.stoppingDistance)
SetState(UnitState.Gather);
}
void GatherUpdate()
{
if(curResourceSource == null)
{
SetState(UnitState.Idle);
return;
}
LookAt(curResourceSource.transform.position);
if(Time.time - lastGatherTime > gatherRate)
{
lastGatherTime = Time.time;
curResourceSource.GatherResource(gatherAmount, player);
}
}
//called every frame the "MoveToEnemy" state is active
void MoveToEnemyUpdate()
{
if(curEnemyTarget == null)
{
SetState(UnitState.Idle);
return;
}
if(Time.time - lastPathUpdateTime > pathUpdateRate)
{
lastPathUpdateTime = Time.time;
navAgent.isStopped = false;
navAgent.SetDestination(curEnemyTarget.transform.position);
}
if(Vector3.Distance(transform.position, curEnemyTarget.transform.position) <= attackDistance)
SetState(UnitState.Attack);
}
//called every frame the "Attack" state is active
void AttackUpdate()
{
//if our target is dead or null, go idle
if(curEnemyTarget == null)
{
SetState(UnitState.Idle);
return;
}
//if we are still moving
if(!navAgent.isStopped)
navAgent.isStopped = true;
//attack every "attackRate" seconds
if(Time.time - lastAttackTime > attackRate)
{
lastAttackTime = Time.time;
curEnemyTarget.TakeDamage(UnityEngine.Random.Range(minAttackDamage, maxAttackDamage + 1));
}
//Look at the enemy
LookAt(curEnemyTarget.transform.position);
//if we are too far away, move towards the enemy
if(Vector3.Distance(transform.position, curEnemyTarget.transform.position) > attackDistance)
SetState(UnitState.MoveToEnemy);
}
//rotate to face the given position
void LookAt(Vector3 pos)
{
Vector3 dir = (pos - transform.position).normalized;
float angle = Mathf.Atan2(dir.x, dir.z) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0, angle, 0);
}
//move to an enemy unit and attack them
public void AttackUnit(Unit target)
{
curEnemyTarget = target;
SetState(UnitState.MoveToEnemy);
}
//called when we take damage from another unit
public void TakeDamage(int damage)
{
curHp -= damage;
if(curHp <= 0)
Die();
//update the health bar
healthBar.UpdateHealthBar(curHp, maxHp);
}
//called when our health reaches 0
void Die()
{
player.units.Remove(this);
Destroy(gameObject);
}
}