Unity-based virtual joystick NGUI simple and can be used directly to achieve (a)

We may have heard about the famous easytouch, however easytouch is based UGUI of two different UI mix, it might be confusing project management, and that could happen as unitary moths, such as event delivery issues of mutual disturbance.

So he's looking for one kind NGUI rocker, search-based online articles, there are a lot of problems, in conclusion, three issues stand out.

One: there is the ability to code for defects or BUG, ​​or too simple, such as not considering the relative deviation of the finger buttons, the actual cause is not practical, only to learn.

Two: NGUI is known as a rocker, but it took some implementations UGUI things.

Three: does not consider versatility, parameters are fixed values, what 73 43 ah ah, do not know how come these values.

So wrote it, NGUI not taught how to use.

① First, create two Sprite (here I use the lazy 2DSprite, because there is no picture pack) and a Texture.

 

NGuiJoystick rocker chassis, Thumb rocker button, NGuiJoystickArea Dynamic mode for displaying the region.

Dynamic mode: Dynamic mode is similar EasyTouch widget usually do not show rocker, rocker fingers pressing the display at a finger, then lift rocker disappeared.

Note: The three UI object names at random, but the hierarchy can not be wrong.

② modify NGuiJoystick and Thumb texture image and adjusted to the appropriate size you want (here length and width equal to the best, because I have not tried ranging okay), to NGuiJoystick and Thumb are Attack on Collider. The depth is set NGuiJoystick 100, Thumb depth of 101 (as at the top, of course, also be changed on demand).

③ modify NGuiJoystickArea size (according to the following Dynamic mode you want to display in the area, I've covered the full screen), the Attack Collider, modify NGuiJoystickArea texture (I use a piece of white direction of the texture), set the color hint of NGuiJoystickArea value (255, 255,255,50), to modify the depth 1 (if it is the default UIRoot and UICamera value of 0).

④ Then there is the code section.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class JoyStickControl : MonoBehaviour
{
    public enum ShowType {Static, Dynamic}; // display mode
    public ShowType showType= ShowType.Static;
    public float radiusOffset = 0.0F; // radius offset value for the deviation of the image problems caused by fine adjustment
    public GameObject area = null; // Dynamic display region in the pattern
    private float radius; // radius chassis
    private float ratio = 1.0F; // scaling value
    private bool isPress = false; // if is pressed
    private bool isFirstPress = false; // if the first press
    private Vector2 offset; // the button with respect to the finger offset value

    private void Awake()
    {
        // Get the chassis radius
        UI2DSprite parentSpirite = transform.parent.GetComponent<UI2DSprite>();
        float parentWidth = parentSpirite.width;
        radius = parentWidth / 2.0F+ radiusOffset;

        // Get scaling value
        UIRoot root = GameObject.FindObjectOfType<UIRoot>();
        if (root != null)
        {
            // actual size and design size ratio
            ratio = (float)root.activeHeight / Screen.height;
        }

        // If Dynamic mode, the beginning of the hidden rocker, set to almost transparent and Area
        if (showType == ShowType.Dynamic)
        {
            transform.parent.gameObject.SetActive(false);
            if (area != null)
            {
                UITexture areaTexture = area.GetComponent<UITexture>();
                areaTexture.color = new Color(1.0F, 1.0F, 1.0F, 1.0F/255.0F);
            }
        }
        else
        {
            if (area != null)
            {
                area.SetActive(false);
            }
        }
    }

    // Update is called once per frame
    private void Update()
    {
        // touch down
        if (isPress)
        {
            // last touch position, based on the screen coordinates
            Vector2 touchpos = UICamera.lastEventPosition;
            // Get the screen coordinates rocker button
            Vector2 childCenterPos = UICamera.currentCamera.WorldToScreenPoint(transform.position);
            // get the first touch when the finger relative to the offset value of the button
            if (!isFirstPress)
            {
                offset = touchpos - childCenterPos;
                isFirstPress = true;
            }
            
            // Get the screen coordinates rocker chassis
            Vector2 centerPos = UICamera.currentCamera.WorldToScreenPoint(transform.parent.position);

            // Get touchpos - the distance between the offset value and centerPos
            // Those who use touchpos - place must not be offset by childCenterPos substitute, can be considered under Why
            float distance = Vector2.Distance(touchpos - offset, centerPos);

            // If the distance is smaller than the radius, then the button to move touchpos - offset position
            // distance to calculate the relative distance, multiplied by the scaling value
            if (distance * ratio <radius) // from the parent background sprite inner circle, radius its radius
            {
                Vector3 worldTouchPos = UICamera.currentCamera.ScreenToWorldPoint(touchpos - offset);
                transform.position = worldTouchPos;
            }
            // distance than the radius, put the location of the button is provided on a circle chassis
            else
            {
                transform.localPosition = (touchpos - offset - centerPos).normalized * radius;
                childCenterPos = UICamera.currentCamera.WorldToScreenPoint(transform.position);
            }

        }
        // touch-up, then the Resume button to position the origin, the isFirstPress home No, if it is Dynamic mode, but also hide rocker
        else
        {
            if (showType == ShowType.Dynamic)
            {
                transform.parent.gameObject.SetActive(false);
            }
            transform.localPosition = Vector2.zero;
            isFirstPress = false;
        }
    }

    // touch down, isPress true, the lift is false
    public void OnPress(bool isPress)
    { 
        this.isPress = isPress;
    }

    // response Dynamic mode press event
    public void startTouch()
    {
        if (showType == ShowType.Dynamic)
        {
            transform.parent.gameObject.SetActive(true);
            Vector2 startTouchPos = UICamera.lastEventPosition;
            Vector2 startTouchWorldPos = UICamera.currentCamera.ScreenToWorldPoint(startTouchPos);
            transform.parent.position = startTouchWorldPos;
            this.isPress = true;
        }
    }

    // response Dynamic mode release event
    public void endTouch()
    {
        if (showType == ShowType.Dynamic)
        {
            transform.parent.gameObject.SetActive(false);
        }
        transform.localPosition = Vector2.zero;
        isFirstPress = false;
    }
}

⑤ the script onto the thumb on the object, and the NGuiJoystickArea onto the public members of the script.

 

⑥ add an event trigger, NGuiJoystickArea-> Add Component-> NGUI-> Interaction-> Event Trigger.

Thumb ⑦ will press onto the trigger event, and to set the response function startTouch (); Thumb onto the release trigger event, and to set the response function endTouch ().

 

[Preview]

 

A few days to upload and figures related story, the realization EasyTouch allow turn and move, and some have been DeadValue configuration parameters.

[This article is the original article, CSDN blog publishing and blog authors garden of the same author, it is noted]

Guess you like

Origin www.cnblogs.com/lionlion/p/11297108.html