If a struct
type has not been given any particular value, it will usually default to a special value helpfully called default
. (Though it's possible the file loading code you use does something different — you haven't shown us, so I'm assuming it's following standard C# convention).
The members of default
will each hold the value corresponding to the default
of their respective types: 0 for numbers, falsefalse
for booleans, null
for reference types, etc.
So you can check:
if (!position.Equals(default)) {/*...*/}
if (rotation != default) {/*...*/}
For a Vector3
, the default value is the same as Vector3.zero
, ie. (0, 0, 0), just less typing, and a bit more explicit that you're checking if it's a default value not looking for a deliberately-set value of zero.
But that highlights a bit of an issue with this code: it won't distinguish between loading an item for which no position
was set, versus loading an item that was set to (0, 0, 0)
deliberately.
If that distinction is important for your loading logic, then as others have suggested, you may want to change the declaration of your variable to:
[SerializeField]
Vector3? position;
This makes it a "nullable" struct — it's still a value type, but it gains an extra flag that tracks whether a value has been set.
You can check this with:
if (!position.HasValue) {/*...*/}
or, for convenience, position == null
translates to this for nullable types.
Then, to access the Vector3
contents, you'd write position.Value
.
You'll note that I used the .Equals()
method instead of ==
above. That's because the equality operator for Vector3
has a built-in tolerance, so a vector very close to zero but not actually zero will return true
if you compare it to a zero vector with ==
. The .Equals()
method only returns true
for an exact match.
For quaternions, you have a somewhat easier time, in that any valid quaternion will have a non-zero value. ie. Quaternion.Dot(rotation, rotation)
should be close to 1.0 — even for Quaternion.identity
, which is (0, 0, 0, 1) (in x, y, z, w order).
So if you ever read an all-zero quaternion (like default
), you can be sure that was not a deliberately set value, and needs to be overridden.
The difference between an all-zero quaternion and a valid one is much larger than the tolerance used in the ==
operator, so you don't strictly need the .Equals()
method in this case.