Completed course 2 adn 3, working on 4
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user