Unity 4.6 Mobile Joystick

I updated the Joystick script that uses Notification Center for use with the new GUI setup in 4.6 beta.

Set up switch out the old joystick scripts and add this one, you can leave the one attached to the player alone. As, this will still output the same for position. You will have to add a background button image which doubles as the size and hit zone for the touch pad option.

//////////////////////////////////////////////////////////////
// Joystick.js
// Penelope iPhone Tutorial
// Moded by Hillary J. Ford for use with the new GUI system
// in Unity 4.6
// Joystick creates a movable joystick (via RectTransform) that
// handles touch input, taps, and phases. Dead zones can control
// where the joystick input gets picked up and can be normalized.
//
// Optionally, you can enable the touchPad property from the editor
// to treat this Joystick as a TouchPad. A TouchPad allows the finger
// to touch down at any point and it tracks the movement relatively
// without moving the graphic
//////////////////////////////////////////////////////////////

#pragma strict

import UnityEngine.UI;

class Boundary
{
    var min : Vector2 = Vector2.zero;
    var max : Vector2 = Vector2.zero;
}
static private var joysticks : Joystick_mod[];                    // A static collection of all joysticks
static private var enumeratedJoysticks : boolean = false;
static private var tapTimeDelta : float = 0.3;                // Time allowed between taps

var touchPad : boolean;                                     // Is this a TouchPad?
var touchZone : Rect;
var position : Vector2;                                     // [-1, 1] in x,y
var tapCount : int;                                            // Current tap count

private var lastFingerId = -1;                                // Finger last used for this joystick
private var tapTimeWindow : float;                            // How much time there is left for a tap to occur
private var fingerDownPos : Vector2;
private var fingerDownTime : float;
private var firstDeltaTime : float = 0.5;

var button : RectTransform;
var ButtonBG_TouchPad  : RectTransform;                                    // Joystick graphic
private var defaultRect : Rect;                                // Default position / extents of the joystick graphic

var isPaused:boolean = false;

function Start()
{
    // Store the default rect , so we can snap back to it
    defaultRect.x = ButtonBG_TouchPad.rect.center.x+ButtonBG_TouchPad.position.x;
    defaultRect.y = ButtonBG_TouchPad.rect.center.y+ButtonBG_TouchPad.position.y;
    
    if ( touchPad )
    {
        // If a texture has been assigned, then use the rect from the gui as our touchZone
        if ( ButtonBG_TouchPad )
            //touchZone = ButtonBG_TouchPad.rect;
            touchZone.width = ButtonBG_TouchPad.rect.width;
            touchZone.height = ButtonBG_TouchPad.rect.height;
            touchZone.x = ButtonBG_TouchPad.position.x;
            touchZone.y = ButtonBG_TouchPad.position.y;
    }
  
    NotificationCenter.DefaultCenter().AddObserver(this, "Pause");
    NotificationCenter.DefaultCenter().AddObserver(this, "Unpause");
    NotificationCenter.DefaultCenter().AddObserver(this, "GameOver");
    NotificationCenter.DefaultCenter().AddObserver(this, "WonRound");
}
  
  
function Disable()
{
    gameObject.SetActive(false);
    enumeratedJoysticks = false;
}

function Pause()
{
    ResetJoystick();
    isPaused = true;
}

function Unpause()
{
    ResetJoystick();
    isPaused = false;
}

function GameOver() {
    Pause();
}

function WonRound() {
    Pause();
}


function ResetJoystick()
{
    // Release the finger control and set the joystick back to the default position
    button.position.x = ButtonBG_TouchPad.rect.center.x+ButtonBG_TouchPad.position.x;
    button.position.y = ButtonBG_TouchPad.rect.center.y+ButtonBG_TouchPad.position.y;
    lastFingerId = -1;
    position = Vector2.zero;
    fingerDownPos = Vector2.zero;
}

function IsFingerDown() : boolean
{
    return (lastFingerId != -1);
}
  
function LatchedFinger( fingerId : int )
{
    // If another joystick has latched this finger, then we must release it
    if ( lastFingerId == fingerId )
        ResetJoystick();
}

