125 lines
3.8 KiB
C#
125 lines
3.8 KiB
C#
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
|
|
public class CitizenAI : MonoBehaviour
|
|
{
|
|
public Transform homeLocation;
|
|
public Transform workLocation;
|
|
public Transform leisureLocation;
|
|
|
|
private StateMachine stateMachine;
|
|
private NavMeshAgent agent;
|
|
[SerializeField] private TextMeshProUGUI stateText;
|
|
|
|
private enum DayType { Weekday, Weekend }
|
|
|
|
private void Start()
|
|
{
|
|
agent = GetComponent<NavMeshAgent>();
|
|
stateMachine = gameObject.AddComponent<StateMachine>();
|
|
UpdateRoutine();
|
|
FindWorkPlace(); // Find the first workplace in the scene
|
|
if (workLocation == null)
|
|
{
|
|
Debug.LogWarning("No workplace found. Please ensure there is at least one workplace in the scene.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (ShouldSwitchState())
|
|
UpdateRoutine();
|
|
}
|
|
|
|
private bool ShouldSwitchState()
|
|
{
|
|
// Example logic to reassign state every hour or based on event
|
|
return true;
|
|
}
|
|
|
|
private void UpdateRoutine()
|
|
{
|
|
float hour = City.Instance.curTime / 3600f; // Assuming CurrentTime is in seconds
|
|
bool isWeekday = (City.Instance.curDay != "Saturday" && City.Instance.curDay != "Sunday");
|
|
|
|
if (isWeekday)
|
|
{
|
|
if (hour >= 7 && hour < 9)
|
|
SetGoToWorkState();
|
|
else if (hour >= 9 && hour < 17)
|
|
SetWorkState();
|
|
else if (hour >= 17 && hour < 22)
|
|
SetLeisureState();
|
|
else
|
|
SetSleepState();
|
|
}
|
|
else
|
|
{
|
|
if (hour >= 9 && hour < 22)
|
|
SetLeisureState();
|
|
else
|
|
SetSleepState();
|
|
}
|
|
}
|
|
|
|
private void SetGoToWorkState()
|
|
{
|
|
stateMachine.SetState(new State(
|
|
() => { agent.SetDestination(workLocation.position); Debug.Log("Heading to work."); },
|
|
() =>
|
|
{
|
|
if (!agent.pathPending && agent.remainingDistance <= 0.2f)
|
|
SetWorkState();
|
|
},
|
|
() => Debug.Log("Arrived at work.")
|
|
));
|
|
}
|
|
|
|
private void SetWorkState()
|
|
{
|
|
stateMachine.SetState(new State(
|
|
() => Debug.Log("Working..."),
|
|
() => { /* Could gain resources here */ },
|
|
() => Debug.Log("Work day over.")
|
|
));
|
|
}
|
|
|
|
private void SetLeisureState()
|
|
{
|
|
stateMachine.SetState(new State(
|
|
() => { agent.SetDestination(leisureLocation.position); Debug.Log("Heading to leisure area."); },
|
|
() => { if (!agent.pathPending && agent.remainingDistance <= 0.2f) Debug.Log("Relaxing."); },
|
|
() => Debug.Log("Leaving leisure spot.")
|
|
));
|
|
}
|
|
|
|
private void SetSleepState()
|
|
{
|
|
stateMachine.SetState(new State(
|
|
() => { agent.SetDestination(homeLocation.position); Debug.Log("Going to sleep."); },
|
|
() => { if (!agent.pathPending && agent.remainingDistance <= 0.2f) Debug.Log("Sleeping..."); },
|
|
() => Debug.Log("Woke up.")
|
|
));
|
|
}
|
|
private void FindWorkPlace()
|
|
{
|
|
Building[] buildings = FindObjectsByType<Building>(FindObjectsSortMode.None);
|
|
foreach (var b in buildings)
|
|
{
|
|
if (IsWorkplaceType(b.preset.buildingType))
|
|
{
|
|
workLocation = b.transform;
|
|
break; // Stop searching after finding the first workplace
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool IsWorkplaceType(object buildingType)
|
|
{
|
|
// Replace 'object' with the actual type of buildingType if known, e.g., BuildingType
|
|
// Ensure BuildingType enum is accessible in this file (add 'using' or move enum if needed)
|
|
return buildingType.ToString() == "Industrial" || buildingType.ToString() == "Commercial";
|
|
}
|
|
} |