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

@@ -3803,7 +3803,7 @@ MonoBehaviour:
m_EditorClassIdentifier: Assembly-CSharp::Building
constructionTime: 30
constructionResources:
constructionCost: 6400000064000000
constructionCost: 3200000032000000
buildingType: 0
unbuiltModel: {fileID: 6653159622886587193}
constructingModel: {fileID: 4914126936048077074}

View File

@@ -784,6 +784,119 @@ Transform:
m_Children: []
m_Father: {fileID: 5090559939260843181}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1877628890848750148
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1880890567730925888}
- component: {fileID: 1908658883244227494}
- component: {fileID: 1898581353130709488}
- component: {fileID: 1938949062149814322}
m_Layer: 0
m_Name: SM_Wep_Axe_09
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1880890567730925888
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1877628890848750148}
serializedVersion: 2
m_LocalRotation: {x: -0.38268566, y: 0.0000010132788, z: 0.9238786, w: 0.000000014901159}
m_LocalPosition: {x: 0.0059671043, y: 0.00000002712477, z: 0.0015260844}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 2216271485333287045}
m_LocalEulerAnglesHint: {x: 0, y: -45, z: 180}
--- !u!33 &1908658883244227494
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1877628890848750148}
m_Mesh: {fileID: 4300000, guid: aad74abaa9c929241842b49ddeee73bc, type: 3}
--- !u!23 &1898581353130709488
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1877628890848750148}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 71e41e43b459a244abaf5acca76b89ee, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_MaskInteraction: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!64 &1938949062149814322
MeshCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1877628890848750148}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 5
m_Convex: 1
m_CookingOptions: 30
m_Mesh: {fileID: 43188902427133874, guid: 140c2933e48fd2b44af4fe01cfa50095, type: 2}
--- !u!1 &2045665840315404223
GameObject:
m_ObjectHideFlags: 0
@@ -847,6 +960,82 @@ Transform:
m_Children: []
m_Father: {fileID: 5020240601765521152}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &2554390962781056119
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5793375072013135131}
- component: {fileID: 5373371927819234237}
- component: {fileID: 7683141406849393373}
m_Layer: 3
m_Name: Image
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5793375072013135131
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2554390962781056119}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 4736914753969933335}
m_Father: {fileID: 9027451830861437583}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0.25, y: 0.25}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &5373371927819234237
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2554390962781056119}
m_CullTransparentMesh: 1
--- !u!114 &7683141406849393373
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2554390962781056119}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier: UnityEngine.UI::UnityEngine.UI.Image
m_Material: {fileID: 0}
m_Color: {r: 0.8867924, g: 0.6398171, b: 0.08784264, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 21145fab1b19bab47a4f21391101f9aa, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &2649705847934579506
GameObject:
m_ObjectHideFlags: 0
@@ -911,7 +1100,7 @@ RectTransform:
m_LocalScale: {x: 1.0000001, y: 1.0000001, z: 1.0000001}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 4736914753969933335}
- {fileID: 5793375072013135131}
m_Father: {fileID: 5301051924229665120}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
@@ -2714,12 +2903,12 @@ RectTransform:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7849837966100312770}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 9027451830861437583}
m_Father: {fileID: 5793375072013135131}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
@@ -2963,6 +3152,7 @@ GameObject:
- component: {fileID: 8714646823312657490}
- component: {fileID: 75681181018508881}
- component: {fileID: 7777674606204040171}
- component: {fileID: 3695866308145665832}
m_Layer: 3
m_Name: NPC
m_TagString: Untagged
@@ -3086,6 +3276,24 @@ CharacterController:
m_SkinWidth: 0.02
m_MinMoveDistance: 0.001
m_Center: {x: 0, y: 0.93, z: 0}
--- !u!114 &3695866308145665832
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8322859804011707589}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6fab5212c04fb442799fa9f3f33247ef, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::Synty.Tools.SyntyPropBoneTool.PropBoneBinder
animator: {fileID: 75681181018508881}
propBoneConfig: {fileID: 11400000, guid: c23cf315e98f6074c81974a4d837b205, type: 2}
updateType: 2
updateInEditMode: 1
rebindOnAwake: 0
_propBoneBindings: []
--- !u!1 &8408235103800595200
GameObject:
m_ObjectHideFlags: 0
@@ -3370,7 +3578,8 @@ Transform:
m_LocalPosition: {x: 0.07455006, y: 0.025735673, z: 0.00072323484}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Children:
- {fileID: 1880890567730925888}
m_Father: {fileID: 2885384352365181324}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &9110552758642604593

View File

@@ -1118,6 +1118,50 @@ MonoBehaviour:
m_MinRegionArea: 2
m_NavMeshData: {fileID: 23800000, guid: b2102742fa1fe07469925ad32dc6a253, type: 2}
m_BuildHeightMesh: 0
--- !u!1 &783418143
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 783418145}
- component: {fileID: 783418144}
m_Layer: 0
m_Name: _JobManager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &783418144
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 783418143}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4bd36540681fbaa4eb9be52d4b051ace, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::JobManager
--- !u!4 &783418145
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 783418143}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -7.08934, y: 0, z: -0.03749}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &832575517
GameObject:
m_ObjectHideFlags: 0
@@ -1773,6 +1817,51 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1677812918}
m_CullTransparentMesh: 1
--- !u!1 &1696539608
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1696539610}
- component: {fileID: 1696539609}
m_Layer: 0
m_Name: _UnitManager
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1696539609
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1696539608}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: e15f1b8b2e6ff654db7a1fb788173296, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::UnitManagement
npcPrefab: {fileID: 8322859804011707589, guid: f97a75ea176e29648bedd5f9d0da92c4, type: 3}
--- !u!4 &1696539610
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1696539608}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -7.08934, y: 0, z: -0.03749}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1805096263
GameObject:
m_ObjectHideFlags: 0
@@ -2365,6 +2454,8 @@ SceneRoots:
m_ObjectHideFlags: 0
m_Roots:
- {fileID: 392525274}
- {fileID: 783418145}
- {fileID: 1696539610}
- {fileID: 330585546}
- {fileID: 410087041}
- {fileID: 832575519}

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

View File

@@ -0,0 +1,24 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ef83fc4eb87f44f279e62ce434242341, type: 3}
m_Name: NPC_PropBoneBindingConfig
m_EditorClassIdentifier: Assembly-CSharp::Synty.Tools.SyntyPropBoneTool.PropBoneConfig
sourceRig: {fileID: 919132149155446097, guid: 68a29e70ae95f6a4195bf0fcbb538019, type: 3}
targetRig: {fileID: 8322859804011707589, guid: f97a75ea176e29648bedd5f9d0da92c4, type: 3}
propBoneDefinitions:
- parentBoneName: Hand_R
boneName: Prop_R
socketName: Prop_R_Socket
rotationOffset: {x: 0, y: 0, z: 0}
scale: 0
scaleCalculationBone1: Hand_R
scaleCalculationBone2: Elbow_R

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c23cf315e98f6074c81974a4d837b205
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant: