Unity 5 - New Mobile Assets - Joystick problem

Hey, I was trying the new Mobile Assets now called “CrossPlatformInput” and I can’t get the joystick prefab (MobileSingleStickControl) to work properly.

The moment I touch the joystick, it moves to the lower left corner of the screen and I can only drag it up and right (these two directions work).

I also tried the MobileAircraftControls prefab and this one worked properly, so the problem might be with the single joystick prefab. Anyone else having the same situation?

2 Likes

I got the exact same problem here, didn´t find a solution yet.

Hey Guys, I spotted this

that seem to address the problem you describe. Hope it helps. I have the problem where I build to my tablet, everything looks fine but none of the movement controls function. Ver 4.6 still do but not Ver 5???

3 Likes

Oh thank god its not just me! I posted a question about it on the Unity Answers forum, but no one has come back with an answer yet.

For a few hours I thought I was going crazy, thinking it was something stupid I forgot to do.

Hope we get an answer soon as I can’t continue on with my game till a solution is found :frowning:

I found a solution, I think it´s a bug.

Here is what I did:

In the MobileJoyStick inside the MobileSingleStickControl, I change the pivot to “bottom, left” and in the
Joystick.cs I changed the line in OnEnable method

from:

m_StartPos = transform.position;

to:

m_StartPos = new Vector3 (transform.localPosition.x, transform.localPosition.y, transform.localPosition.z);

I also changed the x and y position of the MobileJoyStick to 150 to fit on the screen.

I hope it work for you, let me know.

2 Likes

Hey, I might have a sloppy fix for this.

I noticed that in OnPointerUp(), the transform.position of the actual joystick was changing to 0, 0, 0 every time thanks to m_startPos.

So a work around, which is still kinda sloppy but here it goes…

First, take a look at the image below…

While in Play mode, hover your mouse cursor over the button. The red circle and underline shows that the position value will change when you’re hovering over the button. Take a note of the values.

Next, go back to OnPointerUp()

and do something like this…

        public void OnPointerUp(PointerEventData data)
        {

            transform.position = new Vector3(190, 130, 0);

            UpdateVirtualAxes(m_StartPos);


        }

The values 190, 130, 0 were my own values that I got from that window while in play mode. Using this, it goes back to its start point and NOT the bottom left corner.

Hope this helps :slight_smile:

UPDATE: You know, I suspect it has something to do with the Movement Range variable…because has anyone else noticed that when you drag it to the left, it goes way too far off screen? but when you drag it to the right, it barely moves at all? Hmmm

Yes it´s basicly the same thing I did,
but I stored the initial position as a new Vector3,

One thing that I noticed when I comented every piece of code and left only this:

void OnEnable()
{
         m_StartPos = transform.position;           
}

public void OnPointerUp(PointerEventData data)
{
            transform.position = m_StartPos;
       
}

it move to the bottom left after I release the mouse button.

but when I change the code to store the transform.position and transform.localPosition, and use this values later on OnPointerUp the location was correct.
Something is changing the localPosition.
So when you create a new Vector3 with the position that you wanted you are discarding the localPosition that was afecting the position.

But I had to fix the pivot of the joystick to put it to work on the right place on the screen.

1 Like

Hi All,
I found that this should be some changes made on the OnDrag pointerEventData. In order to fix this I have changed the way to move the joystick by changing all transform.position >>> this.getComponent().anchordedPosition. The idea is to move the joystick in the canvas directly.

1 Like

Hey my friends,

Good news! Someone found a simple solution to the problem via my question about it in the Unity Answer Forums.

User Wizza said:

Fixed it like a charm for me :slight_smile:

If you want to give him credit, this is the original post: Unity5 Joystick Prefab Snapping to Bottom Left Corner - Questions & Answers - Unity Discussions

4 Likes

Hey, I know I’m only new here but in my last post I added a You Tube clip that addressed exactly that problem and gave exactly that answer. Just sayin’!

Yes the video addressed the same problem and how to solve it, also tweak it a bit. I didn´t see that part that day.
Sorry and thanks.

1 Like

Hi, i had the same problem
This code runs for me

using System;
using UnityEngine;
using UnityEngine.EventSystems;

namespace UnityStandardAssets.CrossPlatformInput
{
    public class Joystick : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
    {
        public enum AxisOption
        {
            // Options for which axes to use
            Both, // Use both
            OnlyHorizontal, // Only horizontal
            OnlyVertical // Only vertical
        }

        public int MovementRange = 100;
        public AxisOption axesToUse = AxisOption.Both; // The options for the axes that the still will use
        public string horizontalAxisName = "Horizontal"; // The name given to the horizontal axis for the cross platform input
        public string verticalAxisName = "Vertical"; // The name given to the vertical axis for the cross platform input

