레이블이 new input system인 게시물을 표시합니다. 모든 게시물 표시
레이블이 new input system인 게시물을 표시합니다. 모든 게시물 표시

2025년 1월 27일 월요일

Unity New Input System pinch zoom, 핀치 줌

Unity6가 되면서 기본적으로 new input system을 기본으로 포함해서 따로 추가 설치가 필요 없게 되었습니다.

android로 개발하다 보니 pinch zoom이 필요하게 되어서 여기저기 검색도 해봤는데 멀티 터치가 생각보다 디버깅이 힘들었습니다.

제가 작업한 코드를 공개합니다. 디버깅 코드를 풀어서 디버깅 해가면서 적절하게 값을 조절 해서 사용해야 합니다.

카메라의 아래값을 변경하는 코드인데 이 환경은 프로젝트 마다 다를 수 있으므로 해당 부분을 참고하는것보다 저기에 넘기는 값을 보시기 바랍니다.

_camera.orthographicSize

아래는 전체 코드입니다. 다음 feature 부분을 참고 하세요. USE_NEW_INPUT

using UnityEngine;
#if USE_NEW_INPUT
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.EnhancedTouch;
#endif

public class CameraFollow : MonoBehaviour
{
    public Transform player; // 플레이어의 Transform
    public float smoothSpeed = 0.125f; // 부드러운 이동 속도
    public Vector3 offset;         // 카메라와 플레이어 간의 거리

    public bool lockX = false;     // X축 고정 여부
    public bool lockY = false;     // Y축 고정 여부

    public bool useBounds = false; // 경계 제한 사용 여부
    public Vector2 minBounds;      // 카메라 이동 최소값 (X, Y)
    public Vector2 maxBounds;      // 카메라 이동 최대값 (X, Y)

    public Camera _camera;
    public int skipFrame = 1;
    private int curFrame;

    public bool useZoom = false;
    public float zoomSpeed = 1f;
    public float minSize = 2f;
    public float maxSize = 10f;
    void Start()
    {
        if( _camera ==null ){
            _camera = Camera.main;
        }
       
    }
    private void OnEnable() {
        #if USE_NEW_INPUT
        UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.Enable();
        #endif
    }
    private void OnDisable() {
        #if USE_NEW_INPUT
        UnityEngine.InputSystem.EnhancedTouch.EnhancedTouchSupport.Disable();
        #endif
    }
    void LateUpdate()
    {
        if (player == null) return;
        //if (curFrame < skipFrame)
        //{
        //    curFrame++;
        //    return;
        //}
        //curFrame = 0;

        // 목표 위치 계산
        Vector3 targetPosition = new Vector3(
            lockX ? transform.position.x : player.position.x + offset.x, // X축 고정 여부 확인
            lockY ? transform.position.y : player.position.y + offset.y, // Y축 고정 여부 확인
            transform.position.z // Z축은 고정
        );

        // 부드럽게 이동
        Vector3 smoothedPosition = Vector3.Lerp(transform.position, targetPosition, smoothSpeed);

        // 경계 제한 적용
        if (useBounds)
        {
            smoothedPosition.x = Mathf.Clamp(smoothedPosition.x, minBounds.x, maxBounds.x);
            smoothedPosition.y = Mathf.Clamp(smoothedPosition.y, minBounds.y, maxBounds.y);
        }

        // 새로운 위치 적용
        transform.position = smoothedPosition;

        if(useZoom){
            float scrollInput = 0;
            #if USE_NEW_INPUT
                Vector2 scrollInputV2 = Mouse.current.scroll.ReadValue();
                scrollInput = scrollInputV2.y;
            #else
                scrollInput = Input.GetAxis("Mouse ScrollWheel");
            #endif


            if (scrollInput != 0)
            {
                _camera.orthographicSize -= scrollInput * zoomSpeed;
                Debug.Log("scrollInput: " + scrollInput);
                _camera.orthographicSize = Mathf.Clamp(_camera.orthographicSize, minSize, maxSize);
            }
            #if USE_NEW_INPUT
                if( UnityEngine.InputSystem.EnhancedTouch.Touch.activeTouches.Count == 2 ){
                    UnityEngine.InputSystem.EnhancedTouch.Touch touch1 = UnityEngine.InputSystem.EnhancedTouch.Touch.activeTouches[0];
                    UnityEngine.InputSystem.EnhancedTouch.Touch touch2 = UnityEngine.InputSystem.EnhancedTouch.Touch.activeTouches[1];
                    Vector2 touch1PrevPos = touch1.screenPosition - touch1.delta;
                    Vector2 touch2PrevPos = touch2.screenPosition - touch2.delta;

                    float prevTouchDelta = (touch1PrevPos - touch2PrevPos).magnitude; // 이전 프레임에서의 거리
                    float currentTouchDelta = (touch1.screenPosition - touch2.screenPosition).magnitude; // 현재 프레임에서의 거리

                    float deltaMagnitudeDiff = prevTouchDelta - currentTouchDelta;
                    //Debug.Log("scrollInput1: " + deltaMagnitudeDiff);
                    deltaMagnitudeDiff = Mathf.Clamp(deltaMagnitudeDiff, -0.5f, 0.5f);
                    //Debug.Log("scrollInput2: " + deltaMagnitudeDiff);
                    _camera.orthographicSize += deltaMagnitudeDiff * zoomSpeed;
                    _camera.orthographicSize = Mathf.Clamp(_camera.orthographicSize, minSize, maxSize);
                }
                if( UnityEngine.InputSystem.EnhancedTouch.Touch.activeTouches.Count >= 2 ){
                    GameManager.instance.isMultiTouch = true;
                }else{
                    GameManager.instance.isMultiTouch = false;
                }
            #else
                // 두 개의 터치 입력을 받았는지 확인
                if (Input.touchCount == 2)
                {
                    Touch touch1 = Input.GetTouch(0);
                    Touch touch2 = Input.GetTouch(1);

                    // 각 터치의 현재 및 이전 위치 간 거리 계산
                    Vector2 touch1PrevPos = touch1.position - touch1.deltaPosition;
                    Vector2 touch2PrevPos = touch2.position - touch2.deltaPosition;

                    float prevTouchDelta = (touch1PrevPos - touch2PrevPos).magnitude; // 이전 프레임에서의 거리
                    float currentTouchDelta = (touch1.position - touch2.position).magnitude; // 현재 프레임에서의 거리

                    float deltaMagnitudeDiff = prevTouchDelta - currentTouchDelta;
                    Debug.Log("scrollInput1: " + deltaMagnitudeDiff);
                    deltaMagnitudeDiff = Mathf.Clamp(deltaMagnitudeDiff, -0.5f, 0.5f);
                    Debug.Log("scrollInput2: " + deltaMagnitudeDiff);
                    _camera.orthographicSize += deltaMagnitudeDiff * zoomSpeed;
                    _camera.orthographicSize = Mathf.Clamp(_camera.orthographicSize, minSize, maxSize);
                }
            #endif
        }
    }
   
}