You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
4.8 KiB
C#

using FairyGUI;
using UnityEngine;
public class JoystickModule : EventDispatcher
{
float _InitX;
float _InitY;
float _startStageX;
float _startStageY;
float _lastStageX;
float _lastStageY;
GButton _button;
GObject _touchArea;
GObject _thumb;
GObject _center;
int touchId;
GTweener _tweener;
public EventListener onMove { get; private set; }
public EventListener onEnd { get; private set; }
public int radius { get; set; }
public JoystickModule(GComponent mainView)
{
onMove = new EventListener(this, "onMove");
onEnd = new EventListener(this, "onEnd");
_button = mainView.GetChild("joystick").asButton;
_button.changeStateOnClick = false;
_thumb = _button.GetChild("thumb");
_touchArea = mainView.GetChild("joystick_touch");
_center = mainView.GetChild("joystick_center");
_InitX = _center.x + _center.width / 2;
_InitY = _center.y + _center.height / 2;
touchId = -1;
radius = 150;
_touchArea.onTouchBegin.Add(this.OnTouchBegin);
_touchArea.onTouchMove.Add(this.OnTouchMove);
_touchArea.onTouchEnd.Add(this.OnTouchEnd);
}
public void Trigger(EventContext context)
{
OnTouchBegin(context);
}
private void OnTouchBegin(EventContext context)
{
if (touchId == -1)//First touch
{
InputEvent evt = (InputEvent)context.data;
touchId = evt.touchId;
if (_tweener != null)
{
_tweener.Kill();
_tweener = null;
}
Vector2 pt = GRoot.inst.GlobalToLocal(new Vector2(evt.x, evt.y));
float bx = pt.x;
float by = pt.y;
_button.selected = true;
if (bx < 0)
bx = 0;
else if (bx > _touchArea.width)
bx = _touchArea.width;
if (by > GRoot.inst.height)
by = GRoot.inst.height;
else if (by < _touchArea.y)
by = _touchArea.y;
_lastStageX = bx;
_lastStageY = by;
_startStageX = bx;
_startStageY = by;
_center.visible = true;
_center.SetXY(bx - _center.width / 2, by - _center.height / 2);
_button.SetXY(bx - _button.width / 2, by - _button.height / 2);
float deltaX = bx - _InitX;
float deltaY = by - _InitY;
float degrees = Mathf.Atan2(deltaY, deltaX) * 180 / Mathf.PI;
_thumb.rotation = degrees + 90;
context.CaptureTouch();
}
}
private void OnTouchEnd(EventContext context)
{
InputEvent inputEvt = (InputEvent)context.data;
if (touchId != -1 && inputEvt.touchId == touchId)
{
touchId = -1;
_thumb.rotation = _thumb.rotation + 180;
_center.visible = false;
_tweener = _button.TweenMove(new Vector2(_InitX - _button.width / 2, _InitY - _button.height / 2), 0.3f).OnComplete(() =>
{
_tweener = null;
_button.selected = false;
_thumb.rotation = 0;
_center.visible = true;
_center.SetXY(_InitX - _center.width / 2, _InitY - _center.height / 2);
}
);
this.onEnd.Call();
}
}
private void OnTouchMove(EventContext context)
{
InputEvent evt = (InputEvent)context.data;
if (touchId != -1 && evt.touchId == touchId)
{
Vector2 pt = GRoot.inst.GlobalToLocal(new Vector2(evt.x, evt.y));
float bx = pt.x;
float by = pt.y;
float moveX = bx - _lastStageX;
float moveY = by - _lastStageY;
_lastStageX = bx;
_lastStageY = by;
float buttonX = _button.x + moveX;
float buttonY = _button.y + moveY;
float offsetX = buttonX + _button.width / 2 - _startStageX;
float offsetY = buttonY + _button.height / 2 - _startStageY;
float rad = Mathf.Atan2(offsetY, offsetX);
float degree = rad * 180 / Mathf.PI;
_thumb.rotation = degree + 90;
float maxX = radius * Mathf.Cos(rad);
float maxY = radius * Mathf.Sin(rad);
if (Mathf.Abs(offsetX) > Mathf.Abs(maxX))
offsetX = maxX;
if (Mathf.Abs(offsetY) > Mathf.Abs(maxY))
offsetY = maxY;
buttonX = _startStageX + offsetX;
buttonY = _startStageY + offsetY;
if (buttonX < 0)
buttonX = 0;
if (buttonY > GRoot.inst.height)
buttonY = GRoot.inst.height;
_button.SetXY(buttonX - _button.width / 2, buttonY - _button.height / 2);
this.onMove.Call(degree);
}
}
}