1、目标
NPC在指定的时间和条件下完成指定的动作。
2、架构
3、编写代码
(1)修改GameManager.cs脚本
(2)新建NPCScheduleEventSort.cs脚本
在Assets\Scripts\NPC下新建NPCScheduleEventSort.cs脚本,只是用来排序的类。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NPCScheduleEventSort : IComparer<NPCScheduleEvent>
{
public int Compare(NPCScheduleEvent npcScheduleEvent1, NPCScheduleEvent npcScheduleEvent2)
{
if(npcScheduleEvent1?.Time == npcScheduleEvent2?.Time)
{
if(npcScheduleEvent1?.priority < npcScheduleEvent2?.priority)
{
return -1;
}
else
{
return 1;
}
}
else if(npcScheduleEvent1?.Time > npcScheduleEvent2?.Time)
{
return 1;
}
else if(npcScheduleEvent1?.Time < npcScheduleEvent2?.Time)
{
return -1;
}
else
{
return 0;
}
}
}
(3)新建SO_NPCScheduleEventList.cs脚本
在Assets\Scripts\NPC下新建SO_NPCScheduleEventList.cs脚本
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName ="so_NPCScheduleEventList", menuName = "Scriptable Objects/NPC/NPC Schedule Event List")]
public class SO_NPCScheduleEventList : ScriptableObject
{
[SerializeField]
public List<NPCScheduleEvent> npcScheduleEventList;
}
(4)新建NPCSchedule.cs脚本
在Assets\Scripts\NPC下新建NPCSchedule.cs脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(NPCPath))]
public class NPCSchedule : MonoBehaviour
{
[SerializeField] private SO_NPCScheduleEventList so_NPCScheduleEventList = null;
private SortedSet<NPCScheduleEvent> npcScheduleEventSet;
private NPCPath npcPath;
private void Awake()
{
// Load NPC schedule event list into a sorted set
npcScheduleEventSet = new SortedSet<NPCScheduleEvent>(new NPCScheduleEventSort());
foreach(NPCScheduleEvent npcScheduleEvent in so_NPCScheduleEventList.npcScheduleEventList)
{
npcScheduleEventSet.Add(npcScheduleEvent);
}
// Get NPC Path Component
npcPath = GetComponent<NPCPath>();
}
private void OnEnable()
{
EventHandler.AdvanceGameMinuteEvent += GameTimeSystem_AdvanceMinute;
}
private void OnDisable()
{
EventHandler.AdvanceGameMinuteEvent -= GameTimeSystem_AdvanceMinute;
}
private void GameTimeSystem_AdvanceMinute(int gameYear, Season gameSeason, int gameDay, string gameDayOfWeek, int gameHour, int gameMinute, int gameSecond)
{
int time = (gameHour * 100) + gameMinute;
// Attempt to get matching schedule
NPCScheduleEvent matchingNPCScheduleEvent = null;
foreach(NPCScheduleEvent npcScheduleEvent in npcScheduleEventSet)
{
if(npcScheduleEvent.Time == time)
{
// Time match now check if paramenters match
if (npcScheduleEvent.day != 0 && npcScheduleEvent.day != gameDay)
continue;
if(npcScheduleEvent.season != Season.none && npcScheduleEvent.season != gameSeason)
continue;
if(npcScheduleEvent.weather != Weather.none && npcScheduleEvent.weather != GameManager.Instance.currentWeather)
continue;
matchingNPCScheduleEvent = npcScheduleEvent;
break;
}
else if(npcScheduleEvent.Time > time)
{
break;
}
}
// Now test is matchingSchedule != null and do something
if(matchingNPCScheduleEvent != null)
{
// Build path for matching schedule
npcPath.BuildPath(matchingNPCScheduleEvent);
}
}
}
4、配置NPC_Butch对象
给NPC_Butch对象添加NPCSchedule组件,同时Apply to Prefab 'NPC'。
5、添加Scriptable Object实例
配置第一个定时任务如下:
然后配置如下:
运行游戏(可用T键加速时间):