UI를 추가하면 Canvas가 자동으로 추가되는데 Canvas Scaler가 있어 기기에 따라 UI의 크기가 자동으로 변경된다.
우리는 이번에 해상도를 다음과 같이 바군다.
Canvas에 +UI>Legasy>Button을 추가
위치는 앵커를 이용 리퍼런스를 잡아준다.
Ctrl-D로 이미지를 복사
버튼에 넣어줌
버튼에 적용할 함수는 public으로 만들어야함.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARCore;
public class UIManager : MonoBehaviour
{
public ARFaceManager faceManager;
public void ToggleMask()
{
//faceManager컴포넌트에서 생성된 Face 오브젝트 순회
foreach(ARFace face in faceManager.trackables)
{
// 생성된 face 오브젝트 순회
if(face.trackingState == UnityEngine.XR.ARSubsystems.TrackingState.Tracking)
{
//face 오브젝트 상탤글 반대로 변경
face.gameObject.SetActive(!face.gameObject.activeSelf);
}
}
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
마스크 버튼을 선택하고
Inspector의 OnClick() +를 눌러 Object에 Script가 들어있는 Canvas를 끌어다 놔준다. (주의:UIManager Script를 끌어다 놔도 들어는 가는데 그럼 원하는 함수가 안보인다. 꼭 스크립트가 들어있는 객체를 끌어다 놔줘야 한다.)
그런다음 RuntimeOnly옆을 눌러 List UIManager>ToggleMask()를 선택한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARCore;
public class UI_Manager : MonoBehaviour
{
public ARFaceManager faceManager;
public void ToggleMask()
{
foreach(ARFace face in faceManager.trackables)
{
if (face.trackingState == UnityEngine.XR.ARSubsystems.TrackingState.Tracking)
{
// face오브젝트 상태를 반대로 변경
face.gameObject.SetActive(!face.gameObject.activeSelf);
}
}
}
// Start is called before the first frame update
void Start(){}
// Update is called once per frame
void Update(){ }
}
이제 UI_Manager Script안의 ToggleMask()를 버튼과 연결해야한다.
그런데 스크립트는 게임오브젝트와 연결이 안되기 때문에 스크립트를 일단 하라라키의 Cavnas아이콘위에 놓으면 자동으로 컴포넌트로 연결한다. 끌어다 놓으면 된다.
연결후 AR SEssion Origne을 끌어다 FaceManger와 연결해준다.
다음 버튼을 선택하고 OnClick() +를 누르고 Canvas를 끌어다 놓는다. ToggleMask()함수를 선택한다.
AR Session은 AR 앱에서의 생명주기를 담당,앱이 시작하면서부터 끝날 때까지의 라이프사이클을 관리 AR Session Origin은 AR 상에서 중심이 되는 역할
AR 세상에서의 원점으로 AR Session Origin의 자식 오브젝트인 AR Camera로 비춰지고 있는 화면이 사용자가 가지고 있는 AR 디바이스에서 비추는 화면이랑 똑같다고 보시면 됨 AR Default Point Cloud는 카메라를 통해 받아지는 영상에서 특징점들을 노란색 포인트로 표시 AR Default Plane은 Point Cloud에서 얻은 특징점들을 기반으로 평면을 찾는 컴포넌트 AR Default Face는 얼굴 인식에서 사용되는 컴포넌트
MainCamera오브젝트를 제거
이미 XR Origin/Camera Offset/MainCamera의 태그가MainCamera입니다.
AR Camera Manager
XRCameraSubsystem의 수명 주기를 관리
카메라 텍스처 및 조명 추정 정보를 사용할 수 있도록 하려면 장면의 카메라에 이들 중 하나를 추가 해야 합니다.
ARCameraBackground
카메라에 이 구성 요소를 추가하여 컬러 카메라의 텍스처를 배경에 복사합니다.
Ifyouareusingthe Universal Render Pipeline (version 7.0.0 orlater), youmustalsoaddtheARBackgroundRendererFeaturetothelist of renderfeaturesforthescriptablerenderer.
TrackedPoseDriver
TrackedPoseDriver구성 요소는 추적된 장치의 현재 포즈 값을 에 적용합니다.
TrackedPoseDriver는 XR HMD, 컨트롤러 및 리모컨을 포함한 여러 유형의 장치를 추적할 수 있습니다.
그냥 빌드 시도 하면 이렇게 됨
BuildFailedException: ARKit requires a Camera Usage Description (Player Settings > iOS > Other Settings > Camera Usage Description)
빌드후 실행해보기
ARDefaultPointCloud
영상정보를 분석해 특징점을 노란색 파티클로 화면에 출력 해주는 오브젝트
AR Point Cloud Manager
XR Origin 오브젝트에 AR Point Cloud Manager컴포넌트를 추가 합니다.
ARTrackedObjects의 관리자입니다. XRPointCloudSubsystem을 사용하여 물리적 환경에서 포인트 클라우드 데이터를 인식하고 추적합니다.
AR Default Point Cloud 를 프리팹으로 만들고 할당
빌드후 실행 해본다
AR Default Plane
영상정보를 분석해 평면 정보를 노란색 면과 검은색 선의 Mesh로 화면에 출력 하는 오브젝트 입니다.
프리팹으로 만들기
XROrigin 게임 오브젝트를 선택 하고 AR Plane Manager컴포넌트를 부착후 Plane Prefab에 할당 하고 Detect Mode를 Horizontal로 변경 한다
AR Session Origin > Object Manager Modeling의 값을 방금 만든 프리팹을 끌어다 연결해준다.
빌드앤런 해보고 터치하면 펭귄이 앞을 바로 보고 있다 그런데 지금은 터치할때 마다 펭귄이 계속 생기므로 하나만 생기게 해보겠다. ObjectManager CS를 열고 코드를 추가한다 .Instatiate()는 객체참조를 리턴하므로 이걸 저장했다고 null이면 생성하고 아니면 위치를 현재 Indicator로 움직여 보겠다.
//생성된 모델
GameObject placedObject;
void Update()
{
Touch touch = Input.GetTouch(0);
DetectGround();
if (touch.phase == TouchPhase.Began)
{
//만약 생성된 오브젝트가 없다면 모델링 생성및 placedObject변수에 할당
if(placedObject == null)
{ // 인디케이터 위치에 모델링 생성
placedObject = Instantiate(modeling, indicator.transform.position, indicator.transform.rotation);
} else
{
placedObject.transform.SetPositionAndRotation(indicator.transform.position, indicator.transform.rotation);
}
}
}
빌드런 해보면 이제는 하나만 생긴다. 터치하면 계속 중앙으로 이동한다.
이제는 터치하고 드래그 하면 좌우로 회전하게 만들어 보겠다.
스크립터 폴더에 우클릭하고 스크립트를 하나 만들고 이름을 Controller로 한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Controller : MonoBehaviour
{
Vector2 touchStartPos; //터치 시작 시점
float rotationSpeed = 0.1f; // 회전속도
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.touchCount == 1)
{ //인풋의 첫번째 데이터를 가져옴
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began)
{ //터치 시작점을 저장
touchStartPos = touch.position;
} else if (touch.phase == TouchPhase.Moved)
{
//현재 터치위치 - 시작 터치위치
Vector2 touchDelta = touch.position - touchStartPos;
float rotationY = touchDelta.x * rotationSpeed;
transform.Rotate(transform.up, rotationY, Space.World);
touchStartPos = touch.position;
}
}
}
}
이 스트립트는 펭귄을 돌리므로 펭귄 프리펜이 넣어준다 자의할점은 펭귄 프리펩의 자식에 넣어주어야 한다 안그러면 안움직인단다.
Assets폴더밑에 Scripts폴더를 만들고 Script를 만들고 이름을 바로 ObjectManager로 바군다. 클래스명 때문에 그렇다.
만들어진 스크립트를 쳐보면 VisualStudio가 열린다. 안열리면 Edit>Preference를 체크한다.
VisualStudio가 열리면 다음 네임스페이스를 추가한다.
using UnityEngine.XR.ARFoundation;
스크립트를 완성한다.이건 처음 앱리 로딩하면 인디케이터가 사라지게 해준다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
public class ObjectManager : MonoBehaviour
{
//변수선언
public GameObject indicator;
ARRaycastManager arManager;
// Start is called before the first frame update
void Start()
{
//AR Raycast Manager 컴포넌트를 가져옴
arManager = GetComponent<ARRaycastManager>();
//인디케이터 비활성화
indicator.SetActive(false);
}
// Update is called once per frame
void Update()
{
}
}
AR Session Origin을 선택하고 스크립트를 끌어다 추가하고 Indicator변수에 하이라키의 indicator를 끌어다 연결한다.
재생버튼을 누르면
Indicator가 사라진다. 다시 재생버튼을 눌러 멈춘면 나타난다. 플레이버튼이 켜진상태에서는 편집변경이 저장 안된다.
다음 스크립터를 추가하면 앱이 Plane을 생성하면 그 위에 인디케이터를 표시해준다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.ARFoundation;
public class ObjectManager : MonoBehaviour
{
//변수선언
public GameObject indicator;
ARRaycastManager arManager;
// Start is called before the first frame update
void Start()
{
//AR Raycast Manager 컴포넌트를 가져옴
arManager = GetComponent<ARRaycastManager>();
//인디케이터 비활성화
indicator.SetActive(false);
}
// Update is called once per frame
void Update()
{
DetectGround();
}
void DetectGround()
{
//스크린 중앙 지점을 찾음
Vector2 screenSize = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f);
List<ARRaycastHit> hitInfos = new List<ARRaycastHit>();
//만약 스크린 중앙에서 레이를 발사했을 때 평면이 있다면 인디케이터 활성화
if (arManager.Raycast(screenSize, hitInfos, UnityEngine.XR.ARSubsystems.TrackableType.Planes))
{
indicator.SetActive(true);
//인디케이터의 위치와 회전 값을 레이가 닿은 지점에 일치시킴
indicator.transform.position = hitInfos[0].pose.position;
indicator.transform.rotation = hitInfos[0].pose.rotation;
//위치를 위로 0.1m 옮림
indicator.transform.position += indicator.transform.up * 0.1f;
} else
{
indicator.SetActive(false);
}
}
}
빌드하기
실험을 위해 핸드폰에서 실행하기 위해서는 개발자모드 설정을 해야한다. 설정에서 빌드번호를 검색후 계속 누르면 개발자가 된다. 다시 개발자모드를 검색후 사용, USB디버기을 활성화 해준다.
File>Build Setting에 가서 Add Open Scenes를 클릭해서 현재 씬을 넣어준다 물론 Andrid 가 선택되어져있어야한다.
이후 아래 Build and Run을 누른다 파일명을 물어보면 Build폴더를 만들고 적당히 이름을 지정후 저장한다.
오래걸림
난 Build 는 되는데 Build and Run은 연결을 체크해봐라 문제없다면 드라이브 문제라는 헛소리가 나와서 드라이버를 깔아봤는