x


Joystick / Button

Hi,

Im using the Joystick.js script from the penelope iPhone Tutorial. I have a script called TwinStick.js that Im using to access the Joystick script to make my player move and shoot.

I would like to create another button and use this 3rd button to simply print a message when clicked and this is where Im kind of lost. I don't want this 3rd button to move like a Joystick so I enabled TouchPad in the inspector. But how would I print a message by clicking this 3rd button (var spellButton : Joystick) it seems that the Joystick script is registering all inputs and touches So I figured I might as well use it but I dont know how to ask for the hitTest.

Can someone give me a code hint to get the 3rd button to print("3rd button clicked, spell"); from the variable spellButton.

Here is the TwinStick Script which moves my player using the 2 joysticks (one for movement the other for firing) along with a bunch of commented out stuff that I couldn't get to work trying to get a print out for the 3rd button. And I'll put the Joystick script from Penelope below as well.

TwinStick.js

var spellButton : Joystick;;//TouchPad enabled in the inspector so graphic dosent move for animation spell button

var leftStick: Joystick;
var rightStick: Joystick;
var moveSpeed : float = 3.0;

var projectile : Transform;
var shootPos : Transform;
var projectileSpeed : int = 2000;

private var nextFireTime : float; //when can we shoot again
var rapidFireDelay : float = 0.5; //delay between shots
var reloadTime : float = 1.0; //time it takes to reload :)

private var theClip : int; //ammo remaining in clip
var ammoPerClip : int = 5;

var shooting : boolean = false;

function Update() 
{
    //spellButton//somehow register touch through joystick script???
    /*
    if(spellButton.HitTest(touch.position))
    {
       print("Spell Button Enabled");    
    }
    */
    //TouchTarget();
    /*
    var count : int = Input.touchCount;    
    if( count >= 1)
    {
       var touch : Touch = Input.GetTouch(0);

       if (spellButton.HitTest( touch.position ) )
       {
         print("Spell");  
       }
    }
    */ 

    ////////////////Moves the Player & rotates him /////////////////////////////////
    var lh : float = leftStick.position.x;//("LeftStickHorizontal"); X
    var lv : float = leftStick.position.y;//("LeftStickVertical"); Y
    var rh : float = rightStick.position.x;//("RightStickHorizontal"); X
    var rv : float = rightStick.position.y;//("RightStickVertical"); Y

    //LeftStick
    transform.position += Vector3(lh, 0.0, lv).normalized * moveSpeed
                          * Time.deltaTime;
    //RightStick 
    transform.LookAt(transform.position + Vector3(rh, 0.0, rv));

    ////////////////End Player Movement ////////////////////////////////////////////

    //shooting just to turn it off to test other weapon
    if(shooting)
    {
        if(rightStick.position.x || rightStick.position.y > 0 )//stickposition greater than 0 fire
        {
           if (nextFireTime <= Time.time) 
         {
             nextFireTime = Time.time + rapidFireDelay;

             Fire();

         }
        }
    }
}
function Fire()
{
    theClip--;

    if(theClip < 0)
    {
       Reload(); 
    }
    else
    {
       //var bullet = PoolManager.Pools["Shapes"].Spawn(projectile, shootPos.transform.position, shootPos.transform.rotation);
       var bullet = Instantiate(projectile, shootPos.transform.position, shootPos.transform.rotation);
       bullet.rigidbody.AddForce(bullet.transform.forward * projectileSpeed);
        bullet.name = "iBullet";
    }   
}

function Reload()
{
    theClip = ammoPerClip;
    nextFireTime = Time.time + reloadTime;
}
/*
function TouchTarget() 
{
        var count : int = Input.touchCount; 

        if(count >= 1) 
        {
            for (var i = 0; i < Input.touchCount; ++i) 
            {
                if (Input.GetTouch(i).phase == TouchPhase.Began) 
                {
                    if(spellButton.HitTest)
                    {
                       print("touching");
                    }
                }
            }
        }
}
*/      

Here is the Joystick.js

#pragma strict

@script RequireComponent( GUITexture )

// A simple class for bounding how far the GUITexture will move
class Boundary 
{
    var min : Vector2 = Vector2.zero;
    var max : Vector2 = Vector2.zero;
}

