Files

450 lines
13 KiB
C#
Raw Permalink Normal View History

using UnityEngine;
using System.Reflection;
using UnityEngine.UI;
public class touchJoystick : MonoBehaviour
{
[Header ("Main Settings")]
[Space]
public int fingerId = 666;
public float dragDistance = 1;
public bool snapsToFinger = true;
public bool hideOnRelease = false;
public bool touchPad;
public float touchPadHorizontalExtraValue = 1;
public float touchPadVerticalExtraValue = 1;
public bool showJoystick;
[Space]
[Header ("Other Settings")]
[Space]
public bool clampJoystickToScreenSide;
public bool joystickOnRightScreenSide;
[Space]
public bool checkIfPressInsideTouchZone;
public RectTransform touchZoneRectTransform;
[Space]
[Header ("Colors Settings")]
[Space]
public bool useChaneColor;
public float changeColorSpeed;
public Color regularBaseColor;
public Color regularStickColor;
public Color pressedBaseColor;
public Color pressedStickColor;
[Space]
[Header ("Debug")]
[Space]
public bool showDebugPrint;
public Vector2 currentAxisValue;
public Vector2 currentTouchPosition;
public bool touching;
public bool hoveringJoystick;
public bool touchingPreviously;
public bool adjustinColors;
public bool buttonColorVisible = true;
public bool joystickClampedToScreenSideActive;
[Space]
[Header ("Components")]
[Space]
public GameObject stickBase;
public GameObject stick;
public RectTransform baseRectTransform;
public RectTransform stickRectTransform;
public RawImage baseRenderer;
public RawImage stickRenderer;
bool touchPlatform;
Color currentBaseColor;
Color currentStickColor;
Vector3 previousPosition;
Vector2 originalStickPosition;
Vector2 originalBasePosition;
Vector3 globalTouchPosition;
Vector3 differenceVector;
Vector3 difference;
int touchCount;
Touch currentPressedTouch;
Touch currentTouch;
int currentFingerId;
int currentTouchIndex;
bool firstTouchActive;
float screenWidth;
void Start ()
{
touchPlatform = checkTouchPlatform ();
if (!showJoystick) {
setSticksState (false, false);
}
originalStickPosition = stickRectTransform.anchoredPosition;
originalBasePosition = baseRectTransform.anchoredPosition;
if (clampJoystickToScreenSide) {
screenWidth = GKC_Utils.getScreenResolution ().x / 2;
if (screenWidth <= 0) {
screenWidth = Screen.width / 2;
}
}
}
void Update ()
{
setJoystickColors ();
if (currentFingerId > -1) {
moveJoystick ();
}
}
public void setHoverState (bool state)
{
hoveringJoystick = state;
if (hoveringJoystick && !touching) {
touchCount = Input.touchCount;
if (!touchPlatform) {
touchCount++;
}
for (currentTouchIndex = 0; currentTouchIndex < touchCount; currentTouchIndex++) {
if (!touchPlatform) {
currentTouch = convertMouseIntoFinger ();
} else {
currentTouch = Input.GetTouch (currentTouchIndex);
}
//if the touch action has started, check if the finger is inside the touch zone rect, visible in the editor
if (currentTouch.phase == TouchPhase.Began) {
currentTouchPosition = currentTouch.position;
if (clampJoystickToScreenSide) {
joystickClampedToScreenSideActive = false;
bool isScreenRightSide = currentTouchPosition.x > screenWidth;
if (joystickOnRightScreenSide) {
if (!isScreenRightSide) {
joystickClampedToScreenSideActive = true;
}
} else {
if (isScreenRightSide) {
joystickClampedToScreenSideActive = true;
}
}
if (showDebugPrint) {
print ("joystick Clamped " + joystickClampedToScreenSideActive +
" isScreenRightSide " + isScreenRightSide + " " + currentTouchPosition.x +
" " + screenWidth);
}
if (joystickClampedToScreenSideActive) {
return;
}
}
if (checkIfPressInsideTouchZone) {
if (!RectTransformUtility.RectangleContainsScreenPoint (touchZoneRectTransform, currentTouchPosition)) {
if (showDebugPrint) {
print ("outside touch press " + fingerId);
}
return;
}
}
currentFingerId = currentTouch.fingerId;
fingerTouching (true);
if (snapsToFinger) {
stickRectTransform.position = currentTouchPosition;
baseRectTransform.position = stickRectTransform.position;
}
if (touchPad) {
previousPosition = currentTouchPosition;
}
}
}
}
}
// set the value of touching to activate of deactivate the icons of the joystick
void fingerTouching (bool state)
{
touching = state;
if (showJoystick) {
if (hideOnRelease) {
setSticksState (state, state);
} else if ((!stickBase.gameObject.activeSelf || !stick.gameObject.activeSelf)) {
setSticksState (true, true);
}
} else {
setSticksState (false, false);
}
}
void setSticksState (bool stickBaseState, bool stickState)
{
if (stickBase.activeSelf != stickBaseState) {
stickBase.SetActive (stickBaseState);
}
if (stick.activeSelf != stickState) {
stick.SetActive (stickState);
}
}
//if the joystick is released, the icons back to their default positions
void resetJoystickPosition ()
{
stickRectTransform.anchoredPosition = originalStickPosition;
baseRectTransform.anchoredPosition = originalBasePosition;
currentAxisValue = Vector2.zero;
fingerTouching (false);
}
//check if the joystick is being used and set the icons position according to the finger or mouse movement
void moveJoystick ()
{
if (touching) {
touchCount = Input.touchCount;
if (!touchPlatform) {
touchCount++;
}
currentPressedTouch.fingerId = fingerId;
for (currentTouchIndex = 0; currentTouchIndex < touchCount; currentTouchIndex++) {
if (!touchPlatform) {
currentTouch = convertMouseIntoFinger ();
} else {
currentTouch = Input.GetTouch (currentTouchIndex);
}
if (currentTouch.fingerId == currentFingerId) {
currentPressedTouch = currentTouch;
}
}
if (currentPressedTouch.fingerId == fingerId || currentPressedTouch.phase == TouchPhase.Ended) {
resetJoystickPosition ();
currentFingerId = -1;
return;
}
globalTouchPosition = currentPressedTouch.position;
differenceVector = globalTouchPosition - stickBase.transform.position;
if (differenceVector.sqrMagnitude > dragDistance * dragDistance) {
differenceVector.Normalize ();
differenceVector *= dragDistance;
stickRectTransform.position = baseRectTransform.position + differenceVector;
} else {
stickRectTransform.position = globalTouchPosition;
}
if (!touchPad) {
currentAxisValue = differenceVector / dragDistance;
} else {
difference = globalTouchPosition - previousPosition;
if (differenceVector.sqrMagnitude > dragDistance * dragDistance) {
difference.Normalize ();
}
currentAxisValue = (difference / dragDistance);
currentAxisValue.x *= touchPadHorizontalExtraValue;
currentAxisValue.y *= touchPadVerticalExtraValue;
previousPosition = globalTouchPosition;
}
}
}
//get the vertical and horizontal axis values
public Vector2 GetAxis ()
{
return currentAxisValue;
}
public Vector2 getRawAxis ()
{
Vector2 axisValues = Vector2.zero;
if (currentAxisValue.x > 0) {
axisValues.x = 1;
} else if (currentAxisValue.x < 0) {
axisValues.x = -1;
} else {
axisValues.x = 0;
}
if (currentAxisValue.y > 0) {
axisValues.y = 1;
} else if (currentAxisValue.y < 0) {
axisValues.y = -1;
} else {
axisValues.y = 0;
}
return axisValues;
}
void setJoystickColors ()
{
if (useChaneColor) {
if (buttonColorVisible) {
if (touching != touchingPreviously || !firstTouchActive) {
touchingPreviously = touching;
adjustinColors = true;
firstTouchActive = true;
}
if (adjustinColors) {
if (touching) {
currentBaseColor = pressedBaseColor;
currentStickColor = pressedStickColor;
} else {
currentBaseColor = regularBaseColor;
currentStickColor = regularStickColor;
}
baseRenderer.color = Color.Lerp (baseRenderer.color, currentBaseColor, Time.deltaTime * changeColorSpeed);
stickRenderer.color = Color.Lerp (stickRenderer.color, currentStickColor, Time.deltaTime * changeColorSpeed);
if (baseRenderer.color == currentBaseColor && stickRenderer.color == currentStickColor) {
adjustinColors = false;
}
}
}
}
}
//it simulates touch control in the game with the mouse position, using left button as tap finger with press, hold and release actions
public static Touch convertMouseIntoFinger ()
{
object mouseFinger = new Touch ();
FieldInfo phase = mouseFinger.GetType ().GetField ("m_Phase", BindingFlags.NonPublic | BindingFlags.Instance);
FieldInfo fingerId = mouseFinger.GetType ().GetField ("m_FingerId", BindingFlags.NonPublic | BindingFlags.Instance);
FieldInfo position = mouseFinger.GetType ().GetField ("m_Position", BindingFlags.NonPublic | BindingFlags.Instance);
if (Input.GetMouseButtonDown (0)) {
phase.SetValue (mouseFinger, TouchPhase.Began);
} else if (Input.GetMouseButtonUp (0)) {
phase.SetValue (mouseFinger, TouchPhase.Ended);
} else {
phase.SetValue (mouseFinger, TouchPhase.Moved);
}
fingerId.SetValue (mouseFinger, 11);
position.SetValue (mouseFinger, new Vector2 (Input.mousePosition.x, Input.mousePosition.y));
return (Touch)mouseFinger;
}
//check the if the current platform is a touch device
public static bool checkTouchPlatform ()
{
if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer) {
return true;
}
return false;
}
public void setTouchPadState (bool state)
{
touchPad = state;
}
public void setShowJoystickState (bool state)
{
showJoystick = state;
setSticksState (showJoystick, showJoystick);
}
public void setSnapsToFingerState (bool state)
{
snapsToFinger = state;
}
public void setHideOnReleaseState (bool state)
{
hideOnRelease = state;
}
public void setJoystickColorVisibleState (bool state)
{
buttonColorVisible = state;
Color targetColorBase = baseRenderer.color;
Color targetColorStick = stickRenderer.color;
if (buttonColorVisible) {
targetColorBase.a = regularBaseColor.a;
targetColorStick.a = regularStickColor.a;
} else {
targetColorBase.a = 0;
targetColorStick.a = 0;
}
baseRenderer.color = targetColorBase;
stickRenderer.color = targetColorStick;
}
public bool touchJoystickIsPressed ()
{
return touching;
}
}