Josh
2 years ago
6 changed files with 306 additions and 24 deletions
@ -0,0 +1,166 @@ |
|||||
|
using UnityEngine; |
||||
|
using System.Collections; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using UnityEngine.UI; |
||||
|
|
||||
|
|
||||
|
public class TrackballInputManager : MonoBehaviour |
||||
|
{ |
||||
|
const float defaultMiceSensitivity = 1f; |
||||
|
const float upMultiplier = .5f; |
||||
|
const float accelerationThreshold = 40; |
||||
|
const float accelerationMultiplier = 2; |
||||
|
|
||||
|
[DllImport("LibRawInput")] |
||||
|
private static extern bool init(); |
||||
|
|
||||
|
[DllImport("LibRawInput")] |
||||
|
private static extern bool kill(); |
||||
|
|
||||
|
[DllImport("LibRawInput")] |
||||
|
private static extern IntPtr poll(); |
||||
|
|
||||
|
public const byte RE_DEVICE_CONNECT = 0; |
||||
|
public const byte RE_MOUSE = 2; |
||||
|
public const byte RE_DEVICE_DISCONNECT = 1; |
||||
|
|
||||
|
[StructLayout(LayoutKind.Sequential)] |
||||
|
public struct RawInputEvent |
||||
|
{ |
||||
|
public int devHandle; |
||||
|
public int x, y, wheel; |
||||
|
public byte press; |
||||
|
public byte release; |
||||
|
public byte type; |
||||
|
} |
||||
|
|
||||
|
public class MousePointer |
||||
|
{ |
||||
|
public GameObject obj; |
||||
|
public Vector2 position; |
||||
|
public int deviceID; |
||||
|
public int playerID; |
||||
|
public float sensitivity; |
||||
|
} |
||||
|
public static TrackballInputManager instance; |
||||
|
|
||||
|
[SerializeField] List<Player> _players; |
||||
|
// Start is called before the first frame update
|
||||
|
void Start() |
||||
|
{ |
||||
|
instance = this; |
||||
|
bool res = init(); |
||||
|
Debug.Log("Init() ==> " + res); |
||||
|
//Debug.Log(Marshal.SizeOf(typeof(RawInputEvent)));
|
||||
|
//canvas = GetComponent<Canvas>();
|
||||
|
//canvasRect = GetComponent<RectTransform>();
|
||||
|
Cursor.lockState = CursorLockMode.Locked; |
||||
|
Cursor.visible = false; |
||||
|
} |
||||
|
|
||||
|
public void OnDestroy() |
||||
|
{ |
||||
|
instance = null; |
||||
|
} |
||||
|
|
||||
|
int lastEvents = 0; |
||||
|
bool isInit = true; |
||||
|
|
||||
|
void Update() |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
// Poll the events and properly update whatever we need
|
||||
|
IntPtr data = poll(); |
||||
|
int numEvents = Marshal.ReadInt32(data); |
||||
|
if (numEvents > 0) lastEvents = numEvents; |
||||
|
for (int i = 0; i < numEvents; ++i) |
||||
|
{ |
||||
|
var ev = new RawInputEvent(); |
||||
|
long offset = data.ToInt64() + sizeof(int) + i * Marshal.SizeOf(ev); |
||||
|
ev.devHandle = Marshal.ReadInt32(new IntPtr(offset + 0)); |
||||
|
ev.x = Marshal.ReadInt32(new IntPtr(offset + 4)); |
||||
|
ev.y = Marshal.ReadInt32(new IntPtr(offset + 8)); |
||||
|
ev.wheel = Marshal.ReadInt32(new IntPtr(offset + 12)); |
||||
|
ev.press = Marshal.ReadByte(new IntPtr(offset + 16)); |
||||
|
ev.release = Marshal.ReadByte(new IntPtr(offset + 17)); |
||||
|
ev.type = Marshal.ReadByte(new IntPtr(offset + 18)); |
||||
|
//Debug.Log(getEventName(ev.type) + ": H=" + ev.devHandle + "; (" + ev.x + ";" + ev.y + ") Down=" + ev.press + " Up=" + ev.release);
|
||||
|
|
||||
|
if (ev.type == RE_DEVICE_CONNECT) AddPlayer(ev.devHandle); |
||||
|
else if (ev.type == RE_DEVICE_DISCONNECT) RemovePlayer(ev.devHandle); |
||||
|
else if (ev.type == RE_MOUSE) |
||||
|
{ |
||||
|
|
||||
|
Player player = null; |
||||
|
if (_playersByDeviceId.TryGetValue(ev.devHandle, out player)) |
||||
|
{ |
||||
|
float dx = ev.x * defaultMiceSensitivity; |
||||
|
float dy = ev.y * defaultMiceSensitivity; |
||||
|
if (Mathf.Abs(dx) > accelerationThreshold) dx *= accelerationMultiplier; |
||||
|
if (Mathf.Abs(dy) > accelerationThreshold) dy *= accelerationMultiplier; |
||||
|
|
||||
|
if (dy < 0) |
||||
|
dy *= upMultiplier; |
||||
|
|
||||
|
//use this method to move using position
|
||||
|
//player.transform.position = new Vector2(player.transform.position.x + dx, player.transform.position.y - dy);
|
||||
|
//use this method to move using velocity
|
||||
|
player._rigidbody.velocity += new Vector2(dx, -dy); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
Debug.Log("Unknown device found"); |
||||
|
AddPlayer(ev.devHandle); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
Marshal.FreeCoTaskMem(data); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
void RemovePlayer(int deviceId) |
||||
|
{ |
||||
|
|
||||
|
Debug.Log("Removing DeviceID " + deviceId); |
||||
|
_playersByDeviceId[deviceId].DeviceId = null; |
||||
|
_playersByDeviceId.Remove(deviceId); |
||||
|
|
||||
|
} |
||||
|
Dictionary<int, Player> _playersByDeviceId = new Dictionary<int, Player>(); |
||||
|
int AddPlayer(int deviceId) |
||||
|
{ |
||||
|
|
||||
|
if (!isInit) |
||||
|
{ |
||||
|
Debug.LogError("Not initialized"); |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
Player player = null; |
||||
|
_playersByDeviceId.TryGetValue(deviceId, out player); |
||||
|
if (player != null) |
||||
|
{ |
||||
|
Debug.LogError("This device already has a player"); |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
Debug.Log("Adding DeviceID " + deviceId); |
||||
|
|
||||
|
foreach (Player p in _players) |
||||
|
{ |
||||
|
if (p.DeviceId == null) |
||||
|
{ |
||||
|
p.DeviceId = deviceId; |
||||
|
_playersByDeviceId.Add(deviceId, p); |
||||
|
return deviceId; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Debug.Log("no players left to add"); |
||||
|
return -1; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
fileFormatVersion: 2 |
||||
|
guid: 70de4eb8e48bea54b864b5d20448ee50 |
||||
|
MonoImporter: |
||||
|
externalObjects: {} |
||||
|
serializedVersion: 2 |
||||
|
defaultReferences: [] |
||||
|
executionOrder: 0 |
||||
|
icon: {instanceID: 0} |
||||
|
userData: |
||||
|
assetBundleName: |
||||
|
assetBundleVariant: |
Loading…
Reference in new issue