static private var joysticks : Joystick[];            // 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 deadZone : Vector2 = Vector2.zero;             // Control when position is output
var normalize : boolean = false;                 // Normalize output after the dead-zone?
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;

private var gui : GUITexture;                    // Joystick graphic
private var defaultRect : Rect;                    // Default position / extents of the joystick graphic
private var guiBoundary : Boundary = Boundary();         // Boundary for joystick graphic
private var guiTouchOffset : Vector2;               // Offset to apply to touch input
private var guiCenter : Vector2;                   // Center of joystick

function Start()
{
    // Cache this component at startup instead of looking up every frame   
    gui = GetComponent( GUITexture );

    // Store the default rect for the gui, so we can snap back to it
    defaultRect = gui.pixelInset;  

    defaultRect.x += transform.position.x * Screen.width;// + gui.pixelInset.x; // -  Screen.width * 0.5;
    defaultRect.y += transform.position.y * Screen.height;// - Screen.height * 0.5;

    transform.position.x = 0.0;
    transform.position.y = 0.0;

    if ( touchPad )
    {
       // If a texture has been assigned, then use the rect ferom the gui as our touchZone
       if ( gui.texture )
         touchZone = defaultRect;
    }
    else
    {          
       // This is an offset for touch input to match with the top left
       // corner of the GUI
       guiTouchOffset.x = defaultRect.width * 0.2;//was 0.5 so the buttons dont go off screen
       guiTouchOffset.y = defaultRect.height * 0.2;//was 0.5 so the buttons dont go off screen

       // Cache the center of the GUI, since it doesn't change
       guiCenter.x = defaultRect.x + guiTouchOffset.x;
       guiCenter.y = defaultRect.y + guiTouchOffset.y;

       // Let's build the GUI boundary, so we can clamp joystick movement
       guiBoundary.min.x = defaultRect.x - guiTouchOffset.x;
       guiBoundary.max.x = defaultRect.x + guiTouchOffset.x;
       guiBoundary.min.y = defaultRect.y - guiTouchOffset.y;
       guiBoundary.max.y = defaultRect.y + guiTouchOffset.y;
    }
}

function Disable()
{
    gameObject.active = false;
    enumeratedJoysticks = false;
}

function ResetJoystick()
{
    // Release the finger control and set the joystick back to the default position
    gui.pixelInset = defaultRect;
    lastFingerId = -1;
    position = Vector2.zero;
    fingerDownPos = Vector2.zero;

    if ( touchPad )
       gui.color.a = 0.025;  
}

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 ( !enumeratedJoysticks )
    {
       // Collect all joysticks in the game, so we can relay finger latching messages
       joysticks = FindObjectsOfType( Joystick ) as Joystick[];
       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 : int = 0;i < count; i++)
       {
         var touch : Touch = Input.GetTouch(i);      
         var guiTouchPos : Vector2 = touch.position - guiTouchOffset;

         var shouldLatchFinger = false;
         if ( touchPad )
         {          
          if ( touchZone.Contains( touch.position ) )
              shouldLatchFinger = true;
         }
         else if ( gui.HitTest( touch.position ) )
         {
          shouldLatchFinger = true;
         }       

         // Latch the finger if this is a new touch
         if ( shouldLatchFinger && ( lastFingerId == -1 || lastFingerId != touch.fingerId ) )
         {

          if ( touchPad )
          {
              gui.color.a = 0.15;

              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 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
          {             
              // Change the location of the joystick graphic to match where the touch is
              gui.pixelInset.x =  Mathf.Clamp( guiTouchPos.x, guiBoundary.min.x, guiBoundary.max.x );
              gui.pixelInset.y =  Mathf.Clamp( guiTouchPos.y, guiBoundary.min.y, guiBoundary.max.y );       
          }

          if ( touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled )
              ResetJoystick();             
         }         
       }
    }

    if ( !touchPad )
    {
       // Get a value between -1 and 1 based on the joystick graphic location
       position.x = ( gui.pixelInset.x + guiTouchOffset.x - guiCenter.x ) / guiTouchOffset.x;
       position.y = ( gui.pixelInset.y + guiTouchOffset.y - guiCenter.y ) / guiTouchOffset.y;
    }

    // Adjust for dead zone    
    var absoluteX = Mathf.Abs( position.x );
    var absoluteY = Mathf.Abs( position.y );

    if ( absoluteX < deadZone.x )
    {
       // Report the joystick as being at the center if it is within the dead zone
       position.x = 0;
    }
    else if ( normalize )
    {
       // Rescale the output after taking the dead zone into account
       position.x = Mathf.Sign( position.x ) * ( absoluteX - deadZone.x ) / ( 1 - deadZone.x );
    }

    if ( absoluteY < deadZone.y )
    {
       // Report the joystick as being at the center if it is within the dead zone
       position.y = 0;
    }
    else if ( normalize )
    {
       // Rescale the output after taking the dead zone into account
       position.y = Mathf.Sign( position.y ) * ( absoluteY - deadZone.y ) / ( 1 - deadZone.y );
    }
}

