diff --git a/Assets/Samples/CustomComposite/CustomComposite.cs b/Assets/Samples/CustomComposite/CustomComposite.cs index 6c26fb1db1..003c30acb6 100644 --- a/Assets/Samples/CustomComposite/CustomComposite.cs +++ b/Assets/Samples/CustomComposite/CustomComposite.cs @@ -177,7 +177,7 @@ public override void OnGUI() target.scaleFactor = EditorGUILayout.Slider(m_ScaleFactorLabel, currentValue, 0, 2); } -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS public override void OnDrawVisualElements(VisualElement root, Action onChangedCallback) { var slider = new Slider(m_ScaleFactorLabel.text, 0, 2) diff --git a/Assets/Samples/InGameHints/InGameHintsActions.cs b/Assets/Samples/InGameHints/InGameHintsActions.cs index 69dd7b0cde..27c8d642f9 100644 --- a/Assets/Samples/InGameHints/InGameHintsActions.cs +++ b/Assets/Samples/InGameHints/InGameHintsActions.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was auto-generated by com.unity.inputsystem:InputActionCodeGenerator -// version 1.7.0 +// version 1.8.0 // from Assets/Samples/InGameHints/InGameHintsActions.inputactions // // Changes to this file may cause incorrect behavior and will be lost if diff --git a/Assets/Samples/ProjectWideActionsTest.meta b/Assets/Samples/ProjectWideActionsTest.meta new file mode 100644 index 0000000000..efb99bbd41 --- /dev/null +++ b/Assets/Samples/ProjectWideActionsTest.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bd9dcc5a3e3502b42b13e8ad113ab8f1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.asmdef b/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.asmdef new file mode 100644 index 0000000000..e64fd2edc5 --- /dev/null +++ b/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.asmdef @@ -0,0 +1,22 @@ +{ + "name": "ProjectWideActionsTest", + "rootNamespace": "", + "references": [ + "GUID:75469ad4d38634e559750d17036d5f7c" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "Unity", + "expression": "2022.3", + "define": "UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS" + } + ], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.asmdef.meta b/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.asmdef.meta new file mode 100644 index 0000000000..9004363bf3 --- /dev/null +++ b/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 472aaae9fe1ef1f478743ae4c5ef7592 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.cs b/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.cs new file mode 100644 index 0000000000..6bc835bd08 --- /dev/null +++ b/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.cs @@ -0,0 +1,66 @@ +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + +using UnityEngine; +using UnityEngine.InputSystem; + +public class NewBehaviourScript : MonoBehaviour +{ + [SerializeField] public GameObject cube; + + InputAction move; + InputAction look; + InputAction attack; + InputAction jump; + InputAction interact; + InputAction next; + InputAction previous; + InputAction sprint; + InputAction crouch; + + // Start is called before the first frame update + void Start() + { + // Project-Wide Actions + move = InputSystem.actions.FindAction("Player/Move"); + look = InputSystem.actions.FindAction("Player/Look"); + attack = InputSystem.actions.FindAction("Player/Attack"); + jump = InputSystem.actions.FindAction("Player/Jump"); + interact = InputSystem.actions.FindAction("Player/Interact"); + next = InputSystem.actions.FindAction("Player/Next"); + previous = InputSystem.actions.FindAction("Player/Previous"); + sprint = InputSystem.actions.FindAction("Player/Sprint"); + crouch = InputSystem.actions.FindAction("Player/Crouch"); + } + + // Update is called once per frame + void Update() + { + if (attack.WasPressedThisFrame()) + { + cube.GetComponent().material.color = Color.red; + } + else if (attack.WasReleasedThisFrame()) + { + cube.GetComponent().material.color = Color.green; + } + + var moveVal = move.ReadValue(); + if (moveVal.x < 0.0f) + { + cube.transform.Translate(new Vector3(-10 * Time.deltaTime, 0, 0)); + } + else if (moveVal.x > 0.0f) + { + cube.transform.Translate(new Vector3(10 * Time.deltaTime, 0, 0)); + } + if (moveVal.y < 0.0f) + { + cube.transform.Translate(new Vector3(0, -10 * Time.deltaTime, 0)); + } + else if (moveVal.y > 0.0f) + { + cube.transform.Translate(new Vector3(0, 10 * Time.deltaTime, 0)); + } + } +} +#endif diff --git a/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.cs.meta b/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.cs.meta new file mode 100644 index 0000000000..8b37436419 --- /dev/null +++ b/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f28fc6350a3a50a46a9e2448b66b7ab7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.unity b/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.unity new file mode 100644 index 0000000000..79b6997161 --- /dev/null +++ b/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.unity @@ -0,0 +1,461 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 3 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &1227919034 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1227919037} + - component: {fileID: 1227919036} + - component: {fileID: 1227919035} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &1227919035 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1227919034} + m_Enabled: 1 +--- !u!20 &1227919036 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1227919034} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &1227919037 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1227919034} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1239474184 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1239474186} + - component: {fileID: 1239474185} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &1239474185 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1239474184} + m_Enabled: 1 + serializedVersion: 10 + m_Type: 1 + m_Shape: 0 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingLayerMask: 1 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_UseViewFrustumForShadowCasterCull: 1 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &1239474186 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1239474184} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1 &1517955871 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1517955873} + m_Layer: 0 + m_Name: Player + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1517955873 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1517955871} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &1522618675 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1522618680} + - component: {fileID: 1522618679} + - component: {fileID: 1522618678} + - component: {fileID: 1522618677} + - component: {fileID: 1522618676} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1522618676 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1522618675} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f28fc6350a3a50a46a9e2448b66b7ab7, type: 3} + m_Name: + m_EditorClassIdentifier: + cube: {fileID: 1522618675} +--- !u!65 &1522618677 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1522618675} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 0 + serializedVersion: 3 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!23 &1522618678 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1522618675} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1522618679 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1522618675} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &1522618680 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1522618675} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.unity.meta b/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.unity.meta new file mode 100644 index 0000000000..834b062901 --- /dev/null +++ b/Assets/Samples/ProjectWideActionsTest/ProjectWideActionsTest.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c9a118a06bb79c0428c11bb701b6756e +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Samples/SimpleDemo/SimpleControls.cs b/Assets/Samples/SimpleDemo/SimpleControls.cs index 8cc949c6ee..6d78258ea7 100644 --- a/Assets/Samples/SimpleDemo/SimpleControls.cs +++ b/Assets/Samples/SimpleDemo/SimpleControls.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was auto-generated by com.unity.inputsystem:InputActionCodeGenerator -// version 1.7.0 +// version 1.8.0 // from Assets/Samples/SimpleDemo/SimpleControls.inputactions // // Changes to this file may cause incorrect behavior and will be lost if diff --git a/Assets/Tests/InputSystem.Editor/ControlSchemeEditorTests.cs b/Assets/Tests/InputSystem.Editor/ControlSchemeEditorTests.cs index 25d9905dac..20cdc29736 100644 --- a/Assets/Tests/InputSystem.Editor/ControlSchemeEditorTests.cs +++ b/Assets/Tests/InputSystem.Editor/ControlSchemeEditorTests.cs @@ -1,4 +1,4 @@ -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using NUnit.Framework; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Editor; diff --git a/Assets/Tests/InputSystem.Editor/SelectorsTests.cs b/Assets/Tests/InputSystem.Editor/SelectorsTests.cs index d69dc0e169..c3069fb0af 100644 --- a/Assets/Tests/InputSystem.Editor/SelectorsTests.cs +++ b/Assets/Tests/InputSystem.Editor/SelectorsTests.cs @@ -1,6 +1,6 @@ // UITK TreeView is not supported in earlier versions // Therefore the UITK version of the InputActionAsset Editor is not available on earlier Editor versions either. -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System.Linq; using NUnit.Framework; using UnityEngine; diff --git a/Assets/Tests/InputSystem.Editor/TestData.cs b/Assets/Tests/InputSystem.Editor/TestData.cs index d1a987dc4f..4621e529a2 100644 --- a/Assets/Tests/InputSystem.Editor/TestData.cs +++ b/Assets/Tests/InputSystem.Editor/TestData.cs @@ -1,4 +1,4 @@ -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System.Collections.Generic; using UnityEditor; using UnityEngine; diff --git a/Assets/Tests/InputSystem.Editor/TestDataGenerators.cs b/Assets/Tests/InputSystem.Editor/TestDataGenerators.cs index 1099aea180..ae53e4b49c 100644 --- a/Assets/Tests/InputSystem.Editor/TestDataGenerators.cs +++ b/Assets/Tests/InputSystem.Editor/TestDataGenerators.cs @@ -1,4 +1,4 @@ -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System.Collections.Generic; using UnityEngine.InputSystem; diff --git a/Assets/Tests/InputSystem/CoreTests_Actions.cs b/Assets/Tests/InputSystem/CoreTests_Actions.cs index 5ba4527abb..22c7c73776 100644 --- a/Assets/Tests/InputSystem/CoreTests_Actions.cs +++ b/Assets/Tests/InputSystem/CoreTests_Actions.cs @@ -527,6 +527,11 @@ public void Actions_CanTargetMultipleControls() [Category("Actions")] public void Actions_CanTargetSameControlWithMultipleActions() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions?.Disable(); +#endif + var gamepad = InputSystem.AddDevice(); var action1 = new InputAction("action1", binding: "/buttonSouth"); @@ -2042,6 +2047,11 @@ public void Actions_CanCreateActionsWithoutAnActionMap() [Category("Actions")] public void Actions_CanCreateActionAssetWithMultipleActionMaps() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions?.Disable(); +#endif + var asset = ScriptableObject.CreateInstance(); var map1 = new InputActionMap("map1"); @@ -2291,6 +2301,11 @@ public void Actions_CanByPassControlActuationChecks_UsingPasshtroughAction() [Category("Actions")] public void Actions_WithMultipleBoundControls_DriveInteractionsFromControlWithGreatestActuation() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions?.Disable(); +#endif + var gamepad = InputSystem.AddDevice(); // We go through several permutations of the same behavior all in one test. Makes the @@ -2578,6 +2593,11 @@ public void Actions_WithMultipleBoundControls_ProcessesInteractionsOnAllActiveBi [Category("Actions")] public void Actions_WithMultipleBoundControls_CanHandleInteractionsThatTriggerOnlyOnButtonRelease() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions?.Disable(); +#endif + var keyboard = InputSystem.AddDevice(); var gamepad = InputSystem.AddDevice(); @@ -3098,6 +3118,11 @@ public void Actions_CanRecordActions_AndReadValueAsObject() [Category("Actions")] public void Actions_CanRecordAllActionsInTheSystem() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions?.Disable(); +#endif + var gamepad = InputSystem.AddDevice(); var map = new InputActionMap(); @@ -3541,6 +3566,11 @@ public void Actions_CanConvertAssetToAndFromJson() [Category("Actions")] public void Actions_CanQueryAllEnabledActions() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions?.Disable(); +#endif + var action = new InputAction(binding: "/leftStick"); action.Enable(); @@ -3783,6 +3813,12 @@ private InputActionMap CreateSingletonAction() [TestCaseSource(typeof(ModificationCases))] public void Actions_CanHandleModification(Modification modification, IInputActionCollection2 actions) { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions?.Disable(); + InputActionState.DestroyAllActionMapStates(); // Also remove controls so the changed control count is accurate +#endif + var gamepad = InputSystem.AddDevice(); if (modification == Modification.AddDevice || modification == Modification.RemoveDevice) @@ -4669,6 +4705,12 @@ public void Actions_WhenDeviceIsRemoved_ReadingValueInActionListenersWillNotThro [Category("Actions")] public void Actions_WhenDeviceIsRemoved_DeviceIsRemovedFromDeviceMask() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions?.Disable(); + InputActionState.DestroyAllActionMapStates(); // Also remove controls so the changed control count is accurate +#endif + var gamepad = InputSystem.AddDevice(); var map = new InputActionMap(); @@ -4811,6 +4853,12 @@ public void Actions_ControlsUpdate_WhenDeviceConfigurationChanges_AndControlIsNo [Category("Actions")] public void Actions_WhenControlsUpdate_NotificationIsTriggered_ButOnlyAfterBindingsHaveFirstBeenResolved() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions?.Disable(); + InputActionState.DestroyAllActionMapStates(); // Also remove controls so the changed control count is accurate +#endif + var enabledAction = new InputAction("enabledAction", binding: "/leftTrigger"); // Enabling an action resolves its bindings. From the on, we get notifications for when @@ -4867,6 +4915,12 @@ public void Actions_WhenControlsUpdate_NotificationIsTriggered_ButOnlyAfterBindi [Category("Actions")] public void Actions_WhenControlsUpdateInActionMap_NotificationIsTriggered() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions?.Disable(); + InputActionState.DestroyAllActionMapStates(); // Also remove controls so the changed control count is accurate +#endif + var actionMap = new InputActionMap("map"); actionMap.AddAction("action", binding: "/leftTrigger"); actionMap.Enable(); @@ -4893,6 +4947,12 @@ public void Actions_WhenControlsUpdateInActionMap_NotificationIsTriggered() [Category("Actions")] public void Actions_WhenControlsUpdateInActionAsset_NotificationIsTriggered() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions?.Disable(); // Worked in Standalone + InputActionState.DestroyAllActionMapStates(); // Also remove controls so the changed control count is accurate +#endif + var asset = ScriptableObject.CreateInstance(); asset.name = "asset"; var actionMap = new InputActionMap("map"); @@ -4960,6 +5020,12 @@ public void Actions_WhenControlsUpdate_TimeoutsAreCarriedOver() [Category("Actions")] public void Actions_WhenControlsUpdate_InProgressActionsKeepGoing() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // @TODO: This should not need disabled for this test (https://jira.unity3d.com/browse/ISX-1455) + // Causes: "[Assert] Could not find active control after binding resolution" + // when RemoveDevice() called + InputSystem.actions.Disable(); +#endif currentTime = 0; var gamepad = InputSystem.AddDevice(); @@ -5077,6 +5143,11 @@ public void Actions_WhenInProgress_AddingAndRemovingUnusedDevice_DoesNotAffectAc [Category("Actions")] public void Actions_CanFindEnabledActions() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions?.Disable(); +#endif + var action1 = new InputAction(name: "a"); var action2 = new InputAction(name: "b"); @@ -9716,6 +9787,11 @@ public void Actions_CanIterateOverActionsInMap() [Category("Actions")] public void Actions_CanUseTouchWithActions() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions?.Disable(); +#endif + var touchscreen = InputSystem.AddDevice(); var primaryTouchAction = new InputAction("PrimaryTouch" , binding: "/primaryTouch/position"); @@ -9786,6 +9862,11 @@ public void Actions_CanUseTouchWithActions() [Category("Actions")] public void Actions_CanDrivePointerInputFromTouchPenAndMouse() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions?.Disable(); +#endif + // Give us known parameters for tap detection. InputSystem.settings.defaultTapTime = 0.5f; InputSystem.settings.tapRadius = 5; diff --git a/Assets/Tests/InputSystem/CoreTests_Actions_Interactions.cs b/Assets/Tests/InputSystem/CoreTests_Actions_Interactions.cs index c76221328a..fc1fd2ccb1 100644 --- a/Assets/Tests/InputSystem/CoreTests_Actions_Interactions.cs +++ b/Assets/Tests/InputSystem/CoreTests_Actions_Interactions.cs @@ -751,6 +751,11 @@ public void Actions_CanPerformDoubleTapInteraction() [Category("Actions")] public void Actions_CanCustomizeButtonPressPointsOfInteractions() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + InputSystem.actions.Disable(); +#endif + var gamepad = InputSystem.AddDevice(); var pressAction = new InputAction("PressAction", binding: "/leftTrigger", interactions: "press(pressPoint=0.234)"); diff --git a/Assets/Tests/InputSystem/CoreTests_Controls.cs b/Assets/Tests/InputSystem/CoreTests_Controls.cs index 5a749ab4db..28d30529b8 100644 --- a/Assets/Tests/InputSystem/CoreTests_Controls.cs +++ b/Assets/Tests/InputSystem/CoreTests_Controls.cs @@ -478,6 +478,12 @@ public unsafe void Controls_ValueIsReadFromStateMemoryOnlyWhenControlHasBeenMark [Category("Controls")] public void Controls_ValueCachingWorksAcrossEntireDeviceMemoryRange() { + // @TODO: This should not need disabled for this test (https://jira.unity3d.com/browse/ISX-1455) + // Somehow the presence of action controls prevents those controls being marked as stale +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + InputSystem.actions.Disable(); +#endif + var keyboard = InputSystem.AddDevice(); // read all values to initially mark everything as cached diff --git a/Assets/Tests/InputSystem/CoreTests_Devices.cs b/Assets/Tests/InputSystem/CoreTests_Devices.cs index 113a128c36..b963996fb1 100644 --- a/Assets/Tests/InputSystem/CoreTests_Devices.cs +++ b/Assets/Tests/InputSystem/CoreTests_Devices.cs @@ -4097,6 +4097,13 @@ public void Devices_RemovingDevice_CleansUpUpdateCallback() [Retry(2)] // Warm up JIT public void Devices_RemovingAndReaddingDevice_DoesNotAllocateMemory() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Exclude project-wide actions from this test + // Prevent GC Allocations happening later in test + InputSystem.actions.Disable(); + InputActionState.DestroyAllActionMapStates(); +#endif + var description = new InputDeviceDescription { @@ -4383,6 +4390,12 @@ public void TODO_Devices_CanHijackEventStreamOfDevice() [TestCase(false, InputSettings.BackgroundBehavior.ResetAndDisableNonBackgroundDevices, InputSettings.EditorInputBehaviorInPlayMode.AllDeviceInputAlwaysGoesToGameView)] public unsafe void Devices_CanHandleFocusChanges(bool appRunInBackground, InputSettings.BackgroundBehavior backgroundBehavior, InputSettings.EditorInputBehaviorInPlayMode editorInputBehaviorInPlayMode) { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // @TODO: This should not need disabled for this test (https://jira.unity3d.com/browse/ISX-1455) + // Causes: "[Assert] Could not find active control after binding resolution" + // due to: mouse3 = InputSystem.AddDevice(); + InputSystem.actions.Disable(); +#endif // The constant leads to "Unreachable code detected" warnings. #pragma warning disable CS0162 @@ -5350,6 +5363,16 @@ public void Devices_RemovingKeyboardMakesNextKeyboardCurrent() [Category("Devices")] public void Devices_RemovingDevice_MakesNextDeviceOfTypeCurrent() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // @TODO: This should not need disabled for this test (https://jira.unity3d.com/browse/ISX-1455) + // Causes: "[Assert] Could not find active control after binding resolution" + // during point where Pointer is removed + // - InputActionState.OnDeviceChange(device, InputDeviceChange.Removed); + // - LazyResolveBindings(bool fullResolve) + // - ResolveBindings() + // - RestoreActionStatesAfterReResolvingBindings(UnmanagedMemory oldState, InputControlList activeControls, bool isFullResolve) + InputSystem.actions.Disable(); +#endif var mouse = InputSystem.AddDevice(); Press(mouse.leftButton); Assert.That(Pointer.current, Is.EqualTo(mouse)); diff --git a/Assets/Tests/InputSystem/CoreTests_Editor.cs b/Assets/Tests/InputSystem/CoreTests_Editor.cs index 35147e4c26..7b89605e16 100644 --- a/Assets/Tests/InputSystem/CoreTests_Editor.cs +++ b/Assets/Tests/InputSystem/CoreTests_Editor.cs @@ -2837,6 +2837,17 @@ public void Editor_WhenRunUpdatesInEditModeIsEnabled_InputActionsTriggerInEditMo [Category("Editor")] public void Editor_LeavingPlayMode_DestroysAllActionStates() { +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // With Project-wide Actions `InputSystem.actions`, we begin with some initial ActionState + // Exclude project-wide actions from this test + Assert.That(InputActionState.s_GlobalState.globalList.length, Is.EqualTo(1)); + InputSystem.actions.Disable(); + InputActionState.DestroyAllActionMapStates(); +#endif + + // Initial state + Assert.That(InputActionState.s_GlobalState.globalList.length, Is.EqualTo(0)); + InputSystem.AddDevice(); // Enter play mode. diff --git a/Assets/Tests/InputSystem/CoreTests_ProjectWideActions.cs b/Assets/Tests/InputSystem/CoreTests_ProjectWideActions.cs new file mode 100644 index 0000000000..097d7bead6 --- /dev/null +++ b/Assets/Tests/InputSystem/CoreTests_ProjectWideActions.cs @@ -0,0 +1,215 @@ +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + +using System; +using System.IO; +using NUnit.Framework; +using UnityEditor; +using UnityEngine; +using UnityEngine.InputSystem; + +#if UNITY_EDITOR +using UnityEngine.InputSystem.Editor; +#endif + +internal partial class CoreTests +{ + const string TestCategory = "ProjectWideActions"; + const string TestAssetPath = "Assets/TestInputManager.asset"; + string m_TemplateAssetPath; + +#if UNITY_EDITOR + const int initialActionCount = 2; + const int initialMapCount = 1; +#else + const int initialActionCount = 17; + const int initialMapCount = 2; +#endif + + [SetUp] + public override void Setup() + { + // @TODO: Currently we can only inject the TestActionsAsset in PlayMode tests. + // It would be nice to be able to inject it as a Preloaded asset into the Player tests so + // we don't need different tests for the player. + // This also means these tests are dependant on the content of InputManager.asset not being changed. +#if UNITY_EDITOR + // This asset takes the place of ProjectSettings/InputManager.asset for the sake of testing, as we don't + // really want to go changing that asset in every test. + // This is used as a backing for `InputSystem.actions` in PlayMode tests. + var testAsset = ScriptableObject.CreateInstance(); + AssetDatabase.CreateAsset(testAsset, TestAssetPath); + + // Create a template `InputActionAsset` containing some test actions. + // This will then be used to populate the initially empty `TestActionsAsset` when it is first acessed. + var templateActions = ScriptableObject.CreateInstance(); + templateActions.name = "TestAsset"; + var map = templateActions.AddActionMap("InitialActionMapOne"); + map.AddAction("InitialActionOne"); + map.AddAction("InitialActionTwo"); + + m_TemplateAssetPath = Path.Combine(Environment.CurrentDirectory, "Assets/ProjectWideActionsTemplate.inputactions"); + File.WriteAllText(m_TemplateAssetPath, templateActions.ToJson()); + + ProjectWideActionsAsset.SetAssetPaths(m_TemplateAssetPath, TestAssetPath); +#endif + + base.Setup(); + } + + [TearDown] + public override void TearDown() + { +#if UNITY_EDITOR + ProjectWideActionsAsset.Reset(); + + if (File.Exists(m_TemplateAssetPath)) + File.Delete(m_TemplateAssetPath); + + AssetDatabase.DeleteAsset(TestAssetPath); +#endif + + base.TearDown(); + } + +#if UNITY_EDITOR + [Test] + [Category(TestCategory)] + public void ProjectWideActionsAsset_TemplateAssetIsInstalledOnFirstUse() + { + var asset = ProjectWideActionsAsset.GetOrCreate(); + + Assert.That(asset, Is.Not.Null); + Assert.That(asset.actionMaps.Count, Is.EqualTo(initialMapCount)); + Assert.That(asset.actionMaps[0].actions.Count, Is.EqualTo(initialActionCount)); + Assert.That(asset.actionMaps[0].actions[0].name, Is.EqualTo("InitialActionOne")); + } + + [Test] + [Category(TestCategory)] + public void ProjectWideActionsAsset_CanModifySaveAndLoadAsset() + { + var asset = ProjectWideActionsAsset.GetOrCreate(); + + Assert.That(asset, Is.Not.Null); + Assert.That(asset.actionMaps.Count, Is.EqualTo(initialMapCount)); + Assert.That(asset.actionMaps[0].actions.Count, Is.EqualTo(initialActionCount)); + Assert.That(asset.actionMaps[0].actions[0].name, Is.EqualTo("InitialActionOne")); + + asset.Disable(); // Cannot modify active actions + + // Add more actions + asset.actionMaps[0].AddAction("ActionTwo"); + asset.actionMaps[0].AddAction("ActionThree"); + + // Modify existing + asset.actionMaps[0].actions[0].Rename("FirstAction"); + + // Add another map + asset.AddActionMap("ActionMapTwo").AddAction("AnotherAction"); + + // Save + AssetDatabase.SaveAssets(); + + // Reload + asset = ProjectWideActionsAsset.GetOrCreate(); + + Assert.That(asset, Is.Not.Null); + Assert.That(asset.actionMaps.Count, Is.EqualTo(initialMapCount + 1)); + Assert.That(asset.actionMaps[0].actions.Count, Is.EqualTo(initialActionCount + 2)); + Assert.That(asset.actionMaps[1].actions.Count, Is.EqualTo(1)); + Assert.That(asset.actionMaps[0].actions[0].name, Is.EqualTo("FirstAction")); + Assert.That(asset.actionMaps[1].actions[0].name, Is.EqualTo("AnotherAction")); + } + +#endif + + [Test] + [Category(TestCategory)] + public void ProjectWideActions_AreEnabledByDefault() + { + Assert.That(InputSystem.actions, Is.Not.Null); + Assert.That(InputSystem.actions.enabled, Is.True); + } + + [Test] + [Category(TestCategory)] + public void ProjectWideActions_ContainsTemplateActions() + { + Assert.That(InputSystem.actions, Is.Not.Null); + Assert.That(InputSystem.actions.actionMaps.Count, Is.EqualTo(initialMapCount)); + +#if UNITY_EDITOR + Assert.That(InputSystem.actions.actionMaps[0].actions.Count, Is.EqualTo(initialActionCount)); + Assert.That(InputSystem.actions.actionMaps[0].actions[0].name, Is.EqualTo("InitialActionOne")); +#else + Assert.That(InputSystem.actions.actionMaps[0].actions.Count, Is.EqualTo(9)); + Assert.That(InputSystem.actions.actionMaps[0].actions[0].name, Is.EqualTo("Move")); +#endif + } + + [Test] + [Category(TestCategory)] + public void ProjectWideActions_AppearInEnabledActions() + { + var enabledActions = InputSystem.ListEnabledActions(); + Assert.That(enabledActions, Has.Count.EqualTo(initialActionCount)); + + // Add more actions also work + var action = new InputAction(name: "standaloneAction"); + action.Enable(); + + enabledActions = InputSystem.ListEnabledActions(); + Assert.That(enabledActions, Has.Count.EqualTo(initialActionCount + 1)); + Assert.That(enabledActions, Has.Exactly(1).SameAs(action)); + + // Disabling works + InputSystem.actions.Disable(); + enabledActions = InputSystem.ListEnabledActions(); + Assert.That(enabledActions, Has.Count.EqualTo(1)); + Assert.That(enabledActions, Has.Exactly(1).SameAs(action)); + } + + [Test] + [Category(TestCategory)] + public void ProjectWideActions_CanReplaceExistingActions() + { + // Initial State + Assert.That(InputSystem.actions, Is.Not.Null); + Assert.That(InputSystem.actions.enabled, Is.True); + var enabledActions = InputSystem.ListEnabledActions(); + Assert.That(enabledActions, Has.Count.EqualTo(initialActionCount)); + + // Build new asset + var asset = ScriptableObject.CreateInstance(); + var map1 = new InputActionMap("replacedMap1"); + var map2 = new InputActionMap("replacedMap2"); + var action1 = map1.AddAction("replacedAction1", InputActionType.Button); + var action2 = map1.AddAction("replacedAction2", InputActionType.Button); + var action3 = map1.AddAction("replacedAction3", InputActionType.Button); + var action4 = map2.AddAction("replacedAction4", InputActionType.Button); + + action1.AddBinding("/buttonSouth"); + action2.AddBinding("/buttonWest"); + action3.AddBinding("/buttonNorth"); + action4.AddBinding("/buttonEast"); + asset.AddActionMap(map1); + asset.AddActionMap(map2); + + // Replace project-wide actions + InputSystem.actions = asset; + + // State after replacing + Assert.That(InputSystem.actions, Is.Not.Null); + Assert.That(InputSystem.actions.enabled, Is.True); + enabledActions = InputSystem.ListEnabledActions(); + Assert.That(enabledActions, Has.Count.EqualTo(4)); + + Assert.That(InputSystem.actions.actionMaps.Count, Is.EqualTo(2)); + Assert.That(InputSystem.actions.actionMaps[0].actions.Count, Is.EqualTo(3)); + Assert.That(InputSystem.actions.actionMaps[0].actions[0].name, Is.EqualTo("replacedAction1")); + Assert.That(InputSystem.actions.actionMaps[1].actions.Count, Is.EqualTo(1)); + Assert.That(InputSystem.actions.actionMaps[1].actions[0].name, Is.EqualTo("replacedAction4")); + } +} + +#endif diff --git a/Assets/Tests/InputSystem/CoreTests_ProjectWideActions.cs.meta b/Assets/Tests/InputSystem/CoreTests_ProjectWideActions.cs.meta new file mode 100644 index 0000000000..e1b8a266a6 --- /dev/null +++ b/Assets/Tests/InputSystem/CoreTests_ProjectWideActions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 52e6b4a92448f524d99a9465f6cc8b54 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Tests/InputSystem/InputActionCodeGeneratorActions.cs b/Assets/Tests/InputSystem/InputActionCodeGeneratorActions.cs index bf78a3f705..e09c1824ce 100644 --- a/Assets/Tests/InputSystem/InputActionCodeGeneratorActions.cs +++ b/Assets/Tests/InputSystem/InputActionCodeGeneratorActions.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was auto-generated by com.unity.inputsystem:InputActionCodeGenerator -// version 1.7.0 +// version 1.8.0 // from Assets/Tests/InputSystem/InputActionCodeGeneratorActions.inputactions // // Changes to this file may cause incorrect behavior and will be lost if diff --git a/Assets/Tests/InputSystem/InputActionCodeGeneratorActions.inputactions.meta b/Assets/Tests/InputSystem/InputActionCodeGeneratorActions.inputactions.meta index a2cbcc5628..3b44e51dfd 100644 --- a/Assets/Tests/InputSystem/InputActionCodeGeneratorActions.inputactions.meta +++ b/Assets/Tests/InputSystem/InputActionCodeGeneratorActions.inputactions.meta @@ -8,7 +8,7 @@ ScriptedImporter: assetBundleName: assetBundleVariant: script: {fileID: 11500000, guid: 8404be70184654265930450def6a9037, type: 3} - generateWrapperCode: 0 + generateWrapperCode: 1 wrapperCodePath: wrapperClassName: wrapperCodeNamespace: diff --git a/Assets/Tests/InputSystem/Plugins/UITests.cs b/Assets/Tests/InputSystem/Plugins/UITests.cs index 5a4afbcd55..d6365dd3a6 100644 --- a/Assets/Tests/InputSystem/Plugins/UITests.cs +++ b/Assets/Tests/InputSystem/Plugins/UITests.cs @@ -3231,6 +3231,8 @@ public IEnumerator UI_CanPreventAutomaticDeselectionOfGameObjects() Assert.That(scene.eventSystem.currentSelectedGameObject, Is.SameAs(scene.leftGameObject)); } +// @TODO: This should not need disabled for this test (https://jira.unity3d.com/browse/ISX-1455) +#if !UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS || UNITY_EDITOR [UnityTest] [Category("UI")] public IEnumerator UI_WhenBindingsAreReResolved_PointerStatesAreKeptInSync() @@ -3281,6 +3283,8 @@ public IEnumerator UI_WhenBindingsAreReResolved_PointerStatesAreKeptInSync() Assert.That(EventSystem.current.IsPointerOverGameObject(), Is.True); } +#endif + ////REVIEW: While `deselectOnBackgroundClick` does solve the problem of breaking keyboard and gamepad navigation, the question //// IMO is whether navigation should even be affected that way by not having a current selection. Seems to me that the //// the system should remember the last selected object and start up navigation from there when nothing is selected. @@ -3796,6 +3800,8 @@ public IEnumerator UI_WhenAppLosesAndRegainsFocus_WhileUIButtonIsPressed_UIButto Assert.That(clicked, Is.True); } +// @TODO: This should not need disabled for this test (https://jira.unity3d.com/browse/ISX-1455) +#if !UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS || UNITY_EDITOR [UnityTest] [Category("UI")] public IEnumerator UI_WhenCursorIsLockedToScreenCenter_PointerEnterAndExitEventsFire() @@ -3828,6 +3834,8 @@ public IEnumerator UI_WhenCursorIsLockedToScreenCenter_PointerEnterAndExitEvents Assert.That(callbackReceiver.events.Any(e => e.type == EventType.PointerExit), Is.True); } +#endif + #region Multi Display Tests #if UNITY_2022_3_OR_NEWER // displayIndex is only available from 2022.3 onwards diff --git a/Assets/Tests/InputSystem/TestActionsAsset.cs b/Assets/Tests/InputSystem/TestActionsAsset.cs new file mode 100644 index 0000000000..70e1fd9dfb --- /dev/null +++ b/Assets/Tests/InputSystem/TestActionsAsset.cs @@ -0,0 +1,5 @@ +using UnityEngine; + +internal class TestActionsAsset : ScriptableObject +{ +} diff --git a/Assets/Tests/InputSystem/TestActionsAsset.cs.meta b/Assets/Tests/InputSystem/TestActionsAsset.cs.meta new file mode 100644 index 0000000000..90b00f3740 --- /dev/null +++ b/Assets/Tests/InputSystem/TestActionsAsset.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 91991318f6d19a74b9ac916df855fc69 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Tests/InputSystem/Unity.InputSystem.Tests.asmdef b/Assets/Tests/InputSystem/Unity.InputSystem.Tests.asmdef index f7df9c9dce..183d70b1fa 100644 --- a/Assets/Tests/InputSystem/Unity.InputSystem.Tests.asmdef +++ b/Assets/Tests/InputSystem/Unity.InputSystem.Tests.asmdef @@ -40,6 +40,11 @@ "name": "Unity", "expression": "2022.1", "define": "TEMP_DISABLE_STANDALONE_OSX_XINPUT_TEST" + }, + { + "name": "Unity", + "expression": "2022.3", + "define": "UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS" } ], "noEngineReferences": false diff --git a/Packages/com.unity.inputsystem/CHANGELOG.md b/Packages/com.unity.inputsystem/CHANGELOG.md index cf47b0fdb8..c95bb03604 100644 --- a/Packages/com.unity.inputsystem/CHANGELOG.md +++ b/Packages/com.unity.inputsystem/CHANGELOG.md @@ -8,6 +8,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. Due to package verification, the latest version below is the unpublished version and the date is meaningless. however, it has to be formatted properly to pass verification tests. +## [1.8.0-pre.1] - 2023-08-14 + +### Added +- Initial version of Project Wide Actions for pre-release (`InputSystem.actions`). This feature is available only on Unity Editor versions 2022.3 and above and can be modified in the Project Settings. + +### Fixed +- Fixed device selection menu not responding to mouse clicks when trying to add a device in a Control Scheme ([case ISXB-622](https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-622)). + ## [1.7.0] - 2023-08-14 ### Added diff --git a/Packages/com.unity.inputsystem/Documentation~/Images/ProjectSettingsInputActions.png b/Packages/com.unity.inputsystem/Documentation~/Images/ProjectSettingsInputActions.png new file mode 100644 index 0000000000..e19e192ca0 Binary files /dev/null and b/Packages/com.unity.inputsystem/Documentation~/Images/ProjectSettingsInputActions.png differ diff --git a/Packages/com.unity.inputsystem/Documentation~/PreReleaseNotes.md b/Packages/com.unity.inputsystem/Documentation~/PreReleaseNotes.md new file mode 100644 index 0000000000..4663cec33b --- /dev/null +++ b/Packages/com.unity.inputsystem/Documentation~/PreReleaseNotes.md @@ -0,0 +1,92 @@ +# Pre-Release Notes + +## Overview + +This pre-release contains updates to the Input System which simplifies and improves some of the main workflows compared with earlier versions of the Input System package. + +Because this is a pre-release, the rest of the documentation included with this version of the package has not yet been updated to reflect these changes. The documentation on this page explains the improvements and differences between these new features, and the previous version of the input system package. The improvements are as follows: + +**New project-wide actions** + +The Input System now allows you to configure actions in the Project Settings window, in a new Input Actions Settings panel. The actions configured here apply project-wide. This means you no longer need to create an Actions asset and set up a reference to your asset to read input actions. Instead, you can configure your actions in the Project Settings window, and read them directly from your scripts. You can still use Action assets if you like, but for many typical scenarios, they are no longer necessary. + +**New default actions** + +The new project-wide actions come pre-loaded with some default action maps that contain actions suitable for many typical game scenarios, including basic player character controls, and typical UI interactions. In many cases these are enough to allow you to immediately start using input in your project with no configuration required. You are free to either add to, edit, or delete these default configurations to suit your needs. + + +**Note**: The new features in this pre-release are **only documented on this page**. When reading the rest of the documentation in this package, please remember that it *will not mention these features*. So, for example, when another page in the documentation discusses **action assets**, or creating a reference to your action asset, you can in many cases use project-wide actions instead, as described on this page. + +## Project-wide actions and default actions + +Project-wide actions are similar to the actions you would previously define in an actions asset, however instead of being an asset that you create in the Editor, they are stored as part of your project’s settings, and are configured in the Project Settings window. + +Compared with the previous workflow of creating an Action asset, and setting up a reference to that asset to access in your code, project-wide actions reduce the number of steps to set up input in your project, and reduces complexity in your project. + +![The Input Actions settings panel in the Project Settings window, showing the default player actions.](images/ProjectSettingsInputActions.png)
+*The Input Actions settings panel in the Project Settings window, showing the default player actions.* + +The project-wide actions feature has some default action maps set up, which you can add to, modify or delete. They are actions which are useful in typical games, such as moving a player character with WSAD keys or a Joypad stick, pressing a button to jump or interact, as well as common UI controls such as pointing, submitting, or canceling within a user interface. + +**Note**: If you’d like to delete all the default actions so that you can start from an empty configuration, you don’t need to delete the actions individually. You can delete the default Action Maps, which deletes all the Actions contained in those maps in one go. + +### Reading project-wide actions + +You can access the project-wide actions in your script by using the [InputSystem.actions](../api/UnityEngine.InputSystem.InputSystem.html#UnityEngine_InputSystem_InputSystem_actions) property. For example: + + var myAction = InputSystem.actions.FindAction("Player/Jump"); + +The above line of code reads the "Jump" action, from the “Player” action map, which is one of the default actions that comes with the new project-wide actions feature. + +Unlike Input Action assets, the project-wide actions are stored in your project’s Project Settings folder, so they do not appear in your Project window. The **InputSystem.actions** property is a built-in reference to that asset. This means you can use all the same techniques described throughout the rest of the documentation about [using action assets](Workflow-ActionsAsset.html), but instead of referencing an asset from your project, you can use the **InputSystem.actions property** in your scripts to reference the project-wide actions. + +For example, here is the script from the [Action Assets workflow page](Workflow-ActionsAsset.html), adapted to use the project-wide actions, and the default actions in the "Player" action map. + +``` +using UnityEngine; +using UnityEngine.InputSystem; + +public class ExampleScript : MonoBehaviour +{ + // private field to store move action reference + private InputAction moveAction; + + void Awake() + { + // find the "move" action, and keep the reference to it, for use in Update + moveAction = InputSystem.actions.FindAction("Player/move"); + // for the "jump" action, we add a callback method for when it is performed + InputSystem.actions.FindAction("Player/jump").performed += OnJump; + } + + void Update() + { + // our update loop polls the "move" action value each frame + Vector2 moveVector = moveAction.ReadValue(); + } + + private void OnJump(InputAction.CallbackContext context) + { + // this is the "jump" action callback method + Debug.Log("Jump!"); + } +} +``` + +Things to note about the above example script, as compared to the script on the [Action Assets workflow page](Workflow-ActionsAsset.html): + +* Because there is a built-in reference to the project-wide actions, you do not need a public field with an assigned asset to get a reference to the actions. + +* This script does not enable or disable action maps. Project-wide action maps are enabled by default. This means unlike with Action assets, you do not need to enable individual action maps in your script before being able to use them. You may still want to disable or enable action maps if you want to make use of different types of input in different parts of your project. + +### Limitations + +Because this is a pre-release, the project-wide actions feature is not yet complete and has some limitations you should be aware of. + +**The project-wide actions cannot be referenced in an ActionsAsset field in the inspector.** + +You can't assign the project-wide input actions asset to UI fields where you would normally assign an input action asset. For example, if you are using the PlayerInput component, you can’t assign the project wide actions to its "Actions" field. This means if you want to use the PlayerInput component, you must create an Actions asset and set up your input configuration there instead of in the project-wide actions. + +**Some features of the project-wide actions editor are different, or missing, compared with the Actions Editor window for actions assets.** + +Although the UI to edit the project-wide actions in the Project Settings window is very similar to the Actions Editor for action assets, there are some differences and missing features. In particular, the new project-wide actions editor uses a newer UI system, and therefore there are some cosmetic differences such as different icons, and some workflow features are missing such as some of the keyboard shortcuts. You also cannot yet access the project-wide actions [through a C# wrapper](Workflow-ActionsAsset.html#referencing-the-actions-asset-through-a-c-wrapper). diff --git a/Packages/com.unity.inputsystem/Documentation~/TableOfContents.md b/Packages/com.unity.inputsystem/Documentation~/TableOfContents.md index 5db6f652d9..16d0cf0671 100644 --- a/Packages/com.unity.inputsystem/Documentation~/TableOfContents.md +++ b/Packages/com.unity.inputsystem/Documentation~/TableOfContents.md @@ -1,4 +1,5 @@ +* [Important Pre-Release Notes](PreReleaseNotes.md) * [Introduction](index.md) * [Installation](Installation.md) * [Concepts](Concepts.md) diff --git a/Packages/com.unity.inputsystem/Documentation~/config.json b/Packages/com.unity.inputsystem/Documentation~/config.json new file mode 100644 index 0000000000..43dc9e6119 --- /dev/null +++ b/Packages/com.unity.inputsystem/Documentation~/config.json @@ -0,0 +1 @@ +{ "DefineConstants": "UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS" } \ No newline at end of file diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/Composites/Vector2Composite.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/Composites/Vector2Composite.cs index 1aa572b8ef..20fb8e69f5 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/Composites/Vector2Composite.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/Composites/Vector2Composite.cs @@ -204,7 +204,7 @@ public override void OnGUI() target.mode = (Vector2Composite.Mode)EditorGUILayout.EnumPopup(m_ModeLabel, target.mode); } -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS public override void OnDrawVisualElements(VisualElement root, Action onChangedCallback) { var modeField = new EnumField("Mode", target.mode) diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/Composites/Vector3Composite.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/Composites/Vector3Composite.cs index 77b7cc5950..8af9bd4a6d 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/Composites/Vector3Composite.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/Composites/Vector3Composite.cs @@ -177,7 +177,7 @@ public override void OnGUI() target.mode = (Vector2Composite.Mode)EditorGUILayout.EnumPopup(m_ModeLabel, target.mode); } -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS public override void OnDrawVisualElements(VisualElement root, Action onChangedCallback) { var modeField = new EnumField("Mode", target.mode) diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/InputControlScheme.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/InputControlScheme.cs index 070a25721e..bb15893a61 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/InputControlScheme.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/InputControlScheme.cs @@ -112,7 +112,7 @@ public InputControlScheme(string name, IEnumerable devices = } } - #if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR + #if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS internal InputControlScheme(SerializedProperty sp) { var requirements = new List(); diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/HoldInteraction.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/HoldInteraction.cs index 4ef657aee7..63c6d6106c 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/HoldInteraction.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/HoldInteraction.cs @@ -128,7 +128,7 @@ public override void OnGUI() m_DurationSetting.OnGUI(); } -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS public override void OnDrawVisualElements(VisualElement root, Action onChangedCallback) { m_PressPointSetting.OnDrawVisualElements(root, onChangedCallback); diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/MultiTapInteraction.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/MultiTapInteraction.cs index 513c05de5b..93138bcaec 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/MultiTapInteraction.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/MultiTapInteraction.cs @@ -202,7 +202,7 @@ public override void OnGUI() m_PressPointSetting.OnGUI(); } -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS public override void OnDrawVisualElements(VisualElement root, Action onChangedCallback) { var tapCountField = new IntegerField(m_TapCountLabel.text) { value = target.tapCount }; diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/PressInteraction.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/PressInteraction.cs index b9ad14634b..91e32e33fb 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/PressInteraction.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/PressInteraction.cs @@ -218,7 +218,7 @@ public override void OnGUI() m_PressPointSetting.OnGUI(); } -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS public override void OnDrawVisualElements(VisualElement root, Action onChangedCallback) { root.Add(new HelpBox(s_HelpBoxText.text, HelpBoxMessageType.None)); diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/SlowTapInteraction.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/SlowTapInteraction.cs index a800fedeaf..fd395883a3 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/SlowTapInteraction.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/SlowTapInteraction.cs @@ -92,7 +92,7 @@ public override void OnGUI() m_PressPointSetting.OnGUI(); } -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS public override void OnDrawVisualElements(VisualElement root, Action onChangedCallback) { m_DurationSetting.OnDrawVisualElements(root, onChangedCallback); diff --git a/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/TapInteraction.cs b/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/TapInteraction.cs index 6bc6b6fb12..b7199820de 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/TapInteraction.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Actions/Interactions/TapInteraction.cs @@ -106,7 +106,7 @@ public override void OnGUI() m_PressPointSetting.OnGUI(); } -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS public override void OnDrawVisualElements(VisualElement root, Action onChangedCallback) { m_DurationSetting.OnDrawVisualElements(root, onChangedCallback); diff --git a/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs b/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs index 1f1f45767b..cda40f010b 100644 --- a/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs +++ b/Packages/com.unity.inputsystem/InputSystem/AssemblyInfo.cs @@ -15,7 +15,7 @@ public static partial class InputSystem // Keep this in sync with "Packages/com.unity.inputsystem/package.json". // NOTE: Unfortunately, System.Version doesn't use semantic versioning so we can't include // "-preview" suffixes here. - internal const string kAssemblyVersion = "1.7.0"; - internal const string kDocUrl = "https://docs.unity3d.com/Packages/com.unity.inputsystem@1.7"; + internal const string kAssemblyVersion = "1.8.0"; + internal const string kDocUrl = "https://docs.unity3d.com/Packages/com.unity.inputsystem@1.8"; } } diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/Processors/AxisDeadzoneProcessor.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/Processors/AxisDeadzoneProcessor.cs index 4713b2e67a..cb8e93d1af 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/Processors/AxisDeadzoneProcessor.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/Processors/AxisDeadzoneProcessor.cs @@ -97,7 +97,7 @@ public override void OnGUI() m_MaxSetting.OnGUI(); } -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS public override void OnDrawVisualElements(VisualElement root, Action onChangedCallback) { m_MinSetting.OnDrawVisualElements(root, onChangedCallback); diff --git a/Packages/com.unity.inputsystem/InputSystem/Controls/Processors/StickDeadzoneProcessor.cs b/Packages/com.unity.inputsystem/InputSystem/Controls/Processors/StickDeadzoneProcessor.cs index bcb4cf4d0b..14e8511231 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Controls/Processors/StickDeadzoneProcessor.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Controls/Processors/StickDeadzoneProcessor.cs @@ -86,7 +86,7 @@ public override void OnGUI() m_MaxSetting.OnGUI(); } -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS public override void OnDrawVisualElements(VisualElement root, Action onChangedCallback) { m_MinSetting.OnDrawVisualElements(root, onChangedCallback); diff --git a/Packages/com.unity.inputsystem/InputSystem/Devices/Precompiled/FastKeyboard.cs b/Packages/com.unity.inputsystem/InputSystem/Devices/Precompiled/FastKeyboard.cs index bbd94e2467..4c75cb447e 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Devices/Precompiled/FastKeyboard.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Devices/Precompiled/FastKeyboard.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was auto-generated by com.unity.inputsystem:InputLayoutCodeGenerator -// version 1.7.0 +// version 1.8.0 // from "Keyboard" layout // // Changes to this file may cause incorrect behavior and will be lost if diff --git a/Packages/com.unity.inputsystem/InputSystem/Devices/Precompiled/FastMouse.cs b/Packages/com.unity.inputsystem/InputSystem/Devices/Precompiled/FastMouse.cs index 5a59181b3e..72cd3999b7 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Devices/Precompiled/FastMouse.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Devices/Precompiled/FastMouse.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was auto-generated by com.unity.inputsystem:InputLayoutCodeGenerator -// version 1.7.0 +// version 1.8.0 // from "Mouse" layout // // Changes to this file may cause incorrect behavior and will be lost if diff --git a/Packages/com.unity.inputsystem/InputSystem/Devices/Precompiled/FastTouchscreen.cs b/Packages/com.unity.inputsystem/InputSystem/Devices/Precompiled/FastTouchscreen.cs index 6d0f6ca270..be4e6f3043 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Devices/Precompiled/FastTouchscreen.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Devices/Precompiled/FastTouchscreen.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was auto-generated by com.unity.inputsystem:InputLayoutCodeGenerator -// version 1.7.0 +// version 1.8.0 // from "Touchscreen" layout // // Changes to this file may cause incorrect behavior and will be lost if diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/AssetEditor/InputActionEditorWindow.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/AssetEditor/InputActionEditorWindow.cs index 068c5c1138..6a942a521b 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/AssetEditor/InputActionEditorWindow.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/AssetEditor/InputActionEditorWindow.cs @@ -37,11 +37,10 @@ internal class InputActionEditorWindow : EditorWindow, IDisposable [OnOpenAsset] public static bool OnOpenAsset(int instanceId, int line) { -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR - if (InputSystem.settings.IsFeatureEnabled(InputFeatureNames.kUseUIToolkitEditor)) +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + if (InputSystem.settings.IsFeatureEnabled(InputFeatureNames.kUseUIToolkitEditorForAllAssets)) return false; #endif - var path = AssetDatabase.GetAssetPath(instanceId); if (!path.EndsWith(k_FileExtension, StringComparison.InvariantCultureIgnoreCase)) return false; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/AssetEditor/ParameterListView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/AssetEditor/ParameterListView.cs index 4705cb16cf..c51a564066 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/AssetEditor/ParameterListView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/AssetEditor/ParameterListView.cs @@ -247,7 +247,7 @@ public void Clear() m_ParameterEditor = null; } -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS public void OnDrawVisualElements(VisualElement root) { if (m_ParameterEditor != null) diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/InputParameterEditor.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/InputParameterEditor.cs index 0350e8c9ce..dfaba6ccb8 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/InputParameterEditor.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/InputParameterEditor.cs @@ -32,7 +32,7 @@ public abstract class InputParameterEditor /// public abstract void OnGUI(); -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS /// /// Add visual elements for this parameter editor to a root VisualElement. /// @@ -182,6 +182,17 @@ internal override void SetTarget(object target) OnEnable(); } +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + /// + /// Default stub implementation of . + /// Should be overridden to create the desired UI. + /// + public override void OnDrawVisualElements(VisualElement root, Action onChangedCallback) + { + } + +#endif + /// /// Helper for parameters that have defaults (usually from ). /// @@ -212,7 +223,7 @@ public void Initialize(string label, string tooltip, string defaultName, Func o != null && o.name == kAssetName) as InputActionAsset; + if (inputActionsAsset != null) + return inputActionsAsset; + } + + return CreateNewActionAsset(); + } + + private static InputActionAsset CreateNewActionAsset() + { + var json = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, s_DefaultAssetPath)); + + var asset = ScriptableObject.CreateInstance(); + asset.LoadFromJson(json); + asset.name = kAssetName; + + AssetDatabase.AddObjectToAsset(asset, s_AssetPath); + + // Make sure all the elements in the asset have GUIDs and that they are indeed unique. + var maps = asset.actionMaps; + foreach (var map in maps) + { + // Make sure action map has GUID. + if (string.IsNullOrEmpty(map.m_Id) || asset.actionMaps.Count(x => x.m_Id == map.m_Id) > 1) + map.GenerateId(); + + // Make sure all actions have GUIDs. + foreach (var action in map.actions) + { + var actionId = action.m_Id; + if (string.IsNullOrEmpty(actionId) || asset.actionMaps.Sum(m => m.actions.Count(a => a.m_Id == actionId)) > 1) + action.GenerateId(); + } + + // Make sure all bindings have GUIDs. + for (var i = 0; i < map.m_Bindings.LengthSafe(); ++i) + { + var bindingId = map.m_Bindings[i].m_Id; + if (string.IsNullOrEmpty(bindingId) || asset.actionMaps.Sum(m => m.bindings.Count(b => b.m_Id == bindingId)) > 1) + map.m_Bindings[i].GenerateId(); + } + } + + // Create sub-asset for each action. This is so that users can select individual input actions from the asset when they're + // trying to assign to a field that accepts only one action. + foreach (var map in maps) + { + foreach (var action in map.actions) + { + var actionReference = ScriptableObject.CreateInstance(); + actionReference.Set(action); + AssetDatabase.AddObjectToAsset(actionReference, asset); + } + } + + AssetDatabase.SaveAssets(); + + return asset; + } + } +} +#endif diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsAsset.cs.meta b/Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsAsset.cs.meta new file mode 100644 index 0000000000..02e07768b0 --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsAsset.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2a47e68520f79264fb6828f8f9516ef2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsTemplate.inputactions b/Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsTemplate.inputactions new file mode 100644 index 0000000000..5d4dbca6ae --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsTemplate.inputactions @@ -0,0 +1,1017 @@ +{ + "name": "ProjectWideActionsTemplate", + "maps": [ + { + "name": "Player", + "id": "df70fa95-8a34-4494-b137-73ab6b9c7d37", + "actions": [ + { + "name": "Move", + "type": "Value", + "id": "351f2ccd-1f9f-44bf-9bec-d62ac5c5f408", + "expectedControlType": "Vector2", + "processors": "", + "interactions": "", + "initialStateCheck": true + }, + { + "name": "Look", + "type": "Value", + "id": "6b444451-8a00-4d00-a97e-f47457f736a8", + "expectedControlType": "Vector2", + "processors": "", + "interactions": "", + "initialStateCheck": true + }, + { + "name": "Attack", + "type": "Button", + "id": "6c2ab1b8-8984-453a-af3d-a3c78ae1679a", + "expectedControlType": "Button", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "Interact", + "type": "Button", + "id": "852140f2-7766-474d-8707-702459ba45f3", + "expectedControlType": "Button", + "processors": "", + "interactions": "Hold", + "initialStateCheck": false + }, + { + "name": "Crouch", + "type": "Button", + "id": "27c5f898-bc57-4ee1-8800-db469aca5fe3", + "expectedControlType": "Button", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "Jump", + "type": "Button", + "id": "f1ba0d36-48eb-4cd5-b651-1c94a6531f70", + "expectedControlType": "Button", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "Previous", + "type": "Value", + "id": "2776c80d-3c14-4091-8c56-d04ced07a2b0", + "expectedControlType": "Axis", + "processors": "", + "interactions": "", + "initialStateCheck": true + }, + { + "name": "Next", + "type": "Value", + "id": "b7230bb6-fc9b-4f52-8b25-f5e19cb2c2ba", + "expectedControlType": "Axis", + "processors": "", + "interactions": "", + "initialStateCheck": true + }, + { + "name": "Sprint", + "type": "Button", + "id": "641cd816-40e6-41b4-8c3d-04687c349290", + "expectedControlType": "Button", + "processors": "", + "interactions": "", + "initialStateCheck": false + } + ], + "bindings": [ + { + "name": "", + "id": "978bfe49-cc26-4a3d-ab7b-7d7a29327403", + "path": "/leftStick", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Move", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "WASD", + "id": "00ca640b-d935-4593-8157-c05846ea39b3", + "path": "Dpad", + "interactions": "", + "processors": "", + "groups": "", + "action": "Move", + "isComposite": true, + "isPartOfComposite": false + }, + { + "name": "up", + "id": "e2062cb9-1b15-46a2-838c-2f8d72a0bdd9", + "path": "/w", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "Move", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "up", + "id": "8180e8bd-4097-4f4e-ab88-4523101a6ce9", + "path": "/upArrow", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "Move", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "down", + "id": "320bffee-a40b-4347-ac70-c210eb8bc73a", + "path": "/s", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "Move", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "down", + "id": "1c5327b5-f71c-4f60-99c7-4e737386f1d1", + "path": "/downArrow", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "Move", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "left", + "id": "d2581a9b-1d11-4566-b27d-b92aff5fabbc", + "path": "/a", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "Move", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "left", + "id": "2e46982e-44cc-431b-9f0b-c11910bf467a", + "path": "/leftArrow", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "Move", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "right", + "id": "fcfe95b8-67b9-4526-84b5-5d0bc98d6400", + "path": "/d", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "Move", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "right", + "id": "77bff152-3580-4b21-b6de-dcd0c7e41164", + "path": "/rightArrow", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "Move", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "", + "id": "1635d3fe-58b6-4ba9-a4e2-f4b964f6b5c8", + "path": "/{Primary2DAxis}", + "interactions": "", + "processors": "", + "groups": "XR", + "action": "Move", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "3ea4d645-4504-4529-b061-ab81934c3752", + "path": "/stick", + "interactions": "", + "processors": "", + "groups": "Joystick", + "action": "Move", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "c1f7a91b-d0fd-4a62-997e-7fb9b69bf235", + "path": "/rightStick", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Look", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "8c8e490b-c610-4785-884f-f04217b23ca4", + "path": "/delta", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse;Touch", + "action": "Look", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "3e5f5442-8668-4b27-a940-df99bad7e831", + "path": "/{Hatswitch}", + "interactions": "", + "processors": "", + "groups": "Joystick", + "action": "Look", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "143bb1cd-cc10-4eca-a2f0-a3664166fe91", + "path": "/buttonWest", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Attack", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "05f6913d-c316-48b2-a6bb-e225f14c7960", + "path": "/leftButton", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "Attack", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "886e731e-7071-4ae4-95c0-e61739dad6fd", + "path": "/primaryTouch/tap", + "interactions": "", + "processors": "", + "groups": ";Touch", + "action": "Attack", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "ee3d0cd2-254e-47a7-a8cb-bc94d9658c54", + "path": "/trigger", + "interactions": "", + "processors": "", + "groups": "Joystick", + "action": "Attack", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "8255d333-5683-4943-a58a-ccb207ff1dce", + "path": "/{PrimaryAction}", + "interactions": "", + "processors": "", + "groups": "XR", + "action": "Attack", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "b3c1c7f0-bd20-4ee7-a0f1-899b24bca6d7", + "path": "/enter", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Attack", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "cbac6039-9c09-46a1-b5f2-4e5124ccb5ed", + "path": "/2", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Next", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "e15ca19d-e649-4852-97d5-7fe8ccc44e94", + "path": "/dpad/right", + "interactions": "", + "processors": "", + "groups": "Gamepad", + "action": "Next", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "f2e9ba44-c423-42a7-ad56-f20975884794", + "path": "/leftShift", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Sprint", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "8cbb2f4b-a784-49cc-8d5e-c010b8c7f4e6", + "path": "/leftStickPress", + "interactions": "", + "processors": "", + "groups": "Gamepad", + "action": "Sprint", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "d8bf24bf-3f2f-4160-a97c-38ec1eb520ba", + "path": "/trigger", + "interactions": "", + "processors": "", + "groups": "XR", + "action": "Sprint", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "eb40bb66-4559-4dfa-9a2f-820438abb426", + "path": "/space", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Jump", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "daba33a1-ad0c-4742-a909-43ad1cdfbeb6", + "path": "/buttonSouth", + "interactions": "", + "processors": "", + "groups": "Gamepad", + "action": "Jump", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "603f3daf-40bd-4854-8724-93e8017f59e3", + "path": "/secondaryButton", + "interactions": "", + "processors": "", + "groups": "XR", + "action": "Jump", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "1534dc16-a6aa-499d-9c3a-22b47347b52a", + "path": "/1", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Previous", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "25060bbd-a3a6-476e-8fba-45ae484aad05", + "path": "/dpad/left", + "interactions": "", + "processors": "", + "groups": "Gamepad", + "action": "Previous", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "1c04ea5f-b012-41d1-a6f7-02e963b52893", + "path": "/e", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Interact", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "b3f66d0b-7751-423f-908b-a11c5bd95930", + "path": "/buttonNorth", + "interactions": "", + "processors": "", + "groups": "Gamepad", + "action": "Interact", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "4f4649ac-64a8-4a73-af11-b3faef356a4d", + "path": "/buttonEast", + "interactions": "", + "processors": "", + "groups": "Gamepad", + "action": "Crouch", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "36e52cba-0905-478e-a818-f4bfcb9f3b9a", + "path": "/c", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Crouch", + "isComposite": false, + "isPartOfComposite": false + } + ] + }, + { + "name": "UI", + "id": "272f6d14-89ba-496f-b7ff-215263d3219f", + "actions": [ + { + "name": "Navigate", + "type": "PassThrough", + "id": "c95b2375-e6d9-4b88-9c4c-c5e76515df4b", + "expectedControlType": "Vector2", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "Submit", + "type": "Button", + "id": "7607c7b6-cd76-4816-beef-bd0341cfe950", + "expectedControlType": "Button", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "Cancel", + "type": "Button", + "id": "15cef263-9014-4fd5-94d9-4e4a6234a6ef", + "expectedControlType": "Button", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "Point", + "type": "PassThrough", + "id": "32b35790-4ed0-4e9a-aa41-69ac6d629449", + "expectedControlType": "Vector2", + "processors": "", + "interactions": "", + "initialStateCheck": true + }, + { + "name": "Click", + "type": "PassThrough", + "id": "3c7022bf-7922-4f7c-a998-c437916075ad", + "expectedControlType": "Button", + "processors": "", + "interactions": "", + "initialStateCheck": true + }, + { + "name": "RightClick", + "type": "PassThrough", + "id": "44b200b1-1557-4083-816c-b22cbdf77ddf", + "expectedControlType": "Button", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "MiddleClick", + "type": "PassThrough", + "id": "dad70c86-b58c-4b17-88ad-f5e53adf419e", + "expectedControlType": "Button", + "processors": "", + "interactions": "", + "initialStateCheck": false + }, + { + "name": "ScrollWheel", + "type": "PassThrough", + "id": "0489e84a-4833-4c40-bfae-cea84b696689", + "expectedControlType": "Vector2", + "processors": "", + "interactions": "", + "initialStateCheck": false + } + ], + "bindings": [ + { + "name": "Gamepad", + "id": "809f371f-c5e2-4e7a-83a1-d867598f40dd", + "path": "2DVector", + "interactions": "", + "processors": "", + "groups": "", + "action": "Navigate", + "isComposite": true, + "isPartOfComposite": false + }, + { + "name": "up", + "id": "14a5d6e8-4aaf-4119-a9ef-34b8c2c548bf", + "path": "/leftStick/up", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "up", + "id": "9144cbe6-05e1-4687-a6d7-24f99d23dd81", + "path": "/rightStick/up", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "down", + "id": "2db08d65-c5fb-421b-983f-c71163608d67", + "path": "/leftStick/down", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "down", + "id": "58748904-2ea9-4a80-8579-b500e6a76df8", + "path": "/rightStick/down", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "left", + "id": "8ba04515-75aa-45de-966d-393d9bbd1c14", + "path": "/leftStick/left", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "left", + "id": "712e721c-bdfb-4b23-a86c-a0d9fcfea921", + "path": "/rightStick/left", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "right", + "id": "fcd248ae-a788-4676-a12e-f4d81205600b", + "path": "/leftStick/right", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "right", + "id": "1f04d9bc-c50b-41a1-bfcc-afb75475ec20", + "path": "/rightStick/right", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "", + "id": "fb8277d4-c5cd-4663-9dc7-ee3f0b506d90", + "path": "/dpad", + "interactions": "", + "processors": "", + "groups": ";Gamepad", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "Joystick", + "id": "e25d9774-381c-4a61-b47c-7b6b299ad9f9", + "path": "2DVector", + "interactions": "", + "processors": "", + "groups": "", + "action": "Navigate", + "isComposite": true, + "isPartOfComposite": false + }, + { + "name": "up", + "id": "3db53b26-6601-41be-9887-63ac74e79d19", + "path": "/stick/up", + "interactions": "", + "processors": "", + "groups": "Joystick", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "down", + "id": "0cb3e13e-3d90-4178-8ae6-d9c5501d653f", + "path": "/stick/down", + "interactions": "", + "processors": "", + "groups": "Joystick", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "left", + "id": "0392d399-f6dd-4c82-8062-c1e9c0d34835", + "path": "/stick/left", + "interactions": "", + "processors": "", + "groups": "Joystick", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "right", + "id": "942a66d9-d42f-43d6-8d70-ecb4ba5363bc", + "path": "/stick/right", + "interactions": "", + "processors": "", + "groups": "Joystick", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "Keyboard", + "id": "ff527021-f211-4c02-933e-5976594c46ed", + "path": "2DVector", + "interactions": "", + "processors": "", + "groups": "", + "action": "Navigate", + "isComposite": true, + "isPartOfComposite": false + }, + { + "name": "up", + "id": "563fbfdd-0f09-408d-aa75-8642c4f08ef0", + "path": "/w", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "up", + "id": "eb480147-c587-4a33-85ed-eb0ab9942c43", + "path": "/upArrow", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "down", + "id": "2bf42165-60bc-42ca-8072-8c13ab40239b", + "path": "/s", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "down", + "id": "85d264ad-e0a0-4565-b7ff-1a37edde51ac", + "path": "/downArrow", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "left", + "id": "74214943-c580-44e4-98eb-ad7eebe17902", + "path": "/a", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "left", + "id": "cea9b045-a000-445b-95b8-0c171af70a3b", + "path": "/leftArrow", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "right", + "id": "8607c725-d935-4808-84b1-8354e29bab63", + "path": "/d", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "right", + "id": "4cda81dc-9edd-4e03-9d7c-a71a14345d0b", + "path": "/rightArrow", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Navigate", + "isComposite": false, + "isPartOfComposite": true + }, + { + "name": "", + "id": "9e92bb26-7e3b-4ec4-b06b-3c8f8e498ddc", + "path": "*/{Submit}", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse;Gamepad;Touch;Joystick;XR", + "action": "Submit", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "82627dcc-3b13-4ba9-841d-e4b746d6553e", + "path": "*/{Cancel}", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse;Gamepad;Touch;Joystick;XR", + "action": "Cancel", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "c52c8e0b-8179-41d3-b8a1-d149033bbe86", + "path": "/position", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Point", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "e1394cbc-336e-44ce-9ea8-6007ed6193f7", + "path": "/position", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "Point", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "5693e57a-238a-46ed-b5ae-e64e6e574302", + "path": "/touch*/position", + "interactions": "", + "processors": "", + "groups": "Touch", + "action": "Point", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "4faf7dc9-b979-4210-aa8c-e808e1ef89f5", + "path": "/leftButton", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "Click", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "8d66d5ba-88d7-48e6-b1cd-198bbfef7ace", + "path": "/tip", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "Click", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "47c2a644-3ebc-4dae-a106-589b7ca75b59", + "path": "/touch*/press", + "interactions": "", + "processors": "", + "groups": "Touch", + "action": "Click", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "bb9e6b34-44bf-4381-ac63-5aa15d19f677", + "path": "/trigger", + "interactions": "", + "processors": "", + "groups": "XR", + "action": "Click", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "38c99815-14ea-4617-8627-164d27641299", + "path": "/scroll", + "interactions": "", + "processors": "", + "groups": ";Keyboard&Mouse", + "action": "ScrollWheel", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "4c191405-5738-4d4b-a523-c6a301dbf754", + "path": "/rightButton", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "RightClick", + "isComposite": false, + "isPartOfComposite": false + }, + { + "name": "", + "id": "24066f69-da47-44f3-a07e-0015fb02eb2e", + "path": "/middleButton", + "interactions": "", + "processors": "", + "groups": "Keyboard&Mouse", + "action": "MiddleClick", + "isComposite": false, + "isPartOfComposite": false + } + ] + } + ], + "controlSchemes": [ + { + "name": "Keyboard&Mouse", + "bindingGroup": "Keyboard&Mouse", + "devices": [ + { + "devicePath": "", + "isOptional": false, + "isOR": false + }, + { + "devicePath": "", + "isOptional": false, + "isOR": false + } + ] + }, + { + "name": "Gamepad", + "bindingGroup": "Gamepad", + "devices": [ + { + "devicePath": "", + "isOptional": false, + "isOR": false + } + ] + }, + { + "name": "Touch", + "bindingGroup": "Touch", + "devices": [ + { + "devicePath": "", + "isOptional": false, + "isOR": false + } + ] + }, + { + "name": "Joystick", + "bindingGroup": "Joystick", + "devices": [ + { + "devicePath": "", + "isOptional": false, + "isOR": false + } + ] + }, + { + "name": "XR", + "bindingGroup": "XR", + "devices": [ + { + "devicePath": "", + "isOptional": false, + "isOR": false + } + ] + } + ] +} \ No newline at end of file diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsTemplate.inputactions.meta b/Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsTemplate.inputactions.meta new file mode 100644 index 0000000000..c27a6f7bab --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsTemplate.inputactions.meta @@ -0,0 +1,14 @@ +fileFormatVersion: 2 +guid: 8a190d472354bb845973412ac9c5c477 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 8404be70184654265930450def6a9037, type: 3} + generateWrapperCode: 0 + wrapperCodePath: + wrapperClassName: + wrapperCodeNamespace: diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsBuildProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsBuildProvider.cs index d22c0b2f30..17d3fbd9ca 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsBuildProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsBuildProvider.cs @@ -9,21 +9,31 @@ namespace UnityEngine.InputSystem.Editor { internal class InputSettingsBuildProvider : IPreprocessBuildWithReport, IPostprocessBuildWithReport { + InputActionAsset m_ProjectWideActions; + Object[] m_OriginalPreloadedAssets; public int callbackOrder => 0; public void OnPreprocessBuild(BuildReport report) { - if (InputSystem.settings == null) - return; + m_OriginalPreloadedAssets = PlayerSettings.GetPreloadedAssets(); + var preloadedAssets = PlayerSettings.GetPreloadedAssets(); - // If we operate on temporary object instead of input setting asset, - // adding temporary asset would result in preloadedAssets containing null object "{fileID: 0}". - // Hence we ignore adding temporary objects to preloaded assets. - if (!EditorUtility.IsPersistent(InputSystem.settings)) +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + EditorBuildSettings.TryGetConfigObject(InputSettingsProvider.kEditorBuildSettingsActionsConfigKey, + out m_ProjectWideActions); + + if (m_ProjectWideActions != null) + { + if (!preloadedAssets.Contains(InputSystem.actions)) + { + ArrayHelpers.Append(ref preloadedAssets, InputSystem.actions); + PlayerSettings.SetPreloadedAssets(preloadedAssets); + } + } +#endif + if (InputSystem.settings == null) return; - // Add InputSettings object assets, if it's not in there already. - var preloadedAssets = PlayerSettings.GetPreloadedAssets(); if (!preloadedAssets.Contains(InputSystem.settings)) { ArrayHelpers.Append(ref preloadedAssets, InputSystem.settings); @@ -33,19 +43,8 @@ public void OnPreprocessBuild(BuildReport report) public void OnPostprocessBuild(BuildReport report) { - // Revert back to original state by removing all input settings from preloaded assets. - var preloadedAssets = PlayerSettings.GetPreloadedAssets(); - while (preloadedAssets != null && preloadedAssets.Length > 0) - { - var index = preloadedAssets.IndexOf(x => x is InputSettings); - if (index != -1) - { - ArrayHelpers.EraseAt(ref preloadedAssets, index); - PlayerSettings.SetPreloadedAssets(preloadedAssets); - } - else - break; - } + // Revert back to original state + PlayerSettings.SetPreloadedAssets(m_OriginalPreloadedAssets); } } } diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsProvider.cs index 83379fc536..7bb317014c 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/Settings/InputSettingsProvider.cs @@ -16,6 +16,7 @@ namespace UnityEngine.InputSystem.Editor internal class InputSettingsProvider : SettingsProvider, IDisposable { public const string kEditorBuildSettingsConfigKey = "com.unity.input.settings"; + public const string kEditorBuildSettingsActionsConfigKey = "com.unity.input.settings.actions"; public const string kSettingsPath = "Project/Input System Package"; public static void Open() diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/Commands.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/Commands.cs index eabfc72754..e875462882 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/Commands.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/Commands.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Collections.Generic; using System.Linq; @@ -303,7 +303,7 @@ public static Command SaveAsset() { return (in InputActionsEditorState state) => { - InputActionsEditorWindow.SaveAsset(state.serializedObject); + InputActionsEditorWindowUtils.SaveAsset(state.serializedObject); return state; }; } @@ -316,7 +316,7 @@ public static Command ToggleAutoSave(bool newValue) { // If it changed from disabled to enabled, perform an initial save. if (newValue) - InputActionsEditorWindow.SaveAsset(state.serializedObject); + InputActionsEditorWindowUtils.SaveAsset(state.serializedObject); InputEditorUserSettings.autoSaveInputActionAssets = newValue; } diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/ControlSchemeCommands.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/ControlSchemeCommands.cs index fa02be7bdc..4d7e87f5c1 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/ControlSchemeCommands.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Commands/ControlSchemeCommands.cs @@ -1,7 +1,8 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Collections.Generic; using System.Linq; +using UnityEditor; using UnityEngine.InputSystem.Utilities; namespace UnityEngine.InputSystem.Editor @@ -32,7 +33,7 @@ public static Command RemoveDeviceRequirement(int selectedDeviceIndex) }; } - public static Command SaveControlScheme(string newName = "", bool updateExisting = false) + public static Command SaveControlScheme(string newControlSchemeName = "", bool updateExisting = false) { return (in InputActionsEditorState state) => { @@ -42,7 +43,9 @@ public static Command SaveControlScheme(string newName = "", bool updateExisting var controlScheme = controlSchemesArray .FirstOrDefault(sp => sp.FindPropertyRelative(nameof(InputControlScheme.m_Name)).stringValue == controlSchemeName); - // if the control scheme is null, we're saving a new control scheme, otherwise editing an existing one + var actionMaps = state.serializedObject.FindProperty(nameof(InputActionAsset.m_ActionMaps)); + + // If the control scheme is null, we're saving a new control scheme, otherwise editing an existing one if (controlScheme == null && updateExisting) throw new InvalidOperationException("Tried to update a non-existent control scheme."); @@ -52,8 +55,15 @@ public static Command SaveControlScheme(string newName = "", bool updateExisting controlSchemesArray.InsertArrayElementAtIndex(controlSchemesArray.arraySize); controlScheme = controlSchemesArray.GetArrayElementAtIndex(controlSchemesArray.arraySize - 1); } + // If we're renaming a control scheme, we need to update the bindings that use it and make a unique name + if (!string.IsNullOrEmpty(newControlSchemeName)) + { + newControlSchemeName = MakeUniqueControlSchemeName(state, newControlSchemeName); + RenameBindingsControlSchemeHelper(controlScheme, actionMaps, controlSchemeName, newControlSchemeName); + } - controlScheme.FindPropertyRelative(nameof(InputControlScheme.m_Name)).stringValue = string.IsNullOrEmpty(newName) ? controlSchemeName : newName; + controlScheme.FindPropertyRelative(nameof(InputControlScheme.m_Name)).stringValue = string.IsNullOrEmpty(newControlSchemeName) ? controlSchemeName : newControlSchemeName; + controlScheme.FindPropertyRelative(nameof(InputControlScheme.m_BindingGroup)).stringValue = string.IsNullOrEmpty(newControlSchemeName) ? controlSchemeName : newControlSchemeName; var serializedDeviceRequirements = controlScheme.FindPropertyRelative(nameof(InputControlScheme.m_DeviceRequirements)); serializedDeviceRequirements.ClearArray(); @@ -71,16 +81,40 @@ public static Command SaveControlScheme(string newName = "", bool updateExisting } state.serializedObject.ApplyModifiedProperties(); - return state.With(selectedControlScheme: new InputControlScheme(controlScheme)); + return state.With( + selectedControlScheme: new InputControlScheme(controlScheme), + // Select the control scheme updated, otherwise select the new one it was added + selectedControlSchemeIndex: updateExisting? state.selectedControlSchemeIndex: controlSchemesArray.arraySize - 1); }; } + static void RenameBindingsControlSchemeHelper(SerializedProperty controlScheme, SerializedProperty actionMaps, string controlSchemeName, string newName) + { + foreach (SerializedProperty actionMap in actionMaps) + { + var bindings = actionMap + .FindPropertyRelative(nameof(InputActionMap.m_Bindings)) + .Select(sp => new SerializedInputBinding(sp)) + .ToList(); + + var bindingsToRename = bindings.Where(b => b.controlSchemes.Contains(controlSchemeName)).ToList(); + + foreach (var binding in bindingsToRename) + { + var bindingGroups = binding.controlSchemes.ToList(); + bindingGroups.Remove(controlSchemeName); + bindingGroups.Add(newName); + binding.wrappedProperty.FindPropertyRelative(nameof(InputBinding.m_Groups)).stringValue = bindingGroups.Join(InputBinding.kSeparatorString); + } + } + } + public static Command SelectControlScheme(int controlSchemeIndex) { return (in InputActionsEditorState state) => { if (controlSchemeIndex == -1) - return state.With(selectedControlSchemeIndex: controlSchemeIndex); + return state.With(selectedControlSchemeIndex: controlSchemeIndex, selectedControlScheme: new InputControlScheme()); var controlSchemeSerializedProperty = state.serializedObject .FindProperty(nameof(InputActionAsset.m_ControlSchemes)) diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorSettingsProvider.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorSettingsProvider.cs index 801506b3c2..73b7065fec 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorSettingsProvider.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorSettingsProvider.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR // We use some UITK controls that are only available in 2022.2 or later (MultiColumnListView for example) +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System.Collections.Generic; using UnityEditor; using UnityEngine.UIElements; @@ -9,6 +9,10 @@ internal class InputActionsEditorSettingsProvider : SettingsProvider { public const string kSettingsPath = "Project/Input System Package/Actions"; + [SerializeField] InputActionsEditorState m_State; + VisualElement m_RootVisualElement; + StateContainer m_StateContainer; + public InputActionsEditorSettingsProvider(string path, SettingsScope scopes, IEnumerable keywords = null) : base(path, scopes, keywords) { @@ -16,16 +20,31 @@ public InputActionsEditorSettingsProvider(string path, SettingsScope scopes, IEn public override void OnActivate(string searchContext, VisualElement rootElement) { - var visualElement = Resources.Load("InputActionsEditor"); - visualElement.CloneTree(rootElement); + m_RootVisualElement = rootElement; + var asset = ProjectWideActionsAsset.GetOrCreate(); + var serializedAsset = new SerializedObject(asset); + m_State = new InputActionsEditorState(serializedAsset); + BuildUI(); + } + + private void OnStateChanged(InputActionsEditorState newState) + { + if (InputEditorUserSettings.autoSaveInputActionAssets) + InputActionsEditorWindowUtils.SaveAsset(m_State.serializedObject); + } + + private void BuildUI() + { + m_StateContainer = new StateContainer(m_RootVisualElement, m_State); + m_StateContainer.StateChanged += OnStateChanged; + m_RootVisualElement.styleSheets.Add(InputActionsEditorWindowUtils.theme); + new InputActionsEditorView(m_RootVisualElement, m_StateContainer); + m_StateContainer.Initialize(); } [SettingsProvider] public static SettingsProvider CreateGlobalInputActionsEditorProvider() { - if (!InputSystem.settings.IsFeatureEnabled(InputFeatureNames.kUseUIToolkitEditor)) - return null; - var provider = new InputActionsEditorSettingsProvider(kSettingsPath, SettingsScope.Project) { label = "Input Actions" diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorState.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorState.cs index 5a2ab79378..ca9f754b55 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorState.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorState.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Collections.Generic; using System.Collections.ObjectModel; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs index e76064f195..412ae0e2c9 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindow.cs @@ -1,6 +1,6 @@ // UITK TreeView is not supported in earlier versions // Therefore the UITK version of the InputActionAsset Editor is not available on earlier Editor versions either. -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.IO; using System.Linq; @@ -16,8 +16,12 @@ internal static class EnableUITKEditor { static EnableUITKEditor() { - // set this feature flag to true to enable the UITK editor - InputSystem.settings.SetInternalFeatureFlag(InputFeatureNames.kUseUIToolkitEditor, false); + // Controls whether the UITK version of the InputActionAsset Editor is enabled or not for + // editing standalone user Input Action assets. + // At the moment, the UITK Asset Editor doesn't have feature parity with the IMGUI version. + // This is set to false to show the IMGUI version of the InputActionAsset Editor instead. + // UITK Editor is always be used for the Project Settings Editor regardless of this setting. + InputSystem.settings.SetInternalFeatureFlag(InputFeatureNames.kUseUIToolkitEditorForAllAssets, false); } } @@ -25,11 +29,15 @@ internal class InputActionsEditorWindow : EditorWindow { private static readonly string k_FileExtension = "." + InputActionAsset.Extension; private int m_AssetId; + private string m_AssetPath; + private string m_AssetJson; + private bool m_IsDirty; + static readonly Vector2 k_MinWindowSize = new Vector2(650, 450); [OnOpenAsset] public static bool OpenAsset(int instanceId, int line) { - if (!InputSystem.settings.IsFeatureEnabled(InputFeatureNames.kUseUIToolkitEditor)) + if (!InputSystem.settings.IsFeatureEnabled(InputFeatureNames.kUseUIToolkitEditorForAllAssets)) return false; var path = AssetDatabase.GetAssetPath(instanceId); @@ -51,8 +59,10 @@ public static bool OpenAsset(int instanceId, int line) window.Focus(); return true; } + window.m_IsDirty = false; window.m_AssetId = instanceId; window.titleContent = new GUIContent("Input Actions Editor"); + window.minSize = k_MinWindowSize; window.SetAsset(asset); window.Show(); @@ -74,8 +84,10 @@ private static InputActionsEditorWindow GetOrCreateWindow(int id, out bool isAlr private void SetAsset(InputActionAsset asset) { + m_AssetPath = AssetDatabase.GetAssetPath(asset); var serializedAsset = new SerializedObject(asset); m_State = new InputActionsEditorState(serializedAsset); + m_AssetJson = File.ReadAllText(m_AssetPath); bool isGUIDObtained = AssetDatabase.TryGetGUIDAndLocalFileIdentifier(asset, out m_AssetGUID, out long _); Debug.Assert(isGUIDObtained, $"Failed to get asset {asset.name} GUID"); @@ -95,6 +107,8 @@ private void CreateGUI() if (m_State.serializedObject == null) { var asset = GetAssetFromDatabase(); + m_AssetPath = AssetDatabase.GetAssetPath(asset); + m_AssetJson = File.ReadAllText(m_AssetPath); var serializedAsset = new SerializedObject(asset); m_State = new InputActionsEditorState(m_State, serializedAsset); } @@ -119,34 +133,79 @@ private void BuildUI() private void OnStateChanged(InputActionsEditorState newState) { + DirtyInputActionsEditorWindow(newState); if (InputEditorUserSettings.autoSaveInputActionAssets) - SaveAsset(m_State.serializedObject); + InputActionsEditorWindowUtils.SaveAsset(m_State.serializedObject); } - private InputActionAsset GetAssetFromDatabase() + private void DirtyInputActionsEditorWindow(InputActionsEditorState newState) { - Debug.Assert(!string.IsNullOrEmpty(m_AssetGUID), "Asset GUID is empty"); - var assetPath = AssetDatabase.GUIDToAssetPath(m_AssetGUID); - return AssetDatabase.LoadAssetAtPath(assetPath); + var isWindowDirty = !InputEditorUserSettings.autoSaveInputActionAssets && HasAssetChanged(newState.serializedObject); + if (m_IsDirty == isWindowDirty) + return; + m_IsDirty = isWindowDirty; + titleContent = m_IsDirty ? new GUIContent("(*) Input Actions Editor") : new GUIContent("Input Actions Editor"); } - [SerializeField] private InputActionsEditorState m_State; - [SerializeField] private string m_AssetGUID; - - public static void SaveAsset(SerializedObject serializedAsset) + private bool HasAssetChanged(SerializedObject serializedAsset) { var asset = (InputActionAsset)serializedAsset.targetObject; - var assetPath = AssetDatabase.GetAssetPath(asset); - var assetJson = asset.ToJson(); + var newAssetJson = asset.ToJson(); + return newAssetJson != m_AssetJson; + } - var existingJson = File.ReadAllText(assetPath); - if (assetJson != existingJson) + private void OnDestroy() + { + ConfirmSaveChangesIfNeeded(); + } + + private void ConfirmSaveChangesIfNeeded() + { + // Do we have unsaved changes? + if (!m_IsDirty) + return; + + var result = EditorUtility.DisplayDialogComplex("Input Action Asset has been modified", $"Do you want to save the changes you made in:\n{m_AssetPath}\n\nYour changes will be lost if you don't save them.", "Save", "Cancel", "Don't Save"); + switch (result) { - EditorHelpers.CheckOut(assetPath); - File.WriteAllText(assetPath, assetJson); - AssetDatabase.ImportAsset(assetPath); + case 0: // Save + InputActionsEditorWindowUtils.SaveAsset(m_State.serializedObject); + break; + case 1: // Cancel editor quit. (open new editor window with the edited asset) + ReshowEditorWindowWithUnsavedChanges(); + break; + case 2: // Don't save, quit - reload the old asset from the json to prevent the asset from being dirtied + AssetDatabase.ImportAsset(m_AssetPath); + break; } } + + private void ReshowEditorWindowWithUnsavedChanges() + { + var window = CreateWindow(); + CopyOldStatsToNewWindow(window); + window.BuildUI(); + window.Show(); + } + + private void CopyOldStatsToNewWindow(InputActionsEditorWindow window) + { + window.m_AssetId = m_AssetId; + window.m_State = m_State; + window.m_AssetPath = m_AssetPath; + window.m_AssetJson = m_AssetJson; + window.m_IsDirty = true; + } + + private InputActionAsset GetAssetFromDatabase() + { + Debug.Assert(!string.IsNullOrEmpty(m_AssetGUID), "Asset GUID is empty"); + var assetPath = AssetDatabase.GUIDToAssetPath(m_AssetGUID); + return AssetDatabase.LoadAssetAtPath(assetPath); + } + + [SerializeField] private InputActionsEditorState m_State; + [SerializeField] private string m_AssetGUID; } } diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindowUtils.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindowUtils.cs new file mode 100644 index 0000000000..1ace6c81bd --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindowUtils.cs @@ -0,0 +1,35 @@ +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS +using System.IO; +using UnityEditor; +using UnityEngine.UIElements; + +namespace UnityEngine.InputSystem.Editor +{ + internal class InputActionsEditorWindowUtils + { + public static StyleSheet theme => EditorGUIUtility.isProSkin + ? AssetDatabase.LoadAssetAtPath(InputActionsEditorConstants.PackagePath + InputActionsEditorConstants.ResourcesPath + "/InputAssetEditorDark.uss") + : AssetDatabase.LoadAssetAtPath(InputActionsEditorConstants.PackagePath + InputActionsEditorConstants.ResourcesPath + "/InputAssetEditorLight.uss"); + + public static void SaveAsset(SerializedObject serializedAsset) + { + var asset = (InputActionAsset)serializedAsset.targetObject; + // for the global actions asset: save differently (as it is a yaml file and not a json) + if (asset.name == ProjectWideActionsAsset.kAssetName) + { + AssetDatabase.SaveAssets(); + return; + } + var assetPath = AssetDatabase.GetAssetPath(asset); + var assetJson = asset.ToJson(); + var existingJson = File.Exists(assetPath) ? File.ReadAllText(assetPath) : ""; + if (assetJson != existingJson) + { + EditorHelpers.CheckOut(assetPath); + File.WriteAllText(assetPath, assetJson); + AssetDatabase.ImportAsset(assetPath); + } + } + } +} +#endif diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindowUtils.cs.meta b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindowUtils.cs.meta new file mode 100644 index 0000000000..f1509991e7 --- /dev/null +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/InputActionsEditorWindowUtils.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3b8e35f20292579409c899395e30948f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Resources/InputActionsEditor.uxml b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Resources/InputActionsEditor.uxml index f709cfda11..593243960e 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Resources/InputActionsEditor.uxml +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Resources/InputActionsEditor.uxml @@ -4,16 +4,13 @@ - - - - + diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Resources/InputActionsEditorStyles.uss b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Resources/InputActionsEditorStyles.uss index 3603042efa..e9a6e3f089 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Resources/InputActionsEditorStyles.uss +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Resources/InputActionsEditorStyles.uss @@ -7,7 +7,7 @@ } .body-panel-container { - min-width: auto; + min-width: 150px; border-top-width: 1px; border-left-color: rgb(25, 25, 25); border-right-color: rgb(25, 25, 25); @@ -164,9 +164,18 @@ } .search-field { + /* hide while not implemented */ + display: none; width: 190px; } +#save-asset-toolbar-container +{ + /* hide while always autosaving in project wide settings */ + display: none; +} + + .unity-two-pane-split-view__dragline-anchor { background-color: rgb(25, 25, 25); } diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/SerializedInputAction.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/SerializedInputAction.cs index 223b67c98c..e6792023ba 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/SerializedInputAction.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/SerializedInputAction.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using UnityEditor; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/SerializedInputBinding.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/SerializedInputBinding.cs index 466e924c5c..21bef1c96a 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/SerializedInputBinding.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/SerializedInputBinding.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Linq; using UnityEditor; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/StateContainer.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/StateContainer.cs index b9001575b6..04ed660258 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/StateContainer.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/StateContainer.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Linq.Expressions; using UnityEditor; @@ -19,6 +19,7 @@ public StateContainer(VisualElement rootVisualElement, InputActionsEditorState i m_RootVisualElement = rootVisualElement; m_State = initialState; + rootVisualElement.Unbind(); m_RootVisualElement.TrackSerializedObjectValue(initialState.serializedObject, so => { StateChanged?.Invoke(m_State); diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionMapsView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionMapsView.cs index 33f0408a06..184df5dfe8 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionMapsView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionMapsView.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System.Collections.Generic; using System.Linq; using UnityEngine.InputSystem.Utilities; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionPropertiesView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionPropertiesView.cs index a709074d70..b2fa3edab8 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionPropertiesView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionPropertiesView.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Collections.Generic; using System.Linq; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionsTreeView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionsTreeView.cs index f636b20cb9..11f1b241be 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionsTreeView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ActionsTreeView.cs @@ -1,6 +1,6 @@ // UITK TreeView is not supported in earlier versions // Therefore the UITK version of the InputActionAsset Editor is not available on earlier Editor versions either. -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Collections.Generic; using System.Linq; @@ -49,6 +49,7 @@ public ActionsTreeView(VisualElement root, StateContainer stateContainer) if (item.isAction) { addBindingButton.style.display = DisplayStyle.Flex; + addBindingButton.clickable = null; //reset the clickable to avoid multiple subscriptions addBindingButton.clicked += () => AddBinding(item.name); treeViewItem.EditTextFinishedCallback = newName => { @@ -144,21 +145,22 @@ private int GetSelectedElementId(InputActionsEditorState state, List> treeList, int selectedBindingIndex) + private int GetComponentOrBindingID(List> treeItemList, int selectedBindingIndex) { - var currentBindingIndex = -1; - foreach (var action in treeList) + foreach (var actionItem in treeItemList) { - foreach (var bindingOrComponent in action.children) + // Look for the element ID by checking if the selected binding index matches the binding index of + // the ActionOrBindingData of the item. Deals with composite bindings as well. + foreach (var bindingOrComponentItem in actionItem.children) { - currentBindingIndex++; - if (currentBindingIndex == selectedBindingIndex) return bindingOrComponent.id; - if (bindingOrComponent.hasChildren) + if (bindingOrComponentItem.data.bindingIndex == selectedBindingIndex) + return bindingOrComponentItem.id; + if (bindingOrComponentItem.hasChildren) { - foreach (var binding in bindingOrComponent.children) + foreach (var bindingItem in bindingOrComponentItem.children) { - currentBindingIndex++; - if (currentBindingIndex == selectedBindingIndex) return binding.id; + if (bindingOrComponentItem.data.bindingIndex == selectedBindingIndex) + return bindingItem.id; } } } @@ -238,7 +240,7 @@ private void OnKeyDownEvent(KeyDownEvent e) { if (e.keyCode == KeyCode.F2) OnKeyDownEventForRename(); - else if (e.keyCode == KeyCode.Space) + else if (e.keyCode == KeyCode.Delete) OnKeyDownEventForDelete(); } @@ -291,6 +293,7 @@ public static List> GetActionsAsTreeViewDa var actionMapIndex = state.selectedActionMapIndex; var actionMaps = state.serializedObject.FindProperty(nameof(InputActionAsset.m_ActionMaps)); + var controlSchemes = state.serializedObject.FindProperty(nameof(InputActionAsset.m_ControlSchemes)); var actionMap = actionMapIndex == -1 || actionMaps.arraySize <= 0 ? null : actionMaps.GetArrayElementAtIndex(actionMapIndex); @@ -323,10 +326,14 @@ public static List> GetActionsAsTreeViewDa var nextBinding = actionBindings[++i]; while (nextBinding.isPartOfComposite) { - var name = GetHumanReadableCompositeName(nextBinding, state.selectedControlScheme, state.selectedControlSchemeIndex); - - compositeItems.Add(new TreeViewItemData(id++, - new ActionOrBindingData(false, name, actionMapIndex, false, GetControlLayout(nextBinding.path), nextBinding.indexOfBinding))); + var isVisible = ShouldBindingBeVisible(nextBinding, state.selectedControlScheme); + if (isVisible) + { + var name = GetHumanReadableCompositeName(nextBinding, state.selectedControlScheme, controlSchemes); + compositeItems.Add(new TreeViewItemData(id++, + new ActionOrBindingData(false, name, actionMapIndex, false, + GetControlLayout(nextBinding.path), nextBinding.indexOfBinding))); + } if (++i >= actionBindings.Count) break; @@ -340,9 +347,11 @@ public static List> GetActionsAsTreeViewDa } else { - bindingItems.Add(new TreeViewItemData(id++, - new ActionOrBindingData(false, GetHumanReadableBindingName(serializedInputBinding, state.selectedControlSchemeIndex, state.selectedControlScheme), actionMapIndex, - false, GetControlLayout(serializedInputBinding.path), serializedInputBinding.indexOfBinding))); + var isVisible = ShouldBindingBeVisible(serializedInputBinding, state.selectedControlScheme); + if (isVisible) + bindingItems.Add(new TreeViewItemData(id++, + new ActionOrBindingData(false, GetHumanReadableBindingName(serializedInputBinding, state.selectedControlScheme, controlSchemes), actionMapIndex, + false, GetControlLayout(serializedInputBinding.path), serializedInputBinding.indexOfBinding))); } } actionItems.Add(new TreeViewItemData(id++, @@ -351,28 +360,42 @@ public static List> GetActionsAsTreeViewDa return actionItems; } - private static string GetHumanReadableBindingName(SerializedInputBinding serializedInputBinding, int currentControlSchemeIndex, InputControlScheme? currentControlScheme) + private static string GetHumanReadableBindingName(SerializedInputBinding serializedInputBinding, InputControlScheme? currentControlScheme, SerializedProperty allControlSchemes) { var name = InputControlPath.ToHumanReadableString(serializedInputBinding.path); if (String.IsNullOrEmpty(name)) name = ""; - if (!IsBindingPartOfCurrentControlScheme(serializedInputBinding, currentControlScheme, currentControlSchemeIndex)) + if (IsBindingAssignedToNoControlSchemes(serializedInputBinding, allControlSchemes, currentControlScheme)) name += " {GLOBAL}"; return name; } - private static bool IsBindingPartOfCurrentControlScheme(SerializedInputBinding serializedInputBinding, InputControlScheme? currentControlScheme, int currentControlSchemeIndex) + private static bool IsBindingAssignedToNoControlSchemes(SerializedInputBinding serializedInputBinding, SerializedProperty allControlSchemes, InputControlScheme? currentControlScheme) { - if (currentControlScheme.HasValue && currentControlSchemeIndex >= 0) - return serializedInputBinding.controlSchemes.Contains(currentControlScheme.Value.name); + if (allControlSchemes.arraySize <= 0 || !currentControlScheme.HasValue || string.IsNullOrEmpty(currentControlScheme.Value.name)) + return false; + if (serializedInputBinding.controlSchemes.Length <= 0) + return true; + return false; + } + private static bool ShouldBindingBeVisible(SerializedInputBinding serializedInputBinding, InputControlScheme? currentControlScheme) + { + if (currentControlScheme.HasValue && !string.IsNullOrEmpty(currentControlScheme.Value.name)) + { + //if binding is global (not assigned to any control scheme) show always + if (serializedInputBinding.controlSchemes.Length <= 0) + return true; + return serializedInputBinding.controlSchemes.Contains(currentControlScheme.Value.name); + } + //if no control scheme selected then show all bindings return true; } - internal static string GetHumanReadableCompositeName(SerializedInputBinding binding, InputControlScheme? currentControlScheme, int currentControlSchemeIndex) + internal static string GetHumanReadableCompositeName(SerializedInputBinding binding, InputControlScheme? currentControlScheme, SerializedProperty allControlSchemes) { return $"{ObjectNames.NicifyVariableName(binding.name)}: " + - $"{GetHumanReadableBindingName(binding, currentControlSchemeIndex, currentControlScheme)}"; + $"{GetHumanReadableBindingName(binding, currentControlScheme, allControlSchemes)}"; } private static string GetControlLayout(string path) diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/BindingPropertiesView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/BindingPropertiesView.cs index 688b098fab..9fbaf9d099 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/BindingPropertiesView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/BindingPropertiesView.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System.Linq; using UnityEditor; using UnityEngine.UIElements; @@ -23,6 +23,7 @@ public BindingPropertiesView(VisualElement root, Foldout foldout, StateContainer (_, controlSchemes, s) => new ViewState { controlSchemes = controlSchemes, + currentControlScheme = s.selectedControlScheme, selectedBinding = Selectors.GetSelectedBinding(s), selectedBindingIndex = s.selectedBindingIndex, selectedBindingPath = Selectors.GetSelectedBindingPath(s), @@ -57,6 +58,7 @@ public override void RedrawUI(ViewState viewState) { var controlPathEditor = new InputControlPathEditor(viewState.selectedBindingPath, new InputControlPickerState(), () => { Dispatch(Commands.ApplyModifiedProperties()); }); + controlPathEditor.SetControlPathsToMatch(viewState.currentControlScheme.deviceRequirements.Select(x => x.controlPath)); var inputAction = viewState.selectedInputAction; controlPathEditor.SetExpectedControlLayout(inputAction?.expectedControlType ?? ""); @@ -100,6 +102,7 @@ internal class ViewState public int selectedBindingIndex; public SerializedInputBinding? selectedBinding; public ViewStateCollection controlSchemes; + public InputControlScheme currentControlScheme; public SerializedProperty selectedBindingPath; public SerializedInputAction? selectedInputAction; } diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/CompositeBindingPropertiesView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/CompositeBindingPropertiesView.cs index 466dc57537..d8af8b7abe 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/CompositeBindingPropertiesView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/CompositeBindingPropertiesView.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Collections.Generic; using System.Linq; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/CompositePartBindingPropertiesView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/CompositePartBindingPropertiesView.cs index ea225d66d9..686fc5f936 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/CompositePartBindingPropertiesView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/CompositePartBindingPropertiesView.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Collections.Generic; using System.Linq; @@ -40,6 +40,7 @@ public override void RedrawUI(ViewState viewState) var controlPathEditor = new InputControlPathEditor(viewState.selectedBindingPath, new InputControlPickerState(), () => { Dispatch(Commands.ApplyModifiedProperties()); }); + controlPathEditor.SetControlPathsToMatch(viewState.currentControlScheme.deviceRequirements.Select(x => x.controlPath)); controlPathEditor.SetExpectedControlLayout(viewState.expectedControlLayoutName); m_PathEditorContainer.onGUIHandler = controlPathEditor.OnGUI; @@ -59,6 +60,7 @@ internal class ViewState public SerializedProperty selectedBindingPath; public SerializedInputBinding selectedBinding; public IEnumerable compositePartNames; + public InputControlScheme currentControlScheme; public string expectedControlLayoutName; public string selectedCompositePartName; } @@ -78,6 +80,7 @@ public static CompositePartBindingPropertiesView.ViewState GetCompositePartBindi selectedBinding = binding, selectedBindingPath = GetSelectedBindingPath(state), selectedCompositePartName = selectedCompositePartName, + currentControlScheme = state.selectedControlScheme, compositePartNames = compositeParts.Select(ObjectNames.NicifyVariableName).ToList(), expectedControlLayoutName = InputBindingComposite.GetExpectedControlLayoutName(binding.compositePath, binding.name) ?? "" }; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ContextMenu.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ContextMenu.cs index b06ef5d898..fa9a8e4088 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ContextMenu.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ContextMenu.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using UnityEngine.UIElements; namespace UnityEngine.InputSystem.Editor diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ControlSchemesView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ControlSchemesView.cs index 02200e33f7..386df4c0d2 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ControlSchemesView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ControlSchemesView.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Collections.Generic; using System.Linq; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionViewsControlsHolder.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionViewsControlsHolder.cs index 39d1ece872..3bdb74eec1 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionViewsControlsHolder.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionViewsControlsHolder.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using UnityEngine.UIElements; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs index ab046b4a20..55bcef0fe5 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsEditorView.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Collections.Generic; using System.Linq; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsTreeViewItem.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsTreeViewItem.cs index e26a6bade7..9bd463d4ad 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsTreeViewItem.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/InputActionsTreeViewItem.cs @@ -1,6 +1,6 @@ // UITK TreeView is not supported in earlier versions // Therefore the UITK version of the InputActionAsset Editor is not available on earlier Editor versions either. -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System.Threading.Tasks; using UnityEditor; using UnityEngine.InputSystem.Editor; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/NameAndParametersListView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/NameAndParametersListView.cs index e28d287739..0c1a7ee04c 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/NameAndParametersListView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/NameAndParametersListView.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Collections.Generic; using System.Linq; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/PropertiesView.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/PropertiesView.cs index 2c1ed6d523..f1bd92e6fe 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/PropertiesView.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/PropertiesView.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Linq; using UnityEditor; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/Selectors.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/Selectors.cs index 1648b05aac..421bc9fcc1 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/Selectors.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/Selectors.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Collections.Generic; using System.Linq; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ViewBase.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ViewBase.cs index 6db29b955d..ed859e2d7c 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ViewBase.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/ViewBase.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using System.Collections.Generic; diff --git a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/VisualElementExtensions.cs b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/VisualElementExtensions.cs index fc757cb320..aac90094bb 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/VisualElementExtensions.cs +++ b/Packages/com.unity.inputsystem/InputSystem/Editor/UITKAssetEditor/Views/VisualElementExtensions.cs @@ -1,4 +1,4 @@ -#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR +#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS using System; using UnityEngine.UIElements; diff --git a/Packages/com.unity.inputsystem/InputSystem/InputFeatureNames.cs b/Packages/com.unity.inputsystem/InputSystem/InputFeatureNames.cs index a6be01b1ac..d28b6c3484 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputFeatureNames.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputFeatureNames.cs @@ -9,8 +9,8 @@ internal static class InputFeatureNames public const string kUseReadValueCaching = "USE_READ_VALUE_CACHING"; public const string kParanoidReadValueCachingChecks = "PARANOID_READ_VALUE_CACHING_CHECKS"; -#if UNITY_INPUT_SYSTEM_UI_TK_ASSET_EDITOR - public const string kUseUIToolkitEditor = "USE_UITOOLKIT_EDITOR"; +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + public const string kUseUIToolkitEditorForAllAssets = "USE_UITOOLKIT_EDITOR"; #endif } } diff --git a/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs b/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs index 1b83ab4f68..a550ed6f2a 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputManagerStateMonitors.cs @@ -14,7 +14,7 @@ internal partial class InputManager ////TODO: support combining monitors for bitfields public void AddStateChangeMonitor(InputControl control, IInputStateChangeMonitor monitor, long monitorIndex, uint groupIndex) { - Debug.Assert(m_DevicesCount > 0); + if (m_DevicesCount <= 0) return; var device = control.device; var deviceIndex = device.m_DeviceIndex; diff --git a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs index 88cfbc52cf..c9c31911ef 100644 --- a/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs +++ b/Packages/com.unity.inputsystem/InputSystem/InputSystem.cs @@ -3009,6 +3009,68 @@ internal static bool ShouldDrawWarningIconForBinding(string bindingPath) #region Actions +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + + private static InputActionAsset s_projectWideActions; + internal const string kProjectWideActionsAssetName = "ProjectWideInputActions"; + + /// + /// An input action asset (see ) which is always available by default. + /// + /// + /// A default set of actions and action maps are installed and enabled by default on every project. + /// These actions and their bindings may be modified in the Project Settings. + /// + /// + /// + /// + public static InputActionAsset actions + { + get + { + if (s_projectWideActions != null) + return s_projectWideActions; + + #if UNITY_EDITOR + // Load the InputActionsAsset and store it in EditorBuildSettings so it can be packed in Player builds + s_projectWideActions = Editor.ProjectWideActionsAsset.GetOrCreate(); + if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(s_projectWideActions))) + { + EditorBuildSettings.AddConfigObject(InputSettingsProvider.kEditorBuildSettingsActionsConfigKey, + s_projectWideActions, true); + } + #else + s_projectWideActions = Resources.FindObjectsOfTypeAll().FirstOrDefault(o => o != null && o.name == kProjectWideActionsAssetName); + #endif + + if (s_projectWideActions == null) + Debug.LogError($"Couldn't initialize project-wide input actions"); + return s_projectWideActions; + } + + set + { + if (value == null) + throw new ArgumentNullException(nameof(value)); + + if (s_projectWideActions == value) + return; + + #if UNITY_EDITOR + if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(value))) + { + EditorBuildSettings.AddConfigObject(InputSettingsProvider.kEditorBuildSettingsActionsConfigKey, + value, true); + } + #endif + + s_projectWideActions?.Disable(); + s_projectWideActions = value; + s_projectWideActions.Enable(); + } + } +#endif + /// /// Event that is signalled when the state of enabled actions in the system changes or /// when actions are triggered. @@ -3603,6 +3665,12 @@ private static void InitializeInPlayer(IInputRuntime runtime = null, InputSettin if (ShouldEnableRemoting()) SetUpRemoting(); #endif + +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS && !UNITY_INCLUDE_TESTS + // Touching the `actions` property here will initialise it here (if it wasn't already). + // This is the point where we initialise project-wide actions for the Player + actions?.Enable(); +#endif } #endif // UNITY_EDITOR @@ -3690,6 +3758,16 @@ private static void Reset(bool enableRemoting = false, IInputRuntime runtime = n { Profiler.BeginSample("InputSystem.Reset"); +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Avoid touching the `actions` property directly here, to prevent unwanted initialisation. + if (s_projectWideActions) + { + s_projectWideActions.Disable(); + s_projectWideActions?.OnSetupChanged(); // Cleanup ActionState (remove unused controls after disabling) + s_projectWideActions = null; + } +#endif + // Some devices keep globals. Get rid of them by pretending the devices // are removed. if (s_Manager != null) @@ -3730,6 +3808,13 @@ private static void Reset(bool enableRemoting = false, IInputRuntime runtime = n InputEventListener.s_ObserverState = default; InputUser.ResetGlobals(); EnhancedTouchSupport.Reset(); + +#if UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS + // Touching the `actions` property will initialise it here (if it wasn't already). + // This is the point where we initialise project-wide actions for the Editor, Editor Tests and Player Tests. + actions?.Enable(); +#endif + Profiler.EndSample(); } @@ -3744,7 +3829,6 @@ private static void Destroy() // NOTE: Does not destroy InputSystemObject. We want to destroy input system // state repeatedly during tests but we want to not create InputSystemObject // over and over. - s_Manager.Destroy(); if (s_RemoteConnection != null) Object.DestroyImmediate(s_RemoteConnection); diff --git a/Packages/com.unity.inputsystem/InputSystem/Unity.InputSystem.asmdef b/Packages/com.unity.inputsystem/InputSystem/Unity.InputSystem.asmdef index 7b94feeab7..94c020739e 100644 --- a/Packages/com.unity.inputsystem/InputSystem/Unity.InputSystem.asmdef +++ b/Packages/com.unity.inputsystem/InputSystem/Unity.InputSystem.asmdef @@ -1,5 +1,6 @@ { "name": "Unity.InputSystem", + "rootNamespace": "", "references": [ "Unity.ugui" ], @@ -70,6 +71,11 @@ "name": "Unity", "expression": "2022.2", "define": "HAS_SET_LOCAL_POSITION_AND_ROTATION" + }, + { + "name": "Unity", + "expression": "2022.3", + "define": "UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS" } ], "noEngineReferences": false diff --git a/Packages/com.unity.inputsystem/Tests/TestFixture/AssemblyInfo.cs b/Packages/com.unity.inputsystem/Tests/TestFixture/AssemblyInfo.cs index 55ebaa2595..b0820402a2 100644 --- a/Packages/com.unity.inputsystem/Tests/TestFixture/AssemblyInfo.cs +++ b/Packages/com.unity.inputsystem/Tests/TestFixture/AssemblyInfo.cs @@ -4,7 +4,7 @@ // Keep this in sync with "Packages/com.unity.inputsystem/package.json". // NOTE: Unfortunately, System.Version doesn't use semantic versioning so we can't include // "-preview" suffixes here. -[assembly: AssemblyVersion("1.7.0")] +[assembly: AssemblyVersion("1.8.0")] [assembly: InternalsVisibleTo("Unity.InputSystem.Tests.Editor")] [assembly: InternalsVisibleTo("Unity.InputSystem.Tests")] [assembly: InternalsVisibleTo("Unity.InputSystem.IntegrationTests")] diff --git a/Packages/com.unity.inputsystem/package.json b/Packages/com.unity.inputsystem/package.json index 8428aa9ce8..10f2e80a81 100755 --- a/Packages/com.unity.inputsystem/package.json +++ b/Packages/com.unity.inputsystem/package.json @@ -1,7 +1,7 @@ { "name": "com.unity.inputsystem", "displayName": "Input System", - "version": "1.7.0", + "version": "1.8.0-pre.1", "unity": "2019.4", "description": "A new input system which can be used as a more extensible and customizable alternative to Unity's classic input system in UnityEngine.Input.", "keywords": [