Search Unity

Problem moving camera to the right direction in Unity, using parallax and MoveToward

Discussion in 'Cinemachine' started by cinnamonrollapplecider, Jun 28, 2022.

  1. cinnamonrollapplecider

    cinnamonrollapplecider

    Joined:
    Jul 6, 2017
    Posts:
    9
    I have a Cinemachine camera that needs to follow the player swiping left and right using the new input system. To my CM camera, I have attached the following components:

    • A script called Camera Swipe
    • A player input component, which maps to a default map called Swipe Map, in a Screen Controls asset
    • A script called Screen Input Manager
    The screen input manager code is below:

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. using UnityEngine.InputSystem;
    4.  
    5. [DefaultExecutionOrder(-1)]
    6.  
    7. public class ScreenInputManager : MonoBehaviourSingleton<ScreenInputManager>
    8. {
    9.     public GameObject player;
    10.  
    11.     #region
    12.     public delegate void StartTouch(Vector2 position, float time);
    13.     public event StartTouch OnStartTouch;
    14.     public delegate void EndTouch(Vector2 position, float time);
    15.     public event StartTouch OnEndTouch;
    16.     #endregion
    17.  
    18.     private ScreenControls screenControls;
    19.     private Camera mainCamera;
    20.  
    21.     private void Awake()
    22.     {
    23.         screenControls = new ScreenControls(); // new instance of input manager
    24.         screenControls.SwipeMap.Enable();
    25.         screenControls.Enable();
    26.         mainCamera = Camera.main;
    27.     }
    28.  
    29.     private void OnEnable()
    30.     {
    31.         screenControls.Enable();
    32.     }
    33.  
    34.     private void OnDisable()
    35.     {
    36.         screenControls.Disable();
    37.     }
    38.  
    39.     private void Start()
    40.     {
    41.         screenControls.SwipeMap.PrimaryContact.started += context => StartTouchPrimary(context);
    42.         screenControls.SwipeMap.PrimaryContact.canceled += context => EndTouchPrimary(context);
    43.     }
    44.  
    45.     private void StartTouchPrimary(InputAction.CallbackContext context)
    46.     {
    47.         if (OnStartTouch != null) OnStartTouch(Utils.ScreenToWorld(mainCamera, screenControls.SwipeMap.PrimaryPosition.ReadValue<Vector2>()), (float)context.startTime); // avoid using screen to world here, do it later
    48.     }
    49.  
    50.     private void EndTouchPrimary(InputAction.CallbackContext context)
    51.     {
    52.         if (OnEndTouch != null) OnEndTouch(Utils.ScreenToWorld(mainCamera, screenControls.SwipeMap.PrimaryPosition.ReadValue<Vector2>()), (float)context.time); // avoid using screen to world here, do it later
    53.     }
    54.  
    55.     public Vector2 PrimaryPosition()
    56.     {
    57.         return screenControls.SwipeMap.PrimaryPosition.ReadValue<Vector2>();
    58.     }
    59. }
    The Camera Swipe code is below:

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3. using Cinemachine;
    4.  
    5. [DefaultExecutionOrder(-1)]
    6.  
    7. public class CameraSwipe : MonoBehaviour
    8. {
    9.     [SerializeField] private float minimumDistance = 1f;
    10.     [SerializeField] private float maximumTime = 1f;
    11.     [SerializeField, Range(0f, 1f)] private float directionThreshhold = 0.9f;
    12.  
    13.     // private ScreenInputManager inputSystem;
    14.  
    15.     private Vector2 startPosition;
    16.     private float startTime;
    17.     private Vector2 endPosition;
    18.     private float endTime;
    19.     private Vector3 targetPosition;
    20.  
    21.     private ScreenInputManager inputProvider;
    22.     private CinemachineVirtualCamera virtualCamera;
    23.     private Rigidbody2D cameraRigid;
    24.     private Transform cameraTransform;
    25.  
    26.     private void Awake()
    27.     {
    28.         inputProvider = GetComponent<ScreenInputManager>();
    29.         virtualCamera = GetComponent<CinemachineVirtualCamera>();
    30.         cameraRigid = GetComponent<Rigidbody2D>();
    31.         cameraTransform = virtualCamera.VirtualCameraGameObject.transform;
    32.     }
    33.  
    34.     private void OnEnable()
    35.     {
    36.         inputProvider.OnStartTouch += SwipeStart;
    37.         inputProvider.OnEndTouch += SwipeEnd;
    38.     }
    39.  
    40.     private void OnDisable()
    41.     {
    42.         inputProvider.OnStartTouch -= SwipeStart;
    43.         inputProvider.OnEndTouch -= SwipeEnd;
    44.     }
    45.  
    46.     private void SwipeStart(Vector2 position, float time)
    47.     {
    48.         startPosition = position;
    49.         startTime = time;
    50.     }
    51.  
    52.  
    53.     private void SwipeEnd(Vector2 position, float time)
    54.     {
    55.         endPosition = position;
    56.         endTime = time;
    57.     }
    58.  
    59.     private void Update()
    60.     {
    61.         if (Vector3.Distance(startPosition, endPosition) >= minimumDistance && (endTime - startTime) <= maximumTime)
    62.         {
    63.             Debug.DrawLine(startPosition, endPosition, Color.red, 5f);
    64.             Vector3 direction = endPosition - startPosition; // halfway between start and end?
    65.  
    66.             targetPosition = cameraTransform.position;
    67.             targetPosition.x =  -direction.x;
    68.             Vector2 direction2D = new Vector2(direction.x, direction.y).normalized;
    69.             SwipeDirection(targetPosition, direction2D);
    70.         }
    71.     }
    72.  
    73.     private void SwipeDirection(Vector3 direction, Vector2 direction2D)
    74.     {
    75.         if (Vector2.Dot(Vector2.left, direction) > directionThreshhold)
    76.         {
    77.            
    78.             Debug.Log("left " + " the direction 2d is: " + direction2D);
    79.             cameraTransform.position = Vector3.MoveTowards(cameraTransform.position, direction, Time.deltaTime * (float) 3);
    80.  
    81.         }
    82.  
    83.         else if (Vector2.Dot(Vector2.right, direction) > directionThreshhold)
    84.         {
    85.             Debug.Log("right " + " the direction 2d is: " + direction2D);
    86.             cameraTransform.position = Vector3.MoveTowards(cameraTransform.position, direction, Time.deltaTime * (float) 3);
    87.         }
    88.     }
    89. }
    The problem - The issue is that it seems to detect a left swipe sometimes when I'm swiping right, and sometimes it seems to stall and not go past certain parts of the screen. It seems to not be picking apart left swipes from right ones easily.

    What I've tried: - I think it might be to do with calling SwipeDirection in Update(), when it really should just be called at the end of SwipeEnd(). But when I do that, then because it's not continually updated, the camera only moves a tiny bit and not fluidly at all.

    I've also tried to do a bunch of Debug.Logs. It seems to stall when the variable Direction2D (in the second code block) is equal to "0". Can someone help me fix this?
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    This isn't really Cinemachine-related. You might get more response on the general scripting forum.