Greatly Appreciated! Sorry for the long post Im just trying to figure this out.

more ▼

asked Feb 11 '12 at 05:41 PM

michael777 gravatar image

michael777
16 3 3 4

(comments are locked)
10|3000 characters needed characters left

3 answers: sort voted first

I would personally just do the below. The stuff in the update function detects the click and the stuff in the OnGUI draws the texture

function Update(){
for(var i: int = 0;i < count; i++)
{
    var touch : Touch = Input.GetTouch(i);
    if(Rect(0, 0, 100, 100).Contains(touch.position) && touch.phase == TouchPhase.Began)
    {
       print("3rd button clicked, spell");
    }
}}

function OnGUI(){GUI.DrawTexture(Rect(0,540,100,100), texture);}
more ▼

answered Feb 11 '12 at 06:25 PM

G54 gravatar image

G54
30 6 6 12

(comments are locked)
10|3000 characters needed characters left

Its strange that the texture is not where the button is? Its really close to the left joystick but I do think its working :) Once I get the Rect to match the Texture position I'll know for sure.

var btnTexture : Texture;

var leftStick: Joystick;
var rightStick: Joystick;

function Update() 
{
    var count : int = Input.touchCount;

    for(var i: int = 0;i < count; i++)
    {
        var touch : Touch = Input.GetTouch(i);

        if(Rect(0, 0, 100, 100).Contains(touch.position) && touch.phase == TouchPhase.Began)
        {
             print("3rd button clicked, spell");
        }
    }
}   

function OnGUI()
{
    GUI.DrawTexture(Rect(0,0,100,100), btnTexture);    
}

So I looked up Rect and found this on the Scripting reference

// prints inside when mouse is in lower left corner

function Update () {
    var rect = Rect (0, 0, 150, 150);
    if (rect.Contains(Input.mousePosition))
        print("Inside");
}

wouldn't it print when the mouse is in the top-left corner? I thought it was (Rect(position x, position y, width x, height y)) but the scripting reference is saying lower left. So Im a little confused on this? After using GUI buttons for so long.

more ▼

answered Feb 11 '12 at 07:15 PM

michael777 gravatar image

michael777
16 3 3 4

Sorry forgot to explain! For some reason the GUI Rect coordinate system and the Touch Rect system are a little different. The Touch Rect system has the the top coordinate flipped for example in GUI Rect(0,0,10,10) creates something in the top left corner of the screen, but Touch Rect(0,0,10,10) is the BOTTOM left of the screen.

Feb 11 '12 at 07:21 PM G54

so u need to change the if(Rect(0, 0, 100, 100).Contains(touch.position) to if(Rect(0, Screen.height - 100, 100, 100).Contains(touch.position) to have the detection be in the same spot as the GUI texture

Feb 11 '12 at 07:23 PM G54
(comments are locked)
10|3000 characters needed characters left

Seriously Appreciated G54 !!!

I think I have a new understanding and a much easier way of doing things :) You are awesome! thank you very very very much! it works great! The penelope tutorials are nice but confusing for a newbie well not confusing overwhelming and I understand we all have different learning levels though.

Thanks a million! It works AWESOME.

more ▼

answered Feb 11 '12 at 07:32 PM

michael777 gravatar image

michael777
16 3 3 4

your welcome. I always try to help when I can since I was like you about 8 months ago. I also had the same issue with the GUI rect vs Touch rect thing a while back. Good luck with Unity!

Feb 11 '12 at 07:40 PM G54
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x2014
x981
x606
x223
x19

asked: Feb 11 '12 at 05:41 PM

Seen: 3135 times

Last Updated: Feb 11 '12 at 07:40 PM