首先,我想简短说明一下我的问题:
我如何访问附加到另一个游戏对象的其他代码段,或者如何在不附加游戏对象的情况下初始化类。
当我在Unity中制作小型游戏时,我创建了一个单元设计器,您在其中提供一些值,例如它携带多少武器,并且该单元的状态(攻击,射程,速度等)将由ComputeValues( ),然后单击确认保存。但是所有这些值都是通过单击按钮而不是直接输入来调整的。 (即,单击按钮并添加/减少1种武器)
但是,当我尝试在启动时添加一些模板单元时,它将无法正常工作。所以我做了一个CreateDesignWithValue()函数。它接受所有相关数据的输入,并使用上面的ComputeValues()计算该对象的值。
问题是我正在尝试在玩家课堂中做到这一点。但是我无法创建新的ShipDesigner,也无法将其设置为静态。我如何获得它?
最佳答案
不知道确切的用例以及您在说什么方法,我们只能给出一个非常笼统的答案:
并非所有类都必须为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());
}
}