无法在 Unity 中继承 ConfigurableJoint

Cannot subclass ConfigurableJoint in Unity

我有一个已配置的Configurable Joint,在Unity3d项目中使用比较频繁,所以我决定将其配置实现为ConfigurableJoint的子类,如图所示;

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FollowJoint : ConfigurableJoint {

    // Use this for initialization
    void Start () {
        this.anchor = Vector3.zero;
        this.axis = new Vector3 (1, 0, 0);
        this.connectedAnchor = Vector3.zero;
        this.secondaryAxis = new Vector3 (0, 1, 0);
        xMotion = ConfigurableJointMotion.Limited;
        yMotion = ConfigurableJointMotion.Limited;
        zMotion = ConfigurableJointMotion.Limited;
        angularXMotion = ConfigurableJointMotion.Locked;
        angularYMotion = ConfigurableJointMotion.Locked;
        angularZMotion = ConfigurableJointMotion.Locked;

        linearLimitSpring.spring = 100;
        linearLimitSpring.damper = 1;
        linearLimit.limit = 0;
        linearLimit.bounciness = 0;
        linearLimit.contactDistance = 0;

    }
}

但是,这给了我错误“FollowJoint:无法从密封类型‘UnityEngine.ConfigurableJoint’派生”

如果这是不可能的,为什么?什么是好的替代策略(除了实例化可配置关节并通过代码配置它)?

如您所述,问题如前所述:

FollowJoint: cannot derive from sealed type `UnityEngine.ConfigurableJoint

在 C# 中,无法继承密封类型

见于sealed (C# Reference):

When applied to a class, the sealed modifier prevents other classes from inheriting from it.

如何解决这个问题

要解决这个问题,您可以创建一个工厂函数,以便重新创建它:

public static ConfigurableJoint MakeJoint() {
    var joint = new ConfigurableJoint();

    joint.anchor = Vector3.zero;
    joint.axis = new Vector3 (1, 0, 0);
    joint.connectedAnchor = Vector3.zero;
    joint.secondaryAxis = new Vector3 (0, 1, 0);

    // ...

    return joint;
}

// Use factory each time you need the same
var jointA = MakeJoint();
var jointB = MakeJoint();

你也可以通过改变函数的签名来改进工厂来接受参数,并使用参数来设置返回的ConfigurableJoint的参数。例如,可以添加固定的 secondaryAxis 而不是固定的

var joint = MakeJoint(secondaryAxis:new Vector3(0, 0, 1));

阅读更多关于可选参数和命名参数的信息here

ConfigurableJoint 是一个密封的 classes,这意味着您不能继承它。

ConfigurableJoint 也是一个组件,这意味着您可以使用 AddComponentGetComponent 函数简单地完成您正在寻找的东西,该函数将其作为组件添加或获取到 FollowJoint 脚本附加到。

只需对 ConfigurableJoint class 进行包装,然后从中继承。 使用 Awake 函数初始化变量。

1。如果您在编辑器中配置了ConfigurableJoint,请使用GetComponent函数访问它:

public class CustomConfigurableJoint : MonoBehaviour
{
    protected ConfigurableJoint configurableJoint;

    protected virtual void Awake()
    {
        configurableJoint = GetComponent<ConfigurableJoint>();
    }
}

然后你可以继承CustomConfigurableJoint class并像这样使用它:

public class FollowJoint : CustomConfigurableJoint
{
    protected override void Awake()
    {
        base.Awake();
    }

    void Start()
    {
        configurableJoint.xMotion = ConfigurableJointMotion.Limited;
    }
}

2。现在,如果您希望从代码创建和配置 ConfigurableJoint,请使用 AddComponent 函数创建它的新实例,然后修改在 Awake 函数中如您所愿:

public class CustomConfigurableJoint : MonoBehaviour
{
    protected ConfigurableJoint configurableJoint;

    protected virtual void Awake()
    {
        //Create it
        configurableJoint = gameObject.AddComponent<ConfigurableJoint>();

        //Modify it below 
        configurableJoint.xMotion = ConfigurableJointMotion.Limited;
        configurableJoint.yMotion = ConfigurableJointMotion.Limited;
        configurableJoint.zMotion = ConfigurableJointMotion.Limited;
        configurableJoint.angularXMotion = ConfigurableJointMotion.Locked;
        configurableJoint.angularYMotion = ConfigurableJointMotion.Locked;
        configurableJoint.angularZMotion = ConfigurableJointMotion.Locked;

    }
}