得到错误“运算符'+ ='在类型为'Vector3'和'Vector2'的操作数上不明确”

时间:2019-09-14 16:06:13

标签: c# unity3d

在尝试构建时出现此错误:

  

运算符'+ ='在类型为'Vector3'和'Vector2'的操作数上不明确

以下是问题所在的脚本代码:

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

public class Move2D : MonoBehaviour
{
    public float moveSpeed = 5f;
    public bool isGrounded = false;

    [SerializeField] private Rigidbody2D rigidbody;

    private void Awake()
    {
        if (!rigidbody) rigidbody = GetComponent<Rigidbody2D>();
    }

    public void Jump()
    {
        if (isGrounded)
        {
            rigidbody.AddForce(new Vector3(0f, 5f), ForceMode2D.Impulse);
        }
    }

    public void Move(float value)
    {
        Vector2 movement = new Vector3(value, 0f, 0f);
        transform.position += movement * Time.deltaTime * moveSpeed;
    }
}

任何帮助或信息都非常感谢!

1 个答案:

答案 0 :(得分:1)

Vector2具有往返于Vector3的隐式转换,但它们并不是真正等效的,Vector2仅具有X和Y分量,而Vector3具有X,Y和Z。

当您尝试使用someVector3 += someVector2时(反之亦然),Vector3和Vector2中的两个+=运算符都是有效的。

编译器无法确定要使用哪个编译器,因此,例外情况是它告诉您无法安全地做出决定,并且需要为它提供一组明确的类型来使用。在这种情况下,双方都必须是Vector2或Vector3;不能混在一起。

您可以通过以下两种方式进行操作:

  1. 从一开始就使用兼容类型which is what @Ruzihm already pointed out in the comments
  2. 或者您可以将第二个操作数转换为原位:transform.position += (Vector3)movement * Time.deltaTime * moveSpeed;

除此之外,我还可以在代码的其他部分看到两种类型的不健康混合。我强烈建议您保持一致。如果使用2D,请使用Vector2s。

Vector2有它自己的构造函数。而带有2个参数的Vector3构造函数仅使Z默认为零;它不会创建Vector2。

它首先起作用的唯一原因是编译器正在使用我在上文中谈到的隐式转换。但是,这会降低性能。

  • rigidbody.AddForce(new Vector 2 (0f, 5f), ForceMode2D.Impulse);
  • Vector2 movement = new Vector 2 (value, 0f);(或Vector 3 movement

我最近才刚刚了解到的一个细节是,Unity仅在Update中同步变换,而刚体(2D或3D)的运动仅在FixedUpdate中同步。在刚体对象上设置Transform.position时,这可能会导致问题。

这就是为什么这么多资源告诉您“在FixedUpdate中做物理工作”的原因之一。但是,尽管可能发生与遗忘Time.deltaTime有关的其他事情,但是只要不使变换和刚体不同步,就可以直接设置position。您可以使用Rigidbody.position而不是Transform.position来做到这一点。

另一个好处是Rigidbody2D.position是一个Vector2,无需使用Vector3或完全为该+=操作进行强制转换。

public void Move(float value) {
    var movement = new Vector2(value, 0f);
    rigidbody.position += movement * Time.deltaTime * moveSpeed;
}

最后一件事,尽管它肯定是 premature-optimization?(尽管不是坏种类,因为在这种情况下它对可读性的影响为零) ,就是您可以在“ {-1}}

处进行“ vector-last”保存乘法操作

in this other answer解释了原因。