function Update()
{
    if (!isPaused)
    {  
        if ( !enumeratedJoysticks )
        {
            // Collect all joysticks in the game, so we can relay finger latching messages
            joysticks = FindObjectsOfType( Joystick_mod ) as Joystick_mod[];
            enumeratedJoysticks = true;
        }  
          
        var count = Input.touchCount;
      
        // Adjust the tap time window while it still available
        if ( tapTimeWindow > 0 )
            tapTimeWindow -= Time.deltaTime;
        else
            tapCount = 0;
      
        if ( count == 0 )
            ResetJoystick();
        else
        {
            for(var i = 0;i < count; i++)
            {
                var touch : Touch = Input.GetTouch(i);          
      
                var shouldLatchFinger = false;
                if ( touchPad )
                {              
                    if ( touchZone.Contains( touch.position ) )
                        shouldLatchFinger = true;
                }
                else if ( hitme( touch ) )
                {
                    shouldLatchFinger = true;
                }      
      
                // Latch the finger if this is a new touch
                if ( shouldLatchFinger && ( lastFingerId == -1 || lastFingerId != touch.fingerId ) )
                {
                  
                    if ( touchPad )
                    {                      
                        lastFingerId = touch.fingerId;
                        fingerDownPos = touch.position;
                        fingerDownTime = Time.time;
                    }
                  
                    lastFingerId = touch.fingerId;
                  
                    // Accumulate taps if it is within the time window
                    if ( tapTimeWindow > 0 )
                        tapCount++;
                    else
                    {
                        tapCount = 1;
                        tapTimeWindow = tapTimeDelta;
                    }
                                              
                    // Tell other joysticks we've latched this finger
                    for ( var j : Joystick_mod in joysticks )
                    {
                        if ( j != this )
                            j.LatchedFinger( touch.fingerId );
                    }                      
                }              
      
                if ( lastFingerId == touch.fingerId )
                {  
                    // Override the tap count with what the iPhone SDK reports if it is greater
                    // This is a workaround, since the iPhone SDK does not currently track taps
                    // for multiple touches
                    if ( touch.tapCount > tapCount )
                        tapCount = touch.tapCount;
                  
                    if ( touchPad )
                    {  
                        // For a touchpad, let's just set the position directly based on distance from initial touchdown
                        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
                    {                  
                        //Do something with the touches
                        button.position.x = Mathf.Clamp(touch.position.x, ButtonBG_TouchPad.position.x+(button.rect.width/2), ButtonBG_TouchPad.position.x+ButtonBG_TouchPad.rect.width-(button.rect.width/2));
                        button.position.y = Mathf.Clamp(touch.position.y, ButtonBG_TouchPad.position.y+(button.rect.height/2), ButtonBG_TouchPad.position.y+ButtonBG_TouchPad.rect.height-(button.rect.height/2));

                        // Get a value between -1 and 1 based on the joystick graphic location
                        if (button.position.x < defaultRect.x)
                                position.x = -1;
                        else
                        if(button.position.x > defaultRect.x)
                                position.x = 1;
                        else
                        if (button.position.x == defaultRect.x)
                                position.x = 0;
                              
                        if (button.position.y < defaultRect.y)
                                position.y = -1;
                        else
                        if(button.position.y > defaultRect.y)
                                position.y = 1;
                        else
                        if (button.position.y == defaultRect.y)
                                position.y = 0;                      
                          
                    }
                  
                    if ( touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled ) {
                        ResetJoystick();
                    }
                }          
            }
        }
    }
}


function hitme(hit:Touch) : boolean
{
    if( hit.position.x>=ButtonBG_TouchPad.position.x && hit.position.x <= ButtonBG_TouchPad.position.x+ButtonBG_TouchPad.rect.width)
    {
        if(hit.position.y>=ButtonBG_TouchPad.position.y && hit.position.y <= ButtonBG_TouchPad.position.y+ButtonBG_TouchPad.rect.height)
        {
            return true;
        }else{ return false;}
    }else{ return false;}
}

1830593–117347–Joystick_mod.js (7.09 KB)

Why not C# If its for mobile?

I am not that good programming in c# also the script was already in JS which is why I used it.

Is there a difference between C# and JS when it comes to mobile?

Hello MR_Ford,

thank you very much for this script conversion.
The touch_pad work well but I’ve a problem with the normal joystick mode.
When I touch the screen the joystick button flies away out of the screen on my ipad.

  • I’ve replaced the old script Joystick by yours
  • created a panel for the image background
  • assign this panel in the joystick script slot.
  • launch the scene on ipad
  • when I touch the joystick, it moves away from screen.

I don’t know how to fix this.

Can you help me please ?