Search Unity

Rotating field of view with Joystick - 2D

Discussion in '2D' started by Algozx, Apr 1, 2021.

  1. Algozx

    Algozx

    Joined:
    Sep 25, 2020
    Posts:
    1
    Hello everyone, everything good? This is my first post here on the Unity forum and it is also my first big problem which I was unable to solve. Well, I've been learning Unity and C # for a few months now and I'm working on a 2D Zombie project with stealth and a dark environment.

    I needed to create a field of view for the main character, so I found Sebastian Lague's tutorial, which helped me a lot with the field of view and understanding this system.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class FieldOfView : MonoBehaviour {
    6.  
    7.     public float viewRadius;
    8.     [Range(0, 360)]
    9.     public float viewAngle;
    10.  
    11.     public LayerMask targetMask;
    12.     public LayerMask obstacleMask;
    13.  
    14.     [HideInInspector]
    15.     public List<Transform> visibleTargets = new List<Transform>();
    16.  
    17.     void Start() {
    18.         StartCoroutine("FindTargetWithDelay", 0.2f);
    19.     }
    20.  
    21.     IEnumerator FindTargetWithDelay(float delay) {
    22.         while (true) {
    23.             yield return new WaitForSeconds(delay);
    24.             FindVisibleTargets();
    25.         }
    26.     }
    27.    
    28.     //Finds targets inside field of view not blocked by walls
    29.     void FindVisibleTargets() {
    30.         visibleTargets.Clear();
    31.         //Adds targets in view radius to an array
    32.         Collider2D[] targetsInViewRadius = Physics2D.OverlapCircleAll(transform.position, viewRadius, targetMask);
    33.         //For every targetsInViewRadius it checks if they are inside the field of view
    34.         for (int i = 0; i < targetsInViewRadius.Length; i++) {
    35.             Transform target = targetsInViewRadius[i].transform;
    36.             Vector3 dirToTarget = (target.position - transform.position).normalized;
    37.             if (Vector3.Angle(transform.up, dirToTarget) < viewAngle / 2) {
    38.                 float dstToTarget = Vector3.Distance(transform.position, target.position);
    39.                 //If line draw from object to target is not interrupted by wall, add target to list of visible
    40.                 //targets
    41.                 if (!Physics2D.Raycast(transform.position, dirToTarget, dstToTarget, obstacleMask)) {
    42.                     visibleTargets.Add(target);
    43.                 }
    44.             }
    45.         }
    46.     }
    47.  
    48.  
    49.     public Vector3 DirFromAngle(float angleInDegrees, bool angleIsGlobal) {
    50.         if (!angleIsGlobal) {
    51.             angleInDegrees -= transform.eulerAngles.z;
    52.         }
    53.         return new Vector3(Mathf.Sin(angleInDegrees * Mathf.Deg2Rad), Mathf.Cos(angleInDegrees * Mathf.Deg2Rad), 0);
    54.     }
    55. }
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEditor;
    4.  
    5. [CustomEditor (typeof (FieldOfView))]
    6. public class FieldOfViewEditor : Editor {
    7.  
    8.     void OnSceneGUI() {
    9.         FieldOfView fow = (FieldOfView)target;
    10.  
    11.         //Draws view reach
    12.         Handles.color = Color.black;
    13.         Handles.DrawWireArc(fow.transform.position, Vector3.forward, Vector3.up, 360, fow.viewRadius);
    14.  
    15.         //Draws cone of view
    16.         Vector3 viewAngleA = fow.DirFromAngle(-fow.viewAngle / 2, false);
    17.         Vector3 viewAngleB = fow.DirFromAngle(fow.viewAngle / 2, false);
    18.         Handles.DrawLine(fow.transform.position, fow.transform.position + viewAngleA * fow.viewRadius);
    19.         Handles.DrawLine(fow.transform.position, fow.transform.position + viewAngleB * fow.viewRadius);
    20.     }
    21. }
    And since the game is made for mobile, I'm using a virtual joystick. One joystick to move the character horizontally and vertically, and the other to rotate the weapon.

    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4. using UnityEngine.EventSystems;
    5.  
    6. [RequireComponent(typeof(RectTransform))]
    7. public class EasyJoystick : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
    8. {
    9.     public RectTransform stick;                        //stick image;
    10.     public float returnRate = 15.0F;                //default position returning speed;
    11.     public float dragRadius = 65.0f;                //drag radius;
    12.     public AlphaControll colorAlpha;
    13.    
    14.     public event Action<EasyJoystick, Vector2> OnStartJoystickMovement;
    15.     public event Action<EasyJoystick, Vector2> OnJoystickMovement;
    16.     public event Action<EasyJoystick> OnEndJoystickMovement;
    17.    
    18.     private bool _returnHandle, pressed, isEnabled = true;
    19.     private RectTransform _canvas;
    20.     private Vector3 globalStickPos;
    21.     private Vector2 stickOffset;
    22.     private CanvasGroup canvasGroup;
    23.    
    24.     public Vector2 Coordinates
    25.     {
    26.         get
    27.         {
    28.             if (stick.anchoredPosition.magnitude < dragRadius)
    29.                 return stick.anchoredPosition / dragRadius;
    30.             return stick.anchoredPosition.normalized;
    31.         }
    32.     }
    33.    
    34.     void IPointerDownHandler.OnPointerDown(PointerEventData eventData)
    35.     {
    36.         pressed = true;
    37.         _returnHandle = false;
    38.         stickOffset = GetJoystickOffset(eventData);
    39.         stick.anchoredPosition = stickOffset;
    40.         if (OnStartJoystickMovement != null)
    41.             OnStartJoystickMovement(this, Coordinates);
    42.     }
    43.    
    44.     void IDragHandler.OnDrag(PointerEventData eventData)
    45.     {
    46.         stickOffset = GetJoystickOffset(eventData);
    47.         stick.anchoredPosition = stickOffset;
    48.         if (OnJoystickMovement != null)
    49.             OnJoystickMovement(this, Coordinates);
    50.     }
    51.    
    52.     void IPointerUpHandler.OnPointerUp(PointerEventData eventData)
    53.     {
    54.         pressed = false;
    55.         _returnHandle = true;
    56.         if (OnEndJoystickMovement != null)
    57.             OnEndJoystickMovement(this);
    58.     }
    59.    
    60.     private Vector2 GetJoystickOffset(PointerEventData eventData)
    61.     {
    62.         if (RectTransformUtility.ScreenPointToWorldPointInRectangle(_canvas, eventData.position, eventData.pressEventCamera, out globalStickPos))
    63.             stick.position = globalStickPos;
    64.         var handleOffset = stick.anchoredPosition;
    65.         if (handleOffset.magnitude > dragRadius)
    66.         {
    67.             handleOffset = handleOffset.normalized * dragRadius;
    68.             stick.anchoredPosition = handleOffset;
    69.         }
    70.         return handleOffset;
    71.     }
    72.    
    73.     private void Start()
    74.     {
    75.         canvasGroup = GetComponent ("CanvasGroup") as CanvasGroup;
    76.         _returnHandle = true;
    77.         var touchZone = GetComponent("RectTransform") as RectTransform;
    78.         touchZone.pivot = Vector2.one * 0.5F;
    79.         stick.transform.SetParent(transform);
    80.         var curTransform = transform;
    81.         do
    82.         {
    83.             if (curTransform.GetComponent<Canvas>() != null)
    84.             {
    85.                 _canvas = curTransform.GetComponent("RectTransform") as RectTransform;;
    86.                 break;
    87.             }
    88.             curTransform = transform.parent;
    89.         }
    90.         while (curTransform != null);
    91.     }
    92.    
    93.     private void FixedUpdate()
    94.     {
    95.         if (_returnHandle)
    96.             if (stick.anchoredPosition.magnitude > Mathf.Epsilon)
    97.                 stick.anchoredPosition -= new Vector2(stick.anchoredPosition.x * returnRate,
    98.                                                       stick.anchoredPosition.y * returnRate) * Time.deltaTime;
    99.         else
    100.             _returnHandle = false;
    101.  
    102.         switch(isEnabled)
    103.         {
    104.         case true:
    105.             canvasGroup.alpha = pressed ? colorAlpha.pressedAlpha : colorAlpha.idleAlpha;
    106.             canvasGroup.interactable = canvasGroup.blocksRaycasts = true;
    107.             break;
    108.         case false:
    109.             canvasGroup.alpha = 0;
    110.             canvasGroup.interactable = canvasGroup.blocksRaycasts = false;
    111.             break;
    112.         }
    113.     }
    114.  
    115.  
    116.     public Vector2 MoveInput()
    117.     {
    118.         return new Vector2 (Coordinates.x, Coordinates.y);
    119.     }
    120.  
    121.     public void Rotate(Transform transformToRotate, float speed)
    122.     {
    123.         if(Coordinates != Vector2.zero)
    124.             transformToRotate.rotation = Quaternion.Slerp (transformToRotate.rotation,
    125.                                                           Quaternion.LookRotation (new Vector2 (Coordinates.x, Coordinates.y)),
    126.                                                           speed * Time.deltaTime);
    127.     }
    128.  
    129.     public bool IsPressed()
    130.     {
    131.         return pressed;
    132.     }
    133.  
    134.     public void Enable(bool enable)
    135.     {
    136.         isEnabled = enable;
    137.     }
    138. }
    139.  
    140.  
    141. [Serializable]
    142. public class AlphaControll
    143. {
    144.     public float idleAlpha = 0.5F, pressedAlpha = 1.0F;
    145. }


    The idea was to use the field of view with the rotation of the right joystick, but I was unable to make it work in any way, I have already changed several parts of the code and I always find myself in the problem of not being able to rotate the Z axis by the joystick.

    If you guys can help me in any way I really appreciate it, or if need more information,
    I will be available !