Author Topic: NGUI Virtual Joystick  (Read 30604 times)

derkoi

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 57
    • View Profile
Re: NGUI Virtual Joystick
« Reply #15 on: December 12, 2012, 08:56:07 AM »
This script doesn't work properly in Unity 4, when touched the joystick moves in the wrong place of the touch & sticks until dragged a certain distance. See my video:

http://www.youtube.com/watch?v=cwnS9sZiRjE

Here's the full script, can anyone help please?

  1. using UnityEngine;
  2. using System.Collections;
  3. /// <summary>
  4. /// Allows dragging of the specified target object by mouse or touch, optionally limiting it to be within the UIPanel's clipped rectangle.
  5. /// </summary>
  6.  
  7. [AddComponentMenu("NGUI/Interaction/Drag Object")]
  8. public class UIJoystick : MonoBehaviour {
  9.        
  10.         static UIJoystick[] joysticks ;                                         // A static collection of all joysticks
  11.         static bool enumeratedJoysticks = false;
  12.        
  13.         /// <summary>
  14.         /// Target object that will be dragged.
  15.         /// </summary>
  16.        
  17.         public Transform target;
  18.         public Vector3 scale = Vector3.one;
  19.         public float radius = 40f;                                                              // the radius for the joystick to move
  20.         bool mPressed = false;
  21.  
  22.         public bool centerOnPress = true;
  23.         Vector3 userInitTouchPos;
  24.        
  25.         //Joystick vars
  26.         public int tapCount;   
  27.         public bool normalize = false;                                                  // Normalize output after the dead-zone?
  28.         public Vector2 position;                                                                // [-1, 1] in x,y
  29.         public float deadZone = 2f;                                                             // Control when position is output
  30.         public float fadeOutAlpha = 0.2f;
  31.         public float fadeOutDelay = 1f;
  32.         public UIWidget[] widgetsToFade;                                                // UIWidgets that should fadeIn/Out when centerOnPress = true
  33.         public Transform[] widgetsToCenter;                                             // GameObjects to Center under users thumb when centerOnPress = true
  34.         private float lastTapTime = 0f;
  35.         public float doubleTapTimeWindow = 0.5f;                                // time in Seconds to recognize a double tab
  36.         public GameObject doubleTapMessageTarget;
  37.         public string doubleTabMethodeName;
  38.        
  39.         void Awake() {
  40.                 userInitTouchPos = Vector3.zero;
  41.        
  42.         }
  43.        
  44.         void Start () {
  45.                 if (centerOnPress) {
  46.                        
  47.                         StartCoroutine(fadeOutJoystick());
  48.                 }
  49.         }
  50.        
  51.         IEnumerator fadeOutJoystick() {
  52.        
  53.         yield return new WaitForSeconds (fadeOutDelay);
  54.                 foreach(UIWidget widget in widgetsToFade) {
  55.                         Color lastColor = widget.color;
  56.                         Color newColor = lastColor;
  57.                         newColor.a = fadeOutAlpha;
  58. //                      TweenColor.Begin(widget.gameObject, 0.5f, newColor).method = Tweener.Method.EaseOut;
  59.                 }      
  60.     }
  61.        
  62.  
  63.  
  64.         /// <summary>
  65.         /// Create a plane on which we will be performing the dragging.
  66.         /// </summary>
  67.  
  68.         public void OnPress (bool pressed) {
  69.                 if (target != null) {
  70.                         mPressed = pressed;
  71.  
  72.                         if (pressed) {
  73.                                 StopAllCoroutines();
  74.                                 if (Time.time < lastTapTime +doubleTapTimeWindow) {
  75.                                        
  76.                                         if (doubleTapMessageTarget != null && doubleTabMethodeName != "") {
  77.                                                 doubleTapMessageTarget.SendMessage(doubleTabMethodeName,SendMessageOptions.DontRequireReceiver);
  78.                                                  tapCount ++;                                
  79.                                         } else {
  80.                                                 Debug.LogWarning("Double Tab on Joystick but no Reciever or Methodename available");
  81.                                         }
  82.                                 } else {
  83.                                         tapCount = 1;
  84.                                 }
  85.                                 lastTapTime = Time.time;
  86.                                 //set Joystick to fingertouchposition
  87.                                 Ray ray = UICamera.currentCamera.ScreenPointToRay(UICamera.lastTouchPosition);
  88.                                 float dist = 0f;
  89.                                
  90.                                 Vector3 currentPos = ray.GetPoint(dist);
  91.                                 currentPos.z = 0;
  92.                                 if (centerOnPress) {
  93.                                         userInitTouchPos = currentPos;
  94.                                         foreach(UIWidget widget in widgetsToFade) {
  95. //                                              TweenColor.Begin(widget.gameObject, 0.1f, Color.white).method = Tweener.Method.EaseIn;
  96.                                         }
  97.                                         foreach(Transform widgetTF in widgetsToCenter) {
  98.                                                 widgetTF.position = userInitTouchPos;
  99.                                         }
  100.                                 } else {
  101.                                         userInitTouchPos = target.position;
  102.                                         OnDrag(Vector2.zero);
  103.                                 }
  104.                                
  105.                         } else {
  106.                                 ResetJoystick ();
  107.                         }
  108.                 }
  109.         }
  110.  
  111.         /// <summary>
  112.         /// Drag the object along the plane.
  113.         /// </summary>
  114.  
  115.         void OnDrag (Vector2 delta)
  116.     {
  117.         //Debug.Log("delta " +  delta + " delta.magnitude = " + delta.magnitude);
  118.         Ray ray = UICamera.currentCamera.ScreenPointToRay(UICamera.lastTouchPosition);
  119.         float dist = 0f;
  120.        
  121.         Vector3 currentPos = ray.GetPoint(dist);
  122.         Vector3 offset = currentPos - userInitTouchPos;
  123.  
  124.         if (offset.x != 0f || offset.y != 0f) {
  125.             offset = target.InverseTransformDirection(offset);
  126.             offset.Scale(scale);
  127.             offset = target.TransformDirection(offset);
  128.             offset.z = 0f;
  129.         }
  130.        
  131.         target.position = userInitTouchPos +offset;
  132.  
  133.         Vector3 zeroZpos = target.position;
  134.         zeroZpos.z = 0f;
  135.         target.position = zeroZpos;
  136.         // Calculate the length. This involves a squareroot operation,
  137.         // so it's slightly expensive. We re-use this length for multiple
  138.         // things below to avoid doing the square-root more than one.
  139.  
  140.         float length = target.localPosition.magnitude;
  141.        
  142.         if (length > radius) {
  143.             target.localPosition = Vector3.ClampMagnitude(target.localPosition, radius);
  144.         }
  145.         position = target.localPosition;
  146.        
  147.         if (normalize) {
  148.             // Normalize the vector and multiply it with the length adjusted
  149.             // to compensate for the deadZone radius.
  150.             // This prevents the position from snapping from zero to the deadZone radius.
  151.             position = position / radius * Mathf.InverseLerp (radius, deadZone, 1);
  152.         }
  153.     }
  154.  
  155.  
  156.  
  157.  
  158.         /// <summary>
  159.         /// Apply the dragging momentum.
  160.         /// </summary>
  161.  
  162.         void Update () {
  163.                 if (!enumeratedJoysticks) {
  164.                         // Collect all joysticks in the game, so we can relay finger latching messages
  165.                         joysticks = FindObjectsOfType(typeof(UIJoystick)) as UIJoystick[];
  166.                        
  167.                         enumeratedJoysticks = true;
  168.                 }
  169.         }
  170.        
  171.         void ResetJoystick () {
  172.                 // Release the finger control and set the joystick back to the default position
  173.                 tapCount = 0;
  174.                 position = Vector2.zero;
  175.                 target.position = userInitTouchPos;
  176.                 if (centerOnPress) {
  177.                         StartCoroutine(fadeOutJoystick());
  178.                 }
  179.         }
  180.        
  181.         public void Disable () {
  182.                 gameObject.active = false;
  183.                 enumeratedJoysticks = false;
  184.         }
  185. }
  186.  
  187.  

