Started working on building, next to add in spawn location for buildings for units, transporting materials from TownHall/Storage to building site, building naimation continues while building, houses spawn the correct amount of units (not just 1)

This commit is contained in:
2026-06-12 13:58:02 +01:00
parent bd3bb4bc6f
commit d99b2197e5
11 changed files with 469 additions and 10 deletions

View File

@@ -128,6 +128,8 @@ public class Building : MonoBehaviour
return;
buildingState = BuildingState.Active;
SetBuildingModel(buildingState);
if(buildingType == BuildingType.House)
UnitManagement.Instance.CreateUnit("Citizen", storageConfig.Length, transform.position);
}
public void DestroyBuilding()
{

View File

@@ -2,10 +2,16 @@ using UnityEngine;
public class JobManager : MonoBehaviour
{
public static JobManager Instance;
private Building targetBuilding;
private Resource targetResource;
private NPC targetNPC;
public void RequestJob(NPC.Job jobType)
void Awake()
{
Instance = this;
}
public Building RequestJob(NPC.Job jobType)
{
switch (jobType)
{
@@ -13,10 +19,11 @@ public class JobManager : MonoBehaviour
targetBuilding = GetUnfinishedBuildings();
if(targetBuilding != null)
{
targetBuilding.StartBuilding();
return targetBuilding;
}
break;
}
}
return null;
}
private Building GetUnfinishedBuildings()
{

View File

@@ -9,7 +9,7 @@ public class NPC : MonoBehaviour
public Job job = Job.Citizen;
// Added a simple state tracker to cleanly separate gathering and traveling
public enum NPCState { Gathering, Delivering, Idle }
public enum NPCState { Gathering, Delivering, Idle, Building }
public NPCState currentState = NPCState.Idle;
private Resource.ResourceType resourceToWorkWith, carryingResource;
@@ -54,6 +54,14 @@ public class NPC : MonoBehaviour
navMeshAgent.ResetPath();
animationController.SetBool("MovementInputHeld", false);
animationController.SetFloat("MoveSpeed", 0f);
if (CanAddToInventory(gatherAmount) && job != Job.Citizen)
if (inventory.ContainsKey(resourceToWorkWith))
currentState = NPCState.Gathering;
else
DepositResources();
break;
case NPCState.Building:
HandleBuildingPhase();
break;
}
}
@@ -114,6 +122,50 @@ public class NPC : MonoBehaviour
MoveToLocation(currentTargetBuilding.transform.position);
}
}
private void HandleBuildingPhase()
{
// 1. If we finished our building, or someone else finished it, look for a new one
if (currentTargetBuilding == null || currentTargetBuilding.GetBuildingState() != Building.BuildingState.Unbuilt)
{
Building newJob = JobManager.Instance.RequestJob(Job.Builder);
if (newJob != null)
{
currentTargetBuilding = newJob;
}
else
{
currentState = NPCState.Idle;
return;
}
}
// 2. Move towards the unfinished building
float distanceToTarget = Vector3.Distance(transform.position, currentTargetBuilding.transform.position);
if (distanceToTarget <= interactionRadius)
{
WorkOnBuilding();
}
else
{
MoveToLocation(currentTargetBuilding.transform.position);
}
}
private void WorkOnBuilding()
{
// Stop moving and look at the building
navMeshAgent.ResetPath();
animationController.SetBool("MovementInputHeld", false);
animationController.SetFloat("MoveSpeed", 0f);
transform.LookAt(currentTargetBuilding.transform.position);
// You can reuse your IsHarvesting animation boolean, or create an "IsBuilding" one in the Animator
animationController.SetBool("IsHarvesting", true);
// Tell the building to progress its construction
currentTargetBuilding.StartBuilding();
}
private void MoveToLocation(Vector3 destination)
{
@@ -211,26 +263,46 @@ public class NPC : MonoBehaviour
case Job.Builder:
//resourceToWorkWith = Resource.ResourceType.Building;
jobImg.sprite = builder;
CancelTask();
Building buildingTarget = JobManager.Instance.RequestJob(job);
if (buildingTarget != null)
{
currentTargetBuilding = buildingTarget;
currentState = NPCState.Building; // Put them in the Building state
}
else
{
// No buildings need building right now. Stand by.
currentState = NPCState.Idle;
}
break;
case Job.Soldier:
CancelTask();
break;
case Job.Farmer:
resourceToWorkWith = Resource.ResourceType.Food;
CancelTask();
break;
case Job.Forester:
resourceToWorkWith = Resource.ResourceType.Wood;
jobImg.sprite = forester;
CancelTask();
break;
case Job.Merchant:
resourceToWorkWith = Resource.ResourceType.Money;
CancelTask();
break;
case Job.Miner:
resourceToWorkWith = Resource.ResourceType.Stone;
jobImg.sprite = miner;
CancelTask();
break;
case Job.Citizen:
resourceToWorkWith = Resource.ResourceType.Population;
jobImg.sprite = citizen;
CancelTask();
break;
default:
break;
}
@@ -239,7 +311,7 @@ public class NPC : MonoBehaviour
{
currentState = NPCState.Delivering;
}
carryingResource = resourceToWorkWith;
this.job = job;
}
@@ -299,4 +371,13 @@ public class NPC : MonoBehaviour
{
return inventory;
}
private void CancelTask()
{
navMeshAgent.destination = transform.position;
animationController.SetBool("MovementInputHeld", false);
animationController.SetFloat("MoveSpeed", 0f);
currentTargetResource = null;
currentTargetBuilding = null;
currentState = NPCState.Idle;
}
}

View File

@@ -0,0 +1,35 @@
using System;
using UnityEngine;
public class UnitManagement : MonoBehaviour
{
public static UnitManagement Instance;
[SerializeField] GameObject npcPrefab;
void Awake()
{
Instance = this;
}
// 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 CreateUnit(String unit, int quantity, Vector3 spawnLocation)
{
for (int i = 0; i < quantity; i++)
{
switch (unit)
{
case "Citizen":
Instantiate(npcPrefab, spawnLocation, Quaternion.identity);
break;
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e15f1b8b2e6ff654db7a1fb788173296