Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Joystick available on touch

Discussion in 'iOS and tvOS' started by ravinder, Aug 25, 2010.

  1. ravinder

    ravinder

    Joined:
    Aug 25, 2010
    Posts:
    150
    Hello everybody,
    I am a newbie in unity iphone development.
    I just want to implement a joystick that would get active wherever user touches the screen.
    I tried to implement it by using unity iphone inbuilt joystick and some of my coding in other script but the joystick gets available for a second and then restores back to its original position due to the reset coding written in Joystick.js.

    Here is the other script that i used to make joystick active based on the touch position:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class touchpad : MonoBehaviour {
    6.  
    7.     // Use this for initialization
    8.     GameObject lft;
    9.     void Start () {
    10.    
    11.     lft=GameObject.Find("LeftJoystick");
    12.    
    13.     }
    14.     Rect lastloc;
    15.     // Update is called once per frame
    16. void Update ()
    17.     {
    18. foreach(iPhoneTouch touch in iPhoneInput.touches)
    19. {
    20.        
    21. if(touch.phase==iPhoneTouchPhase.Began)
    22. {
    23.     lft.active=true;
    24.     lastloc=new Rect(touch.position.x,touch.position.y,100,100);
    25. ((GUITexture)lft.GetComponent(typeof(GUITexture))).pixelInset=lastloc;
    26. }
    27.         else if(touch.phase==iPhoneTouchPhase.Moved)
    28.         {
    29.             ((GUITexture)lft.GetComponent(typeof(GUITexture))).pixelInset=lastloc;
    30.  
    31.             lft.active=true;
    32.         }
    33.         else if(touch.phase==iPhoneTouchPhase.Ended)
    34.         {
    35.             lft.active=false;
    36.         }
    37.     }
    38.    
    39. }  
    40. }
    41.  
    If anybody has played carnival then h/she must know what type of joystick i want to implement.
    Please help me out. please.
    Any help would be much appreciated.
    Thanks
     
    Last edited: Oct 5, 2010
  2. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Hi, welcome to the forum!

    Do you get the effect you want if you just comment out the body of the Reset function (lines 69 and 70)?
     
  3. ravinder

    ravinder

    Joined:
    Aug 25, 2010
    Posts:
    150
    First of all i pay my sincere thanks to you for replying to my post. Frankly speaking i lost the hope of getting any reply on this topic.

    Anyways, i tried the solution you have mentioned but it too didn't work. Actually it disturbs the actual functionality of the joystick. The joystick doesn't get reset to its center position.
    Please provide me a better solution.
    One more thing if u cud help me in this, is there any proble with Unity iPhone interface. Actually the same things that were working previuosly stops working by themselves. Lets just take the eg of joystick when i make any changes in the "JoyStick" script and reset them to defaults(after seeing the changes). But it starts woking in a weird manner.
     
  4. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    I too am working on getting a functioning version of a C# script doing something similar. Having the joystick appear on the screen and react appropriately to the new relative coordinates(given the iPhone/iPad "touch" input).

    Have you found any working solutions(in JS I assume)? Or better yet C# solutions?

    I like the aaronblohowiak penelope converted joystick script, but wish I could get it to disappear and reappear(then function properly) given the user's touch location on the screen, if that makes sense.
     
    davidjohn123 likes this.
  5. ravinder

    ravinder

    Joined:
    Aug 25, 2010
    Posts:
    150
    Hey zhx! I have posted the coding of the script that i used to implement that joystick but it didn't work.

    I wish and hope somebody posts a solution to this problem.

    Hey do u know how to implement SWIPE.
    I tried to use rigidbody.AddForce mehtod based on the direction of the swipe(although i'm still working on it) but i think there must be some other solution as well. If you do know about this please post here.

    Thanks
     
  6. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    I hope someone with some skills and the will to help out can enlighten us as to how to make a functioning version of a popup "joystick" to control the character movement.

    I get that the joystick should be instantiated at the iPhone touch screenspace location, but I'm having a bit of trouble making all input of the joystick relative to EACH new instantiation point for the joystick spawning on the screen on iphone touch input.

    As for a swipe, I'm guessing a time.deltaTime based distance/velocity check could give you swipe style input, just my first guess. The time it takes for the iPhone touch input to go from one place on the screen space to another divided by the time.DeltaTime, or something like that.
     
  7. elveatles

    elveatles

    Joined:
    May 2, 2009
    Posts:
    147
    Not sure what you're looking for. You first say you don't want it to reset, then when andeeee tells you how to fix it, you say you want it to reset.
     
  8. ravinder

    ravinder

    Joined:
    Aug 25, 2010
    Posts:
    150
    Hey elveatles!
    I tried to give the position of the Joystick at runtime via GUIPixel Inset but somehow(don't know why) the Joystick is flickering to its original (0,0) position.

    I hope you would understand.
    If you could provide any script to implement this then it would be great.

    Do you know how to perform SWIPE in unity iPhone?
     
  9. elveatles

    elveatles

    Joined:
    May 2, 2009
    Posts:
    147
    When it flickers, does it do it really quickly then fix itself, or does it continuously flicker? If it's the first one, I'm guessing you can set it's GUIPixel Inset, then yield a frame (http://unity3d.com/support/documentation/ScriptReference/index.Coroutines_26_Yield.html) before you set active to true. This way, it won't be visible until after it's position has changed for that one frame.

    Something like:

    Code (csharp):
    1.  
    2. else if(touch.phase==iPhoneTouchPhase.Moved)
    3. {
    4.      ActiveJoystick();
    5. }
    6.  
    7. private IEnumerator ActivateJoystick()
    8. {
    9.      ((GUITexture)lft.GetComponent(typeof(GUITexture))).pixelInset=lastloc;
    10.      
    11.      yield return 0; //Wait a frame
    12.      
    13.      lft.active=true;
    14. }
    15.  
    For swipe, you can store previous positions of input then get the Vector between the first and last position

    Code (csharp):
    1.  
    2. Vector2 startPosition;
    3. Vector2 swipeVector;
    4.  
    5. if(iPhoneInput.touches[0].phase == iPhoneTouchPhase.Began)
    6. {
    7.     startPosition = iPhoneInput.touches[0].position;
    8. }
    9.            
    10. if(iPhoneInput.touches[0].phase == iPhoneTouchPhase.Moved)
    11. {
    12.     swipVector = iPhoneInput.touches[0].position - startPosition;
    13. }
    14.  
    I haven't tested any of the code so don't be surprised if it doesn't work right away by mere copypasta.
     
  10. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    @ elveatles
    thanks for the code snippet, I hope this'll work for me too.

    @ ravinder
    if you are still looking for swipe control, try this out to save you some time, if you're interested(till you learn how to do it as you prefer)
    http://gameassets.net/swipeControl.html
     
  11. ravinder

    ravinder

    Joined:
    Aug 25, 2010
    Posts:
    150
    elveatles. Thank you very much for positing the code here. The joystick flickers very quickly. As i activate it on touch.
    The link that you have posted is broken.
    Anyways i'll try what you have advised.

    and zhx,thanks for providing the link. But its not free, its saying to purchase the code.

    Anyways,I really appreciate everybody's support here.
    Thanks

    If my problems get solved i'll definitely post a reply here till then if anybody gets any kinda solution then do provide me here.
    Thanks again
     
  12. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    @ravinder

    the working link is : http://unity3d.com/support/documentation/ScriptReference/index.Coroutines_26_Yield.html

    note that if you are using C#, you'll need to use ienumerators, for proper coroutine syntax
    http://unity3d.com/support/documentation/ScriptReference/index.Writing_Scripts_in_Csharp.html

    This is a GREAT URL on learning coroutines in unity3D c#, just in case you arent already familar with them
    http://www.blog.silentkraken.com/20...source=feed&utm_medium=feed&utm_campaign=feed

    ******************************************************************
    Thanks for offering to post the working version when you find the solution, I'm still searching/working on it too. I look forward to your solution post :)
     
  13. ravinder

    ravinder

    Joined:
    Aug 25, 2010
    Posts:
    150
    Thanks for your support zhx.

    I tried this coding for SWIPE gesture. Please go through it. I may be long but please go through it for once.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class swipe : MonoBehaviour {
    6.  
    7.  
    8. void Start ()
    9. {
    10. sphere=GameObject.Find("Earth");
    11. }
    12.  
    13. GameObject sphere;
    14. Vector3 temp,pos,start,end;
    15. Ray ray;
    16.  
    17. static float starttime,endtime;
    18. static bool touched=false;
    19.  
    20. void Update ()
    21. {
    22.  
    23. foreach(iPhoneTouch touch in iPhoneInput.touches)
    24. {
    25.  
    26. temp=new Vector3(touch.position.x,touch.position.y,4);
    27. ray=camera.ScreenPointToRay(temp);
    28. pos=camera.ScreenToWorldPoint(temp);
    29.  
    30. if(touch.phase==iPhoneTouchPhase.Began)
    31. {
    32.  
    33.  
    34. if(Physics.Raycast(pos,Vector3.up ,0.38f))//To get whether the touch is on Object
    35. {
    36. starttime=Time.time;
    37. start=sphere.transform.position;
    38. touched=true;//To call in the Ended phase that the object was touched
    39. sphere.rigidbody.Sleep();//To reduce the force on this rigidbody
    40. }
    41.  
    42. }//end of Began
    43.  
    44. if(touch.phase==iPhoneTouchPhase.Moved)
    45. {
    46. if(Physics.Raycast(pos,Vector3.up ,0.38f))
    47. {
    48. sphere.transform.position=pos;
    49. start=sphere.transform.position;
    50. }
    51.  
    52. }//end of Moved
    53.  
    54.  
    55. if(touch.phase==iPhoneTouchPhase.Ended)
    56. {
    57. /*Last position of touch*/
    58. end= camera.ScreenToWorldPoint(new Vector3(touch.position.x,touch.position.y,4));
    59. if(endtime-starttime<=2  touched==true)//a particular time to get swipe gesture
    60. {
    61. Vector3 pos1=new Vector3(end.x-start.x,end.y-start.y,4);
    62. sphere.rigidbody.AddForce(pos1*50f);
    63. touched=false;
    64. }
    65.  
    66.  
    67. }//end of Ended
    68.  
    69. }//end of foreach
    70.  
    71. }//end of update()
    72.  
    73. }//end of class
    74.  
    75.  
    Actually i provided the motion in the object via AddForce of the rigidbody but i think it must be implemented in other ways also like Vector3.Lerp to give a smooth and specified distance.
    And there is some problem with AddForce functionality that it keeps on adding the force. I do have provided the rigidbody.Sleep() but i don't like the type of functionality it is actually giving. I want the swipe gesture like that of Spider: The Secret of Bryce Manor.
    I like the swipe provided by them in the game.

    Could anyone please help me in this?
    For better reference please find the script in the attachment.
    Thanks
     

    Attached Files:

  14. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    @Ravinder, did you find any solutions that work yet?
     
  15. ravinder

    ravinder

    Joined:
    Aug 25, 2010
    Posts:
    150
    Sorry zhx for late reply.
    No not yet. Actually i left that topic cuz i got busy in a project that has been assigned to me. And i'm still working on it.
    So i'll try to gain this functionality after the completion of my project and post the solution if got any. :)
     
  16. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    @Ravinder: Thanks for the update, hope your new project is a successful one! If I get it to work as well, I'll post my result... still working on it though.
     
  17. Jfhutchi

    Jfhutchi

    Joined:
    Jan 5, 2010
    Posts:
    32
    Any luck on this? I've been wanting to redo my controls to this as well
     
  18. ravinder

    ravinder

    Joined:
    Aug 25, 2010
    Posts:
    150
    No not yet. Actually GUITexture is placed on a gameObject. Now when you do like

    Code (csharp):
    1.  
    2. gameObject.transform.position=camera.main.ScreenToWorldPoint(touch.position);
    3.  
    It essentially changes the position of that gameObject according to the world coordinates but GUITexture is not aligned to these coordinates so the position varies with that of your finger.
    Moreover when you do gui.PixelInset=touch.position then also it does not provide you the actual position you want.
    The reason may lie in the pivot or center point of GameObject and GUITexture. The axes you see are for GameObject and not for guiTexture.
    Don't know how and when it would be achieved.
     
  19. ravinder

    ravinder

    Joined:
    Aug 25, 2010
    Posts:
    150
    Hey, I have finally got the solution to this problem.
    Here is the code. I tried it with mousePosition but you can replace it with touch.position. I hope that works too.

    Code (csharp):
    1.  
    2. function Update ()
    3. {
    4.    if(Input.GetMouseButtonDown(0))
    5.    {
    6.       var screenPos=Camera.main.ScreenToViewportPoint(Input.mousePosition);
    7.       transform.position.x=Mathf.Abs(screenPos.x);
    8.       transform.position.y=Mathf.Abs(screenPos.y);
    9.    }
    10.  
    11. }//end of Update
    12.  
    Yessssss:):D:cool:
     
  20. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    !!! Testing time, thank you Ravinder for sharing

    hmmm having trouble porting this to a working version for iOS
     
    Last edited: Dec 3, 2010
  21. ravinder

    ravinder

    Joined:
    Aug 25, 2010
    Posts:
    150
    Hmmmm.. Actually you have to enable one script at a time while Joystick is not available enable the above script and as soon as the user touches the device , disable the above coding and enable Unity's Joystick script else the two scripts would conflict with each other resulting in producing a weird functionality.

    [Its just a suggestion i haven't tried this but i think that would be the only solution to achieve this functionality]
     
  22. JamesMobot

    JamesMobot

    Joined:
    Jul 8, 2010
    Posts:
    170
    Just came across this.
    I too have spent more hours than A person should with not much success.
    Predator does this and was made with unity. So i know it can be done very nicely.

    To me it really makes virtual joysticks 100 times better.
     
    Last edited: Jan 15, 2011
  23. ravinder

    ravinder

    Joined:
    Aug 25, 2010
    Posts:
    150
    Hi everybody,

    Finally I was able to find out a working solution to this problem. I went busy in other game so the feature was left out but as I tried to implement this in one of my games I was able to implement it the way it has to be.
    The below code for the Joystick works exactly like that of in the game Hungry Shark

    There are a couple of points you need to follow to achieve this functionality:

    1. Make a prefab of your choice of GUITexture for that Joystick.
    2. Do not add "Joystick" script to that prefab. It would be added explicitly at runtime.

    Code (csharp):
    1.  
    2.  
    3. var joystick: Transform; //The prefab of the GUITexture
    4. private var newPos: Vector3;//Position to be set at runtime
    5. private var joyGenerated: Transform;// The joystick which is going to be generated at runtime
    6.  
    7. if(Input.touchCount==1)
    8. {
    9.  
    10.      if(touch.phase==TouchPhase.Began)
    11.         {
    12.            //We want to create only one instance of the Joystick so generate it only if it is not available in the scene
    13.             if(joyGenerated==null)
    14.             {
    15.                //Position to locate the GUITexture based on Touch Position
    16.                 newPos=Camera.main.ScreenToViewportPoint(touch.position);
    17.  
    18.                //This code checks that the Joystick would not get generated at the top position where buttons are available.
    19.                if(newPos.y>0.8)
    20.                     return;
    21.                 joyGenerated= Instantiate(joystick,newPos,Quaternion.identity)as Transform;
    22.  
    23.                 //The following code does exactly what Joystick script does at Start(), the only difference is that we do all the calculations first before adding the script so that the script won't change the positions by itself.
    24.  
    25.                 var defaultRect:Rect=joyGenerated.guiTexture.pixelInset;
    26.                 defaultRect.x += joyGenerated.position.x * Screen.width;// + gui.pixelInset.x; // -  Screen.width * 0.5;
    27.                 defaultRect.y += joyGenerated.position.y * Screen.height;// - Screen.height * 0.5;
    28.                 joyGenerated.position=Vector3.zero;
    29.                 joyGenerated.guiTexture.pixelInset=defaultRect;
    30.                 joyGenerated.gameObject.AddComponent("Joystick");//Adding the Joystick script at runtime
    31.  
    32.             }//end of joyGenerated
    33.         }//end of Began
    34. }//end of touchCount
    35.  
    Attach this script to your MainCamera or on whichever gameObject you want and see the magic working. ;)
    The above has been tested and it is working for me.
     
  24. sam268

    sam268

    Joined:
    Apr 21, 2014
    Posts:
    149
    Dude, I know I'm totally necroing, but I feel like you deserve a medal. This script is brilliant.
     
  25. andyblueAMS001

    andyblueAMS001

    Joined:
    Aug 13, 2017
    Posts:
    4
    I tried your script but touch is not recognized by unity in your script, i am using unity 2017
     
  26. andyblueAMS001

    andyblueAMS001

    Joined:
    Aug 13, 2017
    Posts:
    4
    i also did what you said, but nothing happens,
     
  27. JulianGke

    JulianGke

    Joined:
    Jun 21, 2020
    Posts:
    3
    Hello everyone,
    I have a simplier solution. Instal the free package: simple Input. In this package you have a joystick with the option "is dynamic Joystick". Enable this and you got it. (Sorry for my English.)
    simple Input
     
  28. b4guw1x

    b4guw1x

    Joined:
    Apr 16, 2020
    Posts:
    12
    Thanks to julian gke it's work like a charm!