首先,我想简短说明一下我的问题: 我该如何访问附加到另一个游戏对象的其他代码段,或者如何在不附加游戏对象的情况下初始化一个类。
当我在Unity中制作小型游戏时,我做了一个单元设计器,您在其中提供一些值,例如它携带多少武器,并计算该单元的状态(攻击,射程,速度等)。按ComputeValues()并在单击确认时保存。但是所有这些值都是通过单击按钮而不是直接输入来调整的。 (即,单击按钮并添加/减少1种武器)
但是,当我尝试在启动时添加一些模板单元时,它将无法工作。所以我做了一个CreateDesignWithValue()函数。它将所有相关数据作为输入,并使用上面的ComputeValues()来计算该对象的值。
问题是我正在尝试在球员课上这样做。但是我无法创建新的ShipDesigner,也无法将其设置为静态。我如何获得它?
答案 0 :(得分:3)
在不知道您确切的用例以及您在说什么方法的情况下,我们只能给出一个非常笼统的答案:
并非所有类都必须为MonoBehaviour
类型,这实际上取决于您的需求。
如果您对某种类型有某种计算,则可以使用Extension Methods,例如
public static class Vector3Extensions
{
public static Vector3 DevideBy(this Vector3 a, Vector3 b)
{
return new Vector(a.x / b.x, a.y / b.y, a.z / b.z);
}
}
您可以使用,例如
var newVector = transform.position.DevideBy(new Vector(1, 2, 3));
在所有其他课程中。
通常,您可以使用public static class
来实现方法和存储应在任何地方(例如,
public static class Settings
{
private static int _currentInt = 7;
public static void SaySomething(string something)
{
Debug.Log(something);
}
public static void DoubleCurrentInt()
{
_currentInt *= 2;
}
public static int GetSquareOfCurrentInt()
{
return _currentInt * _currentInt;
}
}
您现在可以像在任何地方一样致电
Settings.DoubleCurrentInt();
Settings.SaySomething(Settings.GetSquareOfCurrentInt.Tostring);
当然,有时您不希望从任何地方都可以访问某些内容,因此您也可以简单地使用普通的实例化类来进行计算,例如
public class Settings
{
private int _currentInt = 7;
public Settings(int initialInt = 0)
{
_currentInt = initialInt;
}
public void SaySomething(string something)
{
Debug.Log(something);
}
public void DoubleCurrentInt()
{
CurrentInt *= 2;
}
public int GetSquareOfCurrentInt()
{
return CurrentInt * CurrentInt;
}
}
因此您可以使用
private Settings settings;
private void Start()
{
new Settings(3);
}
合一MonoBehaviour
和
private Settings settings;
private void Start()
{
new Settings(26);
}
在另一个MonoBehaviour
中,两者都有不同的实例,但是可以使用其中的所有实现分别计算和处理事情。
您还只能在特定类型(static
)的所有实例之间“共享”一种方法,还可以允许其他类型的方法(public
)
public class A : MonoBehaviour
{
// A prefab only this specific component has access to
[SerializeField] private GameObject prefab;
// example for a kind of singleton pattern
private static GameObject prefabSingleton;
private void Start()
{
prefabSingleton = prefab;
}
public static void Spawn(int someIntToAssign, string someTextToAssign)
{
var obj = Instantiate(prefabSingleton)
; componentReference = obj.GetComponent();
componentReference.someIntField = someIntToAssign;
componentReference.Getcomponent<Text>().text = someTextToAssign;
}
}
您可以从其他类型调用它
A.Setup(someExampleReference, "Yeay!");
(在此示例中,您可以考虑在SomeExampleType
中实现,尽管^^)
您描述的内容听起来也像ScriptableObjects(Tutorial)对您来说很有趣。
ScriptableObject是类似于预制件的资产,但可以存储值和方法。然后,您可以在MonoBehaviour
组件的字段中引用它们,以根据值更改其行为,或作为容器在多个实例和不同类型之间共享该行为。
public
方法的实例最后但并非最不重要的是要做一个
public class A : MonoBehaviour
{
[SerializeField] private Transform someObject;
public Vector3 GetObjectPosition()
{
return someObject.position;
}
}
并通过许多GetComponent
或/和FindObjectOfType
变体之一访问它,或者只需引用相应的组件即可,例如
public class B : MonoBehaviour
{
// drag in via the Inspector
public A AReference;
private void Start()
{
// or get it on runtime e.g.
AReference = GameObject.Find("ObjectWithA").GetComponent<A>();
// or if there is only one e.g.
AReference = FindObjectOfType<A>();
Debug.Log(AReference.GetObjectPosition());
}
}
答案 1 :(得分:0)
简短版本的答案:
我如何访问附加到另一个游戏对象的其他代码段:
为您要访问的脚本声明一个公共字段,例如public ExampleScript exampleScript;
并将具有ExampleScript的游戏对象分配给检查器中的您的字段。
我如何在没有附带游戏对象的情况下初始化类:您不能像new ExampleScript();
一样创建从MonoBehaviour派生的脚本实例。但是相反,您可以使用gameObject.AddComponent<ExampleScript>();
将该脚本添加到现有的游戏对象中,并且可以从另一个脚本中访问该脚本,该脚本附加了与之类似的游戏对象:gameObject.GetComponent<ExampleScript>();