ISXB-512, ISXB-521 Fix TrackedPoseDriver serialization migration#1705
ISXB-512, ISXB-521 Fix TrackedPoseDriver serialization migration#1705jamesmcgill merged 9 commits intodevelopfrom
Conversation
- Removed the no longer necessary m_HasMigratedActions field since it only copies over from the old deprecated fields if the new property has not been initialized. - This fix still does not fix the issue of nested prefabs where the parent prefab has an override to add a new input binding. The base prefab will already have the InputActionProperty upgraded, so the modified old deprecated field with the additional singleton bindings doesn't get copied over to the new property. There doesn't seem to be a way to reliably detect this situation.
…generated for actions in constructor - When adding a serialized InputAction (or with an InputActionProperty), the ID Guid may not be generated, which could cause noise in prefab overrides. Having the constructor generate an ID initially instead of relying on the id property or property drawer generate one and write to the asset makes it more consistent. This specifically fixes the GameObject > XR > XR Origin (VR) creation shortcut not having IDs set since the Inspector is never visible before making a prefab.
| ### Changed | ||
| - Changed the `InputAction` constructors so it generates an ID for the action and the optional binding parameter. This is intended to improve the serialization of input actions on behaviors when created through API when the property drawer in the Inspector window does not have a chance to generate an ID. | ||
|
|
||
| ### Fixed | ||
| - Fixed serialization migration in the Tracked Pose Driver component causing bindings to clear when prefabs are used in some cases ([case ISXB-512](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-512), [case ISXB-521](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-521)). | ||
| - Fixed the `Clone` methods of `InputAction` and `InputActionMap` so it copies the Initial State Check flag (`InputAction.wantsInitialStateCheck`) of input actions. | ||
|
|
There was a problem hiding this comment.
I think we missed the window on 1.6.2, but I'll talk to Lyndon about fast-tracking another patch release to fix this.
There was a problem hiding this comment.
It was a bad merge, I fixed it by moving it from 1.6.2 to Unreleased.
jamesmcgill
left a comment
There was a problem hiding this comment.
Looks good.
You might need to pull in latest develop to fix up the Dry Run failures there (likely requires another CHANGELOG)
| [SerializeField] private bool m_UseReference; | ||
| [SerializeField] private InputAction m_Action; | ||
| [SerializeField] private InputActionReference m_Reference; | ||
| [SerializeField] internal bool m_UseReference; |
There was a problem hiding this comment.
Would testing InputActionProperty.action for null rather than exposing these fields have the same result in TrackedPoseDriver?
It's implementation is:
public InputAction action => m_UseReference ? m_Reference != null ? m_Reference.action : null : m_Action;
which I think will return null in all cases m_Reference and m_Action will both be null.
Otherwise perhaps adding a new member here rather than exposing the private fields so that the TrackedPoseDriver code is not so dependent on how this is implemented.
There was a problem hiding this comment.
It wouldn't be exactly the same. If a user clicked Use Reference to toggle the value in the Inspector window, the action property might start evaluating to null but one of its fields is already set. I wanted the migration code in TPD to skip copying the value from the old serialized field if any InputActionProperty value had already been created.
Instead of making the fields internal, I could expose all the serialized fields in new public properties, which goes along with the Unity coding style rules that all Inspector window values are accessible through API, but that would be an API addition and thus this PR couldn't be included in a patch release.
There was a problem hiding this comment.
Ah right, I get the logic now.
There is another PR incoming that looks like it will need a minor bump, so now might be a good opportunity for getting something in (#1701).
m_Reference and m_Action have public properties already though and adding alternative versions of those that don't hold the invariants might be confusing. I don't know if exposing just m_UseReference will be enough for you to work with?
Alternatively perhaps another method like IsEmpty or IsNull to make the code in TrackedPoseDriver simple.
There was a problem hiding this comment.
Even if I added a property for m_UseReference, I wouldn't be able to duplicate the logic exactly.
To try to address this feedback, I added new internal getter properties for the m_Action and m_Reference fields and reverted the fields back to private, and updated TPD to use those instead.
In the future, we can make them public and potentially add setters along with a property for m_UseReference, but we were scheduling to include this bug fix in a patch release so we can't add public properties yet.
# Conflicts: # Packages/com.unity.inputsystem/CHANGELOG.md
…ernal - We can potentially make the new properties public and even add setters along with a property for useReference, but this way of keeping them internal will avoid having to bump minor version to fix this bug.
# Conflicts: # Packages/com.unity.inputsystem/CHANGELOG.md
Description
Fixes an issue where the bindings were cleared due to invalid serialization migration logic in some cases.
Changes made
Modified the serialization logic so it won't replace the newer InputActionProperties if either the reference or embedded input action are already set.
I also made some other fixes I discovered while fixing the above:
Currently, the IDs of Input Actions are generated automatically when calling the
idproperty or when the InputAction property drawer draws the field. However, if you create a GameObject and add a component with one serialized through API, them_Idfield wouldn't be generated in the serialized asset. This was causing the GameObject > XR > XR Origin (VR) rig created to not have those fields set since it was on a child GameObject. If a user dragged the root to create a prefab, when they would click on the child GameObject in the prefab or in the Hierarchy window, it would create a prefab override with new generated IDs. This change makes the constructor generate an ID so that it doesn't need to be visible in the Inspector window to be generated.Also fixed the
Clonemethods to have it copy them_Flagsfield so that the Initial State Check checkbox is copied.Notes
This fix still does not fix the issue of nested prefabs where the parent prefab has an override to add a new input binding. The base prefab will already have the
InputActionPropertyupgraded, so the modified old deprecated field with the additional singleton bindings doesn't get copied over to the new property. There doesn't seem to be a way to reliably detect this situation. However, this is already the case with the old migration method, so it doesn't make it worse.It's still possible for a prefab instance to have a noisy prefab override of the action name since the name, like the ID, is generated by the property drawer. However, if you create the InputAction with a non-empty name argument, it won't have that issue.
Checklist
Before review:
Changed,Fixed,Addedsections.([case %number%](https://issuetracker.unity3d.com/issues/...)).Area_CanDoX,Area_CanDoX_EvenIfYIsTheCase,Area_WhenIDoX_AndYHappens_ThisIsTheResult.During merge:
NEW: ___.FIX: ___.DOCS: ___.CHANGE: ___.RELEASE: 1.1.0-preview.3.