如何按脚本中存储的DateTime对GameObject列表降序排序?
问题解决:按DateTime降序排序GameObject列表
原代码问题分析
你的SortRollsByDate方法里,rollButtonList.Sort(gameObject.GetComponent<RollHolderController>().rollDateTime);这行调用完全错误——List<GameObject>.Sort()需要的是比较逻辑委托,不是直接传入单个DateTime值。另外每次调用方法都重复查找对象添加到列表,会导致重复元素,也没做空引用防护。
修正后的完整代码
using System; using System.Collections.Generic; using UnityEngine; public class RollingHistoryController : MonoBehaviour { public List<GameObject> rollButtonList = new List<GameObject>(); public int lookBack; public void SortRollsByDate() { // 清空列表避免重复添加对象 rollButtonList.Clear(); // 查找所有目标对象并加入列表 foreach(GameObject obj in GameObject.FindGameObjectsWithTag("RollButtonObject")) { rollButtonList.Add(obj); } // 按rollDateTime降序排序 rollButtonList.Sort((a, b) => { // 获取两个对象的控制器组件 var controllerA = a.GetComponent<RollHolderController>(); var controllerB = b.GetComponent<RollHolderController>(); // 空组件处理:无组件的对象默认排到后面 if (controllerA == null) return 1; if (controllerB == null) return -1; // 降序逻辑:用b的日期和a比较,返回结果 return controllerB.rollDateTime.CompareTo(controllerA.rollDateTime); }); } }
关键说明
- 排序逻辑:使用
Comparison<GameObject>委托(lambda表达式),通过CompareTo方法实现降序——b.rollDateTime.CompareTo(a.rollDateTime)会让日期更晚的对象排在前面。 - 空引用防护:检查每个对象的
RollHolderController组件是否存在,避免空引用报错,无组件的对象默认排到列表末尾。 - 列表维护:每次排序前清空列表,防止重复添加同一GameObject。
优化建议(可选)
如果预制体是实例化时就需要加入列表,建议在RollHolderController的初始化阶段自动加入,避免每次排序都调用FindGameObjectsWithTag(效率较低):
public class RollHolderController : MonoBehaviour { public string rollDate; public DateTime rollDateTime; private void Awake() { // 自动将自身加入历史控制器的列表 var historyController = FindObjectOfType<RollingHistoryController>(); if (historyController != null && !historyController.rollButtonList.Contains(gameObject)) { historyController.rollButtonList.Add(gameObject); } // 确保rollDateTime从rollDate正确转换(如果依赖字符串赋值) if (!string.IsNullOrEmpty(rollDate)) { DateTime.TryParse(rollDate, out rollDateTime); } } }
之后SortRollsByDate方法可以去掉查找对象的代码,直接排序已有列表:
public void SortRollsByDate() { // 直接对已有列表排序 rollButtonList.Sort((a, b) => { var controllerA = a.GetComponent<RollHolderController>(); var controllerB = b.GetComponent<RollHolderController>(); if (controllerA == null) return 1; if (controllerB == null) return -1; return controllerB.rollDateTime.CompareTo(controllerA.rollDateTime); }); }
内容的提问来源于stack exchange,提问作者Brian Wiggins
相关产品推荐
相关产品推荐

