mirror of
https://github.com/ApfelTeeSaft/Slender.git
synced 2026-08-27 03:43:28 +00:00
276 lines
6.9 KiB
C#
276 lines
6.9 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
[Serializable]
|
|
public class Joystick : MonoBehaviour
|
|
{
|
|
[NonSerialized]
|
|
private static Joystick[] joysticks;
|
|
|
|
[NonSerialized]
|
|
private static bool enumeratedJoysticks;
|
|
|
|
[NonSerialized]
|
|
private static float tapTimeDelta = 0.3f;
|
|
|
|
public bool touchPad;
|
|
|
|
public Rect touchZone;
|
|
|
|
public Vector2 deadZone = Vector2.zero;
|
|
|
|
public bool normalize;
|
|
|
|
public Vector2 position;
|
|
|
|
public int tapCount;
|
|
|
|
private int lastFingerId = -1;
|
|
|
|
private float tapTimeWindow;
|
|
|
|
private Vector2 fingerDownPos;
|
|
|
|
private float fingerDownTime;
|
|
|
|
private float firstDeltaTime = 0.5f;
|
|
|
|
private Rect defaultRect;
|
|
|
|
private Boundary guiBoundary = new Boundary();
|
|
|
|
private Vector2 guiTouchOffset;
|
|
|
|
private Vector2 guiCenter;
|
|
|
|
void Start()
|
|
{
|
|
defaultRect = new Rect(
|
|
Screen.width * 0.1f,
|
|
Screen.height * 0.1f,
|
|
128,
|
|
128
|
|
);
|
|
|
|
if (touchPad)
|
|
{
|
|
touchZone = defaultRect;
|
|
return;
|
|
}
|
|
|
|
guiTouchOffset.x = defaultRect.width * 0.5f;
|
|
guiTouchOffset.y = defaultRect.height * 0.5f;
|
|
|
|
guiCenter.x = defaultRect.x + guiTouchOffset.x;
|
|
guiCenter.y = defaultRect.y + guiTouchOffset.y;
|
|
|
|
guiBoundary.min.x = defaultRect.x - guiTouchOffset.x;
|
|
guiBoundary.max.x = defaultRect.x + guiTouchOffset.x;
|
|
|
|
guiBoundary.min.y = defaultRect.y - guiTouchOffset.y;
|
|
guiBoundary.max.y = defaultRect.y + guiTouchOffset.y;
|
|
}
|
|
|
|
public void Disable()
|
|
{
|
|
gameObject.SetActive(false);
|
|
enumeratedJoysticks = false;
|
|
}
|
|
|
|
public void ResetJoystick()
|
|
{
|
|
lastFingerId = -1;
|
|
position = Vector2.zero;
|
|
|
|
defaultRect.x = guiCenter.x - guiTouchOffset.x;
|
|
defaultRect.y = guiCenter.y - guiTouchOffset.y;
|
|
}
|
|
|
|
public bool IsFingerDown()
|
|
{
|
|
return lastFingerId != -1;
|
|
}
|
|
|
|
public void LatchedFinger(int fingerId)
|
|
{
|
|
if (lastFingerId == fingerId)
|
|
{
|
|
ResetJoystick();
|
|
}
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (!enumeratedJoysticks)
|
|
{
|
|
joysticks = FindObjectsOfType<Joystick>();
|
|
enumeratedJoysticks = true;
|
|
}
|
|
|
|
int count = Input.touchCount;
|
|
|
|
if (tapTimeWindow > 0)
|
|
{
|
|
tapTimeWindow -= Time.deltaTime;
|
|
}
|
|
else
|
|
{
|
|
tapCount = 0;
|
|
}
|
|
|
|
if (count == 0)
|
|
{
|
|
ResetJoystick();
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
Touch touch = Input.GetTouch(i);
|
|
|
|
Vector2 guiTouchPos = touch.position - guiTouchOffset;
|
|
|
|
bool shouldLatchFinger = false;
|
|
|
|
if (touchPad)
|
|
{
|
|
if (touchZone.Contains(touch.position))
|
|
{
|
|
shouldLatchFinger = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Rect touchRect = new Rect(
|
|
guiCenter.x - guiTouchOffset.x,
|
|
guiCenter.y - guiTouchOffset.y,
|
|
guiTouchOffset.x * 2,
|
|
guiTouchOffset.y * 2
|
|
);
|
|
|
|
if (touchRect.Contains(touch.position))
|
|
{
|
|
shouldLatchFinger = true;
|
|
}
|
|
}
|
|
|
|
if (
|
|
shouldLatchFinger &&
|
|
(lastFingerId == -1 || lastFingerId != touch.fingerId)
|
|
)
|
|
{
|
|
if (touchPad)
|
|
{
|
|
fingerDownPos = touch.position;
|
|
fingerDownTime = Time.time;
|
|
}
|
|
|
|
lastFingerId = touch.fingerId;
|
|
|
|
if (tapTimeWindow > 0)
|
|
{
|
|
tapCount++;
|
|
}
|
|
else
|
|
{
|
|
tapCount = 1;
|
|
tapTimeWindow = tapTimeDelta;
|
|
}
|
|
|
|
foreach (Joystick j in joysticks)
|
|
{
|
|
if (j != this)
|
|
{
|
|
j.LatchedFinger(touch.fingerId);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (lastFingerId == touch.fingerId)
|
|
{
|
|
if (touch.tapCount > tapCount)
|
|
{
|
|
tapCount = touch.tapCount;
|
|
}
|
|
|
|
if (touchPad)
|
|
{
|
|
position.x = Mathf.Clamp(
|
|
(touch.position.x - fingerDownPos.x) /
|
|
(touchZone.width / 2),
|
|
-1,
|
|
1
|
|
);
|
|
|
|
position.y = Mathf.Clamp(
|
|
(touch.position.y - fingerDownPos.y) /
|
|
(touchZone.height / 2),
|
|
-1,
|
|
1
|
|
);
|
|
}
|
|
else
|
|
{
|
|
defaultRect.x = Mathf.Clamp(
|
|
guiTouchPos.x,
|
|
guiBoundary.min.x,
|
|
guiBoundary.max.x
|
|
);
|
|
|
|
defaultRect.y = Mathf.Clamp(
|
|
guiTouchPos.y,
|
|
guiBoundary.min.y,
|
|
guiBoundary.max.y
|
|
);
|
|
}
|
|
|
|
if (
|
|
touch.phase == TouchPhase.Ended ||
|
|
touch.phase == TouchPhase.Canceled
|
|
)
|
|
{
|
|
ResetJoystick();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!touchPad)
|
|
{
|
|
position.x =
|
|
(defaultRect.x + guiTouchOffset.x - guiCenter.x) /
|
|
guiTouchOffset.x;
|
|
|
|
position.y =
|
|
(defaultRect.y + guiTouchOffset.y - guiCenter.y) /
|
|
guiTouchOffset.y;
|
|
}
|
|
|
|
float absoluteX = Mathf.Abs(position.x);
|
|
float absoluteY = Mathf.Abs(position.y);
|
|
|
|
if (absoluteX < deadZone.x)
|
|
{
|
|
position.x = 0;
|
|
}
|
|
else if (normalize)
|
|
{
|
|
position.x =
|
|
Mathf.Sign(position.x) *
|
|
(absoluteX - deadZone.x) /
|
|
(1 - deadZone.x);
|
|
}
|
|
|
|
if (absoluteY < deadZone.y)
|
|
{
|
|
position.y = 0;
|
|
}
|
|
else if (normalize)
|
|
{
|
|
position.y =
|
|
Mathf.Sign(position.y) *
|
|
(absoluteY - deadZone.y) /
|
|
(1 - deadZone.y);
|
|
}
|
|
}
|
|
} |