andytouch
4 年前
当前提交
0c6909f3
共有 18 个文件被更改,包括 1495 次插入 和 670 次删除
-
4InputSystem_Warriors_Project/Assets/Input/InputActions_Player.inputactions
-
51InputSystem_Warriors_Project/Assets/Samples/Input System/1.0.0/Rebinding UI/RebindUIPrefab.prefab
-
892InputSystem_Warriors_Project/Assets/Scenes/Scene_Example_Warriors.unity
-
5InputSystem_Warriors_Project/Assets/Scripts/Behaviours/Player/PlayerController.cs
-
80InputSystem_Warriors_Project/Assets/Scripts/Behaviours/UI/UIRebindActionBehaviour.cs
-
5InputSystem_Warriors_Project/Assets/Scripts/Editor/DeviceDisplayConfiguratorEditor.cs
-
7InputSystem_Warriors_Project/Assets/Scripts/Editor/GameManagerEditor.cs
-
27InputSystem_Warriors_Project/Assets/Scripts/Managers/CameraManager.cs
-
1InputSystem_Warriors_Project/Assets/Scripts/Managers/EventSystemManager.cs
-
7InputSystem_Warriors_Project/Assets/Scripts/Managers/GameManager.cs
-
2InputSystem_Warriors_Project/Packages/manifest.json
-
2InputSystem_Warriors_Project/Assets/Scripts/Utilities/DeviceDisplayIconSettings.cs.meta
-
18InputSystem_Warriors_Project/Assets/Scripts/Utilities/DeviceDisplayIconSettings.cs
-
104InputSystem_Warriors_Project/Assets/UI/Sprites/Rectangle_Curved_Outline_White.png
-
116InputSystem_Warriors_Project/Assets/UI/Sprites/Rectangle_Curved_Outline_White.png.meta
-
375InputSystem_Warriors_Project/Packages/packages-lock.json
-
469InputSystem_Warriors_Project/Assets/Scripts/Behaviours/PlayerDeviceRebindBehaviour.cs
-
0/InputSystem_Warriors_Project/Assets/Scripts/Utilities/DeviceDisplayIconSettings.cs.meta
892
InputSystem_Warriors_Project/Assets/Scenes/Scene_Example_Warriors.unity
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
|
|||
public class DeviceDisplayIconSettings : MonoBehaviour |
|||
{ |
|||
// Start is called before the first frame update
|
|||
void Start() |
|||
{ |
|||
|
|||
} |
|||
|
|||
// Update is called once per frame
|
|||
void Update() |
|||
{ |
|||
|
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: f1504f7af547d78489d19063349a0a26 |
|||
TextureImporter: |
|||
internalIDToNameTable: [] |
|||
externalObjects: {} |
|||
serializedVersion: 11 |
|||
mipmaps: |
|||
mipMapMode: 0 |
|||
enableMipMap: 1 |
|||
sRGBTexture: 1 |
|||
linearTexture: 0 |
|||
fadeOut: 0 |
|||
borderMipMap: 0 |
|||
mipMapsPreserveCoverage: 0 |
|||
alphaTestReferenceValue: 0.5 |
|||
mipMapFadeDistanceStart: 1 |
|||
mipMapFadeDistanceEnd: 3 |
|||
bumpmap: |
|||
convertToNormalMap: 0 |
|||
externalNormalMap: 0 |
|||
heightScale: 0.25 |
|||
normalMapFilter: 0 |
|||
isReadable: 0 |
|||
streamingMipmaps: 0 |
|||
streamingMipmapsPriority: 0 |
|||
grayScaleToAlpha: 0 |
|||
generateCubemap: 6 |
|||
cubemapConvolution: 0 |
|||
seamlessCubemap: 0 |
|||
textureFormat: 1 |
|||
maxTextureSize: 2048 |
|||
textureSettings: |
|||
serializedVersion: 2 |
|||
filterMode: 1 |
|||
aniso: -1 |
|||
mipBias: -100 |
|||
wrapU: 1 |
|||
wrapV: 1 |
|||
wrapW: -1 |
|||
nPOTScale: 0 |
|||
lightmap: 0 |
|||
compressionQuality: 50 |
|||
spriteMode: 1 |
|||
spriteExtrude: 1 |
|||
spriteMeshType: 1 |
|||
alignment: 0 |
|||
spritePivot: {x: 0.5, y: 0.5} |
|||
spritePixelsToUnits: 100 |
|||
spriteBorder: {x: 350, y: 350, z: 350, w: 350} |
|||
spriteGenerateFallbackPhysicsShape: 1 |
|||
alphaUsage: 1 |
|||
alphaIsTransparency: 1 |
|||
spriteTessellationDetail: -1 |
|||
textureType: 8 |
|||
textureShape: 1 |
|||
singleChannelComponent: 0 |
|||
maxTextureSizeSet: 0 |
|||
compressionQualitySet: 0 |
|||
textureFormatSet: 0 |
|||
applyGammaDecoding: 0 |
|||
platformSettings: |
|||
- serializedVersion: 3 |
|||
buildTarget: DefaultTexturePlatform |
|||
maxTextureSize: 2048 |
|||
resizeAlgorithm: 0 |
|||
textureFormat: -1 |
|||
textureCompression: 1 |
|||
compressionQuality: 50 |
|||
crunchedCompression: 0 |
|||
allowsAlphaSplitting: 0 |
|||
overridden: 0 |
|||
androidETC2FallbackOverride: 0 |
|||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
|||
- serializedVersion: 3 |
|||
buildTarget: Standalone |
|||
maxTextureSize: 2048 |
|||
resizeAlgorithm: 0 |
|||
textureFormat: -1 |
|||
textureCompression: 1 |
|||
compressionQuality: 50 |
|||
crunchedCompression: 0 |
|||
allowsAlphaSplitting: 0 |
|||
overridden: 0 |
|||
androidETC2FallbackOverride: 0 |
|||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
|||
- serializedVersion: 3 |
|||
buildTarget: Android |
|||
maxTextureSize: 2048 |
|||
resizeAlgorithm: 0 |
|||
textureFormat: -1 |
|||
textureCompression: 1 |
|||
compressionQuality: 50 |
|||
crunchedCompression: 0 |
|||
allowsAlphaSplitting: 0 |
|||
overridden: 0 |
|||
androidETC2FallbackOverride: 0 |
|||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
|||
spriteSheet: |
|||
serializedVersion: 2 |
|||
sprites: [] |
|||
outline: [] |
|||
physicsShape: [] |
|||
bones: [] |
|||
spriteID: 5e97eb03825dee720800000000000000 |
|||
internalID: 0 |
|||
vertices: [] |
|||
indices: |
|||
edges: [] |
|||
weights: [] |
|||
secondaryTextures: [] |
|||
spritePackingTag: |
|||
pSDRemoveMatte: 0 |
|||
pSDShowRemoveMatteOption: 0 |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
{ |
|||
"dependencies": { |
|||
"com.unity.2d.sprite": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.cinemachine": { |
|||
"version": "2.6.3", |
|||
"depth": 0, |
|||
"source": "registry", |
|||
"dependencies": {}, |
|||
"url": "https://packages.unity.com" |
|||
}, |
|||
"com.unity.collab-proxy": { |
|||
"version": "1.2.16", |
|||
"depth": 0, |
|||
"source": "registry", |
|||
"dependencies": {}, |
|||
"url": "https://packages.unity.com" |
|||
}, |
|||
"com.unity.ext.nunit": { |
|||
"version": "1.0.0", |
|||
"depth": 1, |
|||
"source": "registry", |
|||
"dependencies": {}, |
|||
"url": "https://packages.unity.com" |
|||
}, |
|||
"com.unity.ide.rider": { |
|||
"version": "1.1.4", |
|||
"depth": 0, |
|||
"source": "registry", |
|||
"dependencies": { |
|||
"com.unity.test-framework": "1.1.1" |
|||
}, |
|||
"url": "https://packages.unity.com" |
|||
}, |
|||
"com.unity.ide.vscode": { |
|||
"version": "1.2.1", |
|||
"depth": 0, |
|||
"source": "registry", |
|||
"dependencies": {}, |
|||
"url": "https://packages.unity.com" |
|||
}, |
|||
"com.unity.inputsystem": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "registry", |
|||
"dependencies": {}, |
|||
"url": "https://packages.unity.com" |
|||
}, |
|||
"com.unity.probuilder": { |
|||
"version": "4.2.3", |
|||
"depth": 0, |
|||
"source": "registry", |
|||
"dependencies": { |
|||
"com.unity.settings-manager": "1.0.0" |
|||
}, |
|||
"url": "https://packages.unity.com" |
|||
}, |
|||
"com.unity.render-pipelines.core": { |
|||
"version": "7.3.1", |
|||
"depth": 1, |
|||
"source": "registry", |
|||
"dependencies": { |
|||
"com.unity.ugui": "1.0.0" |
|||
}, |
|||
"url": "https://packages.unity.com" |
|||
}, |
|||
"com.unity.render-pipelines.universal": { |
|||
"version": "7.3.1", |
|||
"depth": 0, |
|||
"source": "registry", |
|||
"dependencies": { |
|||
"com.unity.render-pipelines.core": "7.3.1", |
|||
"com.unity.shadergraph": "7.3.1" |
|||
}, |
|||
"url": "https://packages.unity.com" |
|||
}, |
|||
"com.unity.settings-manager": { |
|||
"version": "1.0.0", |
|||
"depth": 1, |
|||
"source": "registry", |
|||
"dependencies": {}, |
|||
"url": "https://packages.unity.com" |
|||
}, |
|||
"com.unity.shadergraph": { |
|||
"version": "7.3.1", |
|||
"depth": 1, |
|||
"source": "registry", |
|||
"dependencies": { |
|||
"com.unity.render-pipelines.core": "7.3.1" |
|||
}, |
|||
"url": "https://packages.unity.com" |
|||
}, |
|||
"com.unity.test-framework": { |
|||
"version": "1.1.14", |
|||
"depth": 0, |
|||
"source": "registry", |
|||
"dependencies": { |
|||
"com.unity.ext.nunit": "1.0.0", |
|||
"com.unity.modules.imgui": "1.0.0", |
|||
"com.unity.modules.jsonserialize": "1.0.0" |
|||
}, |
|||
"url": "https://packages.unity.com" |
|||
}, |
|||
"com.unity.textmeshpro": { |
|||
"version": "2.0.1", |
|||
"depth": 0, |
|||
"source": "registry", |
|||
"dependencies": { |
|||
"com.unity.ugui": "1.0.0" |
|||
}, |
|||
"url": "https://packages.unity.com" |
|||
}, |
|||
"com.unity.timeline": { |
|||
"version": "1.2.12", |
|||
"depth": 0, |
|||
"source": "registry", |
|||
"dependencies": {}, |
|||
"url": "https://packages.unity.com" |
|||
}, |
|||
"com.unity.ugui": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.ui": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.ai": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.androidjni": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.animation": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.assetbundle": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.audio": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.cloth": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.physics": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.director": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.audio": "1.0.0", |
|||
"com.unity.modules.animation": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.imageconversion": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.imgui": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.jsonserialize": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.particlesystem": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.physics": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.physics2d": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.screencapture": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.imageconversion": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.subsystems": { |
|||
"version": "1.0.0", |
|||
"depth": 1, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.jsonserialize": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.terrain": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.terrainphysics": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.physics": "1.0.0", |
|||
"com.unity.modules.terrain": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.tilemap": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.physics2d": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.ui": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.uielements": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.imgui": "1.0.0", |
|||
"com.unity.modules.jsonserialize": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.umbra": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.unityanalytics": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.unitywebrequest": "1.0.0", |
|||
"com.unity.modules.jsonserialize": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.unitywebrequest": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.unitywebrequestassetbundle": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.assetbundle": "1.0.0", |
|||
"com.unity.modules.unitywebrequest": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.unitywebrequestaudio": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.unitywebrequest": "1.0.0", |
|||
"com.unity.modules.audio": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.unitywebrequesttexture": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.unitywebrequest": "1.0.0", |
|||
"com.unity.modules.imageconversion": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.unitywebrequestwww": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.unitywebrequest": "1.0.0", |
|||
"com.unity.modules.unitywebrequestassetbundle": "1.0.0", |
|||
"com.unity.modules.unitywebrequestaudio": "1.0.0", |
|||
"com.unity.modules.audio": "1.0.0", |
|||
"com.unity.modules.assetbundle": "1.0.0", |
|||
"com.unity.modules.imageconversion": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.vehicles": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.physics": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.video": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.audio": "1.0.0", |
|||
"com.unity.modules.ui": "1.0.0", |
|||
"com.unity.modules.unitywebrequest": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.vr": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.jsonserialize": "1.0.0", |
|||
"com.unity.modules.physics": "1.0.0", |
|||
"com.unity.modules.xr": "1.0.0" |
|||
} |
|||
}, |
|||
"com.unity.modules.wind": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": {} |
|||
}, |
|||
"com.unity.modules.xr": { |
|||
"version": "1.0.0", |
|||
"depth": 0, |
|||
"source": "builtin", |
|||
"dependencies": { |
|||
"com.unity.modules.physics": "1.0.0", |
|||
"com.unity.modules.jsonserialize": "1.0.0", |
|||
"com.unity.modules.subsystems": "1.0.0" |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using UnityEngine.Events; |
|||
using UnityEngine.InputSystem; |
|||
using UnityEngine.InputSystem.Utilities; |
|||
using UnityEngine.UI; |
|||
using UnityEngine; |
|||
using TMPro; |
|||
|
|||
////TODO: localization support
|
|||
|
|||
////TODO: deal with composites that have parts bound in different control schemes
|
|||
|
|||
|
|||
|
|||
public class PlayerDeviceRebindBehaviour : MonoBehaviour |
|||
{ |
|||
|
|||
public InputActionReference actionReference |
|||
{ |
|||
get => m_Action; |
|||
set |
|||
{ |
|||
m_Action = value; |
|||
UpdateActionLabel(); |
|||
UpdateBindingDisplay(); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// ID (in string form) of the binding that is to be rebound on the action.
|
|||
/// </summary>
|
|||
/// <seealso cref="InputBinding.id"/>
|
|||
public string bindingId |
|||
{ |
|||
get => m_BindingId; |
|||
set |
|||
{ |
|||
m_BindingId = value; |
|||
UpdateBindingDisplay(); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Index of of the <see cref="PlayerInput"/> (see <see cref="PlayerInput.playerIndex"/>) on which to rebind
|
|||
/// the action referenced by <see cref="actionReference"/>.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// This is -1 by default which deactivated the feature. If this is set to a number >= 0, the <see cref="PlayerInput"/>
|
|||
/// with a matching <see cref="PlayerInput.playerIndex"/> will be looked up and the ID of the action referenced by
|
|||
/// <see cref="actionReference"/> will be looked up in the <see cref="PlayerInput.actions"/> of the player. This
|
|||
/// allows targeting rebinds to a specific player.
|
|||
/// </remarks>
|
|||
/// <seealso cref="PlayerInput.playerIndex"/>
|
|||
/// <seealso cref="PlayerInput.all"/>
|
|||
public int playerIndex |
|||
{ |
|||
get => m_PlayerIndex; |
|||
set |
|||
{ |
|||
m_PlayerIndex = value; |
|||
UpdateBindingDisplay(); |
|||
} |
|||
} |
|||
|
|||
public InputBinding.DisplayStringOptions displayStringOptions |
|||
{ |
|||
get => m_DisplayStringOptions; |
|||
set |
|||
{ |
|||
m_DisplayStringOptions = value; |
|||
UpdateBindingDisplay(); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Text component that receives the name of the action. Optional.
|
|||
/// </summary>
|
|||
public TextMeshProUGUI actionLabel |
|||
{ |
|||
get => m_ActionLabel; |
|||
set |
|||
{ |
|||
m_ActionLabel = value; |
|||
UpdateActionLabel(); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Text component that receives the display string of the binding. Can be <c>null</c> in which
|
|||
/// case the component entirely relies on <see cref="updateBindingUIEvent"/>.
|
|||
/// </summary>
|
|||
public TextMeshProUGUI bindingText |
|||
{ |
|||
get => m_BindingText; |
|||
set |
|||
{ |
|||
m_BindingText = value; |
|||
UpdateBindingDisplay(); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Optional UI that is activated when an interactive rebind is started and deactivated when the rebind
|
|||
/// is finished. This is normally used to display an overlay over the current UI while the system is
|
|||
/// waiting for a control to be actuated.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// If neither <see cref="rebindPrompt"/> nor <c>rebindOverlay</c> is set, the component will temporarily
|
|||
/// replaced the <see cref="bindingText"/> (if not <c>null</c>) with <c>"Waiting..."</c>.
|
|||
/// </remarks>
|
|||
/// <seealso cref="startRebindEvent"/>
|
|||
/// <seealso cref="rebindPrompt"/>
|
|||
public GameObject rebindOverlay |
|||
{ |
|||
get => m_RebindOverlay; |
|||
set => m_RebindOverlay = value; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Event that is triggered every time the UI updates to reflect the current binding.
|
|||
/// This can be used to tie custom visualizations to bindings.
|
|||
/// </summary>
|
|||
public UpdateBindingUIEvent updateBindingUIEvent |
|||
{ |
|||
get |
|||
{ |
|||
if (m_UpdateBindingUIEvent == null) |
|||
m_UpdateBindingUIEvent = new UpdateBindingUIEvent(); |
|||
return m_UpdateBindingUIEvent; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Event that is triggered when an interactive rebind is started on the action.
|
|||
/// </summary>
|
|||
public InteractiveRebindEvent startRebindEvent |
|||
{ |
|||
get |
|||
{ |
|||
if (m_RebindStartEvent == null) |
|||
m_RebindStartEvent = new InteractiveRebindEvent(); |
|||
return m_RebindStartEvent; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Event that is triggered when an interactive rebind has been completed or canceled.
|
|||
/// </summary>
|
|||
public InteractiveRebindEvent stopRebindEvent |
|||
{ |
|||
get |
|||
{ |
|||
if (m_RebindStopEvent == null) |
|||
m_RebindStopEvent = new InteractiveRebindEvent(); |
|||
return m_RebindStopEvent; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// When an interactive rebind is in progress, this is the rebind operation controller.
|
|||
/// Otherwise, it is <c>null</c>.
|
|||
/// </summary>
|
|||
public InputActionRebindingExtensions.RebindingOperation ongoingRebind => m_RebindOperation; |
|||
|
|||
/// <summary>
|
|||
/// Return the action and binding index for the binding that is targeted by the component
|
|||
/// according to
|
|||
/// </summary>
|
|||
/// <param name="action">Receives the action that is to be rebound.</param>
|
|||
/// <param name="bindingIndex">Receives the index of the binding to rebind.</param>
|
|||
/// <returns>True if a valid action and binding index has been selected.</returns>
|
|||
public bool ResolveActionAndBinding(out InputAction action, out int bindingIndex) |
|||
{ |
|||
bindingIndex = -1; |
|||
|
|||
action = m_Action?.action; |
|||
if (action == null) |
|||
return false; |
|||
|
|||
if (m_PlayerIndex >= 0) |
|||
{ |
|||
var player = PlayerInput.GetPlayerByIndex(m_PlayerIndex); |
|||
if (player == null || player.actions == null) |
|||
return false; // Fail the lookup if the specified player does not exist or it has no actions.
|
|||
|
|||
action = player.actions.FindAction(action.id); |
|||
if (action == null) |
|||
return false; |
|||
} |
|||
|
|||
if (string.IsNullOrEmpty(m_BindingId)) |
|||
{ |
|||
var controls = action.controls; |
|||
if (controls.Count > 0) |
|||
{ |
|||
var index = action.GetBindingIndexForControl(controls[0]); |
|||
if (index != -1) |
|||
{ |
|||
while (action.bindings[index].isPartOfComposite) |
|||
{ |
|||
--index; |
|||
if (index < 0) |
|||
return false; |
|||
} |
|||
bindingIndex = index; |
|||
return true; |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
// Look up binding index.
|
|||
var bindingId = new Guid(m_BindingId); |
|||
bindingIndex = action.bindings.IndexOf(x => x.id == bindingId); |
|||
if (bindingIndex == -1) |
|||
{ |
|||
Debug.LogError($"Cannot find binding with ID '{bindingId}' on '{action}'", this); |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Trigger a refresh of the currently displayed binding.
|
|||
/// </summary>
|
|||
public void UpdateBindingDisplay() |
|||
{ |
|||
var displayString = string.Empty; |
|||
var deviceLayoutName = default(string); |
|||
var controlPath = default(string); |
|||
|
|||
// Get display string from action.
|
|||
if (ResolveActionAndBinding(out var action, out var bindingIndex)) |
|||
displayString = action.GetBindingDisplayString(bindingIndex, out deviceLayoutName, out controlPath, displayStringOptions); |
|||
|
|||
// Set on label (if any).
|
|||
if (m_BindingText != null) |
|||
m_BindingText.text = displayString; |
|||
|
|||
// Give listeners a chance to configure UI in response.
|
|||
m_UpdateBindingUIEvent?.Invoke(this, displayString, deviceLayoutName, controlPath); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Remove currently applied binding overrides.
|
|||
/// </summary>
|
|||
public void ResetToDefault() |
|||
{ |
|||
if (!ResolveActionAndBinding(out var action, out var bindingIndex)) |
|||
return; |
|||
|
|||
if (action.bindings[bindingIndex].isComposite) |
|||
{ |
|||
// It's a composite. Remove overrides from part bindings.
|
|||
for (var i = bindingIndex + 1; i < action.bindings.Count && action.bindings[i].isPartOfComposite; ++i) |
|||
action.RemoveBindingOverride(i); |
|||
} |
|||
else |
|||
{ |
|||
action.RemoveBindingOverride(bindingIndex); |
|||
} |
|||
UpdateBindingDisplay(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initiate an interactive rebind that lets the player actuate a control to choose a new binding
|
|||
/// for the action.
|
|||
/// </summary>
|
|||
public void StartInteractiveRebind() |
|||
{ |
|||
if (!ResolveActionAndBinding(out var action, out var bindingIndex)) |
|||
return; |
|||
|
|||
// If the binding is a composite, we need to rebind each part in turn.
|
|||
if (action.bindings[bindingIndex].isComposite) |
|||
{ |
|||
var firstPartIndex = bindingIndex + 1; |
|||
if (firstPartIndex < action.bindings.Count && action.bindings[firstPartIndex].isPartOfComposite) |
|||
PerformInteractiveRebind(action, firstPartIndex, allCompositeParts: true); |
|||
} |
|||
else |
|||
{ |
|||
PerformInteractiveRebind(action, bindingIndex); |
|||
} |
|||
} |
|||
|
|||
private void PerformInteractiveRebind(InputAction action, int bindingIndex, bool allCompositeParts = false) |
|||
{ |
|||
m_RebindOperation?.Cancel(); // Will null out m_RebindOperation.
|
|||
|
|||
void CleanUp() |
|||
{ |
|||
m_RebindOperation?.Dispose(); |
|||
m_RebindOperation = null; |
|||
} |
|||
|
|||
// Configure the rebind.
|
|||
m_RebindOperation = action.PerformInteractiveRebinding(bindingIndex) |
|||
.OnCancel( |
|||
operation => |
|||
{ |
|||
m_RebindStopEvent?.Invoke(this, operation); |
|||
m_RebindOverlay?.SetActive(false); |
|||
UpdateBindingDisplay(); |
|||
CleanUp(); |
|||
}) |
|||
.OnComplete( |
|||
operation => |
|||
{ |
|||
m_RebindOverlay?.SetActive(false); |
|||
m_RebindStopEvent?.Invoke(this, operation); |
|||
UpdateBindingDisplay(); |
|||
CleanUp(); |
|||
|
|||
// If there's more composite parts we should bind, initiate a rebind
|
|||
// for the next part.
|
|||
if (allCompositeParts) |
|||
{ |
|||
var nextBindingIndex = bindingIndex + 1; |
|||
if (nextBindingIndex < action.bindings.Count && action.bindings[nextBindingIndex].isPartOfComposite) |
|||
PerformInteractiveRebind(action, nextBindingIndex, true); |
|||
} |
|||
}); |
|||
|
|||
// If it's a part binding, show the name of the part in the UI.
|
|||
var partName = default(string); |
|||
if (action.bindings[bindingIndex].isPartOfComposite) |
|||
partName = $"Binding '{action.bindings[bindingIndex].name}'. "; |
|||
|
|||
// Bring up rebind overlay, if we have one.
|
|||
m_RebindOverlay?.SetActive(true); |
|||
|
|||
// Give listeners a chance to act on the rebind starting.
|
|||
m_RebindStartEvent?.Invoke(this, m_RebindOperation); |
|||
|
|||
m_RebindOperation.Start(); |
|||
} |
|||
|
|||
protected void OnEnable() |
|||
{ |
|||
if (s_RebindActionUIs == null) |
|||
s_RebindActionUIs = new List<PlayerDeviceRebindBehaviour>(); |
|||
s_RebindActionUIs.Add(this); |
|||
if (s_RebindActionUIs.Count == 1) |
|||
InputSystem.onActionChange += OnActionChange; |
|||
} |
|||
|
|||
protected void OnDisable() |
|||
{ |
|||
m_RebindOperation?.Dispose(); |
|||
m_RebindOperation = null; |
|||
|
|||
s_RebindActionUIs.Remove(this); |
|||
if (s_RebindActionUIs.Count == 0) |
|||
{ |
|||
s_RebindActionUIs = null; |
|||
InputSystem.onActionChange -= OnActionChange; |
|||
} |
|||
} |
|||
|
|||
// When the action system re-resolves bindings, we want to update our UI in response. While this will
|
|||
// also trigger from changes we made ourselves, it ensures that we react to changes made elsewhere. If
|
|||
// the user changes keyboard layout, for example, we will get a BoundControlsChanged notification and
|
|||
// will update our UI to reflect the current keyboard layout.
|
|||
private static void OnActionChange(object obj, InputActionChange change) |
|||
{ |
|||
if (change != InputActionChange.BoundControlsChanged) |
|||
return; |
|||
|
|||
var action = obj as InputAction; |
|||
var actionMap = action?.actionMap ?? obj as InputActionMap; |
|||
var actionAsset = actionMap?.asset ?? obj as InputActionAsset; |
|||
|
|||
for (var i = 0; i < s_RebindActionUIs.Count; ++i) |
|||
{ |
|||
var component = s_RebindActionUIs[i]; |
|||
var referencedAction = component.actionReference?.action; |
|||
if (referencedAction == null) |
|||
continue; |
|||
|
|||
if (referencedAction == action || |
|||
referencedAction.actionMap == actionMap || |
|||
referencedAction.actionMap?.asset == actionAsset) |
|||
component.UpdateBindingDisplay(); |
|||
} |
|||
} |
|||
|
|||
[Tooltip("Reference to action that is to be rebound from the UI.")] |
|||
[SerializeField] |
|||
private InputActionReference m_Action; |
|||
|
|||
[SerializeField] |
|||
private string m_BindingId; |
|||
|
|||
[Tooltip("Optional index of the player (see PlayerInput.playerIndex) to rebind the action on. If this is set, the action referenced by the rebind UI component " |
|||
+ "will be looked up dynamically on the set of actions found on the player.")] |
|||
[SerializeField] |
|||
private int m_PlayerIndex = -1; |
|||
|
|||
[SerializeField] |
|||
private InputBinding.DisplayStringOptions m_DisplayStringOptions; |
|||
|
|||
[Tooltip("Text label that will receive the name of the action. Optional. Set to None to have the " |
|||
+ "rebind UI not show a label for the action.")] |
|||
[SerializeField] |
|||
private TextMeshProUGUI m_ActionLabel; |
|||
|
|||
[Tooltip("Text label that will receive the current, formatted binding string.")] |
|||
[SerializeField] |
|||
private TextMeshProUGUI m_BindingText; |
|||
|
|||
[Tooltip("Optional UI that will be shown while a rebind is in progress.")] |
|||
[SerializeField] |
|||
private GameObject m_RebindOverlay; |
|||
|
|||
[Tooltip("Event that is triggered when the way the binding is display should be updated. This allows displaying " |
|||
+ "bindings in custom ways, e.g. using images instead of text.")] |
|||
[SerializeField] |
|||
private UpdateBindingUIEvent m_UpdateBindingUIEvent; |
|||
|
|||
[Tooltip("Event that is triggered when an interactive rebind is being initiated. This can be used, for example, " |
|||
+ "to implement custom UI behavior while a rebind is in progress. It can also be used to further " |
|||
+ "customize the rebind.")] |
|||
[SerializeField] |
|||
private InteractiveRebindEvent m_RebindStartEvent; |
|||
|
|||
[Tooltip("Event that is triggered when an interactive rebind is complete or has been aborted.")] |
|||
[SerializeField] |
|||
private InteractiveRebindEvent m_RebindStopEvent; |
|||
|
|||
private InputActionRebindingExtensions.RebindingOperation m_RebindOperation; |
|||
|
|||
private static List<PlayerDeviceRebindBehaviour> s_RebindActionUIs; |
|||
|
|||
// We want the label for the action name to update in edit mode, too, so
|
|||
// we kick that off from here.
|
|||
#if UNITY_EDITOR
|
|||
protected void OnValidate() |
|||
{ |
|||
UpdateActionLabel(); |
|||
UpdateBindingDisplay(); |
|||
} |
|||
|
|||
#endif
|
|||
|
|||
private void UpdateActionLabel() |
|||
{ |
|||
if (m_ActionLabel != null) |
|||
{ |
|||
var action = m_Action?.action; |
|||
m_ActionLabel.text = action != null ? action.name : string.Empty; |
|||
} |
|||
} |
|||
|
|||
[Serializable] |
|||
public class UpdateBindingUIEvent : UnityEvent<PlayerDeviceRebindBehaviour, string, string, string> |
|||
{ |
|||
} |
|||
|
|||
[Serializable] |
|||
public class InteractiveRebindEvent : UnityEvent<PlayerDeviceRebindBehaviour, InputActionRebindingExtensions.RebindingOperation> |
|||
{ |
|||
} |
|||
} |
|||
|
撰写
预览
正在加载...
取消
保存
Reference in new issue