Skip to content

NEW: Object picker for InputActionReference combining results from Project-wide Input Actions Asset and Project Input Actions Assets #1768

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
8a40bb6
wip
ekcoh Oct 5, 2023
c5b7cff
wip object picker for Input Action References
ekcoh Oct 5, 2023
d7dd88c
Simplified the advance picker workflow. Add a MonoBehavior to test pi…
lochrist Oct 5, 2023
feba8d4
Refactoring
ekcoh Oct 5, 2023
cece135
Create advance picker in UITK
lochrist Oct 5, 2023
48abd7f
Modified description to be possible to decipher when min zoom mode (f…
ekcoh Oct 5, 2023
98d9b30
Fixed duplicates returned when loading project settings asset, modifi…
ekcoh Oct 6, 2023
54eb471
Merge branch 'develop' into inspector-poc
ekcoh Oct 6, 2023
260e8b3
Modified property drawer to rely on UITK to avoid bug in IMGUI versio…
ekcoh Oct 6, 2023
b2ec69c
Added workaround for Unity older than 2022_2
ekcoh Oct 6, 2023
f261264
Minor refactoring and cleanup relating to implemented functionality. …
ekcoh Oct 9, 2023
ae426ee
Fixed problem in InputActionAsset importer
ekcoh Oct 9, 2023
1fd79e5
Removed test files that should never have been part of PR
ekcoh Oct 9, 2023
1181c67
Simplified code, adressed filter from review.
ekcoh Oct 9, 2023
46f677c
Merge branch 'develop' into inspector-poc
ekcoh Oct 9, 2023
efe707f
Removed comment that is obsolete due to it commenting on an internal …
ekcoh Oct 9, 2023
33f11da
Merge branch 'inspector-poc' of github.com:Unity-Technologies/InputSy…
ekcoh Oct 9, 2023
909cfa2
Merge branch 'develop' into inspector-poc
ekcoh Oct 9, 2023
f15abff
Merge branch 'develop' into inspector-poc
ekcoh Oct 11, 2023
51b78c6
wip
ekcoh Oct 18, 2023
203e978
Merge branch 'develop' into inspector-poc
jfreire-unity Oct 19, 2023
2c76576
Change asset search provider to same logic as project-wide actions pr…
jfreire-unity Oct 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion Assets/Tests/InputSystem/CoreTests_Actions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9307,7 +9307,6 @@ public void Actions_CanApplyOverrideToActionWithEmptyBinding()
action.Disable();
action.ApplyBindingOverride(0, "/gamepad/leftTrigger");
action.Enable();

Press(gamepad.leftTrigger);

Assert.That(performed);
Expand Down Expand Up @@ -9550,6 +9549,36 @@ public void Actions_CanResolveActionReference()

Assert.That(referencedAction, Is.SameAs(action2));
}

[Test]
[Category("Actions")]
public void Actions_CanResolveActionReference_WhenUsingToInputActionToConstructANewReference()
{
var map = new InputActionMap("map");
map.AddAction("action1");
var action2 = map.AddAction("action2");
var asset = ScriptableObject.CreateInstance<InputActionAsset>();
asset.AddActionMap(map);

var reference = ScriptableObject.CreateInstance<InputActionReference>();
reference.Set(asset, "map", "action2");

var copy1 = InputActionReference.Create(reference.action);
var copy2 = InputActionReference.Create(reference.ToInputAction());

// Expecting action to be the same
Assert.That(reference.action, Is.SameAs(copy1.action));
Assert.That(reference.action, Is.SameAs(copy2.action));
}

[Test]
[Category("Actions")]
public void Actions_CanImplicitlyConvertReferenceToAction_WhenAssigningActionFromReference()
{
var reference = ScriptableObject.CreateInstance<InputActionReference>();
InputAction action = reference; // implicit conversion
Assert.That(reference.action, Is.Null);
}
Comment on lines +9553 to +9581
Copy link
Collaborator

