Skip to content

Commit 5dc88c4

Browse files
authored
Multi touch event supported (#25)
* multi-touch event supported * touch event phase support (C#) * touch event phase support * MouseWheel Support (C#) * MouseWheel support (javascript)
1 parent faf96d2 commit 5dc88c4

File tree

6 files changed

+312
-108
lines changed

6 files changed

+312
-108
lines changed

Assets/Scenes/SampleScene.unity

+82-1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,85 @@ NavMeshSettings:
120120
debug:
121121
m_Flags: 0
122122
m_NavMeshData: {fileID: 0}
123+
--- !u!1 &145210077
124+
GameObject:
125+
m_ObjectHideFlags: 0
126+
m_CorrespondingSourceObject: {fileID: 0}
127+
m_PrefabInstance: {fileID: 0}
128+
m_PrefabAsset: {fileID: 0}
129+
serializedVersion: 6
130+
m_Component:
131+
- component: {fileID: 145210078}
132+
- component: {fileID: 145210080}
133+
- component: {fileID: 145210079}
134+
m_Layer: 5
135+
m_Name: Text
136+
m_TagString: Untagged
137+
m_Icon: {fileID: 0}
138+
m_NavMeshLayer: 0
139+
m_StaticEditorFlags: 0
140+
m_IsActive: 1
141+
--- !u!224 &145210078
142+
RectTransform:
143+
m_ObjectHideFlags: 0
144+
m_CorrespondingSourceObject: {fileID: 0}
145+
m_PrefabInstance: {fileID: 0}
146+
m_PrefabAsset: {fileID: 0}
147+
m_GameObject: {fileID: 145210077}
148+
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
149+
m_LocalPosition: {x: 0, y: 0, z: 0}
150+
m_LocalScale: {x: 1, y: 1, z: 1}
151+
m_Children: []
152+
m_Father: {fileID: 1647766022}
153+
m_RootOrder: 1
154+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
155+
m_AnchorMin: {x: 0, y: 0}
156+
m_AnchorMax: {x: 1, y: 0}
157+
m_AnchoredPosition: {x: 50, y: 50}
158+
m_SizeDelta: {x: -100, y: 50}
159+
m_Pivot: {x: 0, y: 0}
160+
--- !u!114 &145210079
161+
MonoBehaviour:
162+
m_ObjectHideFlags: 0
163+
m_CorrespondingSourceObject: {fileID: 0}
164+
m_PrefabInstance: {fileID: 0}
165+
m_PrefabAsset: {fileID: 0}
166+
m_GameObject: {fileID: 145210077}
167+
m_Enabled: 1
168+
m_EditorHideFlags: 0
169+
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
170+
m_Name:
171+
m_EditorClassIdentifier:
172+
m_Material: {fileID: 0}
173+
m_Color: {r: 1, g: 1, b: 1, a: 1}
174+
m_RaycastTarget: 1
175+
m_OnCullStateChanged:
176+
m_PersistentCalls:
177+
m_Calls: []
178+
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
179+
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
180+
m_FontData:
181+
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
182+
m_FontSize: 32
183+
m_FontStyle: 0
184+
m_BestFit: 0
185+
m_MinSize: 3
186+
m_MaxSize: 40
187+
m_Alignment: 6
188+
m_AlignByGeometry: 0
189+
m_RichText: 1
190+
m_HorizontalOverflow: 0
191+
m_VerticalOverflow: 0
192+
m_LineSpacing: 1
193+
m_Text: New Text
194+
--- !u!222 &145210080
195+
CanvasRenderer:
196+
m_ObjectHideFlags: 0
197+
m_CorrespondingSourceObject: {fileID: 0}
198+
m_PrefabInstance: {fileID: 0}
199+
m_PrefabAsset: {fileID: 0}
200+
m_GameObject: {fileID: 145210077}
201+
m_CullTransparentMesh: 0
123202
--- !u!1 &170076733
124203
GameObject:
125204
m_ObjectHideFlags: 0
@@ -389,7 +468,7 @@ MonoBehaviour:
389468
m_Script: {fileID: 11500000, guid: 045786cf504bd7347842d6948241cbd0, type: 3}
390469
m_Name:
391470
m_EditorClassIdentifier:
392-
urlSignaling: http://192.168.11.2
471+
urlSignaling: http://10.81.35.130
393472
urlSTUN: stun:stun.l.google.com:19302
394473
interval: 5
395474
--- !u!4 &1343183829
@@ -513,6 +592,7 @@ MonoBehaviour:
513592
m_Name:
514593
m_EditorClassIdentifier:
515594
cursor: {fileID: 1597907846}
595+
text: {fileID: 145210079}
516596
--- !u!114 &1647766019
517597
MonoBehaviour:
518598
m_ObjectHideFlags: 0
@@ -585,6 +665,7 @@ RectTransform:
585665
m_LocalScale: {x: 0, y: 0, z: 0}
586666
m_Children:
587667
- {fileID: 1597907846}
668+
- {fileID: 145210078}
588669
m_Father: {fileID: 0}
589670
m_RootOrder: 3
590671
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}

Assets/Scripts/RemoteInput.cs

+71-34
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,24 @@
55

66
namespace Unity.RenderStreaming
77
{
8-
enum KeyEventType
8+
enum KeyboardEventType
99
{
10-
KeyDown = 0,
11-
KeyUp,
12-
KeyPress
10+
KeyUp = 0,
11+
KeyDown = 1,
1312
}
1413
enum EventType
1514
{
1615
Keyboard = 0,
17-
MouseDown = 2,
18-
MouseMove = 4,
19-
MouseWheel = 5,
20-
TouchMove = 6
16+
Mouse = 1,
17+
MouseWheel = 2,
18+
Touch = 3
2119
}
2220

2321
public static class RemoteInput
2422
{
25-
static Keyboard keyboard;
26-
static Mouse mouse;
27-
static Touchscreen touch;
23+
public static Keyboard Keyboard { get; private set; }
24+
public static Mouse Mouse { get; private set; }
25+
public static Touchscreen Touch { get; private set; }
2826

2927
static TDevice GetOrAddDevice<TDevice>() where TDevice : InputDevice
3028
{
@@ -36,59 +34,98 @@ static TDevice GetOrAddDevice<TDevice>() where TDevice : InputDevice
3634
return InputSystem.AddDevice<TDevice>();
3735
}
3836

39-
static RemoteInput()
37+
public static void Initialize()
4038
{
41-
keyboard = GetOrAddDevice<Keyboard>();
42-
mouse = GetOrAddDevice<Mouse>();
43-
touch = GetOrAddDevice<Touchscreen>();
39+
Keyboard = GetOrAddDevice<Keyboard>();
40+
Mouse = GetOrAddDevice<Mouse>();
41+
Touch = GetOrAddDevice<Touchscreen>();
4442
}
4543

4644
public static void ProcessInput(byte[] bytes)
4745
{
4846
switch ((EventType)bytes[0])
4947
{
5048
case EventType.Keyboard:
51-
ProcessKeyEvent((char)bytes[1]);
49+
var type = (KeyboardEventType)bytes[1];
50+
var repeat = bytes[2] == 1;
51+
var key = (char)bytes[3];
52+
ProcessKeyEvent(type, repeat, key);
5253
break;
53-
case EventType.MouseDown:
54-
ProcessMouseDownEvent(bytes[1]);
55-
break;
56-
case EventType.MouseMove:
54+
case EventType.Mouse:
5755
var deltaX = BitConverter.ToInt16(bytes, 1);
5856
var deltaY = BitConverter.ToInt16(bytes, 3);
59-
ProcessMouseMoveEvent(deltaX, deltaY, bytes[5]);
57+
var button = bytes[5];
58+
ProcessMouseMoveEvent(deltaX, deltaY, button);
6059
break;
61-
case EventType.TouchMove:
62-
var pageX = BitConverter.ToInt16(bytes, 1);
63-
var pageY = BitConverter.ToInt16(bytes, 3);
64-
ProcessTouchMoveEvent(pageX, pageY);
60+
case EventType.MouseWheel:
61+
var scrollX = BitConverter.ToSingle(bytes, 1);
62+
var scrollY = BitConverter.ToSingle(bytes, 5);
63+
ProcessMouseWheelEvent(scrollX, scrollY);
64+
break;
65+
case EventType.Touch:
66+
var phase = (PointerPhase)bytes[1];
67+
var length = bytes[2];
68+
var index = 3;
69+
for (int i = 0; i < length; i++)
70+
{
71+
var pageX = BitConverter.ToInt16(bytes, index);
72+
var pageY = BitConverter.ToInt16(bytes, index+2);
73+
var force = BitConverter.ToSingle(bytes, index+4);
74+
ProcessTouchMoveEvent(i, phase, pageX, pageY, force);
75+
index += 8;
76+
}
6577
break;
66-
6778
}
6879
}
6980

70-
static void ProcessKeyEvent(char keyCode)
81+
public static void Reset()
7182
{
72-
InputSystem.QueueStateEvent(keyboard, new KeyboardState((Key)keyCode));
73-
InputSystem.QueueTextEvent(keyboard, keyCode);
83+
InputSystem.QueueStateEvent(Mouse, new MouseState());
84+
InputSystem.QueueStateEvent(Keyboard, new KeyboardState());
85+
InputSystem.QueueStateEvent(Touch, new TouchState());
86+
InputSystem.Update();
87+
}
88+
89+
static void ProcessKeyEvent(KeyboardEventType state, bool repeat, char keyCode)
90+
{
91+
switch(state)
92+
{
93+
case KeyboardEventType.KeyDown:
94+
if (!repeat)
95+
{
96+
InputSystem.QueueStateEvent(Keyboard, new KeyboardState((Key)keyCode));
97+
}
98+
InputSystem.QueueTextEvent(Keyboard, keyCode);
99+
break;
100+
case KeyboardEventType.KeyUp:
101+
InputSystem.QueueStateEvent(Keyboard, new KeyboardState());
102+
break;
103+
}
74104
InputSystem.Update();
75105
}
76106

77107
static void ProcessMouseMoveEvent(short deltaX, short deltaY, byte button)
78108
{
79-
InputSystem.QueueStateEvent(mouse, new MouseState { delta = new Vector2Int(deltaX, deltaY), buttons = button });
109+
InputSystem.QueueStateEvent(Mouse, new MouseState { delta = new Vector2Int(deltaX, deltaY), buttons = button });
80110
InputSystem.Update();
81111
}
82112

83-
static void ProcessMouseDownEvent(byte button)
113+
static void ProcessMouseWheelEvent(float scrollX, float scrollY)
84114
{
85-
InputSystem.QueueStateEvent(mouse, new MouseState { buttons = button });
115+
InputSystem.QueueStateEvent(Mouse, new MouseState { scroll = new Vector2(scrollX, scrollY) });
86116
InputSystem.Update();
87117
}
88118

89-
static void ProcessTouchMoveEvent(short pageX, short pageY)
119+
static void ProcessTouchMoveEvent(int index, PointerPhase phase, short pageX, short pageY, float force)
90120
{
91-
InputSystem.QueueStateEvent(touch, new TouchState { position = new Vector2Int(pageX, pageY) });
121+
InputSystem.QueueDeltaStateEvent(Touch.allTouchControls[index],
122+
new TouchState
123+
{
124+
touchId = index,
125+
phase = phase,
126+
position = new Vector2Int(pageX, pageY),
127+
pressure = force
128+
});
92129
InputSystem.Update();
93130
}
94131
}

Assets/Scripts/RenderStreaming.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,11 @@ void OnDataChannel(RTCPeerConnection pc, RTCDataChannel channel)
174174
}
175175
channels.Add(channel.Id, channel);
176176

177-
channel.OnMessage = new DelegateOnMessage(bytes => { RemoteInput.ProcessInput(bytes); });
177+
if(channel.Label == "data")
178+
{
179+
channel.OnMessage = new DelegateOnMessage(bytes => { RemoteInput.ProcessInput(bytes); });
180+
channel.OnClose = new DelegateOnClose(() => { RemoteInput.Reset(); });
181+
}
178182
}
179183
}
180184
}