n8

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 23
    • View Profile
Re: NGUI Virtual Joystick
« Reply #16 on: December 12, 2012, 03:34:13 PM »
unfortunately, I don't see the problem in your video.  The video doesn't show where your physical touch so you can't really tell how the joystick is reacting to the touch.  Try adding a debug sprite to the screen that follows the physical touch (make this separate from the joystick script), so that we can see the true behavior.

The only thing I could think of off the top of my head is to make sure that the cameras are setup correctly.  The joystick script uses a raycast from the "currentCamera", make sure that camera is the one you are expecting and that it is setup how it should be.
« Last Edit: December 12, 2012, 03:36:22 PM by n8 »

mikeuzda

  • Guest
Re: NGUI Virtual Joystick
« Reply #17 on: February 25, 2013, 02:49:02 PM »
Does anyone have a link to the unitypackage mentioned at the top of the post?  The link doesn't bring me to a post that has it or a place to download it.  Many thanks,

Mike

Criimson

  • Guest
Re: NGUI Virtual Joystick
« Reply #18 on: March 06, 2013, 05:23:23 PM »
Hello everyone

I have been testing this joystick and it everything is going well, except for one issue I am having.
I have the stick controlling the character except that I am using the OnDrag function and I think I may be doing things a bit wrong.
It seems OnDrag isn't called except when the offset.x or offset.y change.  My character will move if I keep moving the stick, but if I hold the stick forward (for example) then the character stops moving.