@jfreire-unity jfreire-unity Oct 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unclear to me why these tests are needed in this PR as they seem to be unrelated to the object picker. Maybe I'm missing something or this is just being used for testing.


[Test]
[Category("Actions")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.InputSystem.Utilities;

////TODO: make the FindAction logic available on any IEnumerable<InputAction> and IInputActionCollection via extension methods
Expand Down Expand Up @@ -924,11 +923,41 @@ private void OnDestroy()
}
}

#if UNITY_EDITOR

private void OnValidate()
{
// Only currently validates references if serialized property has been set to true
if (m_ValidateReferencesInEditMode)
Editor.InputActionReferenceValidator.ValidateReferences(this);
}

#endif

internal InputAction FindActionById(string actionId)
{
if (m_ActionMaps == null)
return null;

foreach (var t in m_ActionMaps)
{
var action = t.FindAction(actionId);
if (action != null)
return action;
}

return null;
}

////TODO: ApplyBindingOverrides, RemoveBindingOverrides, RemoveAllBindingOverrides

[SerializeField] internal InputActionMap[] m_ActionMaps;
[SerializeField] internal InputControlScheme[] m_ControlSchemes;

// Note: not serialized to JSON only as asset objects
[NonSerialized] internal InputActionReference[] m_References; // TODO Tentative
[SerializeField] internal bool m_ValidateReferencesInEditMode;// TODO Tentative

////TODO: make this persistent across domain reloads
/// <summary>
/// Shared state for all action maps in the asset.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using UnityEditor;

////REVIEW: Can we somehow make this a simple struct? The one problem we have is that we can't put struct instances as sub-assets into
//// the import (i.e. InputActionImporter can't do AddObjectToAsset with them). However, maybe there's a way around that. The thing
Expand Down Expand Up @@ -160,6 +161,29 @@ public override string ToString()
return base.ToString();
}

#if UNITY_EDITOR

private void OnEnable()
{
// This is invoked after InputActionReference deserialization
if (m_Action == null && m_Asset != null)
{
m_Action = m_Asset.FindActionById(m_ActionId);
Invalidate();
}
}

internal void Invalidate()
{
// TODO Check if it makes a difference to do full re-evaluation here (only to see if reference invalidation for asset is broken)

// Reflect action name as the name of this SerializableObject
if (m_Action != null)
name = GetDisplayName(m_Action);
}

#endif // #if UNITY_EDITOR

