【问题标题】:Unexpected Symbol '=' in class, struct or interface declaration类、结构或接口声明中的意外符号“=”
【发布时间】:2018-01-06 10:57:54
【问题描述】:

请原谅并纠正我在代码中的严重错误,我有点菜鸟。

我最近在随便写一个脚本来控制带有铰链电机的汽车,我想,我为什么不使用统一文档。我去把代码转移到我的项目中:

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
void Start() {
    HingeJoint hinge = GetComponent<HingeJoint>();
    JointMotor motor = hinge.motor;
    motor.force = 100;
    motor.targetVelocity = 90;
    motor.freeSpin = false;
    hinge.motor = motor;
    hinge.useMotor = true;
    }
}

我试图更改代码:

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

public class WHEELSPIN : MonoBehaviour {

    HingeJoint hinge = GetComponent<HingeJoint>();
    private JointMotor motor = hinge.motor;
    hinge.useMotor = true;
    hinge.motor = float motorz;
    motorz.freeSpin = true;


    private void Update()
     {
        if (Input.GetAxis("Vertical"))
        {
            motorz.force = 1000;
            motorz.targetVelocity = 900;
        }
    }
}

之前有人建议我不要使用与对象相同的变量,因此它被称为 motorz。我还被告知不要在 start 函数中声明变量,否则我不能在其他函数中使用它,我也改变了它,但现在我收到一条错误消息,说 '=' 符号是意外的。我该如何解决这个问题?

编辑:忘了提到这个脚本是进入汽车的后轮,而不是实际的汽车对象。

【问题讨论】:

  • 不能在函数外使用函数。在WHEELSPIN 脚本中,将hinge = GetComponent&lt;HingeJoint&gt;(); 移动到一个函数中。对motor = hinge.motor; 和它下面的代码执行相同的操作,Update 函数中的代码除外。
  • hinge.motor = float motorz; 语法无效。
  • @Dennis_E 它部分有效,但我需要知道它是如何无效的。去除浮动有帮助吗?另外,现在我收到一条错误消息,说 motorz 不存在。
  • @DavZRazorbladesDJDavZ 我不知道您要做什么,所以我无法回答。但是浮动不允许在spot。正如程序员所说,您不能在方法之外调用该代码。
  • 这条线应该做什么? hinge.motor = float motorz; 因为它看起来像胡言乱语。

标签: c# debugging unity3d


【解决方案1】:

在 WheelSpin 类中,您在类的构造函数中分配铰链。然而,单一行为是由 Unity 引擎任意构造的(当 Unity 序列化类实例时,这可能由于很多原因而发生)。相反,应该使用 Start() 和 Awake() 回调来初始化变量。

【讨论】:

  • 我不认为代码意味着它在类的构造函数中分配铰链。它根本不编译!所以它与Unity引擎无关。此外,对于 MonoBehaviours,公共无参数构造函数实际上是有效的(也就是说,它不会破坏事物)。我怀疑 Unity 使用 Activator.CreatInstance() 反序列化对象,因此除了公共无参数构造函数之外,您不应定义任何构造函数。
【解决方案2】:

我无法对此进行测试,因为我没有您正在使用的库,但这应该会有所帮助....

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

public class WHEELSPIN : MonoBehaviour 
{

    HingeJoint hinge;
    JointMotor motorz;

    private void Awake()
    {
        hinge = GetComponent<HingeJoint>();
        motorz = hinge.motor;
        hinge.useMotor = true;
        motorz.freeSpin = true;
    }

    private void Update() 
    {       
        if (Input.GetAxis("Vertical") > 0f) 
        {
            motorz.force = 1000;
            motorz.targetVelocity = 900;
        }
    }
}

【讨论】:

  • 为什么会有帮助?
  • 至少这是可构建的并且似乎很有意义
  • 感谢脚本,它没有错误,但它不会转动轮子。我会尝试解决这个问题。
【解决方案3】:

我猜你对字段初始化器感到困惑。但在解释什么是字段初始值设定项之前,我应该先从如何正确​​定义一个开始。

c# 中的类就像现实世界中的合同或模具。定义类后,您可以使用它来创建实例(就像使用模具在现实世界中铸造对象一样)。同一类的每个实例都遵循该类中定义的行为。它有一定的字段来存储数据和方法来操作。

这是一个类的通常定义方式:

// Double slashes starts a one-line comment
// Comments will be **ignored** when the program is running
// So comments are actually memos for programmers
// Here the class is named as "Creature"
class Creature
{
    // Here you can put some fields that will be used to store data
    int _heathPoint;

    // _healthPoint = 10; // Not permitted because this is not a field declaration

    // Here you can define methods that can be operated with
    public void DoSomething()
    {
        // A method can be empty, just do nothing.
    }
}

