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