        Vector3 m_StartPos;
        bool m_UseX; // Toggle for using the x axis
        bool m_UseY; // Toggle for using the Y axis
        CrossPlatformInputManager.VirtualAxis m_HorizontalVirtualAxis; // Reference to the joystick in the cross platform input
        CrossPlatformInputManager.VirtualAxis m_VerticalVirtualAxis; // Reference to the joystick in the cross platform input

        void Start() //OnEnable()
        {
            //m_StartPos = transform.position;
            m_StartPos = this.GetComponent<RectTransform>().anchoredPosition3D;
            CreateVirtualAxes();
        }

        void UpdateVirtualAxes(Vector3 value)
        {
            var delta = m_StartPos - value;
            delta.y = -delta.y;
            delta /= MovementRange;
            if (m_UseX)
            {
                m_HorizontalVirtualAxis.Update(-delta.x);
            }

            if (m_UseY)
            {
                m_VerticalVirtualAxis.Update(delta.y);
            }
        }

        void CreateVirtualAxes()
        {
            // set axes to use
            m_UseX = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyHorizontal);
            m_UseY = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyVertical);

            // create new axes based on axes to use
            if (m_UseX)
            {
                m_HorizontalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(horizontalAxisName);
                CrossPlatformInputManager.RegisterVirtualAxis(m_HorizontalVirtualAxis);
            }
            if (m_UseY)
            {
                m_VerticalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(verticalAxisName);
                CrossPlatformInputManager.RegisterVirtualAxis(m_VerticalVirtualAxis);
            }
        }


        public void OnDrag(PointerEventData data)
        {
         

            Vector3 newPos = Vector3.zero;

            if (m_UseX)
            {
                int delta = (int)(data.position.x - m_StartPos.x);
                delta = Mathf.Clamp(delta, -MovementRange, MovementRange);
                newPos.x = delta;
            }

            if (m_UseY)
            {
                int delta = (int)(data.position.y - m_StartPos.y);
                delta = Mathf.Clamp(delta, -MovementRange, MovementRange);
                newPos.y = delta;
            }
            this.GetComponent<RectTransform>().anchoredPosition3D = new Vector3(m_StartPos.x + newPos.x, m_StartPos.y + newPos.y, m_StartPos.z + newPos.z);
            UpdateVirtualAxes(this.GetComponent<RectTransform>().anchoredPosition3D);
        }


        public void OnPointerUp(PointerEventData data)
        {
            this.GetComponent<RectTransform>().anchoredPosition3D = m_StartPos;
            UpdateVirtualAxes(m_StartPos);
        }


        public void OnPointerDown(PointerEventData data) { }

        void OnDisable()
        {
            // remove the joysticks from the cross platform input
            if (m_UseX)
            {
                m_HorizontalVirtualAxis.Remove();
            }
            if (m_UseY)
            {
                m_VerticalVirtualAxis.Remove();
            }
        }
    }
}

So this still not officially fixed after Unity broke it, another annoying glitch, btw broke in Unity 4.6.3 also…UI team whatsup?

Hi, I hope this can help:

In the void start of the Joystick Script: add the vector 3 values to the m_StartPos(as you can see below). When you click or touch the button in the game the axis will change to the vector3 of 150,150,0.

You can see what the m_StartPos is below.

void Start()
{
m_StartPos = new Vector3 (150, 150, 0);//transform.position;
CreateVirtualAxes();
}

I have a different issue I think. It’ not an issue with the joystick position. That seems to be ok but I can’t move the joystick on built version of the game (Android/Nexus7)

I tried all your suggestions but nothing works in my case.

In Unity5 I can move the joystick in the game window with the mouse and it also works with Unity remote on my nexus 7.

When building the game the joystick reacts very badly. It moves but I can’t drag it anywhere, it always comes back to its original position immediately after touching it and trying to move it. I use the modified version of joystick.cs as shown in Devis tutorial.

This is driving me mad, can not get any joystick controls working on android same as the post above. could it be to do with my player settings? cos it works with unity remote. is it a bug or am i just doing something really stupid?

Any fix for this yet - is issue still present on latest builds?

Thank you worked!

This is a huge pain in the ass. Doesn’t work.

That was what I was looking for example the Survival Shooter Joystick script has :

    void OnEnable() {

        startPos = transform.position;
        CreateVirtualAxes();
    }

and the standard assets has

        void OnEnable()
        {
            CreateVirtualAxes();
        }

        void Start()
        {
            m_StartPos = transform.position;
        }

So I used:

    void OnEnable() {
        CreateVirtualAxes();
    }

    void Start() {
        startPos = transform.position;
    }

Thanks for the help with using virtual joysticks for mobile input

2 Likes