您可能会看到,在这个类中,我定义了一个字段_healthPoint 和一个方法DoSomething,仅此而已。事实上,在类的“范围”内(class 关键字后面的第一级花括号包围的区域),只有 字段和方法声明是允许的(嗯,不完全是,你实际上可以添加嵌套类。但这超出了本问答的范围)。

如果您创建类Creature 的新实例,该实例将具有一个整数字段_heathPoint 和一个方法DoSomething。但是它的领域的价值是什么?在上面的定义中,它没有任何关于初始值的说明,所以_healthPoint 将被设置为其默认 值:这意味着0 用于int 数据。

在大多数情况下,这样的字段值默认值并不是我们想要的。在我们的例子中,将Creature 实例的初始_healthPoint 设置为0 是没有任何意义的。假设我们希望它的初始 _healthPoint100。我们可以这样做:

class Creature
{
    int _heathPoint;

    // Below is something new.
    // Please note that although it looks like an ordinary method like DoSomething(),
    // it lacks the return type and has the same name as the class name
    // Such a method is called **constructor**
    public Creature()
    {
        _healthPoint = 100;
    }

    public void DoSomething()
    {
    }
}

在这里您可以看到我们添加了一个新方法,该方法与其宿主类同名。这种方法称为构造函数。顾名思义,当您尝试构造类的实例时,会自动调用构造函数。
然而,这并不意味着构造函数会创建实例,它们实际上是用于初始化 个实例。调用构造函数时,已经创建了实例。但细节超出了这里的范围。
您需要知道的是,这里Creature 的构造函数在创建Creature 的新实例时将_healthPoint 的值初始化为100
但是,如果我们在一个类中有一百个字段需要初始化呢?在构造函数中一一初始化它们会很乏味且容易出错。
所以字段初始化器来拯救。除了在构造函数中显式初始化字段外,还可以使用字段初始化器为字段设置初始值在它们被声明的地方。这是我们示例中的样子:

class Creature
{
    // Here the = 100 part is the field initializer
    int _heathPoint = 100;
    // Each field can only have one initializer
    // So the line below is wrong and will not compile
    // _healthPoint = 30; // wrong because _heathPoint has been declared above

    public Creature()
    {
        // Do not need to do anything because the field initializer does what we want
    }

    public void DoSomething()
    {
    }
}

在这里您可能会看到字段声明 int _healthPoint; 变为 int _healthPoint = 100;。这意味着我们定义类Creature的所有实例将有一个名为_healthPoint的字段,我们希望将其值初始化为100
更有趣的是,您可以在赋值运算符 = 之后放置任何内容,只要它评估为声明字段的类型(在我们的例子中为 int)。
所以int _healthPoint = 100 + 20; 是有效的,int _healthPoint = Int.Parse("100"); 也是有效的。 (你可以试试看!)

回到你原来的代码,我看到你似乎试图初始化你的字段(尤其是hinge)。我希望从上面的解释中你现在明白hinge.useMotor = true; 是无效的,因为它不是字段声明,也不是字段初始值设定项的一部分。

好的,那么如果我们真的想初始化hinge 呢?还记得字段初始值设定项可以是对字段类型求值的任何东西吗?这意味着我们可以在一个方法中进行我们的初始化,并让字段初始化器调用该方法,例如:

class ExampleClass : MonoBehaviour
{
    HingeJoint hinge = InitializeHinge();

    private HingeJoint InitializeHinge()
    {
        // Note that the line below compiles but may not run or will report runtime error
        // I am not sure if you can call GetComponent() in field initializer
        HingeJoint returnValue = GetComponent<HingeJoint>();
        returnValue.useMotor = true;
        return returnValue;
    }
}

这样,一旦创建了ExampleClass 的实例,其字段hinge 将被初始化为GetComponent&lt;HingeJoint&gt;() 返回的HingeJoint,并将其useMotor 字段设置为true

【讨论】:

  • 哦,现在我明白了!我可以在 void start 中初始化铰链吗?还是我必须创建一个像私有 HingeJoint InitialiseHinge 这样的自定义?
  • 当然你可以在Start中初始化铰链,因为Unity保证任何派生MonoBehaviour的类的Start在任何Update被调用之前被调用一次。但是,如果你从其他类访问这个对象(这个类的一个实例),你可能需要确保你所有的初始化都已经完成,比如一个方向盘可能会改变这个轮子的方向。
  • 或者正如其他答案所暗示的,您也可以在Awake 中初始化。您可以查看它们之间的差异here。由于执行顺序,Unity 中的初始化/终结(特别是MonoBehaviours)可能会出现很多问题。但是恕我直言,您可以在当前阶段忽略这些问题,实现您想要的任何功能,让生活更轻松。
猜你喜欢
  • 1970-01-01
  • 2014-05-29
  • 2013-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-07
相关资源
最近更新 更多