@@ -137,7 +137,9 @@ public void Set(InputActionAsset asset, string mapName, string actionName)
137137
138138 private void SetInternal ( InputActionAsset assetArg , InputAction actionArg )
139139 {
140- CheckImmutableReference ( ) ;
140+ #if UNITY_EDITOR
141+ s_CheckImmutableReference ? . Invoke ( this ) ;
142+ #endif
141143
142144 // If we are setting the reference in edit-mode, we want the state to be reflected in the serialized
143145 // object and hence assign serialized fields. This is a destructive operation.
@@ -207,13 +209,6 @@ public static InputActionReference Create(InputAction action)
207209 /// This method is used to clear the Action references when exiting PlayMode since those objects are no
208210 /// longer valid.
209211 /// </remarks>
210- #if UNITY_EDITOR
211- // Callbacks set by Editor to check asset status without direct UnityEditor dependency
212- internal static Func < Object , bool > s_IsSubAsset ;
213- internal static Func < Object , string > s_GetAssetPath ;
214- internal static Func < string , Object > s_LoadMainAssetAtPath ;
215- #endif
216-
217212 internal static void InvalidateAll ( )
218213 {
219214 // It might be possible that Object.FindObjectOfTypeAll(true) would be sufficient here since we only
@@ -224,6 +219,14 @@ internal static void InvalidateAll()
224219 ( ( InputActionReference ) obj ) . Invalidate ( ) ;
225220 }
226221
222+ #if UNITY_EDITOR
223+ /// <summary>
224+ /// Set by the editor to prevent mutating <see cref="InputActionReference"/> sub-assets inside
225+ /// <see cref="InputActionAsset"/> files. Not used in player builds.
226+ /// </summary>
227+ internal static Action < InputActionReference > s_CheckImmutableReference ;
228+ #endif
229+
227230 /// <summary>
228231 /// Clears the cached <see cref="m_Action"/> field for this <see cref="InputActionReference"/> instance.
229232 /// </summary>
@@ -256,65 +259,5 @@ public InputAction ToInputAction()
256259 {
257260 return action ;
258261 }
259-
260- /// <summary>
261- /// Checks if this input action reference instance can be safely mutated without side effects.
262- /// </summary>
263- /// <remarks>
264- /// This check isn't needed in player builds since ScriptableObject would never be persisted if mutated
265- /// in a player.
266- /// </remarks>
267- /// <exception cref="InvalidOperationException">Thrown if this input action reference is part of an
268- /// input actions asset and mutating it would have side-effects on the projects assets.</exception>
269- private void CheckImmutableReference ( )
270- {
271- #if UNITY_EDITOR
272- // Prevent accidental mutation of the source asset if this InputActionReference is a persisted object
273- // residing as a sub-asset within a .inputactions asset.
274- // This is not needed for players since scriptable objects aren't serialized back from within a player.
275- if ( ! CanSetReference ( ) )
276- {
277- throw new InvalidOperationException ( "Attempting to modify an immutable InputActionReference instance " +
278- "that is part of an .inputactions asset. This is not allowed since it would modify the source " +
279- "asset in which the reference is serialized and potentially corrupt it. " +
280- "Instead use InputActionReference.Create(action) to create a new mutable " +
281- "in-memory instance or serialize it as a separate asset if the intent is for changes to " +
282- "survive domain reloads." ) ;
283- }
284- #endif // UNITY_EDITOR
285- }
286-
287- #if UNITY_EDITOR
288- // Note that we do a lot of checking here, but it is only for a rather slim (unintended) use case in
289- // editor and not in final builds. The alternative would be to set a non-serialized field on the reference
290- // when importing assets which would simplify this class, but it adds complexity to import stage and
291- // is more difficult to assess from a asset version portability perspective.
292- private bool CanSetReference ( )
293- {
294- // If callbacks aren't set, allow the operation
295- if ( s_IsSubAsset == null || s_GetAssetPath == null || s_LoadMainAssetAtPath == null )
296- return true ;
297-
298- // "Immutable" input action references are always sub-assets of InputActionAsset.
299- var isSubAsset = s_IsSubAsset ( this ) ;
300- if ( ! isSubAsset )
301- return true ;
302-
303- // If we cannot get the path of our reference, we cannot be a persisted asset within an InputActionAsset.
304- var path = s_GetAssetPath ( this ) ;
305- if ( path == null )
306- return true ;
307-
308- // If we cannot get the main asset we cannot be a persisted asset within an InputActionAsset.
309- // Also we check that it is the expected type.
310- var mainAsset = s_LoadMainAssetAtPath ( path ) ;
311- if ( ! mainAsset )
312- return true ;
313-
314- // We can only allow setting the reference if it is not part of an persisted InputActionAsset.
315- return ( mainAsset is not InputActionAsset ) ;
316- }
317-
318- #endif // UNITY_EDITOR
319262 }
320263}
0 commit comments