반응형

 

 

 

 

유니티 엔진의 Input 클래스에는 touch라는 구조체가 존재한다. 이 touch라는 구조체의 정보를 바탕으로 모바일 환경에서의 제스처기능을 적용해 카메라를 이동하거나 줌 인/아웃 기능을 구현할 수 있다.

 

 

카메라 이동

using UnityEngine

enum GESTURE
{
    MOVE = 1,
    ZOOM,
}

private void MoveCam()
{
    if (Input.touchCount == (int)GESTURE.MOVE)
    {
        Touch touch = Input.touches[0];
        Camera.main.transform.position = new Vector3(
            Camera.main.transform.position.x - touch.deltaPosition.x,
            Camera.main.transform.position.y - touch.deltaPosition.y,
            Camera.main.transform.position.z);
    }
}
  • Touch 구조체에는 deltaPosition이 존재하는데 이전 프레임과 현재 프레임 사이의 움직인 벡터 값을 받을 수 있다.
  • 이 벡터 값을 이용해서 카메라의 위치를 변경해주면 된다.
  • deltaPosition을 바로 적용해주면 카메라가 엄청 빠르게 움직이니 해당 값에 speed(float) 값을 곱해서 적용해준다.
  • 간단하게 보여주기 위해 작성된 코드로, Camera.main의 카메라 클래스는 캐싱해서 사용하는게 최적화에 도움이 된다.

 

 

 

카메라 줌 인/아웃

private void ZoomCam()
{
    if (Input.touchCount == (int)TOUCH.ZOOM)
    {
        Touch touch_1 = Input.touches[0];
        Touch touch_2 = Input.touches[1];

        //이전 프레임의 터치 좌표를 구한다.
        Vector2 t1PrevPos = touch_1.position - touch_1.deltaPosition;
        Vector2 t2PrevPos = touch_2.position - touch_2.deltaPosition;

        //이전 프레임과 현재 프레임 움직임 크기를 구함.
        float prevDeltaMag = (t1PrevPos - t2PrevPos).magnitude;
        float deltaMag = (touch_1.position - touch_2.position).magnitude;

        //두 크기값의 차를 구해 줌 인/아웃의 크기값을 구한다.
        float deltaMagDiff = prevDeltaMag - deltaMag;

        Camera.main.orthographicSize += deltaMagDiff;
        Camera.main.orthographicSize = Mathf.Clamp(Camera.main.orthographicSize, 7, 30);
    }
}
  • 줌 기능은 카메라 이동 코드와는 다르게 조금 복잡한데, 결론적으로 이전 프레임과 현제 프레임의 두 터치 사이의 벡터 크기(Maginitude) 값을 이용해서 deltaMagnitude 값을 구한다.
  • 이렇게 구해진 deltaMagnitude 값을 Camera의 orthographicSize에 더해주면 줌 인/아웃 기능 구현이 가능하다.
  • orthographicSize가 너무 작아져서 음수로 내려가면 화면이 뒤집어져 보이므로 Mathf.Clamp로 적절하게 최소, 최대값을 고정해준다.
  • deltaMagnitude 값을 바로 적용하면 줌이 빠르게 적용되니 해당 값에 speed(float) 값을 곱해서 사용해준다.

 

 

 

결과

 

 

 

 

 

 

반응형
반응형

 

 

 유니티는 기본적으로 Handheld.Vibrate() 함수로 진동기능이 들어가있지만. 해당 함수로 실행되는 진동은 약 1초가량으로 생각보다 진동이 길다. (진동 시간 조절이 불가능)

 

게임을 제작하다보면 1초의 긴 진동보다 짧은 진동이 필요할때가 생각보다 많다. 따라서, 짧은 진동을 필요로 할때 Handheld.Vibrate()는 완전히 무쓸모다.

 

안드로이드의 경우 AndroidManifest권한 추가에 코드 몇줄만 넣어주면 되지만, 이놈의 iOS는 뭐가 이리 복잡한지.. 아이폰 유저도 아니라 방법 찾는데 생각보다 많이 헤맸다.

 

iOS의 경우 햅틱이라는 기능이 있는데, 6S모델부터 들어가있다고 한다.

 

UISelectionFeedbackGenerator을 통해 햅틱 기능을 사용할수 있는것 같은데, 개발하는 게임들의 최소 버전이 아이폰5 부터라 최대한 낮은 모델에서도 진동 사용이 가능해야했기에 AudioServicesPlaySystemSound를 사용하기로 했다.

 

AudioServicesPlaySystemSound를 사용하기 위해 일단 에디터에 Plugins/iOS 폴더에 Vibrate.mm파일을 만들어준다. 그리고 이어서 플러그인 파일에 코드 작성.

 

#import <UIKit/UIKit.h>
#import <AudioToolBox/AudioToolBox.h>

extern "C" void Vibrate(int _n)
{
    AudioServicesPlaySystemSound(_n);
}

 

그리고 이어서 스크립트를 생성 후, 다음과 같이 작성 후 사용하면 된다.

 

using System.Runtime.InteropServices;

[DllImport("__Internal")]
public static extern void Vibrate(int _n);

※ 참고로 플러그인 파일명과 함수명은 입맛대로 바꿔도 상관없다.

 

인수에 들어가는 int값은 밑에 값들 중 입맛대로 선택해서 넣으면 된다.

 

1519 // Actuate `Peek` feedback (weak boom)

1520 // Actuate `Pop` feedback (strong boom)

1521 // Actuate `Nope` feedback (series of three weak booms)

 

실행해보니 잘 된다. (물론 잘 되는건 6S부터다. 그 밑의 폰들은 당연히 안된다.)

 

 

반응형

+ Recent posts