我有一个游戏管理器,用于管理所有其他脚本中特定 Unity 回调(FixedUpdate
、Update
和LateUpdate
)的执行顺序。
具体来说,我写了这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
}
}
游戏管理器脚本在 Awake 时获取对实现接口的所有脚本的引用,创建一个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();
}
}
}
我尝试了不同的事情,但没有成功,而且我对如何做到这一点一无所知。任何帮助将不胜感激。
首先,您需要一个涵盖该IsActive
方法的接口。
public interface IActive {
bool IsActive { get; }
}
public interface IFixedAt : IActive {
void FixedAt();
}
public interface IUpdateAt : IActive {
void UpdateAt();
}
public interface ILateUpdateAt : IActive {
void LateUpdateAt();
}
然后你需要使用泛型Action<T>
,然后你可以传入 lambdas
private void FixedUpdate() {
Method (fixedAtList, f => f.FixedAt() );
}
private void Update() {
Method (updateAtList, u => u.UpdateAt() );
}
private void LateUpdate() {
Method (lateUpdateAtList, l => l.LateUpdateAt() );
}
private void Method<T> (List<T> list, Action<T> method) where T : IActive {
if (list != null) {
for (int i = 0; i < list.Count; i++) {
if (list[i].IsActive)
method(list[i]);
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句