Assets/Scripts/UIController.cs

+58-20
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,73 @@
55
using UnityEngine.InputSystem;
66
using UnityEngine.EventSystems;
77

8-
public class UIController : MonoBehaviour
8+
namespace Unity.RenderStreaming
99
{
10-
[SerializeField] RectTransform cursor;
11-
Image image;
12-
void Start()
10+
public class UIController : MonoBehaviour
1311
{
14-
image = cursor.GetComponent<Image>();
15-
}
12+
#pragma warning disable 0649
13+
[SerializeField] RectTransform cursor;
14+
[SerializeField] Text text;
1615

17-
void FixedUpdate()
18-
{
19-
var delta = Mouse.current.delta.ReadValue();
20-
cursor.Translate(delta.x, -delta.y, 0);
16+
#pragma warning restore 0649
2117

22-
if (Mouse.current.leftButton.ReadValue() > 0)
23-
{
24-
image.color = Color.red;
25-
}
26-
else if (Mouse.current.middleButton.ReadValue() > 0)
18+
Image image;
19+
Vector2 baseSize;
20+
float scroll = 1f;
21+
float multiplier = 0.01f;
22+
23+
void Start()
2724
{
28-
image.color = Color.blue;
25+
image = cursor.GetComponent<Image>();
26+
baseSize = cursor.sizeDelta;
27+
28+
RemoteInput.Initialize();
29+
Keyboard.current.onTextInput += OnTextInput;
2930
}
30-
else if (Mouse.current.rightButton.ReadValue() > 0)
31+
32+
void OnTextInput(char c)
3133
{
32-
image.color = Color.green;
34+
text.text += c;
3335
}
34-
else
36+
37+
void FixedUpdate()
3538
{
36-
image.color = Color.white;
39+
var delta = Mouse.current.delta.ReadValue();
40+
cursor.Translate(delta.x, -delta.y, 0);
41+
42+
if (Touchscreen.current.activeTouches.Count > 0)
43+
{
44+
cursor.position = Touchscreen.current.activeTouches[0].position.ReadValue();
45+
}
46+
47+
if (!Keyboard.current.anyKey.isPressed)
48+
{
49+
text.text = string.Empty;
50+
}
51+
52+
53+
if (Mouse.current.leftButton.ReadValue() > 0)
54+
{
55+
image.color = Color.red;
56+
}
57+
else if (Mouse.current.middleButton.ReadValue() > 0)
58+
{
59+
image.color = Color.blue;
60+
}
61+
else if (Mouse.current.rightButton.ReadValue() > 0)
62+
{
63+
image.color = Color.green;
64+
}
65+
else
66+
{
67+
image.color = Color.white;
68+
}
69+
if(!Mathf.Approximately(Mouse.current.scroll.ReadValue().y, 0f))
70+
{
71+
scroll += Mouse.current.scroll.ReadValue().y * multiplier;
72+
cursor.sizeDelta = baseSize * scroll;
73+
}
3774
}
3875
}
76+
3977
}

WebApp/public/scripts/app.js

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ function showPlayButton() {
2727
function onClickPlayButton() {
2828
const playerDiv = document.getElementById('player');
2929
const element = document.createElement('video');
30+
element.style.touchAction = 'none';
3031
playerDiv.appendChild(element);
3132
const videoPlayer = setupVideoPlayer(element);
3233
registerKeyboardEvents(videoPlayer);

0 commit comments

Comments
 (0)