private static string GetDisplayName(InputAction action)
{
return !string.IsNullOrEmpty(action?.actionMap?.name) ? $"{action.actionMap?.name}/{action.name}" : action?.name;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#if UNITY_EDITOR
using UnityEditor;

namespace UnityEngine.InputSystem.Editor
{
/// <summary>
/// Provides access to icons associated with <code>InputActionAsset</code>.
/// </summary>
internal static class InputActionAssetIconProvider
{
private const string kActionIcon = "Packages/com.unity.inputsystem/InputSystem/Editor/Icons/InputAction.png";
private const string kAssetIcon = "Packages/com.unity.inputsystem/InputSystem/Editor/Icons/InputActionAsset.png";

/// <summary>
/// Attempts to load the icon associated with an <code>InputActionAsset</code> (.inputactions) asset.
/// </summary>
/// <returns>Icon resource reference or <code>null</code> if the resource could not be loaded.</returns>
public static Texture2D LoadAssetIcon()
{
return (Texture2D)EditorGUIUtility.Load(kAssetIcon);
}

/// <summary>
/// Attempts to load the icon associated with an <code>InputActionReference</code> sub-asset of an
/// <code>InputActionAsset</code> (.inputactions) asset.
/// </summary>
/// <returns>Icon resource reference or <code>null</code> if the resource could not be loaded.</returns>
public static Texture2D LoadActionIcon()
{
return (Texture2D)EditorGUIUtility.Load(kActionIcon);
}
}
}

#endif // #if UNITY_EDITOR

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
Expand Down Expand Up @@ -29,9 +30,6 @@ internal class InputActionImporter : ScriptedImporter
{
private const int kVersion = 13;

private const string kActionIcon = "Packages/com.unity.inputsystem/InputSystem/Editor/Icons/InputAction.png";
private const string kAssetIcon = "Packages/com.unity.inputsystem/InputSystem/Editor/Icons/InputActionAsset.png";

[SerializeField] private bool m_GenerateWrapperCode;
[SerializeField] private string m_WrapperCodePath;
[SerializeField] private string m_WrapperClassName;
Expand Down Expand Up @@ -88,8 +86,8 @@ public override void OnImportAsset(AssetImportContext ctx)

// Load icons.
////REVIEW: the icons won't change if the user changes skin; not sure it makes sense to differentiate here
var assetIcon = (Texture2D)EditorGUIUtility.Load(kAssetIcon);
var actionIcon = (Texture2D)EditorGUIUtility.Load(kActionIcon);
var assetIcon = InputActionAssetIconProvider.LoadAssetIcon();
var actionIcon = InputActionAssetIconProvider.LoadActionIcon();

// Add asset.
ctx.AddObjectToAsset("<root>", asset, assetIcon);
Expand Down Expand Up @@ -212,12 +210,50 @@ public override void OnImportAsset(AssetImportContext ctx)
InputActionEditorWindow.RefreshAllOnAssetReimport();
}

internal static IEnumerable<InputActionReference> LoadInputActionReferencesFromAsset(InputActionAsset asset)
{
//Get all InputActionReferences are stored at the same asset path as InputActionAsset
return AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(asset)).Where(
o => o is InputActionReference).Cast<InputActionReference>();
}

internal static IEnumerable<InputActionReference> LoadInputActionReferencesFromAssetDatabase(string[] folderPath = null)
{
string[] searchInFolderPath = null;
// If folderPath is null, search in "Assets" folder.
if (folderPath == null)
{
searchInFolderPath = new string[] { "Assets" };
}

// Get all InputActionReference from assets in "Asset" folder. It does not search inside "Packages" folder.
var inputActionReferenceGUIDs = AssetDatabase.FindAssets($"t:{typeof(InputActionReference).Name}", searchInFolderPath);

// To find all the InputActionReferences, the GUID of the asset containing at least one action reference is
// used to find the asset path. This is because InputActionReferences are stored in the asset database as sub-assets of InputActionAsset.
// Then the whole asset is loaded and all the InputActionReferences are extracted from it.
// Also, the action references are duplicated to have backwards compatibility with the 1.0.0-preview.7. That
// is why we look for references withouth the `HideFlags.HideInHierarchy` flag.
var inputActionReferencesList = new List<InputActionReference>();
foreach (var guid in inputActionReferenceGUIDs)
{
var assetName = AssetDatabase.GUIDToAssetPath(guid);
var assetInputActionReferenceList = AssetDatabase.LoadAllAssetsAtPath(assetName).Where(
o => o is InputActionReference &&
!((InputActionReference)o).hideFlags.HasFlag(HideFlags.HideInHierarchy))
.Cast<InputActionReference>().ToList();

inputActionReferencesList.AddRange(assetInputActionReferenceList);
}
return inputActionReferencesList;
}

// Add item to plop an .inputactions asset into the project.
[MenuItem("Assets/Create/Input Actions")]
public static void CreateInputAsset()
{
ProjectWindowUtil.CreateAssetWithContent("New Controls." + InputActionAsset.Extension,
InputActionAsset.kDefaultAssetLayoutJson, (Texture2D)EditorGUIUtility.Load(kAssetIcon));
InputActionAsset.kDefaultAssetLayoutJson, InputActionAssetIconProvider.LoadAssetIcon());
}
}
}
Expand Down
Loading