- Home /
How to make virtual joystick change position depending on touch position?
Hello, I have this code for virtual joystick, it works fine, but I want the player to press anywhere on the screen and joystick should appear in that position and work. The problem is, that currently OnDrag() does not get called after I change the position of the joystick (which is expected) . How to get around it?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class VirtualJoystick : MonoBehaviour, IDragHandler, IPointerDownHandler, IPointerUpHandler
{
private Image bgImg, joystickImg;
private Vector2 defaultPos;
private Vector3 InputDirection { get; set; }
// Start is called before the first frame update
void Start()
{
InputDirection = Vector3.zero;
bgImg = GetComponent<Image>();
joystickImg = transform.GetChild(0).GetComponent<Image>();
defaultPos = new Vector2(Screen.width / 2 - bgImg.rectTransform.sizeDelta.x / 2, Screen.height / 10);
transform.position = defaultPos;
}
// Update is called once per frame
void Update()
{
#if UNITY_EDITOR
if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject() && Time.timeScale != 0)
{
transform.position = Input.mousePosition - Vector3.right * bgImg.rectTransform.sizeDelta.x / 2 + Vector3.down * bgImg.rectTransform.sizeDelta.y / 2;
}
#endif
}
public virtual void OnDrag(PointerEventData ped)
{
Vector2 pos = Vector2.zero;
if(RectTransformUtility.ScreenPointToLocalPointInRectangle(bgImg.rectTransform, ped.position, ped.pressEventCamera, out pos))
{
pos.x = (pos.x / bgImg.rectTransform.sizeDelta.x);
pos.y = (pos.y / bgImg.rectTransform.sizeDelta.y);
float x = (bgImg.rectTransform.pivot.x == 1) ? pos.x * 2 + 1 : pos.x * 2 - 1;
float y = (bgImg.rectTransform.pivot.y == 1) ? pos.y * 2 + 1 : pos.y * 2 - 1;
InputDirection = new Vector3(x, 0, y);
InputDirection = (InputDirection.magnitude > 1) ? InputDirection.normalized : InputDirection;
joystickImg.rectTransform.anchoredPosition = new Vector3(InputDirection.x * (bgImg.rectTransform.sizeDelta.x / 3), InputDirection.z * (bgImg.rectTransform.sizeDelta.y / 3));
}
}
public virtual void OnPointerDown(PointerEventData ped)
{
OnDrag(ped);
}
public virtual void OnPointerUp(PointerEventData ped)
{
InputDirection = Vector3.zero;
joystickImg.rectTransform.anchoredPosition = Vector3.zero;
transform.position = defaultPos;
}
}
Comment
Best Answer
Answer by GiViZed · Sep 17, 2019 at 07:23 AM
Solved it myself, was tired yesterday, the problem is not hard at all.
if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject() && Time.timeScale != 0)
{
transform.position = Input.mousePosition - Vector3.right * bgImg.rectTransform.sizeDelta.x / 2 + Vector3.down * bgImg.rectTransform.sizeDelta.y / 2;
startTouch = Input.mousePosition;
}
else if(startTouch != Vector3.zero && Input.GetMouseButton(0))
{
Vector2 pos = Input.mousePosition - transform.position;
pos.x = (pos.x / bgImg.rectTransform.sizeDelta.x);
pos.y = (pos.y / bgImg.rectTransform.sizeDelta.y);
float x = (bgImg.rectTransform.pivot.x == 1) ? pos.x * 2 + 1 : pos.x * 2 - 1;
float y = (bgImg.rectTransform.pivot.y == 1) ? pos.y * 2 + 1 : pos.y * 2 - 1;
InputDirection = new Vector3(x, 0, y);
InputDirection = (InputDirection.magnitude > 1) ? InputDirection.normalized : InputDirection;
joystickImg.rectTransform.anchoredPosition = new Vector3(InputDirection.x * (bgImg.rectTransform.sizeDelta.x / 3), InputDirection.z * (bgImg.rectTransform.sizeDelta.y / 3));
}
else if(Input.GetMouseButtonUp(0))
{
startTouch = Vector3.zero;
joystickImg.rectTransform.anchoredPosition = Vector3.zero;
transform.position = defaultPos;
}
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
How do you get Virtual Joysticks to work? 1 Answer
Android C# JoyStick Movement 0 Answers