首先,我想简短说明一下我的问题:
我如何访问附加到另一个游戏对象的其他代码段,或者如何在不附加游戏对象的情况下初始化类。

当我在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中实现它,尽管^^)

脚本对象

您描述的内容听起来也像ScriptableObjectsTutorial)一样,可能对您来说很有趣。

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());
    }
}

10-08 03:31