93 lines
2.8 KiB
C#
93 lines
2.8 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace Cryville.Common.Unity.Input {
|
|
public class AndroidTouchHandler : InputHandler {
|
|
readonly AndroidTouchListener _listener;
|
|
readonly AndroidJavaClass _systemClock;
|
|
|
|
public AndroidTouchHandler() {
|
|
if (Environment.OSVersion.Platform != PlatformID.Unix)
|
|
throw new NotSupportedException("Android touch is not supported on this device");
|
|
_systemClock = new AndroidJavaClass("android.os.SystemClock");
|
|
new AndroidJavaClass("com.unity3d.player.UnityPlayer")
|
|
.GetStatic<AndroidJavaObject>("currentActivity")
|
|
.Get<AndroidJavaObject>("mUnityPlayer")
|
|
.Call("setOnTouchListener", _listener = new AndroidTouchListener(this));
|
|
}
|
|
|
|
protected override void Activate() {
|
|
_listener.Activated = true;
|
|
}
|
|
|
|
protected override void Deactivate() {
|
|
_listener.Activated = false;
|
|
}
|
|
|
|
public override void Dispose(bool disposing) {
|
|
if (disposing) {
|
|
Deactivate();
|
|
}
|
|
}
|
|
|
|
public override bool IsNullable(int type) {
|
|
if (type != 0) throw new ArgumentOutOfRangeException("type");
|
|
return true;
|
|
}
|
|
|
|
public override byte GetDimension(int type) {
|
|
if (type != 0) throw new ArgumentOutOfRangeException("type");
|
|
return 2;
|
|
}
|
|
|
|
public override string GetTypeName(int type) {
|
|
switch (type) {
|
|
case 0: return "Android Touch";
|
|
default: throw new ArgumentOutOfRangeException("type");
|
|
}
|
|
}
|
|
|
|
public override double GetCurrentTimestamp() {
|
|
return _systemClock.CallStatic<long>("uptimeMillis") / 1000.0;
|
|
}
|
|
|
|
class AndroidTouchListener : AndroidJavaProxy {
|
|
public bool Activated { get; set; }
|
|
|
|
readonly AndroidTouchHandler _handler;
|
|
|
|
public AndroidTouchListener(AndroidTouchHandler handler) : base("android.view.View$OnTouchListener") {
|
|
_handler = handler;
|
|
}
|
|
|
|
#pragma warning disable IDE1006
|
|
#pragma warning disable IDE0060
|
|
public bool onTouch(AndroidJavaObject v, AndroidJavaObject e) {
|
|
if (!Activated) return false;
|
|
try {
|
|
int pointerCount = e.Call<int>("getPointerCount");
|
|
for (int i = 0; i < pointerCount; i++) {
|
|
int id = e.Call<int>("getPointerId", i);
|
|
double time = e.Call<long>("getEventTime") / 1000.0;
|
|
int action = e.Call<int>("getActionMasked");
|
|
Vector2 pos = UnityCameraUtils.ScreenToWorldPoint(new Vector2(
|
|
e.Call<float>("getX", i),
|
|
e.Call<float>("getY", i)
|
|
));
|
|
_handler.Feed(0, id, new InputVector(time, pos));
|
|
if (action == 1 /*ACTION_UP*/ || action == 3 /*ACTION_CANCEL*/ || (action == 6 /*ACTION_POINTER_UP*/ && e.Call<int>("getActionIndex") == i)) {
|
|
_handler.Feed(0, id, new InputVector(time));
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex) {
|
|
Logger.Log("main", 4, "Input", "An error occured while handling an Android touch event: {0}", ex);
|
|
}
|
|
return false;
|
|
}
|
|
#pragma warning restore IDE0060
|
|
#pragma warning restore IDE1006
|
|
}
|
|
}
|
|
}
|