Added Unity project files

This commit is contained in:
2026-06-07 16:58:24 +01:00
parent 3cc05d260b
commit 23bbcab156
3942 changed files with 453676 additions and 0 deletions

View File

@ -0,0 +1,379 @@

#if ENABLE_INPUT_SYSTEM
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.InputSystem;
using VRC.SDKBase;
#endif
using VRC.Udon.Common;
namespace VRC.SDK3.ClientSim
{
// TODO refactor Input system to queue events from Unity's input system instead of firing events right away.
// Unity's input events are processed and sent before ALL monobehaviours. In test environment, this will happen
// right after modifying the input device, which will happen at the end of the frame instead. In order to properly
// process input events the same in runtime and tests, the events will need to be queued and processed in mono behaviours.
// This would also allow for other event types to be included that does not use the Input System (eg vr controls).
/// <summary>
/// An implementation of ClientSimInput that receives input events from Unity's Input System using InputActions.
/// Events from the action system are then sent to systems listening to input events.
/// </summary>
public class ClientSimInputActionBased : ClientSimInputBase
{
private readonly ClientSimSettings _settings;
/* Items need to be wrapped in this define to prevent compiler errors on initial import
when the Input System has not yet been imported or enabled.*/
#if ENABLE_INPUT_SYSTEM
private readonly InputAction _movementHorizontal;
private readonly InputAction _movementVertical;
private readonly InputAction _lookHorizontal;
private readonly InputAction _lookVertical;
private readonly InputAction _jumpLeft;
private readonly InputAction _jumpRight;
private readonly InputAction _useLeft;
private readonly InputAction _useRight;
private readonly InputAction _grabLeft;
private readonly InputAction _grabRight;
private readonly InputAction _dropLeft;
private readonly InputAction _dropRight;
private readonly InputAction _toggleMenuLeft;
private readonly InputAction _toggleMenuRight;
#region NonVR Only
private readonly InputAction _run;
private readonly InputAction _toggleCrouch;
private readonly InputAction _toggleProne;
private readonly InputAction _releaseMouse;
private readonly InputAction _pickupRotateUpDown;
private readonly InputAction _pickupRotateLeftRight;
private readonly InputAction _pickupRotateCwCcw;
private readonly InputAction _pickupManipulateForwardBack;
#endregion
private InputActionAsset InputActions;
public ClientSimInputActionBased(InputActionAsset actionAsset, ClientSimSettings settings)
{
InputActions = actionAsset;
_settings = settings;
_lookHorizontal = actionAsset["LookHorizontal"];
_lookVertical = actionAsset["LookVertical"];
_movementHorizontal = actionAsset["MovementHorizontal"];
_movementVertical = actionAsset["MovementVertical"];
_jumpLeft = actionAsset["JumpLeft"];
_jumpRight = actionAsset["JumpRight"];
_useLeft = actionAsset["UseLeft"];
_useRight = actionAsset["UseRight"];
_grabLeft = actionAsset["GrabLeft"];
_grabRight = actionAsset["GrabRight"];
_dropLeft = actionAsset["DropLeft"];
_dropRight = actionAsset["DropRight"];
_toggleMenuLeft = actionAsset["ToggleMenuLeft"];
_toggleMenuRight = actionAsset["ToggleMenuRight"];
// Desktop only input options.
_run = actionAsset["Run"];
_toggleCrouch = actionAsset["ToggleCrouch"];
_toggleProne = actionAsset["ToggleProne"];
_releaseMouse = actionAsset["ReleaseMouse"];
_pickupRotateUpDown = actionAsset["PickupRotateUpDown"];
_pickupRotateLeftRight = actionAsset["PickupRotateLeftRight"];
_pickupRotateCwCcw = actionAsset["PickupRotateCwCcw"];
_pickupManipulateForwardBack = actionAsset["PickupManipulateForwardBack"];
_jumpLeft.performed += HandleJumpLeft;
_jumpLeft.canceled += HandleJumpLeft;
_jumpRight.performed += HandleJumpRight;
_jumpRight.canceled += HandleJumpRight;
_useLeft.performed += HandleUseLeft;
_useLeft.canceled += HandleUseLeft;
_useRight.performed += HandleUseRight;
_useRight.canceled += HandleUseRight;
_grabLeft.performed += HandleGrabLeft;
_grabLeft.canceled += HandleGrabLeft;
_grabRight.performed += HandleGrabRight;
_grabRight.canceled += HandleGrabRight;
_dropLeft.performed += HandleDropLeft;
_dropLeft.canceled += HandleDropLeft;
_dropRight.performed += HandleDropRight;
_dropRight.canceled += HandleDropRight;
_toggleMenuLeft.performed += HandleToggleMenuLeft;
_toggleMenuLeft.canceled += HandleToggleMenuLeft;
_toggleMenuRight.performed += HandleToggleMenuRight;
_toggleMenuRight.canceled += HandleToggleMenuRight;
_run.performed += HandleRun;
_run.canceled += HandleRun;
_toggleCrouch.performed += HandleToggleCrouch;
_toggleCrouch.canceled += HandleToggleCrouch;
_toggleProne.performed += HandleToggleProne;
_toggleProne.canceled += HandleToggleProne;
_releaseMouse.performed += HandleReleaseMouse;
_releaseMouse.canceled += HandleReleaseMouse;
foreach (InputAction action in actionAsset)
{
action.performed += SetInputDevice;
}
}
private VRCInputMethod _lastInputMethod = VRCInputMethod.Count;
public VRCInputMethod LastInputMethod
{
get => _lastInputMethod;
set
{
// Only send events for changes
if(_lastInputMethod == value) return;
_lastInputMethod = value;
SendInputMethodChangedEvent(_lastInputMethod);
}
}
private const string MOUSE_LOOK_PATTERN = @"Player/Look.*Mouse/delta";
bool isTouchActive = false;
private void SetInputDevice(InputAction.CallbackContext ctx)
{
if(Regex.IsMatch(ctx.action.ToString(), MOUSE_LOOK_PATTERN)) return; // This is to avoid changing the tooltip icon when looking with a mouse
isTouchActive = (ctx.control.device.description.empty || Touchscreen.current != null && ctx.control.device.GetType().Equals(Touchscreen.current.GetType())); // On screen controls
if (!isTouchActive)
{
if (Keyboard.current != null && ctx.control.device.GetType().Equals(Keyboard.current.GetType()))
{
#if VRC_MOBILE && UNITY_ANDROID
//This prevents the android back button from switching to keyboard and disabling touch UI
if (ctx.control.device.description.interfaceName == "Android")
return;
#endif
LastInputMethod = VRCInputMethod.Keyboard;
return;
}
if (Mouse.current != null && ctx.control.device.GetType().Equals(Mouse.current.GetType()))
{
LastInputMethod = VRCInputMethod.Mouse;
return;
}
if (Gamepad.current != null && ctx.control.device.GetType().Equals(Gamepad.current.GetType()))
{
LastInputMethod = VRCInputMethod.Controller;
return;
}
}
else
{
LastInputMethod = VRCInputMethod.Touch;
}
}
public override void Dispose()
{
base.Dispose();
// Go through and unsubscribe from all input actions
_jumpLeft.performed -= HandleJumpLeft;
_jumpLeft.canceled -= HandleJumpLeft;
_jumpRight.performed -= HandleJumpRight;
_jumpRight.canceled -= HandleJumpRight;
_useLeft.performed -= HandleUseLeft;
_useLeft.canceled -= HandleUseLeft;
_useRight.performed -= HandleUseRight;
_useRight.canceled -= HandleUseRight;
_grabLeft.performed -= HandleGrabLeft;
_grabLeft.canceled -= HandleGrabLeft;
_grabRight.performed -= HandleGrabRight;
_grabRight.canceled -= HandleGrabRight;
_dropLeft.performed -= HandleDropLeft;
_dropLeft.canceled -= HandleDropLeft;
_dropRight.performed -= HandleDropRight;
_dropRight.canceled -= HandleDropRight;
_toggleMenuLeft.performed -= HandleToggleMenuLeft;
_toggleMenuLeft.canceled -= HandleToggleMenuLeft;
_toggleMenuRight.performed -= HandleToggleMenuRight;
_toggleMenuRight.canceled -= HandleToggleMenuRight;
_run.performed -= HandleRun;
_run.canceled -= HandleRun;
_toggleCrouch.performed -= HandleToggleCrouch;
_toggleCrouch.canceled -= HandleToggleCrouch;
_toggleProne.performed -= HandleToggleProne;
_toggleProne.canceled -= HandleToggleProne;
_releaseMouse.performed -= HandleReleaseMouse;
_releaseMouse.canceled -= HandleReleaseMouse;
}
private void HandleJumpLeft(InputAction.CallbackContext context)
{
SendJumpEvent(context.ReadValueAsButton(), HandType.LEFT);
}
private void HandleJumpRight(InputAction.CallbackContext context)
{
SendJumpEvent(context.ReadValueAsButton(), HandType.RIGHT);
}
private void HandleUseLeft(InputAction.CallbackContext context)
{
SendUseEvent(context.ReadValueAsButton(), HandType.LEFT);
}
private void HandleUseRight(InputAction.CallbackContext context)
{
SendUseEvent(context.ReadValueAsButton(), HandType.RIGHT);
}
private void HandleGrabLeft(InputAction.CallbackContext context)
{
SendGrabEvent(context.ReadValueAsButton(), HandType.LEFT);
}
private void HandleGrabRight(InputAction.CallbackContext context)
{
SendGrabEvent(context.ReadValueAsButton(), HandType.RIGHT);
}
private void HandleDropLeft(InputAction.CallbackContext context)
{
SendDropEvent(context.ReadValueAsButton(), HandType.LEFT);
}
private void HandleDropRight(InputAction.CallbackContext context)
{
SendDropEvent(context.ReadValueAsButton(), HandType.RIGHT);
}
private void HandleToggleMenuLeft(InputAction.CallbackContext context)
{
SendToggleMenuEvent(context.ReadValueAsButton(), HandType.LEFT);
}
private void HandleToggleMenuRight(InputAction.CallbackContext context)
{
SendToggleMenuEvent(context.ReadValueAsButton(), HandType.RIGHT);
}
private void HandleRun(InputAction.CallbackContext context)
{
SendRunEvent(context.ReadValueAsButton());
}
private void HandleToggleCrouch(InputAction.CallbackContext context)
{
SendToggleCrouchEvent(context.ReadValueAsButton());
}
private void HandleToggleProne(InputAction.CallbackContext context)
{
SendToggleProneEvent(context.ReadValueAsButton());
}
private void HandleReleaseMouse(InputAction.CallbackContext context)
{
SendReleaseMouseEvent(context.ReadValueAsButton());
}
#endif
public override float GetMovementHorizontal()
{
#if ENABLE_INPUT_SYSTEM
return _movementHorizontal.ReadValue<float>();
#else
return 0;
#endif
}
public override float GetMovementVertical()
{
#if ENABLE_INPUT_SYSTEM
return _movementVertical.ReadValue<float>();
#else
return 0;
#endif
}
public override float GetLookHorizontal()
{
#if ENABLE_INPUT_SYSTEM
if (_pickupRotateLeftRight.ReadValue<float>() != 0)
{
return 0;
}
return _lookHorizontal.ReadValue<float>();
#else
return 0;
#endif
}
public override float GetLookVertical()
{
#if ENABLE_INPUT_SYSTEM
if (_pickupRotateUpDown.ReadValue<float>() != 0)
{
return 0;
}
return _lookVertical.ReadValue<float>() * (_settings.invertMouseLook ? -1 : 1);
#else
return 0;
#endif
}
public override float GetPickupRotateUpDown()
{
#if ENABLE_INPUT_SYSTEM
return _pickupRotateUpDown.ReadValue<float>();
#else
return 0;
#endif
}
public override float GetPickupRotateLeftRight()
{
#if ENABLE_INPUT_SYSTEM
return _pickupRotateLeftRight.ReadValue<float>();
#else
return 0;
#endif
}
public override float GetPickupRotateCwCcw()
{
#if ENABLE_INPUT_SYSTEM
return _pickupRotateCwCcw.ReadValue<float>();
#else
return 0;
#endif
}
public override float GetPickupManipulateDistance()
{
#if ENABLE_INPUT_SYSTEM
return _pickupManipulateForwardBack.ReadValue<float>();
#else
return 0;
#endif
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 606ef90f0aab477f88f3df2bd3dece3b
timeCreated: 1640211870

View File

@ -0,0 +1,242 @@
using System;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon.Common;
namespace VRC.SDK3.ClientSim
{
/// <summary>
/// Base method for handling subscribing to and sending input events.
/// Class is abstract to allow for Test versions to mock sending input events.
/// </summary>
public abstract class ClientSimInputBase : IClientSimInput, IDisposable
{
private Action<bool, HandType> _jumpEvent;
private Action<bool, HandType> _useEvent;
private Action<bool, HandType> _grabEvent;
private Action<bool, HandType> _dropEvent;
private Action<bool, HandType> _toggleMenuEvent;
private Action<bool> _runEvent;
private Action<bool> _toggleCrouchEvent;
private Action<bool> _toggleProneEvent;
private Action<bool> _releaseMouseEvent;
private Action<VRCInputMethod> _inputMethodChangedEvent;
public virtual void Dispose()
{
// Clear all subscriptions
_jumpEvent = null;
_useEvent = null;
_grabEvent = null;
_dropEvent = null;
_toggleMenuEvent = null;
_inputMethodChangedEvent = null;
_runEvent = null;
_toggleCrouchEvent = null;
_toggleProneEvent = null;
_releaseMouseEvent = null;
}
#region Event Subscriptions
public void SubscribeJump(Action<bool, HandType> handler)
{
_jumpEvent += handler;
}
public void UnsubscribeJump(Action<bool, HandType> handler)
{
_jumpEvent -= handler;
}
public void SubscribeUse(Action<bool, HandType> handler)
{
_useEvent += handler;
}
public void UnsubscribeUse(Action<bool, HandType> handler)
{
_useEvent -= handler;
}
public void SubscribeGrab(Action<bool, HandType> handler)
{
_grabEvent += handler;
}
public void UnsubscribeGrab(Action<bool, HandType> handler)
{
_grabEvent -= handler;
}
public void SubscribeDrop(Action<bool, HandType> handler)
{
_dropEvent += handler;
}
public void UnsubscribeDrop(Action<bool, HandType> handler)
{
_dropEvent -= handler;
}
public void SubscribeToggleMenu(Action<bool, HandType> handler)
{
_toggleMenuEvent += handler;
}
public void UnsubscribeToggleMenu(Action<bool, HandType> handler)
{
_toggleMenuEvent -= handler;
}
public void SubscribeRun(Action<bool> handler)
{
_runEvent += handler;
}
public void UnsubscribeRun(Action<bool> handler)
{
_runEvent -= handler;
}
public void SubscribeToggleCrouch(Action<bool> handler)
{
_toggleCrouchEvent += handler;
}
public void UnsubscribeToggleCrouch(Action<bool> handler)
{
_toggleCrouchEvent -= handler;
}
public void SubscribeToggleProne(Action<bool> handler)
{
_toggleProneEvent += handler;
}
public void UnsubscribeToggleProne(Action<bool> handler)
{
_toggleProneEvent -= handler;
}
public void SubscribeReleaseMouse(Action<bool> handler)
{
_releaseMouseEvent += handler;
}
public void UnsubscribeReleaseMouse(Action<bool> handler)
{
_releaseMouseEvent -= handler;
}
public void SubscribeInputChangedEvent(Action<VRCInputMethod> handler)
{
_inputMethodChangedEvent += handler;
}
public void UnsubscribeInputChangedEvent(Action<VRCInputMethod> handler)
{
_inputMethodChangedEvent -= handler;
}
#endregion
#region GetAxisData
public Vector2 GetMovementAxes()
{
float x = GetMovementHorizontal();
float y = GetMovementVertical();
return new Vector2(x, y);
}
public Vector2 GetLookAxes()
{
float x = GetLookHorizontal();
float y = GetLookVertical();
return new Vector2(x, y);
}
public abstract float GetMovementHorizontal();
public abstract float GetMovementVertical();
public abstract float GetLookHorizontal();
public abstract float GetLookVertical();
public abstract float GetPickupRotateUpDown();
public abstract float GetPickupRotateLeftRight();
public abstract float GetPickupRotateCwCcw();
public abstract float GetPickupManipulateDistance();
#endregion
public void SendJumpEvent(bool value, HandType handType)
{
_jumpEvent?.Invoke(value, handType);
}
public void SendUseEvent(bool value, HandType handType)
{
_useEvent?.Invoke(value, handType);
}
public void SendGrabEvent(bool value, HandType handType)
{
_grabEvent?.Invoke(value, handType);
}
public void SendDropEvent(bool value, HandType handType)
{
_dropEvent?.Invoke(value, handType);
}
public void SendToggleMenuEvent(bool value, HandType handType)
{
_toggleMenuEvent?.Invoke(value, handType);
}
public void SendRunEvent(bool value)
{
_runEvent?.Invoke(value);
}
public void SendToggleCrouchEvent(bool value)
{
_toggleCrouchEvent?.Invoke(value);
}
public void SendToggleProneEvent(bool value)
{
_toggleProneEvent?.Invoke(value);
}
public void SendReleaseMouseEvent(bool value)
{
_releaseMouseEvent?.Invoke(value);
}
public void SendInputMethodChangedEvent(VRCInputMethod value)
{
_inputMethodChangedEvent?.Invoke(value);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9f663f3afb8c43b9bde934ce5e27b320
timeCreated: 1640210807

View File

@ -0,0 +1,58 @@
using UnityEngine;
using VRC.SDKBase;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
namespace VRC.SDK3.ClientSim
{
/// <summary>
/// Wrapper around ClientSimInputActionBased that supplies the input actions.
/// Classes were split to allow for testing without monobehaviours.
/// </summary>
[AddComponentMenu("")]
public class ClientSimInputManager : ClientSimBehaviour
{
#if ENABLE_INPUT_SYSTEM
private PlayerInput _playerInput;
private ClientSimInputActionBased _input;
protected override void Awake()
{
base.Awake();
_playerInput = GetComponent<PlayerInput>();
}
private void OnDestroy()
{
_input?.Dispose();
}
#endif
public void Initialize(ClientSimSettings settings)
{
#if ENABLE_INPUT_SYSTEM
_input = new ClientSimInputActionBased(_playerInput.actions, settings);
#endif
}
public IClientSimInput GetInput()
{
#if ENABLE_INPUT_SYSTEM
return _input;
#else
return null;
#endif
}
public VRCInputMethod GetLastUsedInputMethod()
{
#if ENABLE_INPUT_SYSTEM
return _input.LastInputMethod;
#else
return VRCInputMethod.Generic;
#endif
}
}
}

View File

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

View File

@ -0,0 +1,938 @@
{
"name": "ClientSimInputMapping",
"maps": [
{
"name": "Player",
"id": "2f50182f-8d0e-45db-86fb-c28a4c2928c3",
"actions": [
{
"name": "LookHorizontal",
"type": "Value",
"id": "fd5ba6df-78c4-4e25-9fd5-7e3d97cff8c1",
"expectedControlType": "Axis",
"processors": "",
"interactions": ""
},
{
"name": "LookVertical",
"type": "Value",
"id": "d9675fd8-9661-4368-984d-f6f7683fe821",
"expectedControlType": "Axis",
"processors": "",
"interactions": ""
},
{
"name": "MovementHorizontal",
"type": "Value",
"id": "c5e34fa0-7b42-436a-aac5-43719b6671e5",
"expectedControlType": "Axis",
"processors": "",
"interactions": ""
},
{
"name": "MovementVertical",
"type": "Value",
"id": "9e5c4572-7e08-413a-8992-d08e65de6588",
"expectedControlType": "Axis",
"processors": "",
"interactions": ""
},
{
"name": "JumpLeft",
"type": "Button",
"id": "4bcd4015-fce1-40e8-bac9-17c60193e8a6",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "JumpRight",
"type": "Button",
"id": "e1d78f1c-246d-42ce-8dad-64769265bc40",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "UseLeft",
"type": "Button",
"id": "1c0d0334-cacd-4c50-81e3-c9efb4436ccb",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "UseRight",
"type": "Button",
"id": "5e78bbbe-04e6-44df-bc85-404f92936b98",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "GrabLeft",
"type": "Button",
"id": "a9b3a7e3-2b29-48d1-8be7-c7a2fba1d70d",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "GrabRight",
"type": "Button",
"id": "e77cb057-0a67-47a5-b73b-cf5f750feae1",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "DropLeft",
"type": "Button",
"id": "5e9b0664-5568-442e-bc7b-000386ea8cb7",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "DropRight",
"type": "Button",
"id": "5ae3c089-7d25-41d2-8245-78c24b806ae9",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "ToggleMenuLeft",
"type": "Button",
"id": "1fe9ba51-431d-42df-b3b8-fb55b37a26d9",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "ToggleMenuRight",
"type": "Button",
"id": "8a4af8b2-f882-4ae3-a6ea-f8d10c88a1f6",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "Run",
"type": "Button",
"id": "e47a69fe-eadc-47da-a81f-909b6c277e00",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "ToggleCrouch",
"type": "Button",
"id": "2064b4f9-486f-476d-800b-52f1208aff6c",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "ToggleProne",
"type": "Button",
"id": "28ffcaeb-1d40-48b8-8ed9-593338b8e9be",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "ReleaseMouse",
"type": "Button",
"id": "20ba4d98-6df4-4d39-aab4-5a0b170f1526",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "PickupRotateUpDown",
"type": "Button",
"id": "5f707c29-abb7-489d-9762-4a19e7a44caf",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "PickupRotateLeftRight",
"type": "Button",
"id": "aaf0f321-7c3d-49d6-991f-1c7ee7cf6425",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "PickupRotateCwCcw",
"type": "Button",
"id": "97928f76-bc32-45a3-94fd-211a439b5a9e",
"expectedControlType": "Button",
"processors": "",
"interactions": ""
},
{
"name": "PickupManipulateForwardBack",
"type": "Value",
"id": "768b624a-5837-4f36-9f89-e4953a7a8951",
"expectedControlType": "Axis",
"processors": "",
"interactions": ""
}
],
"bindings": [
{
"name": "",
"id": "550c6b6a-81c1-4282-b4fd-ac579d21ac6c",
"path": "<Keyboard>/space",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "JumpLeft",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "730090f3-1e28-4ef7-8a82-0ebb910ef667",
"path": "<Keyboard>/c",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "ToggleCrouch",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "b4cfeb73-71f8-45b9-8cdd-8e649dde9d1b",
"path": "<Keyboard>/z",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "ToggleProne",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "e7ed5e53-bd0b-40a1-a286-8b86a4372292",
"path": "<Gamepad>/leftStickPress",
"interactions": "Hold",
"processors": "",
"groups": "Gamepad",
"action": "ToggleProne",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "9d0b9b99-72c2-46cf-8765-fbcc9b4589ef",
"path": "<Keyboard>/tab",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "ReleaseMouse",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "UpDown",
"id": "599162a8-d480-47e8-a889-c48d14357572",
"path": "1DAxis",
"interactions": "",
"processors": "",
"groups": "",
"action": "MovementVertical",
"isComposite": true,
"isPartOfComposite": false
},
{
"name": "negative",
"id": "ef0c2b1a-07ce-45fc-8d51-1bd6fdcbb28f",
"path": "<Keyboard>/s",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "MovementVertical",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "positive",
"id": "554ed0de-b631-49a1-b623-878c3ab03682",
"path": "<Keyboard>/w",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "MovementVertical",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "",
"id": "094901d9-a4fa-43ef-8c9f-bfed9d7d8920",
"path": "<Gamepad>/leftStick/y",
"interactions": "",
"processors": "AxisDeadzone",
"groups": "Gamepad",
"action": "MovementVertical",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "LeftRight",
"id": "3c1a54d3-a057-4e61-8b9a-5b1f13341d5a",
"path": "1DAxis",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "MovementHorizontal",
"isComposite": true,
"isPartOfComposite": false
},
{
"name": "negative",
"id": "57ae784a-0a44-45cb-b7b8-fcec8b04cad3",
"path": "<Keyboard>/a",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "MovementHorizontal",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "positive",
"id": "a334ecdc-1430-4b6a-afde-3ff6d2154773",
"path": "<Keyboard>/d",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "MovementHorizontal",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "",
"id": "b1ab7f24-f82a-42df-b586-cced45f62b2e",
"path": "<Gamepad>/leftStick/x",
"interactions": "",
"processors": "AxisDeadzone",
"groups": "Gamepad",
"action": "MovementHorizontal",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "adab09ec-3821-417c-82b8-314882199eb0",
"path": "<XRController>{RightHand}/primary2daxis/y",
"interactions": "",
"processors": "",
"groups": "XRController",
"action": "LookVertical",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "a7212801-53a8-4fe8-831b-01974f0c2d9f",
"path": "<Mouse>/delta/y",
"interactions": "",
"processors": "Scale(factor=0.1)",
"groups": "KeyboardMouse",
"action": "LookVertical",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "7d1e21de-8a59-41db-9f28-c95b92b3da8c",
"path": "<Gamepad>/rightStick/y",
"interactions": "",
"processors": "AxisDeadzone,Scale(factor=2)",
"groups": "",
"action": "LookVertical",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "3481d65f-35c3-48f7-b259-6f8d2cac26c8",
"path": "<Mouse>/delta/x",
"interactions": "",
"processors": "Scale(factor=0.1)",
"groups": "KeyboardMouse",
"action": "LookHorizontal",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "4aeeecac-4996-47e7-bd05-af550efb62ac",
"path": "<XRController>{RightHand}/primary2daxis/x",
"interactions": "",
"processors": "Scale(factor=4)",
"groups": "XRController",
"action": "LookHorizontal",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "6533983e-06ef-4adc-abd2-6cd33b462ac8",
"path": "<Gamepad>/rightStick/x",
"interactions": "",
"processors": "AxisDeadzone,Scale(factor=2)",
"groups": "Gamepad",
"action": "LookHorizontal",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "f5444cd9-f41a-4ebb-aadf-c10211534afa",
"path": "<XRController>{RightHand}/grippressed",
"interactions": "",
"processors": "",
"groups": "XRController",
"action": "GrabRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "ba0f411d-3372-4c6d-b9d5-c26e875be59c",
"path": "<Mouse>/leftButton",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "GrabRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "ad175ec7-32cb-49e5-a110-f579d3d3413c",
"path": "<Mouse>/rightButton",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "DropRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "1d68fa18-5dc4-4d90-9365-9c4db81311e2",
"path": "<Gamepad>/buttonNorth",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "DropRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "50eac56e-5677-4524-8d0f-a1fbf16f3900",
"path": "<Gamepad>/rightShoulder",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "DropRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "157bf0cb-a7e7-48d9-88fa-1517693070c5",
"path": "<XRController>{RightHand}/triggerpressed",
"interactions": "",
"processors": "",
"groups": "XRController",
"action": "UseRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "3127ec01-bb2b-4e6d-a7ff-130d739c6b31",
"path": "<Mouse>/leftButton",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "UseRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "5ff2efde-e215-4a78-b8bc-0bff8e57e630",
"path": "<Gamepad>/rightTrigger",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "UseRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "66ff8685-5751-48e9-b8e1-52b8eee82e34",
"path": "<Gamepad>/buttonEast",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "UseRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "9f1da403-960f-41db-b08c-65d7599e899a",
"path": "<Keyboard>/leftShift",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "Run",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "UpDown",
"id": "394c9c63-26cd-4401-a397-184c01a7fb06",
"path": "1DAxis",
"interactions": "",
"processors": "",
"groups": "",
"action": "PickupRotateUpDown",
"isComposite": true,
"isPartOfComposite": false
},
{
"name": "negative",
"id": "bf93b7e2-55ce-481e-85c2-0e8b4ae2f3c9",
"path": "<Keyboard>/i",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "PickupRotateUpDown",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "positive",
"id": "9de24fef-2a7c-4bcf-b274-63daff07abfe",
"path": "<Keyboard>/k",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "PickupRotateUpDown",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "ClockwiseCounterClockwise",
"id": "80006719-f2f8-4dc6-9fdf-443d2486f309",
"path": "1DAxis",
"interactions": "",
"processors": "",
"groups": "",
"action": "PickupRotateCwCcw",
"isComposite": true,
"isPartOfComposite": false
},
{
"name": "negative",
"id": "f3d77344-6c16-4b26-9dfb-ff765db9be87",
"path": "<Keyboard>/u",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "PickupRotateCwCcw",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "positive",
"id": "aae8cb97-dffd-4fb5-b4d3-8bc92c76da7c",
"path": "<Keyboard>/o",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "PickupRotateCwCcw",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "",
"id": "943c5ae4-0943-427d-95d9-cf4e676b20b0",
"path": "<Mouse>/scroll/y",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "PickupManipulateForwardBack",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "012bc491-7c79-43cd-872a-c9d5c56e6e6f",
"path": "<XRController>{LeftHand}/primary2daxis/y",
"interactions": "",
"processors": "",
"groups": "XRController",
"action": "MovementVertical",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "94d2aec0-a0b9-4934-9b0a-8a27e75d118c",
"path": "<XRController>{LeftHand}/primary2daxis/x",
"interactions": "",
"processors": "",
"groups": "XRController",
"action": "MovementHorizontal",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "11375370-60ed-4eff-968c-85131e5900f9",
"path": "<XRController>{RightHand}/joystickorpadpressed",
"interactions": "",
"processors": "",
"groups": "XRController",
"action": "JumpRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "0650c167-2c34-4480-8deb-3c9c251c9563",
"path": "<Gamepad>/buttonSouth",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "JumpRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "9928474d-83f2-4067-a555-bc7dd2bdf3dd",
"path": "<XRController>{LeftHand}/triggerpressed",
"interactions": "",
"processors": "",
"groups": "XRController",
"action": "UseLeft",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "3462f0fd-c25f-4223-88e1-e448815e9f90",
"path": "<XRController>{LeftHand}/grippressed",
"interactions": "",
"processors": "",
"groups": "XRController",
"action": "GrabLeft",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "6be33530-03b7-47d5-baef-a1873dab0483",
"path": "<XRController>{LeftHand}/primary",
"interactions": "",
"processors": "",
"groups": "XRController",
"action": "ToggleMenuLeft",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "a6937a04-1651-4f9b-b532-f1b1f52f91ea",
"path": "<Keyboard>/escape",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "ToggleMenuLeft",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "LeftRight",
"id": "dc3ca725-f9f3-4b9d-b73d-ccab2de20c89",
"path": "1DAxis",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "PickupRotateLeftRight",
"isComposite": true,
"isPartOfComposite": false
},
{
"name": "negative",
"id": "edbe58fa-0e59-446c-9765-589870585e9c",
"path": "<Keyboard>/l",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "PickupRotateLeftRight",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "positive",
"id": "6eab6abd-f646-4064-a093-bef75d51704f",
"path": "<Keyboard>/j",
"interactions": "",
"processors": "",
"groups": "KeyboardMouse",
"action": "PickupRotateLeftRight",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "",
"id": "41374253-d07b-4eb9-b76f-68ff25ad6099",
"path": "<XRController>{RightHand}/primary",
"interactions": "",
"processors": "",
"groups": "XRController",
"action": "ToggleMenuRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "98ed6e07-cbe7-4332-9ab3-7d130fc2be70",
"path": "<Gamepad>/start",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "ToggleMenuRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "813f1ec6-f321-4bd5-b091-a936c2173904",
"path": "<Gamepad>/rightTrigger",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "GrabRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "d2eb4465-b94a-4012-ab0d-5c9fa72c9cb7",
"path": "<Gamepad>/buttonEast",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "GrabRight",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "d39fd262-9f80-4061-bf54-a42d997bb0d6",
"path": "<Gamepad>/leftStickPress",
"interactions": "Press",
"processors": "",
"groups": "Gamepad",
"action": "ToggleCrouch",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "RightStickWithLeftShoulder",
"id": "b2aff2a5-4826-433b-b14b-4c2c8925e56c",
"path": "ButtonWithOneModifier",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "PickupRotateUpDown",
"isComposite": true,
"isPartOfComposite": false
},
{
"name": "modifier",
"id": "42575b80-955d-494a-bdff-4e83a6beb850",
"path": "<Gamepad>/leftShoulder",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "PickupRotateUpDown",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "button",
"id": "ada6cac4-3fc3-4dc5-a418-2d6c3f218d24",
"path": "<Gamepad>/rightStick/y",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "PickupRotateUpDown",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "RightStickWithLeftShoulder",
"id": "a69e5173-82f8-4ed7-8d30-af528c6fa262",
"path": "ButtonWithOneModifier",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "PickupRotateLeftRight",
"isComposite": true,
"isPartOfComposite": false
},
{
"name": "modifier",
"id": "52c40760-cb07-427d-95c9-cd8539c939e8",
"path": "<Gamepad>/leftShoulder",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "PickupRotateLeftRight",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "button",
"id": "f3ce62de-2286-499f-bfbb-aaad0021a224",
"path": "<Gamepad>/rightStick/x",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "PickupRotateLeftRight",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "LeftStickWithLeftShoulder",
"id": "5466362d-116f-4eb8-9825-010812d07ff7",
"path": "ButtonWithOneModifier",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "PickupRotateCwCcw",
"isComposite": true,
"isPartOfComposite": false
},
{
"name": "modifier",
"id": "79ec2bba-44b3-4a1a-a18c-e03370ecce44",
"path": "<Gamepad>/leftShoulder",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "PickupRotateCwCcw",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "button",
"id": "3c906a95-8491-42be-a414-8d69ecdf037b",
"path": "<Gamepad>/leftStick/x",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "PickupRotateCwCcw",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "LeftStickWithLeftShoulder",
"id": "9170df3e-d37e-4c49-8bb3-5a944ff141d5",
"path": "ButtonWithOneModifier",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "PickupManipulateForwardBack",
"isComposite": true,
"isPartOfComposite": false
},
{
"name": "modifier",
"id": "07f0af65-6b32-4bf4-ac49-52784277b1fc",
"path": "<Gamepad>/leftShoulder",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "PickupManipulateForwardBack",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "button",
"id": "0f1b2753-f8d1-4106-b35b-1551d1c825db",
"path": "<Gamepad>/leftStick/y",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "PickupManipulateForwardBack",
"isComposite": false,
"isPartOfComposite": true
}
]
}
],
"controlSchemes": [
{
"name": "KeyboardMouse",
"bindingGroup": "KeyboardMouse",
"devices": [
{
"devicePath": "<Keyboard>",
"isOptional": false,
"isOR": false
},
{
"devicePath": "<Mouse>",
"isOptional": false,
"isOR": false
}
]
},
{
"name": "Gamepad",
"bindingGroup": "Gamepad",
"devices": [
{
"devicePath": "<Gamepad>",
"isOptional": false,
"isOR": false
}
]
},
{
"name": "XRController",
"bindingGroup": "XRController",
"devices": [
{
"devicePath": "<XRController>{RightHand}",
"isOptional": true,
"isOR": false
},
{
"devicePath": "<XRController>{LeftHand}",
"isOptional": true,
"isOR": false
}
]
}
]
}

View File

@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: 2a08897387d5ffd4795ccec0e8384a6a
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 8404be70184654265930450def6a9037, type: 3}
generateWrapperCode: 0
wrapperCodePath:
wrapperClassName: ClientSimInputMapping
wrapperCodeNamespace: VRC.SDK3.ClientSim

View File

@ -0,0 +1,193 @@

using System;
using System.Collections.Generic;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
using VRC.Udon.Common;
namespace VRC.SDK3.ClientSim
{
/// <summary>
/// System responsible for listening to Input Events and sending them to UdonBehaviours.
/// </summary>
/// <remarks>
/// Listens to Events:
/// - ClientSimMenuStateChangedEvent
/// Listens to Input Events:
/// - Jump
/// - Grab
/// - Use
/// - Drop
/// </remarks>
public class ClientSimUdonInput : IDisposable
{
private const float MINIMUM_MOVE_INPUT_EPS = 1e-3f;
private const float MINIMUM_LOOK_INPUT_EPS = 1e-5f;
private readonly IClientSimInput _input;
private readonly IClientSimEventDispatcher _eventDispatcher;
/// <summary>
/// A wrapper for sending events to all UdonBehaviours to create unit tests not dependent on UdonManager.
/// </summary>
private readonly IClientSimUdonInputEventSender _udonInputEventSender;
private Vector2 _prevInput;
private Vector2 _prevLookInput = Vector2.zero;
private Vector2 _prevMoveAxes = Vector2.zero;
private bool _isMenuOpen;
private int _lastMenuUpdateFrame; // TODO update based on processing tick instead of time to allow for better testing.
// All button based events are queued until process time. This is done to ensure that all udon input events
// happen at the same time in the frame and not mixed between when unity's update for the new Input Manager
// sends events. Without this, input events would happen before UdonBehaviour.Update, causing strange out of
// order issues.
private readonly Queue<Action> _queuedEvents = new Queue<Action>();
public ClientSimUdonInput(
IClientSimEventDispatcher eventDispatcher,
IClientSimInput input,
IClientSimUdonInputEventSender udonInputEventSender)
{
_input = input;
_eventDispatcher = eventDispatcher;
_udonInputEventSender = udonInputEventSender;
_eventDispatcher.Subscribe<ClientSimMenuStateChangedEvent>(SetMenuOpen);
// Input will be null with incorrect Unity input project settings.
_input?.SubscribeJump(JumpInput);
_input?.SubscribeUse(UseInput);
_input?.SubscribeGrab(GrabInput);
_input?.SubscribeDrop(DropInput);
_input?.SubscribeInputChangedEvent(SendInputChangedEvent);
}
public void Dispose()
{
_eventDispatcher?.Unsubscribe<ClientSimMenuStateChangedEvent>(SetMenuOpen);
_input?.UnsubscribeJump(JumpInput);
_input?.UnsubscribeUse(UseInput);
_input?.UnsubscribeGrab(GrabInput);
_input?.UnsubscribeDrop(DropInput);
_input?.UnsubscribeInputChangedEvent(SendInputChangedEvent);
}
#region ClientSim Events
private void SetMenuOpen(ClientSimMenuStateChangedEvent stateChangedEvent)
{
_lastMenuUpdateFrame = Time.frameCount;
_isMenuOpen = stateChangedEvent.isMenuOpen;
}
#endregion
#region ClientSim Input
private void JumpInput(bool value, HandType hand)
{
QueueButtonInputEvent(value, hand, UdonManager.UDON_INPUT_JUMP);
}
private void UseInput(bool value, HandType hand)
{
QueueButtonInputEvent(value, hand, UdonManager.UDON_INPUT_USE);
}
private void GrabInput(bool value, HandType hand)
{
QueueButtonInputEvent(value, hand, UdonManager.UDON_INPUT_GRAB);
}
private void DropInput(bool value, HandType hand)
{
QueueButtonInputEvent(value, hand, UdonManager.UDON_INPUT_DROP);
}
private void SendInputChangedEvent(VRCInputMethod inputMethod)
{
_queuedEvents.Enqueue(() =>
{
UdonManager.Instance.RunEvent(UdonManager.UDON_EVENT_ONINPUTMETHODCHANGED, ("inputMethod", inputMethod));
});
}
#endregion
private void SendUdonInputBoolEvent(bool value, HandType hand, string eventName)
{
var args = new UdonInputEventArgs(value, hand);
_udonInputEventSender.RunInputAction(eventName, args);
}
private void SendUdonInputFloatEvent(float value, HandType hand, string eventName)
{
var args = new UdonInputEventArgs(value, hand);
_udonInputEventSender.RunInputAction(eventName, args);
}
private void QueueButtonInputEvent(bool value, HandType hand, string eventName)
{
// Do not queue event if the menu is open.
if (IsMenuOpen())
{
return;
}
_queuedEvents.Enqueue(() =>
{
SendUdonInputBoolEvent(value, hand, eventName);
});
}
public void ProcessInputEvents()
{
// If the menu is open or the menu was updated on this frame, skip sending input events.
if (IsMenuOpen())
{
_queuedEvents.Clear();
return;
}
// Ensure that all udon input events happen at the same time in the frame and not mixed between when unity's
// update for the new Input Manager sends events. Without this, input events would happen before
// UdonBehaviour.Update, causing strange out of order issues.
while (_queuedEvents.Count > 0)
{
Action inputEvent = _queuedEvents.Dequeue();
inputEvent?.Invoke();
}
Vector2 lookAxes = _input.GetLookAxes();
if (Mathf.Abs(lookAxes.x - _prevLookInput.x) > MINIMUM_LOOK_INPUT_EPS)
{
SendUdonInputFloatEvent(lookAxes.x, HandType.RIGHT, UdonManager.UDON_LOOK_HORIZONTAL);
}
if (Mathf.Abs(lookAxes.y - _prevLookInput.y) > MINIMUM_LOOK_INPUT_EPS)
{
SendUdonInputFloatEvent(lookAxes.y, HandType.RIGHT, UdonManager.UDON_LOOK_VERTICAL);
}
_prevLookInput = lookAxes;
Vector2 moveAxes = _input.GetMovementAxes();
if (Mathf.Abs(_prevMoveAxes.x - moveAxes.x) > MINIMUM_MOVE_INPUT_EPS)
{
SendUdonInputFloatEvent(moveAxes.x, HandType.LEFT, UdonManager.UDON_MOVE_HORIZONTAL);
}
if (Mathf.Abs(_prevMoveAxes.y - moveAxes.y) > MINIMUM_MOVE_INPUT_EPS)
{
SendUdonInputFloatEvent(moveAxes.y, HandType.LEFT, UdonManager.UDON_MOVE_VERTICAL);
}
_prevMoveAxes = moveAxes;
}
private bool IsMenuOpen()
{
return _isMenuOpen || _lastMenuUpdateFrame == Time.frameCount;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1e963688a1c048ddac34d738cc8f3072
timeCreated: 1638891929

View File

@ -0,0 +1,33 @@
using UnityEngine;
using VRC.Udon;
namespace VRC.SDK3.ClientSim
{
/// <summary>
/// Wrapper class for UdonInput
/// </summary>
[AddComponentMenu("")]
[DefaultExecutionOrder(1)] // Ensure that input events happen after UdonBehaviour.Update
public class ClientSimUdonInputBehaviour : ClientSimBehaviour
{
private ClientSimUdonInput _udonInput;
public void Initialize(IClientSimEventDispatcher eventDispatcher, IClientSimInput input)
{
_udonInput = new ClientSimUdonInput(
eventDispatcher,
input,
new ClientSimUdonManagerInputEventSender(UdonManager.Instance));
}
private void OnDestroy()
{
_udonInput?.Dispose();
}
public void Update()
{
_udonInput?.ProcessInputEvents();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5fc129f391f3488e947eb13a9208bae4
timeCreated: 1640233289

View File

@ -0,0 +1,23 @@
using VRC.Udon;
using VRC.Udon.Common;
namespace VRC.SDK3.ClientSim
{
/// <summary>
/// Wrapper for UdonManager. Only needed to prevent direct dependency to UdonManger in the UdonInput class.
/// </summary>
public class ClientSimUdonManagerInputEventSender : IClientSimUdonInputEventSender
{
private readonly UdonManager _udonManager;
public ClientSimUdonManagerInputEventSender(UdonManager udonManager)
{
_udonManager = udonManager;
}
public void RunInputAction(string eventName, UdonInputEventArgs args)
{
_udonManager.RunInputAction(eventName, args);
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4025ed62957542d2b0609cfa37d16946
timeCreated: 1640269473

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 44c15dbef57edea4eb564bd9c5e634b9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,56 @@
using System;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon.Common;
namespace VRC.SDK3.ClientSim
{
public interface IClientSimInput
{
float GetMovementHorizontal();
float GetMovementVertical();
Vector2 GetMovementAxes();
float GetLookHorizontal();
float GetLookVertical();
Vector2 GetLookAxes();
float GetPickupRotateUpDown();
float GetPickupRotateLeftRight();
float GetPickupRotateCwCcw();
float GetPickupManipulateDistance();
void SubscribeJump(Action<bool, HandType> handler);
void UnsubscribeJump(Action<bool, HandType> handler);
void SubscribeUse(Action<bool, HandType> handler);
void UnsubscribeUse(Action<bool, HandType> handler);
void SubscribeGrab(Action<bool, HandType> handler);
void UnsubscribeGrab(Action<bool, HandType> handler);
void SubscribeDrop(Action<bool, HandType> handler);
void UnsubscribeDrop(Action<bool, HandType> handler);
void SubscribeToggleMenu(Action<bool, HandType> handler);
void UnsubscribeToggleMenu(Action<bool, HandType> handler);
void SubscribeRun(Action<bool> handler);
void UnsubscribeRun(Action<bool> handler);
void SubscribeToggleCrouch(Action<bool> handler);
void UnsubscribeToggleCrouch(Action<bool> handler);
void SubscribeToggleProne(Action<bool> handler);
void UnsubscribeToggleProne(Action<bool> handler);
void SubscribeReleaseMouse(Action<bool> handler);
void UnsubscribeReleaseMouse(Action<bool> handler);
public void SubscribeInputChangedEvent(Action<VRCInputMethod> handler);
public void UnsubscribeInputChangedEvent(Action<VRCInputMethod> handler);
public void SendToggleMenuEvent(bool value, HandType hand);
}
}

View File

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

View File

@ -0,0 +1,9 @@
using VRC.Udon.Common;
namespace VRC.SDK3.ClientSim
{
public interface IClientSimUdonInputEventSender
{
void RunInputAction(string eventName, UdonInputEventArgs args);
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 64c08af8f4f24106a5c7d231af1a4ca0
timeCreated: 1640269388