我有多個腳本,它們具有一個同名的公共布爾變數。如下所示:
腳本1.cs
public bool isTrigger = false;
腳本2.cs
public bool isTrigger = false;
……
現在我有一個主腳本,它應該找到所有具有公共布爾名稱的腳本并進行更改。在示例中,這里allScripts是所有具有 isTrigger 布林值的腳本的串列。
MasterScript.cs
for(int i = 0; i<allScripts.Length; i ){
allScripts[i].isTrigger = true;
}
我如何實作這一目標?如何找到所有具有相同布爾變數的腳本并將其添加到串列中?
uj5u.com熱心網友回復:
如上所述,基本上有兩種選擇:
公共基類
為您的組件使用公共基類,例如
public abstract class MyBase : MonoBehaviour
{
public bool IsTrigger;
// more common fields, properties and methods
}
然后從那個繼承你的其他類
public class ClassA : MyBase
{
// additional A specific stuff
}
public class ClassB : MyBase
{
// additional B specific stuff
}
由于ClassA和ClassBaready繼承了MyBase你的成員,然后可以直接使用
public class Master : MonoBehaviour
{
// Use the common base type!
// Either populated via the Inspector
public MyBase[] allInstances;
// Or on runtime
private void Awake()
{
// e.g. find everything of the base type in your scene
allInstances = FindObjectsOfType<MyBase>(true);
foreach(var instance in allInstances)
{
instance.IsTrigger = true;
}
}
}
- 好處
- 每個子類都已經有了這個欄位
IsTrigger,沒有更多的事情要做 - 基類已經可以實作一般的通用行為,并且可以使用
virtual,abstract然后override在子類中進行擴展
- 每個子類都已經有了這個欄位
- 缺點
- 您只能從一個類繼承,因此用另一個基類擴展它是非常不靈活的
界面
您可以使用interface. 介面不帶來任何自己的實作,而是一個成員模板。
就像在界面中一樣,您無法定義欄位,您將不得不使用屬性
public interface IMyThing
{
bool IsTrigger { get; set; }
}
進而
public class ClassA : MonoBehaviour, IMyThing
{
// example using a serialzed auto-property
[field: SerializeField] public bool IsTrigger { get; set; }
}
public class ClassB : MonoBehaviour, IMyThing
{
// Example using a backing field
[SerializeField] private bool isTrigger;
public bool IsTrigger
{
get => isTrigger;
set => isTrigger = value;
}
}
然后在你的主人
public class Master : MonoBehaviour
{
// reference via Inspector
// Using the SeriaizeReferenceAttribute enables to serialize and reference any instances of
// classes inheriting from UnityEngine.Object and implementing the interface
[SeriaizeReference] public IMyThing[] allInstances;
private void Awake()
{
// since FindObjectOfType can not be sued on interfaces here i gets a bit more complex
// find all instances from all scenes
var list = new List<IMyThing>();
for (var i = 0; i < SceneManager.sceneCount; i )
{
var scene = SceneManager.GetSceneAt(i);
var roots = scene.GetRootGameObjects( );
foreach (var root in roots)
{
list.AddRange(root.GetComponentsInChildren<IMyThing>(true));
}
}
allInstances = list.ToArray();
foreach(var instance in allInstances)
{
instance.isTrigger = true;
}
}
}
- 優勢
- 解決基類的限制:可以實作任意多個介面
- 壞處
- 不再保證實作的類
IMyThing是MonoBehaviour! =>FindObjectsOfType不能使用 andGetComponent等可能會在運行時失敗 - 每個類都必須根據成員本身來實作
- Unity 不直接序列化介面
- 不再保證實作的類
uj5u.com熱心網友回復:
您可以創建一個界面,在其中定義您的屬性。然后,您的腳本繼承自此類。
實體化物件時,您需要將它們添加到串列中。
public interface IExampleA
{
public bool isTrigger { get; set;}
}
public class B : IExampleA
{
}
class masterscript
{
public void function()
{
// Create objects that has class B
// if object has class B add it to a list
// do your loop
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/371807.html
