Unity3D仿星露谷物语开发65之NPC时间表

发布于:2025-06-21 ⋅ 阅读:(11) ⋅ 点赞:(0)

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键加速时间):


网站公告

今日签到

点亮在社区的每一天
去签到