Here is the snippet of code from OnDrag that I added:
  1.      if(offset.y != 0f) {
  2.                                 //Debug.Log("Move Player = " + offset.y);
  3.                                 _myCharController.SimpleMove(playerTransform.TransformDirection(Vector3.forward) * (offset.y*10) * moveSpeed);
  4.                                
  5.                                 //animation.CrossFade("run");
  6.                         }
  7.                        
  8.                         if(offset.x != 0f) {
  9.                                 //Debug.Log("Rotate Player = " + offset.x);
  10.                                 playerTransform.Rotate(0, offset.x * Time.deltaTime * rotateSpeed, 0);
  11.                         }

Any ideas on how to do this better?

Thank you
Criimson

EDIT:
So after some more work I figured it out.
Adding the code for anyone else that is looking.
In the Update function add a call to Move()

and add this function at the bottom of the code

  1. private void Move() {
  2.                
  3.                 Ray ray = UICamera.currentCamera.ScreenPointToRay(UICamera.lastTouchPosition);
  4.         float dist = 0f;
  5.        
  6.         Vector3 currentPos = ray.GetPoint(dist);
  7.         offset = currentPos - userInitTouchPos;
  8.  
  9.        
  10.                        
  11.                         //Debug.Log("offset.x " +  offset.x + " and offset.y = " + offset.y);
  12.                        
  13.                         //Add movement scripts here
  14.                         if(offset.y != 0f && mPressed == true) {
  15.                                 Debug.Log("Move Player = " + offset.y);
  16.                                 _myCharController.SimpleMove(playerTransform.TransformDirection(Vector3.forward) * (offset.y*10) * moveSpeed);
  17.                                
  18.                                 //animation.CrossFade("run");
  19.                         }
  20.                        
  21.                         if(offset.x != 0f && mPressed == true) {
  22.                                 //Debug.Log("Rotate Player = " + offset.x);
  23.                                 playerTransform.Rotate(0, offset.x * Time.deltaTime * rotateSpeed, 0);
  24.                         }
  25.        
  26.         }

Criimson
« Last Edit: March 07, 2013, 02:35:01 AM by Criimson »

Dover8

  • Newbie
  • *
  • Thank You
  • -Given: 1
  • -Receive: 0
  • Posts: 20
    • View Profile
Re: NGUI Virtual Joystick
« Reply #19 on: June 13, 2014, 06:59:50 AM »
Does this package still exist? I was hoping to look at it myself.

Rick74

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 34
    • View Profile
Re: NGUI Virtual Joystick
« Reply #20 on: June 23, 2014, 11:08:48 AM »
Actually I'm trying to hunt this down as well.  Can't seem to find it anywhere...

Caio.Lib

  • Newbie
  • *
  • Thank You
  • -Given: 7
  • -Receive: 2
  • Posts: 26
    • View Profile
