반응형

 

 

 

 

유니티 엔진의 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) 값을 곱해서 사용해준다.

 

 

 

결과

 

 

 

 

 

 

반응형
반응형

 

 

 

 

 비주얼 스튜디오에서 프로젝트를 유니티에 연결해서 디버깅하다 어느날 유니티 디버깅 관련 경고가 떴다. 비주얼 스튜디오 상단 툴박스에 Unity에 연결 버튼으로 편하게 하고있었는데 해당 경고가 뜨는 순간부터 빌드 버튼으로 변경되었다. 그래도 상단 메뉴에서 디버그 카테고리에 유니티 디버깅 연결은 가능했지만 역체감이라고 그냥 버튼하나만 누르면 바로 연결 됐던데 프로젝트 연결창에서 일일이 선택하는 과정을 거쳐야하다보니 번거로워서 해결해보기로 했다.

 

 

 

 

에러 내용

- 이 Unity 프로젝트는 Visual Studio Tools for Unity용으로 생성되지 않았습니다. 향상된 환경을 이용하려면 Unity 편집기에서 [기본설정] > [외부도구]로 이동하고 Visual Studio를 선택하세요.

 

 

 

 

해결 방법

시도 1. 유니티 에셋 및 비주얼 스튜디오 업데이트

  • 유니티 에디터에서 Window-Package Manager-Visual studio Editor

 

  • 비주얼 스튜디오에서 도움말-업데이트 확인

 

시도 2. 스크립트로 프로젝트를 열지 말고 에디터에서 프로젝트 열기

  • 비주얼 스튜디오 프로젝트를 닫고 유니티 에디터에서 Assets-Open C# Project으로 비주얼 스튜디오를 열어주면 연결이 자동적으로 된다.

 

 

 

결과

- 위 순서대로 수행해서 해결했기 때문에 업데이트 → 에디터에서 비주얼 스튜디오 열기 순으로 작성되었지만, 시도2부터 한다음 해결이 안되면 시도1로 넘어가도 될듯하다.

 

 

 

 

기타 (Microsoft Docs)

 

Quickstart: Install & configure Visual Studio Tools for Unity

Learn how to connect Unity and Visual Studio for cross-platform development.

docs.microsoft.com

 

 

 

 

 

반응형
반응형

 

 

 

 

SafeArea

- 해상도가 세로로 길어지면서 생겨난 개념이다.

- 초창기에는 iPhone의 노치라는 변태 해상도(?)를 출발로 현재는 안드로이드도 펀치홀 디스플레이가 적용되서 이런 비정상적인 화면에 맞춰 UI를 정상적으로 보이게 배치해줘야한다.

- 안드로이드같은 경우 유니티 내장 기능에서 펀치홀 라인을 레터박스로 날리는 옵션지 주어져있다. (하지만 이 포스팅에서 이 옵션을 사용하지 않는다.)

 

 

 

Screen.safeArea

- 단어 뜻 그대로 화면의 안전 영역의 픽셀 단위를 반환한다.

- 기기 해상도 값과 SafeArea 해상도 값을 계산해서 UI의 anchor의 위치값을 계산해서 UI Rect의 새로운 값을 만들어낸다.

 

 

 

Hierachy 세팅

- Canvas 자식으로 빈 UI 게임오브젝트를 넣어주고 자식으로 넣은 게임오브젝트의 RectTransform AnchorPreset을 화면 전체로 세팅해준다.

- 다른 UI 요소는 위에 자식으로 넣은 게임오브젝트의 자식으로 넣어주면 된다.

- 다음 코드로 스크립트를 생성해 Safe Area를 적용할 게임오브젝트에 붙여준다.

 

 

 

코드

using UnityEngine;

public class SafeArea : MonoBehaviour
{
    private void Awake()
    {
        ApplySafeArea();
    }

    private void ApplySafeArea()
    {
        Rect safeAreaRect = Screen.safeArea;
        Vector2 anchorMin = safeAreaRect.position;
        Vector2 anchorMax = safeAreaRect.position + safeAreaRect.size;

        //Calculate anchorMin
        anchorMin.x /= Screen.width;
        anchorMin.y /= Screen.height;

        //Calculate anchorMax
        anchorMax.x /= Screen.width;
        anchorMax.y /= Screen.height;

        var rectTr = GetComponent<RectTransform>();
        //Apply anchor
        rectTr.anchorMin = anchorMin;
        rectTr.anchorMax = anchorMax;

        rectTr.offsetMin = Vector2.zero;
        rectTr.offsetMax = Vector2.zero;
    }
}
  • 먼저 anchor의 Min, Max 값을 구한다음, offset을 각각 0으로 지정해주면 화면(Rect)이 SafeArea에 맞춰진다.
  • Screen.safeArea.position의 값을 포함시키는 이유는 iPhone의 경우 Safe Area가 화면 밑부분을 더 띄워주므로 다른 위치값이 나온다.
  • Screen.safeArea 실제 기기에서만 SafeArea에 맞는 값을 반환하기 때문에 에디터에서는 SafeArea가 적용 안되서 보이는게 정상이다.

 

 

 

