Add GC-less standalone input module.

This commit is contained in:
2023-05-19 23:14:59 +08:00
parent 0d0902735a
commit ed60859406
6 changed files with 171 additions and 21 deletions

View File

@@ -624,7 +624,7 @@ GameObject:
m_Component:
- component: {fileID: 155472387}
- component: {fileID: 155472386}
- component: {fileID: 155472385}
- component: {fileID: 155472388}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
@@ -632,26 +632,6 @@ GameObject:
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &155472385
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 155472383}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3}
m_Name:
m_EditorClassIdentifier:
m_SendPointerHoverToParent: 1
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
m_CancelButton: Cancel
m_InputActionsPerSecond: 10
m_RepeatDelay: 0.5
m_ForceModuleActive: 0
--- !u!114 &155472386
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -682,6 +662,26 @@ Transform:
m_Father: {fileID: 0}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &155472388
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 155472383}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d457e7b17951c6940ac8306e52498bbc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_SendPointerHoverToParent: 1
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
m_CancelButton: Cancel
m_InputActionsPerSecond: 10
m_RepeatDelay: 0.5
m_ForceModuleActive: 0
--- !u!1 &221975151
GameObject:
m_ObjectHideFlags: 0

View File

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

View File

@@ -0,0 +1,14 @@
{
"name": "Cryville.Unity.EventSystems",
"rootNamespace": "",
"references": [],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f27578110a12bd048804c6492d1d9c27
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,110 @@
using Cryville.Common.Buffers;
using UnityEngine;
using UnityEngine.EventSystems;
namespace Cryville.Unity.EventSystems {
[AddComponentMenu("Event/GC-less Standalone Input Module")]
public class StandaloneInputModule : UnityEngine.EventSystems.StandaloneInputModule {
private bool ShouldIgnoreEventsOnNoFocus() {
#if UNITY_EDITOR
return !UnityEditor.EditorApplication.isRemoteConnected;
#else
return true;
#endif
}
public override void Process() {
if (!eventSystem.isFocused && ShouldIgnoreEventsOnNoFocus()) {
return;
}
bool usedEvent = SendUpdateEventToSelectedObject();
if (!ProcessTouchEvents() && input.mousePresent) {
ProcessMouseEvent();
}
if (eventSystem.sendNavigationEvents) {
if (!usedEvent) {
usedEvent |= SendMoveEventToSelectedObject();
}
if (!usedEvent) {
SendSubmitEventToSelectedObject();
}
}
}
private bool ProcessTouchEvents() {
for (int i = 0; i < input.touchCount; i++) {
Touch touch = input.GetTouch(i);
if (touch.type != TouchType.Indirect) {
bool pressed, released;
PointerEventData pointer = GetTouchPointerEventData(touch, out pressed, out released);
ProcessTouchPress(pointer, pressed, released);
if (!released) {
ProcessMove(pointer);
ProcessDrag(pointer);
}
else {
RemovePointerData(pointer);
}
}
}
return input.touchCount > 0;
}
protected new PointerEventData GetTouchPointerEventData(Touch input, out bool pressed, out bool released) {
PointerEventData pointerData;
bool created = GetPointerData(input.fingerId, out pointerData, create: true);
pointerData.Reset();
pressed = created || input.phase == TouchPhase.Began;
released = input.phase == TouchPhase.Canceled || input.phase == TouchPhase.Ended;
if (created) {
pointerData.position = input.position;
}
if (pressed) {
pointerData.delta = Vector2.zero;
}
else {
pointerData.delta = input.position - pointerData.position;
}
pointerData.position = input.position;
pointerData.button = PointerEventData.InputButton.Left;
if (input.phase == TouchPhase.Canceled) {
pointerData.pointerCurrentRaycast = default(RaycastResult);
}
else {
eventSystem.RaycastAll(pointerData, m_RaycastResultCache);
pointerData.pointerCurrentRaycast = FindFirstRaycast(m_RaycastResultCache);
m_RaycastResultCache.Clear();
}
pointerData.pressure = input.pressure;
pointerData.altitudeAngle = input.altitudeAngle;
pointerData.azimuthAngle = input.azimuthAngle;
pointerData.radius = Vector2.one * input.radius;
pointerData.radiusVariance = Vector2.one * input.radiusVariance;
return pointerData;
}
class PointerEventDataPool : ObjectPool<PointerEventData> {
readonly EventSystem _eventSystem;
public PointerEventDataPool(EventSystem eventSystem, int capacity) : base(capacity) {
_eventSystem = eventSystem;
}
protected override PointerEventData Construct() {
return new PointerEventData(_eventSystem);
}
}
PointerEventDataPool _pool;
protected override void OnEnable() {
base.OnEnable();
_pool = new PointerEventDataPool(eventSystem, 64);
}
protected new bool GetPointerData(int id, out PointerEventData data, bool create) {
if (!m_PointerData.TryGetValue(id, out data) && create) {
data = _pool.Rent();
data.pointerId = id;
m_PointerData.Add(id, data);
return true;
}
return false;
}
protected new void RemovePointerData(PointerEventData data) {
m_PointerData.Remove(data.pointerId);
_pool.Return(data);
}
}
}

View File

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