Getting error “Operator '+=' is ambiguous on operands of type 'Vector3' and 'Vector2'”

前端 未结 1 2027
长发绾君心
长发绾君心 2021-01-27 02:48

While trying to build I\'m getting this error:

Operator \'+=\' is ambiguous on operands of type \'Vector3\' and \'Vector2\'

Here is

相关标签:
1条回答
  • 2021-01-27 03:25

    Vector2 has implicit conversion to and from Vector3, but they are not really equivalent, with Vector2 having only X and Y components, while Vector3 has X, Y and Z.

    When you try to use someVector3 += someVector2 (or vice-versa), both += operators, from Vector3 and Vector2, are valid.

    The compiler cannot be sure of which one you want to use, so that exception is it's way of telling you it can't safely make a decision, and you need to give it a non-ambiguous set of types to work with. In this case, both sides need to be Vector2 or Vector3; not a mix.

    You can do that in 2 ways:

    1. Working with the compatible type from the start, which is what @Ruzihm already pointed out in the comments.
    2. Or you can cast the second operand in-place: transform.position += (Vector3)movement * Time.deltaTime * moveSpeed;

    Apart from that, I can also see an unhealthy mix of the two types in other portions of the code. I'd strongly suggest you to be consistent. If you are working with 2D, use Vector2s.

    Vector2 has it's own constructor. And the Vector3 constructor with 2 parameters only makes the Z default to zero; it does not create a Vector2.

    The only reason it works in the first place is that the compiler is using that implicit conversion I talked about above. That, however, has a performance cost.

    • rigidbody.AddForce(new Vector2(0f, 5f), ForceMode2D.Impulse);
    • Vector2 movement = new Vector2(value, 0f); (Or Vector3movement)

    A detail I only learned recently myself is that Unity only syncs Transforms in Update, while movement of a Rigidbody (2D or 3D) is only synced in FixedUpdate. This can cause issues when you set Transform.position on a Rigidbody'ed object.

    And that is one of the reasons why so many sources tell you to "do physics stuff in FixedUpdate". However, while other stuff related to forgetting Time.deltaTime can happen, as long as the transform and rigidbody are not desynced, you can set position directly. You do that by using Rigidbody.position instead of Transform.position.

    An additional nicety of this is that Rigidbody2D.position is a Vector2, eliminating the need to work with Vector3 or cast for that += operation entirely.

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

    One last thing, although it is definitely premature-optimization

    0 讨论(0)
提交回复
热议问题