결과 확인 (Safe Area 스크립트 적용 차이, 유니티 내장 Safe Area 적용)

 

 

 

 

 

반응형
반응형

 

 

 

 

유니티 이벤트 함수

- 유니티는 미리 정의된 순서대로 실행되는 이벤트 함수들이 존재한다.

- 종류와 실행 순서(Life cycle)는 다음 페이지 참조

 

이벤트 함수의 실행 순서 - Unity 매뉴얼

Unity 스크립트를 실행하면 사전에 지정한 순서대로 여러 개의 이벤트 함수가 실행됩니다. 이 페이지에서는 이러한 이벤트 함수를 소개하고 실행 시퀀스에 어떻게 포함되는지 설명합니다.

docs.unity3d.com

 

 

 

 

Awake(), Start(), OnEnable()

- Awake

  • Scene이 로드될 때 스크립트가 포함된 게임오브젝트가 초기화되거나 비활성화된 게임오브젝트가 활성화 될 때, Instantiate로 생성된 게임 오브젝트가 초기화 된 후에 호출된다.
  • 스크립트가 비활성화 되어있을때도 호출이 되며, 게임 오브젝트가 초기화된 후, 단 한번 호출된다.
  • 모든 게임오브젝트가 초기화된 후 호출되기 때문에 Find와 같은 함수를 사용하여 안전하게 쿼리할 수 있다.
  • 멤버를 초기화할 때 사용된다.
  • 호출하는 순서가 정해져있지 않기 때문에 스크립트들 사이에서 Awake전이나 후에 호출되는것에 의존해서는 안된다.

- OnEnable

  • 게임오브젝트 또는 스크립트가 활성화될 때마다 호출된다. (1회성이 아님)
  • 이벤트 연결시 사용된다.

- Start

  • Update가 호출되기 전에 호출되는 함수이다.
  • Awake와 마찬가지로 단 한번 호출된다.
  • Awake와 달리 스크립트가 비활성화 되어있을때 호출이 되지 않아서 비활성화 된 스크립트에서는 Awake와 동일한 프레임에 호출되지 않을수도 있다.
  • 한 객체가 다른 객체에 의존하는 경우에 유용하게 사용할 수 있는 함수이다. (의존하는 객체 초기화는 Start에서 의존되는 객체 초기화는 Awake에서하게되면 안정성이 높아진다.)
  • 해당 함수는 코루틴으로 정의가 가능해서 yield문으로 흐름제어가 가능하다.

 

 

 

Update(), FixedUpdate(), LateUpdate()

- Update

  • 스크립트가 활성화 되어있을 때, 매 프레임마다 호출된다.
  • 게임의 핵심 로직을 작성한다.

- FixedUpdate

  • 물리 시스템 주파수에 따라 일정한 주기로 호출된다. (기본설정 기준 0.02초마다 호출됨.)
  • 프레임 속도에따라 Update보다 더 많이 호출될 수도 있고 적게 호출될 수도 있다.
  • 프레임 속도와 독립적으로 다른 타이머에서 호출되기 때문에 Time.deltaTime을 곱할 필요가 없다.

- LateUpdate

  • Update가 호출된 후 프레임마다 한 번씩 호출된다.
  • 일반적으로 Update에서 플레이어를 움직이는 계산을 하고, LateUpdate에서 카메라의 계산을 수행하기 위해 사용한다.

 

 

 

 

반응형
반응형

 

 

 

 

에러 현상

- 스킨정보가 있는 SkeletonDataAsset을 교체한 뒤, 스킨 설정 방법에 따라 Material 정보가 없어지는 현상이 있다.

- Skeleton 정보는 정상적으로 적용되고 텍스쳐만 없는 상태로 보여진다.

- 해당 현상은 SkeletonAnimation 컴포넌트에서만 일어나며, SkeletonGraphic 컴포넌트에서는 이상이 없다.

 

 

 

코드

using Spine.Unity;

SkeletonAnimationClass.skeletonDataAsset = SomeSkeletonDataAsset;
SkeletonAnimationClass.Initialize(true);

//필드 값을 변경하면 MeshRenderer의 Material이 로드되지 않음.
SkeletonAnimationClass.initialSkinName = "skin name";
//SetSkin(str) 함수로 스킨을 변경하면 Material이 정상적으로 로드 됨.
SkeletonAnimationClass.skeleton.SetSkin("skin name";);
  • SkeletonGraphic 컴포넌트는 InitialSkinName 필드값을 변경해도 정상적으로 작동한다.

 

 

 

 

 

반응형

+ Recent posts