This commit is contained in:
2025-01-17 13:10:42 +01:00
commit 4536213c91
15115 changed files with 1442174 additions and 0 deletions

View File

@@ -0,0 +1,242 @@
#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine.InputSystem.Utilities;
namespace UnityEngine.InputSystem.Editor
{
internal static class ProjectWideActionsAsset
{
private const string kDefaultAssetName = "InputSystem_Actions";
private const string kDefaultAssetPath = "Assets/" + kDefaultAssetName + ".inputactions";
private const string kDefaultTemplateAssetPath = "Packages/com.unity.inputsystem/InputSystem/Editor/ProjectWideActions/ProjectWideActionsTemplate.json";
internal static class ProjectSettingsProjectWideActionsAssetConverter
{
class ProjectSettingsPostprocessor : AssetPostprocessor
{
#if UNITY_2021_2_OR_NEWER
private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths, bool didDomainReload)
#else
private static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
#endif
{
if (!Application.isPlaying)
{
// If the Library folder is deleted, InputSystem will fail to retrieve the assigned Project-wide Asset because this look-up occurs
// during initialization while the Library is being rebuilt. So, afterwards perform another check and assign PWA asset if needed.
var pwaAsset = ProjectWideActionsBuildProvider.actionsToIncludeInPlayerBuild;
if (InputSystem.actions == null && pwaAsset != null)
InputSystem.actions = pwaAsset;
}
}
}
}
// Returns the default asset path for where to create project-wide actions asset.
internal static string defaultAssetPath => kDefaultAssetPath;
// Returns the default template JSON content.
internal static string GetDefaultAssetJson()
{
return File.ReadAllText(EditorHelpers.GetPhysicalPath(kDefaultTemplateAssetPath));
}
// Creates an asset at the given path containing the default template JSON.
internal static InputActionAsset CreateDefaultAssetAtPath(string assetPath = kDefaultAssetPath)
{
return CreateAssetAtPathFromJson(assetPath, File.ReadAllText(EditorHelpers.GetPhysicalPath(kDefaultTemplateAssetPath)));
}
// These may be moved out to internal types if decided to extend validation at a later point.
/// <summary>
/// Interface for reporting asset verification errors.
/// </summary>
internal interface IReportInputActionAssetVerificationErrors
{
/// <summary>
/// Reports a failure to comply to requirements with a message meaningful to the user.
/// </summary>
/// <param name="message">User-friendly error message.</param>
void Report(string message);
}
/// <summary>
/// Interface for asset verification.
/// </summary>
internal interface IInputActionAssetVerifier
{
/// <summary>
/// Verifies the given asset.
/// </summary>
/// <param name="asset">The asset to be verified</param>
/// <param name="reporter">The reporter to be used to report failure to meet requirements.</param>
public void Verify(InputActionAsset asset, IReportInputActionAssetVerificationErrors reporter);
}
/// <summary>
/// Verifier managing verification and reporting of asset compliance with external requirements.
/// </summary>
class Verifier : IReportInputActionAssetVerificationErrors
{
private readonly IReportInputActionAssetVerificationErrors m_Reporter;
// Default verification error reporter which generates feedback as debug warnings.
private class DefaultInputActionAssetVerificationReporter : IReportInputActionAssetVerificationErrors
{
public void Report(string message)
{
Debug.LogWarning(message);
}
}
/// <summary>
/// Constructs a an instance associated with the given reporter.
/// </summary>
/// <param name="reporter">The associated reporter instance. If null, a default reporter will be constructed.</param>
public Verifier(IReportInputActionAssetVerificationErrors reporter = null)
{
m_Reporter = reporter ?? new DefaultInputActionAssetVerificationReporter();
errors = 0;
}
#region IReportInputActionAssetVerificationErrors interface
/// <inheritdoc cref="IReportInputActionAssetVerificationErrors"/>
public void Report(string message)
{
++errors;
try
{
m_Reporter.Report(message);
}
catch (Exception e)
{
// Only log unexpected but non-fatal exception
Debug.LogException(e);
}
}
#endregion
/// <summary>
/// Returns the total number of errors seen in verification (accumulative).
/// </summary>
public int errors { get; private set; }
/// <summary>
/// Returns <c>true</c> if the number of reported errors in verification is zero, else <c>false</c>.
/// </summary>
public bool isValid => errors == 0;
private static List<Func<IInputActionAssetVerifier>> s_VerifierFactories;
/// <summary>
/// Registers a factory instance.
/// </summary>
/// <param name="factory">The factory instance.</param>
/// <returns>true if successfully added, <c>false</c> if the factory have already been registered.</returns>
public static bool RegisterFactory(Func<IInputActionAssetVerifier> factory)
{
if (s_VerifierFactories == null)
s_VerifierFactories = new List<Func<IInputActionAssetVerifier>>(1);
if (s_VerifierFactories.Contains(factory))
return false;
s_VerifierFactories.Add(factory);
return true;
}
/// <summary>
/// Unregisters a factory instance that has previously been registered.
/// </summary>
/// <param name="factory">The factory instance to be removed.</param>
/// <returns>true if successfully unregistered, <c>false</c> if the given factory instance could not be found.</returns>
public static bool UnregisterFactory(Func<IInputActionAssetVerifier> factory)
{
return s_VerifierFactories.Remove(factory);
}
/// <summary>
/// Verifies the given project-wide input action asset using all registered verifiers.
/// </summary>
/// <param name="asset">The asset to be verified.</param>
/// <returns><c>true</c> if no verification errors occurred, else <c>false</c>.</returns>
/// <remarks>
/// Throws <c>System.ArgumentNullException</c> if <c>asset</c> is <c>null</c>.
///
/// If any registered factory and/or verifier instance throws an exception this will be evaluated
/// as a verification error since the execution of the verifier could not continue. However, any
/// exceptions thrown will be caught and logged but not stop execution of the calling thread.
/// </remarks>
bool Verify(InputActionAsset asset)
{
if (asset == null)
throw new ArgumentNullException(nameof(asset));
if (s_VerifierFactories == null || s_VerifierFactories.Count == 0)
return true;
var instance = new Verifier(m_Reporter);
foreach (var factory in s_VerifierFactories)
{
try
{
factory.Invoke().Verify(asset, instance);
}
catch (Exception e)
{
// Only log unexpected but non-fatal exception and count to fail verification
++errors;
Debug.LogException(e);
}
}
return errors == 0;
}
/// <summary>
/// Verifies the given project-wide input action asset using all registered verifiers.
/// </summary>
/// <param name="asset">The asset to be verified.</param>
/// <param name="reporter">The reporter to be used. If this argument is <c>null</c> the default reporter will be used.</param>
/// <returns><c>true</c> if no verification errors occurred, else <c>false</c>.</returns>
/// <remarks>Throws <c>System.ArgumentNullException</c> if <c>asset</c> is <c>null</c>.</remarks>
public static bool Verify(InputActionAsset asset, IReportInputActionAssetVerificationErrors reporter = null)
{
return (s_VerifierFactories == null || s_VerifierFactories.Count == 0) || new Verifier(reporter).Verify(asset);
}
}
internal static bool Verify(InputActionAsset asset, IReportInputActionAssetVerificationErrors reporter = null)
{
return Verifier.Verify(asset, reporter);
}
internal static bool RegisterInputActionAssetVerifier(Func<IInputActionAssetVerifier> factory)
{
return Verifier.RegisterFactory(factory);
}
internal static bool UnregisterInputActionAssetVerifier(Func<IInputActionAssetVerifier> factory)
{
return Verifier.UnregisterFactory(factory);
}
// Creates an asset at the given path containing the given JSON content.
private static InputActionAsset CreateAssetAtPathFromJson(string assetPath, string json)
{
// Note that the extra work here is to override the JSON name from the source asset
var inputActionAsset = InputActionAsset.FromJson(json);
inputActionAsset.name = InputActionImporter.NameFromAssetPath(assetPath);
InputActionAssetManager.SaveAsset(assetPath, inputActionAsset.ToJson());
return AssetDatabase.LoadAssetAtPath<InputActionAsset>(assetPath);
}
}
}
#endif // UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2a47e68520f79264fb6828f8f9516ef2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,74 @@
#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS
using System;
using System.Linq;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine.InputSystem.Utilities;
namespace UnityEngine.InputSystem.Editor
{
internal class ProjectWideActionsBuildProvider : IPreprocessBuildWithReport, IPostprocessBuildWithReport
{
private Object m_Asset;
public int callbackOrder => 0;
// In the editor, we keep track of the appointed project-wide action asset through EditorBuildSettings.
internal const string EditorBuildSettingsActionsConfigKey = "com.unity.input.settings.actions";
/// <summary>
/// Holds an editor build setting for which InputActionAsset to be included as a preloaded asset in
/// player builds.
/// </summary>
internal static InputActionAsset actionsToIncludeInPlayerBuild
{
get
{
// Attempt to get any persisted configuration
EditorBuildSettings.TryGetConfigObject(EditorBuildSettingsActionsConfigKey, out InputActionAsset value);
return value;
}
set
{
// Get the current persisted configuration and remove tag when changed
if (EditorBuildSettings.TryGetConfigObject(EditorBuildSettingsActionsConfigKey,
out InputActionAsset current))
{
current.m_IsProjectWide = false;
}
// Get asset path (note that this will fail if this is an in-memory object)
var path = AssetDatabase.GetAssetPath(value);
if (string.IsNullOrEmpty(path))
{
// Remove the object to not keep a broken reference
EditorBuildSettings.RemoveConfigObject(EditorBuildSettingsActionsConfigKey);
}
else
{
// Add configuration object as a persisted setting
value.m_IsProjectWide = true;
EditorBuildSettings.AddConfigObject(EditorBuildSettingsActionsConfigKey, value, true);
}
}
}
public void OnPreprocessBuild(BuildReport report)
{
// Make sure flag is set to indicate project-wide in build
var actions = actionsToIncludeInPlayerBuild;
if (actions != null)
actions.m_IsProjectWide = true;
// Add asset
m_Asset = BuildProviderHelpers.PreProcessSinglePreloadedAsset(actions);
}
public void OnPostprocessBuild(BuildReport report)
{
BuildProviderHelpers.PostProcessSinglePreloadedAsset(ref m_Asset);
}
}
}
#endif // UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1cbae3eee4bd4f6f9b9ad85aab8174e4
timeCreated: 1709540697

View File

@@ -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: