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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Question Customize mobile touchzone script (from starter assets)

Discussion in 'Scripting' started by SiMULOiD, Nov 13, 2022.

  1. SiMULOiD

    SiMULOiD

    Joined:
    Dec 23, 2013
    Posts:
    121
    Hi all,
    I'm trying to adapt the below script (mobile virtual controls from the Starter Assets) to work more like a swipe than a joystick. Currently, the camera keeps rotating, even when the touch has come to a stop and user is still touching the screen. Essentially, the current controls works more like a joystick, but I’m trying to customize it for the camera to move more like a touchzone- think Minecraft / GTA etc.


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.EventSystems;
    5. using UnityEngine.Events;
    6.  
    7. public class UIVirtualTouchZone : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
    8. {
    9.  
    10.     [Header("Rect References")]
    11.     public RectTransform containerRect;
    12.     public RectTransform handleRect;
    13.  
    14.     [Header("Settings")]
    15.     public bool clampToMagnitude;
    16.     public float magnitudeMultiplier = 1f;
    17.     public bool invertXOutputValue;
    18.     public bool invertYOutputValue;
    19.  
    20.     //Stored Pointer Values
    21.     private Vector2 pointerDownPosition;
    22.     private Vector2 currentPointerPosition;
    23.  
    24.     [Header("Output")]
    25.     public UnityEvent<Vector2> touchZoneOutputEvent;
    26.  
    27.     void Start()
    28.     {
    29.         SetupHandle();
    30.     }
    31.  
    32.     private void SetupHandle()
    33.     {
    34.         if(handleRect)
    35.         {
    36.             SetObjectActiveState(handleRect.gameObject, false);
    37.         }
    38.     }
    39.  
    40.     public void OnPointerDown(PointerEventData eventData)
    41.     {
    42.  
    43.         RectTransformUtility.ScreenPointToLocalPointInRectangle(containerRect, eventData.position, eventData.pressEventCamera, out pointerDownPosition);
    44.  
    45.         if(handleRect)
    46.         {
    47.             SetObjectActiveState(handleRect.gameObject, true);
    48.             UpdateHandleRectPosition(pointerDownPosition);
    49.         }
    50.     }
    51.  
    52.     public void OnDrag(PointerEventData eventData)
    53.     {
    54.  
    55.         RectTransformUtility.ScreenPointToLocalPointInRectangle(containerRect, eventData.position, eventData.pressEventCamera, out currentPointerPosition);
    56.  
    57.         Vector2 positionDelta = GetDeltaBetweenPositions(pointerDownPosition, currentPointerPosition);
    58.  
    59.         Vector2 clampedPosition = ClampValuesToMagnitude(positionDelta);
    60.  
    61.         Vector2 outputPosition = ApplyInversionFilter(clampedPosition);
    62.  
    63.         OutputPointerEventValue(outputPosition * magnitudeMultiplier);
    64.     }
    65.  
    66.     public void OnPointerUp(PointerEventData eventData)
    67.     {
    68.         pointerDownPosition = Vector2.zero;
    69.         currentPointerPosition = Vector2.zero;
    70.  
    71.         OutputPointerEventValue(Vector2.zero);
    72.  
    73.         if(handleRect)
    74.         {
    75.             SetObjectActiveState(handleRect.gameObject, false);
    76.             UpdateHandleRectPosition(Vector2.zero);
    77.         }
    78.     }
    79.  
    80.     void OutputPointerEventValue(Vector2 pointerPosition)
    81.     {
    82.         touchZoneOutputEvent.Invoke(pointerPosition);
    83.     }
    84.  
    85.     void UpdateHandleRectPosition(Vector2 newPosition)
    86.     {
    87.         handleRect.anchoredPosition = newPosition;
    88.     }
    89.  
    90.     void SetObjectActiveState(GameObject targetObject, bool newState)
    91.     {
    92.         targetObject.SetActive(newState);
    93.     }
    94.  
    95.     Vector2 GetDeltaBetweenPositions(Vector2 firstPosition, Vector2 secondPosition)
    96.     {
    97.         return secondPosition - firstPosition;
    98.     }
    99.  
    100.     Vector2 ClampValuesToMagnitude(Vector2 position)
    101.     {
    102.         return Vector2.ClampMagnitude(position, 1);
    103.     }
    104.  
    105.     Vector2 ApplyInversionFilter(Vector2 position)
    106.     {
    107.         if(invertXOutputValue)
    108.         {
    109.             position.x = InvertValue(position.x);
    110.         }
    111.  
    112.         if(invertYOutputValue)
    113.         {
    114.             position.y = InvertValue(position.y);
    115.         }
    116.  
    117.         return position;
    118.     }
    119.  
    120.     float InvertValue(float value)
    121.     {
    122.         return -value;
    123.     }
    124.  
    125. }
     
    Last edited: Nov 13, 2022
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,947
    Making something work...

    ... is basically this:

    With a joystick, the difference between finger down point and finger now point is used as a continuous signal.

    EG touch at x = 10, then move and hold at x = 20 means +10 right continuously as long as you hold... go go go

    With a swipe zone, the difference is always between this frame and the previous frame.

    EG. touch at x = 10, move to 20, generate a single +10 (or a series of smalls +1s if the user does it slowly). But now that you are on 20, everything outputs as zero... if you go to 19 then it outputs a -1... if you then goto 22 it outputs +3, etc.

    You might be better off making a simple version of what I describe above in fresh code.

    If you want to hack up the above script it might be as simple as re-saving the
    pointerDownPosition
    with the
    currentPointerPosition
    , AFTER doing all the math to compute your output.
     
    SiMULOiD likes this.
  3. SiMULOiD

    SiMULOiD

    Joined:
    Dec 23, 2013
    Posts:
    121
    Thanks for the info / suggestion! I’m working on a new script and will post here if get it working.
     
  4. riosst100

    riosst100

    Joined:
    Aug 24, 2020
    Posts:
    1
    Hi sir,, sorry, are you already solved it? I want to doing same thing like that,,