我有一个游戏管理器,它用于管理所有其他脚本中特定Unity回调(FixedUpdate
,Update
和LateUpdate
)的执行顺序。如何通过列表<Interface>和从另一个类实现的方法
具体来说,我写了这3个接口:
public interface IFixedAt {
bool IsActive { get; }
void FixedAt();
}
public interface IUpdateAt {
bool IsActive { get; }
void UpdateAt();
}
public interface ILateUpdateAt {
bool IsActive { get; }
void LateUpdateAt();
}
这些接口在游戏对象的脚本,在需要的地方实现,像这样的例子:
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour, IUpdateAt, ILateUpdateAt {
[SerializeField]
bool isActive = true;
public bool IsActive {
get {
return (isActive && gameObject.activeInHierarchy);
}
}
public void UpdateAt() {
// Do stuff in Update
}
public void LateUpdateAt() {
// Do stuff in Late Update
}
}
的游戏管理器脚本获得的唤醒对实现接口的所有脚本的引用,创建一个List<Interface>
,然后在运行时使用该列表仅在需要时执行回调:
using UnityEngine;
using System.Collections.Generic;
public class GameManager : MonoBehaviour {
public List<GameObject> GameObjectsWithScripts;
List<IFixedAt> fixedAtList { get; set; }
List<IUpdateAt> updateAtList { get; set; }
List<ILateUpdateAt> lateUpdateAtList { get; set; }
private void Awake() {
PopulateAllLists();
}
private void FixedUpdate() {
if (fixedAtList != null) {
for (int i = 0; i < fixedAtList.Count; i++) {
if (fixedAtList[i].IsActive)
fixedAtList[i].FixedAt();
}
}
}
private void Update() {
if (updateAtList != null) {
for (int i = 0; i < updateAtList.Count; i++) {
if (updateAtList[i].IsActive)
updateAtList[i].UpdateAt();
}
}
}
private void LateUpdate() {
if (lateUpdateAtList != null) {
for (int i = 0; i < lateUpdateAtList.Count; i++) {
if (lateUpdateAtList[i].IsActive)
lateUpdateAtList[i].LateUpdateAt();
}
}
}
void PopulateAllLists() {
fixedAtList = PopulateList<IFixedAt>(GameObjectsWithScripts);
updateAtList = PopulateList<IUpdateAt>(GameObjectsWithScripts);
lateUpdateAtList = PopulateList<ILateUpdateAt>(GameObjectsWithScripts);
}
List<T> PopulateList<T> (List<GameObject> goScripts) {
//Scans the GOs list and adds existent interface elements to the list
var list = new List<T>();
for (int i = 0; i < goScripts.Count; i++) {
if (goScripts[i].GetComponent<T>() != null) {
list.Add(goScripts[i].GetComponent<T>());
}
}
//Returns list (null if list is empty)
if (list.Count > 0) {
return list;
}
else {
return null;
}
}
}
现在,我有什么麻烦了解是否有可能做的问题,如果是的话,如何。
正如你可以看到,里面FixedUpdate
,Update
和LateUpdate
代码基本上是一样的:它遍历具体List
,检查当前元素处于活动状态,如果为真则执行专有的回调。
我想知道的是,如果有可能创建一个通用的方法,可以从三个回调内部调用,并传递给它的List
遍历和具体的方法来调用该List
,这样的事情在伪代码:
private void FixedUpdate() {
Method (fixedAtList, FixedAt());
}
private void Update() {
Method (updateAtList, UpdateAt());
}
private void LateUpdate() {
Method (lateUpdateAtList, LateUpdateAt());
}
private void Method<T> (List<T> list, Action method) {
if (list != null) {
for (int i = 0; i < list.Count; i++) {
if (list[i].IsActive)
list[i].method();
}
}
}
我已经尝试过不同的事情,没有成功,并atm我很无知如何做到这一点。任何帮助将非常感激。
的解决方案是如此简单,我觉得愚蠢没有想到这一点,谢谢通过。 :>顺便说一句,为清楚起见,你使用'f','l'和'u'作为lambda参数,对吧?我可以在所有三个参数中使用'x',它的工作原理是一样的,还是在这个选择背后还有其他的东西? – Galandil
您已为lambda表使用任何参数名称。我只是选择这些来匹配类/方法的第一个字母。 – juharr