[무료특강,서울] VR 가상현실 기술 동향 및 VR 콘텐츠 제작 실습, 체험
가상현실
마그네틱 스위치를 이용해서 메뉴 선택이나 확인 버튼으로 이용할 수 있으나 마그네틱 스위치가 없을 경우 가장 기본적으로 적용할 수 있는 스위치 방법이 일정 시간동안 오브젝트를 바라 보았을 때, 오브젝트가 선택되는 방식을 기본적으로 이용할 수 있습니다.
따라서, 이번 강의에서는 일정 시간동안 오브젝트를 바라 보았을때 동작하는 기능을 만들어 보겠습니다.
이전 예제에서 이용한 BoxCtrl과 RayCast 개념을 그대로 사용하고, 여기에 타이머를 추가하여 응용할 수 있습니다.
하이어라키 창에서 오른쪽 클릭 -> 3D Object -> Sphere로 구를 추가합니다.
이 구에 BoxCtrl 스크립트를 그대로 추가합니다.
Tag는 Ball을 추가하여 설정합니다.
마그네틱 스위치 인식과 오브젝트 선택 기억나지 않으면 아래 링크를 참고 합니다.
http://vrschool.co.kr/bbs/board.php?bo_table=leture&wr_id=12
프리팹으로 만든 후 여러 개 적당한 위치에 배치 해 봅시다.
using UnityEngine;
using System.Collections;
public class TriggerTextCtrl : MonoBehaviour {
//결합할 텍스트 상수입니다.
private const string TEXT = "Count : ";
//접근 제어자를 public으로 하면 유니티 에디터에서 이 변수를 설정할 수 있습니다.
public Cardboard cardBoard;
//3DText의 글자는 TextMesh 컴포넌트에서 변경했기 때문에 TextMesh 컴포넌트를 가져와야 합니다.
private TextMesh textMesh;
//카운트 변수입니다.
private int count = 0;
//Update 메소드가 호출되기 전 단 한 번 호출 됩니다. 보통 변수들을 초기화 하는것을 여기에다 작성합니다.
private Vector3 screenCenter;
// 몇 초간 바라보는 것으로 설정할 것인지에 대한 변수입니다. 에디터에서 수정가능하도록 했습니다.
public float durTime = 3f;
// 쳐다보고 있는 오브젝트가 저장됩니다.
public GameObject recentObject;
// 쳐다보기 시작한 시간을 저장합니다.
private float startTime;
void Start()
{
//gameObject에는 본 컴포넌트가 추가된 게임 오브젝트가 들어가 있습니다. GetComponent<가져올 컴포넌트>(); 를 이용하면 컴포넌트를 가져올 수 있습니다.
textMesh = gameObject.GetComponent<TextMesh>();
screenCenter = new Vector3(Camera.main.pixelWidth / 2, Camera.main.pixelHeight / 2);
}
//매 프레임마다 호출되는 메소드 입니다. 여기서 게임 오브젝트의 변화를 설정합니다.
void Update()
{
Ray ray = Camera.main.ScreenPointToRay(screenCenter);
RaycastHit hit;
//레이저가 공을 맞췄는지에 대한 불리언 값입니다.
bool isRayHitBox = Physics.Raycast(ray, out hit, 500f) && hit.collider.gameObject.tag == "Ball";
if (isRayHitBox)
{
//최근 쳐다본 오브젝트가 비어있지 않고, 지금 레이저에 맞은 오브젝트와 같은지 여부를 불리언 값으로 저장합니다.
bool isRecentObjEqualsCollObj = recentObject != null && recentObject.gameObject.Equals(hit.collider.gameObject);
if (startTime + durTime < Time.time)
{
BoxCtrl ctrl = hit.collider.gameObject.GetComponent<BoxCtrl>();
ctrl.Select();
}
else
{
recentObject = hit.collider.gameObject;
startTime = Time.time;
}
}
else
{
recentObject = null;
}
//카드보드에서 Triggered Getter는 트리거가 발생했는지 알 수 있습니다.
if (cardBoard.Triggered)
{
//박스에 초점이고
if (Physics.Raycast(ray, out hit, 500f))
{
if (hit.collider.gameObject.tag == "Box")
{
BoxCtrl boxCtrl = hit.collider.gameObject.GetComponent<BoxCtrl>();
boxCtrl.Select();
//TextMesh 컴포넌트의 text를 변경합니다.
count++;
textMesh.text = TEXT + count.ToString();
}
}
}
}
}
TriggerTextCtrl 스크립트를 그대로 사용합니다.
위 처럼 코드를 추가 해 주세요.
추가 된 부분을 설명 하겠습니다.
// 몇 초간 바라보는 것으로 설정할 것인지에 대한 변수입니다. 에디터에서 수정가능하도록 했습니다.
public float durTime = 3f;
// 쳐다보고 있는 오브젝트가 저장됩니다.
public GameObject recentObject;
// 쳐다보기 시작한 시간을 저장합니다.
private float startTime;
bool isRayHitBox = Physics.Raycast(ray, out hit, 500f) && hit.collider.gameObject.tag == "Ball";
레이저가 공을 맞췄는지에 대한 불리언 값입니다.
bool isRecentObjEqualsCollObj = recentObject != null && recentObject.gameObject.Equals(hit.collider.gameObject);
최근 쳐다본 오브젝트가 비어있지 않고, 지금 레이저에 맞은 오브젝트와 같은지 여부를 불리언 값으로 저장합니다.
if (startTime + durTime < Time.time)
{
BoxCtrl ctrl = hit.collider.gameObject.GetComponent<BoxCtrl>();
ctrl.Select();
}
Time.time은 게임이 시작된 후 경과된 시간이 저장되어 있습니다.
보기 시작한 시간과 바라 볼 시간을 더한 값이 경과 시간보다 작아질 경우, 그러니까 durTime만큼 시간이 지나면
오브젝트에서 BoxCtrl 컴포넌트를 얻어 색을 변경합니다.
else
{
recentObject = hit.collider.gameObject;
startTime = Time.time;
}
최근 쳐다본 오브젝트가 비어있지 않고, 지금 레이저에 맞은 오브젝트가 같지 않다면 지금 쳐다보고 있는 오브젝트로 변경 해 주고, 시작 시간을 다시 초기화 합니다.
else
{
recentObject = null;
}
레이캐스트에 적중한 오브젝트가 없고, 적중했더라도 태그가 Ball이 아니라면 recentObject 는 null로 비워주어야 합니다.
구글 카드보드의 마그네틱 스위치?
https://developers.google.com/cardboard/
마그네틱 스위치는 스마트폰의 자기력 센서의 변화를 측정해 입력하는 방식 입니다.
테스트 해보기 위해 구글플레이에서 "마그네틱 센스"로 검색후 앱을 다운로드
https://play.google.com/store/apps/details?id=imoblife.androidsensorbox
앱을 실행 후 자석을 스마트폰에 가까이 가져가면 자기장 수치가 변화는 것을 보실 수 있습니다.
즉, 자석을 이용해서 간단한 VR(Virtual Reality) 가상공간 속에서의 콘트롤러로 이용할 수 있습니다.
간단하게 메뉴를 클릭하거나 게임에서 무기를 발사하는 등의 기능으로 사용 가능 합니다.
스위치 인식하는 예제를 만들어 보겠습니다.
CardboardMain오브젝트를 선택 하면 가장 오른쪽 Inspector창에 Cardboard 스크립트 컴포넌트가 추가되어 있는것을 알 수 있습니다.
마그네틱 스위치 입력은 Cardboard 스크립트에서 감지 하도록 되어 있습니다.
마그네틱 입력이 감지 되었는지 확인하기 위해 몇 번 입력이 감지되었는지 확인 할 텍스트를 배치 해 보겠습니다.
하이어라키 창 빈 공간에 오른쪽 클릭을 해서 -> 3D Object -> 3D Text를 선택 해 주시고 Inspector창의 Text Mesh 컴포넌트의 변수들을 위 이미지와 같이 설정 해 주세요.
카메라가 텍스트를 볼 수 있는 위치에 배치 합니다.
다음은 트리거를 감지해서 카운트 값을 증가시키는 스크립트를 작성해 보겠습니다.
우선 정리를 쉽게 하기 위해 Scripts 폴더를 만들어 주시고 Scripts 폴더 오른쪽 클릭 -> Create -> C# Script 를 선택 해 주세요.
스크립트 이름은 TriggerTextCtrl로 하겠습니다.
처음 스크립트를 생성 할 때 정해준 이름 대로 스크립트의 클래스 이름을 자동으로 생성 해 줍니다.
생성 후에 스크립트 이름을 변경 할 때엔 스크립트 안의 클래스 이름도 스크립트 이름으로 바꾸어 줘야 합니다.
위의 스크립트를 작성해 주세요
스크립트 해석하면 다음과 같습니다.
//MonoBehaviour 클래스를 상속 합니다. 유니티에서 오브젝트의 행동 양식을 결정하는 클래스 입니다.
public class TriggerTextCtrl : MonoBehaviour
{
//결합할 텍스트 상수입니다.
private const string TEXT = "TriggerCount : ";
//접근 제어자를 public으로 하면 유니티 에디터에서 이 변수를 설정할 수 있습니다.
public Cardboard cardBoard;
//3DText의 글자는 TextMesh 컴포넌트에서 변경했기 때문에 TextMesh 컴포넌트를 가져와야 합니다.
private TextMesh textMesh;
//카운트 변수입니다.
private int count = 0;
//Update 메소드가 호출되기 전 단 한 번 호출 됩니다. 보통 변수들을 초기화 하는것을 여기에다 작성합니다.
void Start()
{
//gameObject에는 본 컴포넌트가 추가된 게임 오브젝트가 들어가 있습니다. GetComponent<가져올 컴포넌트>(); 를 이용하면 컴포넌트를 가져올 수 있습니다.
textMesh = gameObject.GetComponent<TextMesh>();
}
//매 프레임마다 호출되는 메소드 입니다. 여기서 게임 오브젝트의 변화를 설정합니다.
void Update()
{
//카드보드에서 Triggered Getter는 트리거가 발생했는지 알 수 있습니다.
if (cardBoard.Triggered)
{
//TextMesh 컴포넌트의 text를 변경합니다.
count++;
textMesh.text = TEXT + count.ToString();
}
}
}
스크립트를 모두 작성 했으면 컴포넌트를 추가해야 합니다.
TriggerCount 오브젝트를 선택하여 Inspector 창의 아래에 Add Component로 Trigger Text Ctrl 스크립트를 추가해 줍니다.
Cardboard 스크립트 컴포넌트는 에디터에서 추가해 봅시다.
Trigger Text Ctrl 컴포넌트를 보면 에디터에서 설정 가능한 변수 목록이 보입니다.
하이어라키 창에서 Cardboard컴포넌트를 가지고 있는 CardboardMain을 마우스로 변수에 끌어다 놓으면
에디터에서 자동으로 CardboardMain이 가지고 있는 Cardboard 컴포넌트로 설정해 줍니다.
에디터에서 실행 한 후 터치를 해 보면 TriggerCount 값이 증가 하는 것을 볼 수 있습니다.
다음은 가운데 있는 오브젝트를 감지하는 기능을 추가 해 보겠습니다.
일단 하이어라키 창에서 3D Object -> Cube를 추가 해 보겠습니다.
그리고 저는 카메라 왼쪽에 큐브들을 배치 하였습니다.
큐브의 색깔을 바꾸는 스크립트를 작성해 보겠습니다.
Scripts 폴더 오른쪽 클릭 -> Create -> C# Script 를 선택 해 주세요.
스크립트 이름을 BoxCtrl 으로 만듭니다.
public class BoxCtrl : MonoBehaviour {
private MeshRenderer meshRenderer;
void Start () {
//메쉬는 월드에 배치된 오브젝트의 모양입니다.
meshRenderer = gameObject.GetComponent<MeshRenderer>();
}
void Update () {
}
public void Select()
{
//meshRenderer의 재질 (material)을 가져와 색깔을 파란색 (R = 0, G = 0 , B = 1)으로 변경합니다.
meshRenderer.material.color = new Color(0, 0, 1f);
}
}
다음은 쉽게 색이 바뀌는 박스인지 확인할 수 있게 해당 오브젝트의 태그를 설정하겠습니다.
Inspector창의 Tag옆의 드롭다운 메뉴에서 Add Tag...를 선택합니다.
그럼 태그를 설정하는 창으로 바뀌는데 여기서 +버튼을 눌러 Box 태그를 추가합니다.
그리고 SelectBox의 태그를 Box로 설정합니다.
박스를 여러개 만드려고 하는데 하이어라키에서 복사 붙여넣기 하는 방법도 있지만 프리팹을 이용해 보도록 하겠습니다.
프리팹은 월드에 배치된 오브젝트를 그대로 파일로 만드는 것 입니다.
하이라키 창의 SelectBox를 Prefabs폴더를 만들어 거기에 끌어다 놓으면 쉽게 프리팹을 만들 수 있습니다.
만든 프리팹으로 월드에 몇 개 배치해서 적당한 위치로 옮겨 주세요
그다음엔 눈의 가운데를 표시할 크로스 헤어를 만들어 보겠습니다.
캔버스를 이용하여 만듭니다.
캔버스는 플로팅된 UI를 만들 때 사용합니다.
하이어라키 창에서 오른쪽 클릭하여 UI -> Canvas를 선택합니다.
다음 만들어진 캔버스 오른쪽 클릭하여 이미지를 추가합니다.
Inspector창에서 적당히 수정합니다.
기본 이미지를 이용하겠습니다.
기본적으로 캔버스는 메인 카메라를 기준으로 Overlay되어 있습니다.
VR의 카메라는 두개 이므로 각각 카메라를 기준으로 떠 있도록 해야 합니다
Canvas를 선택하여 Canvas 컴포넌트의 Render Mode를 Screen Space - Camera로 바꾸어 줍니다.
그러면 아래 매개 변수들이 바뀌는데 RenderCamera를 CardboardMain->Head->MainCamera의 자식 Main Camera Left 를 끌어다 놓습니다.
그리고 하이어라키 창에서 Canvas를 선택하여 Ctrl + D를 누르면 Canvas가 복제 됩니다.
그럼 복제된 Canvas의 Canvas 컴포넌트 Render Camera에 Main Camera Right를 끌어다 놓습니다.
이제 트리거가 발생 했을 때, 화면 가운데에 있는 오브젝트가 무엇인지 감지하여 그 오브젝트가 박스라면 색깔을 변경하도록 하겠습니다.
TriggerTextCtrl에서 코드를 추가하도록 하겠습니다.
화면 가운데에 있는 오브젝트가 무엇인지 감지 할 때엔 RayCast라는 것을 사용합니다.
간단하게 RayCast가 무엇인지 설명 하면 레이저를 쏴서 이 레이저에 맞는 오브젝트를 감지하는 것 입니다.
screenCenter = new Vector3(Camera.main.pixelWidth / 2, Camera.main.pixelHeight / 2);
Vector3는 3개의 float형 변수를 계산할 때 이용이 되며
화면의 픽셀 개수는 Camera.main.pixelWidth , Camera.main.pixelHeight 를 가져와 반으로 나누면 가운데 위치를 가져 올 수 있습니다.
Ray ray = Camera.main.ScreenPointToRay(screenCenter);
메인 카메라를 기준으로 screenCenter 위치에서 발사한 레이를 가져옵니다.
Physics.Raycast(ray, out hit, 500f)
ray에 맞은 500f 범위 안에 있는 적중 정보를 hit에 저장합니다.
맞은 오브젝트의 태그가 Box라면 맞은 오브젝트의 BoxCtrl 컴포넌트를 가져와 Select() 메소드를 호출합니다.
public class TriggerTextCtrl : MonoBehaviour
{
private const string TEXT = "COUNT : ";
public Cardboard cardBoard;
private TextMesh textMesh;
private int count = 0;
private Vector3 screenCenter;
void Start()
{
textMesh = gameObject.GetComponent<TextMesh>();
screenCenter = new Vector3(Camera.main.pixelWidth / 2, Camera.main.pixelHeight / 2);
}
void Update()
{
if (cardBoard.Triggered)
{
++count;
textMesh.text = TEXT + count.ToString();
Ray ray = Camera.main.ScreenPointToRay(screenCenter);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, 500f))
{
if (hit.collider.gameObject.tag == "Box")
{
BoxCtrl boxCtrl = hit.collider.gameObject.GetComponent<BoxCtrl>();
boxCtrl.Select();
}
}
}
}
}
작성자 : 이경용
안드로이드 스터디 운영자 이경용 입니다.
저희 회원분들에게 꼭 추천할만한 행사 소식을 소개 합니다.
구글에서 진행하는 행사이며, 아래 내용 참조하시고 많은 참여 바랍니다.
Google for Mobile은 모바일 앱 개발사의 비즈니스 성장을 지원하기 위해 마련한 자리로써, 앱 비즈니스의 성장단계인 Develop, Engage 그리고 Earn에 대해 각 단계별로 최적화된 성공 포인트를 공유하는 기회의 장이 될 것입니다. 본 행사가 귀사의 더 큰 성공에 도움을 드리는 자리가 되길 기원합니다.
감사합니다.
When: 2015년 11월 24일(화)
Where: 동대문 디자인 플라자(DDP) 알림1관, 2관
Schedule: 10 AM ~ 7:30 PM (5:30PM ~ Happy hour)
• 9:30AM - 10:00AM : Door opens
• 10:00AM - 10:50AM: Keynote presentations
• 10:50AM - 5:30PM: Track Session
• 5:30PM - 7:30PM: Happy hour
(* 세부 프로그램은 곧 업로드 될 예정입니다.)
[Google for Mobile Highlight]
• 25개 이상의 세션이 진행되며, 원하는 세션을 선택하여 참석하실 수 있습니다.
• 글로벌 앱 시장에서 성공을 주도한 주인공들을 만나볼 수 있습니다.
• 새로이 출시된 최신 제품들과 Google의 기술들을 직접 체험해 볼 수 있습니다.
• 한국 뿐만 아니라 주요 국가에서 참가한 Google 담당자 및 여러 개발자들과 함께 네트워킹 할 수 있는 Happy Hour 시간이 준비되어 있습니다.
• 점심식사가 제공될 예정입니다.
[등록안내]
* 한 회사에서 5명까지 등록이 가능합니다.
[참가신청]
https://events.withgoogle.com/google-for-mobile-seoul/
신청서 작성시 "등록코드(Invitation Code):" 에 "GA11GS24" 라고 입력해 주세요!
삼성 겔럭시S 출시후 안드로이드에 관심을 갖게 되어 안드로이드 개발 관련 게시판을 추가 하였습니다.
다음 글은 구글에서 제공하는 안드로이드 개발 안내 페이지 입니다.
Android는 운영체제, 미들웨어 및 핵심 응용프로그램을 포함하는 휴대기기용 소프트웨어 스택입니다. Android SDK에서는 Android 구동 기기에서 실행되는 응용프로그램을 개발하는 데 필요한 도구 및 API를 제공합니다.
Android SDK : http://developer.android.com/sdk/index.html
이 사이트에서는 Android 플랫폼을 확장하는 외부 라이브러리, Android 응용프로그램, 호스팅 서비스 및 API, Android 개발자 대회 등 Android 플랫폼을 기반으로 한 Google 프로젝트에 대한 정보를 제공합니다. 이 사이트 내용은 모두 Android 개발자를 위해 Google에서 제공합니다.
Android에 대한 일반적인 정보는 www.android.com 사이트를 참조하세요. Android 기기용 응용프로그램을 개발하는 데 관심이 있으시면 Android 개발자 사이트(developer.android.com)를 방문하세요.
Android 개발자 사이트 : http://developer.android.com
* 개발을 위해서 일단 위 사이트 부터 방문해서 자료를 찾아 봐야겠습니다. ^^
구글 애드센스로 부터 송금 받아서 수금하는 방법
한국 내 가까운 웨스턴 유니온 가맹점을 방문 하셔서 간단한 신분 확인후 수금 하실 수 있습니다.
1. 송금 상태 확인
송금인, 온라인 트랙킹, 혹은 고객서비스센터 (00798 8521 3000 : 무료, 한국내 전화가능) 를 통해 웨스턴 유니온을 통한 송금인지 확인합니다.
2. 웨스턴 유니온 가맹점 방문
송금인의 이름, 송금국가, 송금액, MTCN을 확인한 후, 신분증을 지참하고 가까운 웨스턴 유니온 가맹점을 방문합니다.
3. 수취 신청서 작성
송금 수취 신청서를 작성한 후, 적합한 신분증과 함께 제시합니다.
4. 영수증 검토
영수증의 모든 사항을 확인한 후, 싸인합니다.
5. 송금액 수취
송금된 금액과 영수증을 받으십시오.
6. 한국에서 수금시 주의사항
- 수금한도액 : 1일 1인 1건 당, USD 7,000 혹은 그에 상응하는 KRW.
- 수금을 위해서는 반드시 적합한 신분증과 MTCN을 제시해야 합니다.
- 한국내에서 'Test 질문'은 제공되지 않습니다.
- 도박과 관련된 송금은 법으로 금지되어 있습니다.
7. 가까운 방문점 조회는 다음 페이지에서 조회 가능 합니다.
http://www.westernunion.co.kr/kr/how_to_receive.php
웨스턴 유니언은 인터넷상으로 송금을 하고 송금번호만있어도 보낸 해당은행에서 직접 찾을수 있는 가장 간단한 송금방법입니다.
이름이 틀리면 다른 절차를 밟아서 본인여부를 확인해야 합니다.
다른 이름으로 다시 써서는 안됩니다.
이미 송금시에 수령인을 지정했기때문입니다.
* 아래 은행은 부산에 위치한 은행 입니다.
다른지역 은행 확인 하실려면 아래 주소 접속하셔서 지역을 선택후 검색 하세요.
http://www.westernunion.co.kr/kr/location_search.php
http://chart.apis.google.com/chart?<parameter 1>&<parameter 2>&<parameter n>
즉 GET 방식으로 파라메터들을 묶어서 날리면 알맞은 이미지가 날아오는 것입니다.
위의 헬로우 월드를 그린 URL은 다음과 같습니다.
http://chart.apis.google.com/chart?cht=p3&chd=s:hW&chs=250x100&chl=Hello|World여기서 각 파트를 나눠서 설명 해보면 다음과 같습니다.
A(0), B(1), C(2) ... Z(25), a(26), b(27), c(28) ... z(51), 0(52), 1(53), 2(54) ... 9(61)이렇게 대문자 A부터 숫자 9까지 61단계로 데이터를 표시 할 수 있으며, 각 데이터는 콤마(,)로 나누어 집니다. 또한 빈 데이터는 언더바(_) 로 나타냅니다.
chd=t:10.0,-1,95.0|30.0,8.0,63.0예를 들어 위처럼 표시 됩니다.
A(0), B(1), ... Z(25), a(26), b(27), ... z(51), 0(52), 1(53), 2(54) ... 9(61), -(62), .(63)한 자리에는 Simple encoding 의 문자에 하이픈(-)과 포인트(.)를 추가 하여 2단계 더 많은 64단계를 한 자리에 쓰게 됩니다. 여기에 2자리 이므로
위처럼 쓰게 됩니다.AA
= 0,AZ
= 25,Aa
= 26,Az
= 51,A0
= 52,A9
= 61,A-
= 62,A.
= 63BA
= 64,BZ
= 89,Ba
= 90,Bz
= 115,B0
= 116,B9
= 125,B-
= 126,B.
= 127.A
= 4032,.Z
= 4057,.a
= 4058,.z
= 4083,.0
= 4084,.9
= 4093,.-
= 4094,..
= 4095.
댓글을 달아 주세요