我有一个游戏管理器,用于管理所有其他脚本中特定Unity回调(Update
,LateUpdate
和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>
游戏管理器脚本获取Awake对实现接口的所有脚本的引用,创建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
上进行迭代,检查当前元素是否为active,如果为true,则执行专有回调。
我想知道的是,是否可以创建一个可以从三个回调中调用的泛型方法,并向其传递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();
}
}
}
,在伪代码中是这样的:
getEmployeeCredits(id) {
if (this.state.company_roles) {
return this.state.company_roles.map(function (cr, i) {
if (cr.id === id) {
return cr.assigned_credits
}
else
return undefined;
}.bind(this));
}
}
我尝试了不同的事情,但没有成功,而且我对如何做到这一点毫无头绪。任何帮助将非常感激。
答案 0 :(得分:3)
首先,您需要一个涵盖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]);
}
}
}