Re: NGUI Virtual Joystick
« Reply #21 on: June 23, 2014, 09:59:10 PM »
I'm using UIJoyStick:
http://www.youtube.com/watch?v=SqJQjgmWO4E
https://gist.github.com/anonymous/6949309

You need to change UpdateRealTimeDelta() to RealTime.deltaTime and it works.
Thanks 白明翰 for the video and the code.

Rick74

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 34
    • View Profile
Re: NGUI Virtual Joystick
« Reply #22 on: June 24, 2014, 06:39:13 AM »
Thanks, I couldn't for the life of me find it yesterday.  So I went with VirtualControlSuite. 

I'm curious why this doesn't come with NGUI?  At least I don't see it anywhere.  I don't see much in the way of tutorials or documentation either.  It's just sorta...on the internet.
« Last Edit: June 24, 2014, 07:36:37 AM by Rick74 »

blackant

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 22
    • View Profile
    • blackant master
Re: NGUI Virtual Joystick
« Reply #23 on: December 15, 2014, 09:52:44 AM »
Hi Guys,

i'm trying to use this script i fund on this post, but i get an error while unity compile it


Error:
Assets/NGUI/Scripts/Interaction/UIJoyStick.cs(14,27): error CS0246: The type or namespace name `IgnoreTimeScale' could not be found. Are you missing a using directive or an assembly reference?


  1. //----------------------------------------------
  2. //            NGUI: Next-Gen UI kit
  3. // Copyright © 2011-2013 Tasharen Entertainment
  4. //----------------------------------------------
  5.  
  6. using UnityEngine;
  7. using System.Collections;
  8.  
  9. /// <summary>
  10. /// Allows dragging of the specified target object by mouse or touch, optionally limiting it to be within the UIPanel's clipped rectangle.
  11. /// </summary>
  12.  
  13. [AddComponentMenu("NGUI/Interaction/JoyStick")]
  14. public class UIJoyStick : IgnoreTimeScale
  15. {
  16.         public enum DragEffect
  17.         {
  18.                 None,
  19.                 Momentum,
  20.                 MomentumAndSpring,
  21.         }
  22.        
  23.         public float joyStickPosX;
  24.         public float joyStickPosY;
  25.         private float posDivision;
  26.        
  27.         /// <summary>
  28.         /// Target object that will be dragged.
  29.         /// </summary>
  30.        
  31.         public Transform target;
  32.        
  33.         /// <summary>
  34.         /// Scale value applied to the drag delta. Set X or Y to 0 to disallow dragging in that direction.
  35.         /// </summary>
  36.        
  37.         private Vector3 scale = Vector3.one;
  38.        
  39.         /// <summary>
  40.         /// Effect the scroll wheel will have on the momentum.
  41.         /// </summary>
  42.        
  43.         public float scrollWheelFactor = 0f;
  44.        
  45.         /// <summary>
  46.         /// Whether the dragging will be restricted to be within the parent panel's bounds.
  47.         /// </summary>
  48.        
  49.         public bool restrictWithinPanel = false;
  50.        
  51.         /// <summary>
  52.         /// 限制按鈕移動半徑範圍
  53.         /// The clamp radius.
  54.         /// </summary>
  55.         public float ClampRadius = 100.0f;
  56.        
  57.         /// <summary>
  58.         /// How much momentum gets applied when the press is released after dragging.
  59.         /// </summary>
  60.        
  61.         Plane mPlane;
  62.         Vector3 mLastPos;
  63.         UIPanel mPanel;
  64.         bool mPressed = false;
  65.         Vector3 mMomentum = Vector3.zero;
  66.         float mScroll = 0f;
  67.         Bounds mBounds;
  68.        
  69.         void Awake ()
  70.         {
  71.                 posDivision = 1 / ClampRadius;
  72.         }
  73.        
  74.         /// <summary>
  75.         /// Find the panel responsible for this object.
  76.         /// </summary>
  77.        
  78.         void FindPanel ()
  79.         {
  80.                 mPanel = (target != null) ? UIPanel.Find(target.transform, false) : null;
  81.                 if (mPanel == null) restrictWithinPanel = false;
  82.         }
  83.        
  84.         /// <summary>
  85.         /// Create a plane on which we will be performing the dragging.
  86.         /// </summary>
  87.         void OnHover (bool Hover)
  88.         {
  89.                 //print ("!!");
  90.         }
  91.         void OnPress (bool pressed)
  92.         {
  93.                 if (enabled && NGUITools.GetActive(gameObject) && target != null)
  94.                 {
  95.                         mPressed = pressed;
  96.                        
  97.                         if (pressed)
  98.                         {
  99.                                 if (restrictWithinPanel && mPanel == null) FindPanel();
  100.                                
  101.                                 // Calculate the bounds
  102.                                 if (restrictWithinPanel) mBounds = NGUIMath.CalculateRelativeWidgetBounds(mPanel.cachedTransform, target);
  103.                                
  104.                                 // Remove all momentum on press
  105.                                 mMomentum = Vector3.zero;
  106.                                 mScroll = 0f;
  107.                                
  108.                                 // Disable the spring movement
  109.                                 SpringPosition sp = target.GetComponent<SpringPosition>();
  110.                                 if (sp != null) sp.enabled = false;
  111.                                
  112.                                 // Remember the hit position
  113.                                 mLastPos = UICamera.lastHit.point;
  114.                                
  115.                                 // Create the plane to drag along
  116.                                 Transform trans = UICamera.currentCamera.transform;
  117.                                 mPlane = new Plane((mPanel != null ? mPanel.cachedTransform.rotation : trans.rotation) * Vector3.back, mLastPos);
  118.                         }
  119.                         else if (restrictWithinPanel && mPanel.clipping != UIDrawCall.Clipping.None)
  120.                         {
  121.                                 mPanel.ConstrainTargetToBounds(target, ref mBounds, false);
  122.                         }
  123.                         if (!pressed)
  124.                         {
  125.                                 StartCoroutine("SpringPositionUpdate");
  126.                                
  127.                         }
  128.                 }
  129.         }
  130.        
  131.         /// <summary>
  132.         /// Drag the object along the plane.
  133.         /// </summary>
  134.        
  135.         void OnDrag (Vector2 delta)
  136.         {
  137.                 //print ("haha");
  138.                 if (enabled && NGUITools.GetActive(gameObject) && target != null)
  139.                 {
  140.                         UICamera.currentTouch.clickNotification = UICamera.ClickNotification.BasedOnDelta;
  141.                        
  142.                         Ray ray = UICamera.currentCamera.ScreenPointToRay(UICamera.currentTouch.pos);
  143.                         float dist = 0f;
  144.                        
  145.                         if (mPlane.Raycast(ray, out dist))
  146.                         {
  147.                                 //print (ray.GetPoint(dist).x+","+ray.GetPoint(dist).y);
  148.                                 Vector3 currentPos = ray.GetPoint(dist);
  149.                                 mLastPos = currentPos;
  150.                                
  151.                                 // We want to constrain the UI to be within bounds
  152.                                 target.position = currentPos;                  
  153.                                 // 限制虛擬搖桿目標移動半徑
  154.                                 target.transform.localPosition = new Vector3(Vector3.ClampMagnitude(target.transform.localPosition, ClampRadius).x, Vector3.ClampMagnitude(target.transform.localPosition, ClampRadius).y, 0);
  155.                                 // 獲取目標
  156.                                 joyStickPosX = target.transform.localPosition.x * posDivision;
  157.                                 joyStickPosY = target.transform.localPosition.y * posDivision;
  158.                         }
  159.                 }
  160.         }
  161.        
  162.         /// <summary>
  163.         /// Apply the dragging momentum.
  164.         /// </summary>
  165.        
  166.         void LateUpdate ()
  167.         {
  168.                 float delta = UpdateRealTimeDelta();
  169.                 if (target == null) return;
  170.                
  171.                 if (mPressed)
  172.                 {
  173.                         // Disable the spring movement
  174.                         SpringPosition sp = target.GetComponent<SpringPosition>();
  175.                         if (sp != null) sp.enabled = false;
  176.                         mScroll = 0f;
  177.                 }
  178.                 else
  179.                 {
  180.                         mMomentum += scale * (-mScroll * 0.05f);
  181.                         mScroll = NGUIMath.SpringLerp(mScroll, 0f, 20f, delta);
  182.                        
  183.                         if (mMomentum.magnitude > 0.0001f)
  184.                         {
  185.                                 // Apply the momentum
  186.                                 if (mPanel == null) FindPanel();
  187.                                
  188.                                 if (mPanel != null)
  189.                                 {
  190.                                         target.position += NGUIMath.SpringDampen(ref mMomentum, 9f, delta);
  191.                                        
  192.                                         if (restrictWithinPanel && mPanel.clipping != UIDrawCall.Clipping.None)
  193.                                         {
  194.                                                 mBounds = NGUIMath.CalculateRelativeWidgetBounds(mPanel.cachedTransform, target);
  195.                                                
  196.                                                
  197.                                         }
  198.                                         return;
  199.                                 }
  200.                         }
  201.                         else mScroll = 0f;
  202.                 }
  203.                
  204.                 // Dampen the momentum
  205.                 NGUIMath.SpringDampen(ref mMomentum, 9f, delta);
  206.         }
  207.        
  208.         /// <summary>
  209.         /// If the object should support the scroll wheel, do it.
  210.         /// </summary>
  211.        
  212.         void OnScroll (float delta)
  213.         {
  214.                 if (enabled && NGUITools.GetActive(gameObject))
  215.                 {
  216.                         if (Mathf.Sign(mScroll) != Mathf.Sign(delta)) mScroll = 0f;
  217.                         mScroll += delta * scrollWheelFactor;
  218.                 }
  219.         }      
  220.        
  221.         //public delegate void OnFinished (UIJoyStick);
  222.         /// <summary>
  223.         /// Target position to tween to.
  224.         /// </summary>
  225.        
  226.         private Vector3 targetPosition = Vector3.zero;
  227.        
  228.         /// <summary>
  229.         /// How strong is the pull of the spring. Higher value means it gets to the target faster.
  230.         /// </summary>
  231.        
  232.         public float strength = 10f;
  233.        
  234.        
  235.         /// <summary>
  236.         /// Whether the time scale will be ignored. Generally UI components should set it to 'true'.
  237.         /// </summary>
  238.        
  239.         public bool ignoreTimeScale = false;
  240.        
  241.         /// <summary>
  242.         /// Delegate to trigger when the spring finishes.
  243.         /// </summary>
  244.         //public OnFinished onFinished;
  245.        
  246.         float mThreshold = 0f;
  247.        
  248.         IEnumerator SpringPositionUpdate ()
  249.         {
  250.                 while (true)
  251.                 {
  252.                         float delta = ignoreTimeScale ? UpdateRealTimeDelta() : Time.deltaTime;
  253.                         if (mThreshold == 0f) mThreshold = (targetPosition - target.localPosition).magnitude * 0.001f;
  254.                         target.localPosition = NGUIMath.SpringLerp(target.localPosition, targetPosition, strength, delta);
  255.                        
  256.                         joyStickPosX = target.transform.localPosition.x * posDivision;
  257.                         joyStickPosY = target.transform.localPosition.y * posDivision;
  258.                        
  259.                         if (mThreshold >= (targetPosition - target.localPosition).magnitude)
  260.                         {
  261.                                 target.localPosition = targetPosition; 
  262.                                 joyStickPosX = 0;
  263.                                 joyStickPosY = 0;
  264.                                 break;
  265.                         }
  266.                         yield return 0;
  267.                 }
  268.         }
  269. }

by the way, next month i was using a script like this one with NGUI and i don't remember where i fund it, but i'm pretty sure i didn't copy past any line of code to fund it....
isn't it another existing script in NGUI package ??
« Last Edit: December 15, 2014, 11:07:29 AM by blackant »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: NGUI Virtual Joystick
« Reply #24 on: December 15, 2014, 12:53:45 PM »
IgnoreTimeScale was removed a long time ago... back in NGUI 2 days I think. It's not needed anymore. Use RealTime.deltaTime to get the non-timescaled delta time.