'Developer/GAME'에 해당되는 글 34건

  1. 2006/04/21 글뻥 스케치업으로 시작하다.
  2. 2006/04/07 글뻥 free 3D game Engine인 irrlicht으로 만들어 보기로 최종결정
  3. 2006/04/07 글뻥 Ovorp C# 2D Game Engine
  4. 2006/03/29 글뻥 C# vs C++ in Game Engine (4)
유니티3D에서 자이로 효과를 카메라에 적용하는 스크립트입니다.
(Marker 없이 자이로로만 캐릭터를 바닥에 닫게 한다던가... 그럴때 사용하는...)

using UnityEngine;
using System.Collections;

public class CameraPivot : MonoBehaviour
{
 float _BaseAngle = -90f;

 void Start()
 {
 Input.gyro.enabled = true;
 }

 void Update()
 {
 Quaternion q1 = Input.gyro.attitude;
 Quaternion q2 = new Quaternion(q1.y, -q1.z, -q1.x, q1.w);

 transform.rotation = Quaternion.Euler(new Vector3(q2.eulerAngles.x, _BaseAngle, q2.eulerAngles.z));
 if (transform.rotation.eulerAngles.z <= 275f && transform.rotation.eulerAngles.z > 180f)
 transform.rotation = Quaternion.Euler(new Vector3(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, 275f));
 if (transform.rotation.eulerAngles.z >= 355f || transform.rotation.eulerAngles.z <= 180f)
 transform.rotation = Quaternion.Euler(new Vector3(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, 355f));
 }
}


1. 빈 게임오브젝트 만들어서 이름 바꾼뒤에 아래와 같이 스크립트 포함시킵니다.
사용자 삽입 이미지
2. Pivot 해줄 오브젝트 만들어서 다음과 같이 Rotation값을 (90, -90, 0)으로 설정합니다.
사용자 삽입 이미지
3. 마지막으로 Gyro camera를 설정한다.
사용자 삽입 이미지
4. Main Camera에서 다음과 같이 설정해주면 끝!
사용자 삽입 이미지

* Marker기반 AR과의 차이점.
1. Zoom in-out이 수동임.
2. 화면 Center를 중앙으로 인식함.
3. 회전이 수동임. (축이 고정되어 자동으로 먹히게 하는것 처럼 보이는 건 https://github.com/keijiro/GyroCam 참고)

2015/01/19 17:20 2015/01/19 17:20
씬간 데이터를 이동한다던가...
씬내에서 SQL처럼 데이터를 읽거나 쓰고 싶을때가 있을 것이다.

이전에는 playerprefs 에다가 JSON으로 데이터를 넣어두고 씬마다 리셋했는데... 
연구를 하다보니 씬 이동에도 불편하게 Dontdestroy 옵션을 설정하지 않아도 사라지지 않는 Entity Class 구현방법을 알게되어 포스팅하게 되었다.

(how to get data in other scene on the unity3d player with C# entity class)

먼저 다음과 같이 List 객체를 가지고 있는 Entity라는 정적 Class를 만들자.
e는 _e class 타입의 List이다. (hash 테이블보다는 일반 DB에 가까워서 List를 자주쓴다. 또한 JSON / XML 의 Deserializing / serializing에 유리하기도 하다.)

using System.Collections;
using System.Collections.Generic;

public static class Entity
{
     public static List<_e> e = new List<_e>();
}

public class _e
{
     public string _s;
}



이제 "test1Behavior" 테스트코드를 다음과 같이 작성하고 Main Camera에 스크립트를 Attach시켜둔다.
using UnityEngine;
using System.Collections;

public class test1Behavior : MonoBehaviour {

void Start () {
 Entity.e.Add(new _e { _s = "1234" });
 Application.LoadLevel(1);
 }
}


씬이름을 test1로 저장하고 새로운 씬을 연다.

위의 코드와 비슷하게 다음과 같이 작성하고 새로운 씬의 Main Camera에 스크립트를 Attach시켜두자.

using UnityEngine;
using System.Collections;

public class test2Behavior : MonoBehaviour {

 void Start () {
 foreach (_e x in Entity.e)
 {
 Debug.Log(x._s);
 }
 }
}


마지막으로 test2로 씬을 저장한 후에 

이로써 모든 작업이 완료 되었다.
build setting 에서 test1와 test2 씬을 차례대로 넣어두자.

이제 실행해보면 다음과 같이 test1Behavior에서 넣어두었던 데이터 "1234"가 새로운 씬에서 작동한다.

사용자 삽입 이미지
2015/01/15 16:06 2015/01/15 16:06
2015년 신년부터는 일하게 되는 곳이 바뀌게 되었고 그 기념으로 포스팅하려 합니다.

상인으로 3년을 보내며, 조금 많은 회사와 협력관계를 맺기도 했고, 게임팀을 맡겨보기도 했습니다만...
한가지 재미있는 사실은... "게임 만드는 사람이 게임의 문법을 모른다는 사실"을 깨달았습니다.

영화나 소설에도 기승전결이 있습니다.
물론 일부 괴랄맞은 감독은(크리스토퍼 놀란) 자신만의 문법으로 "결"부분에 꼭 애매하게 매듭을 묶어 놔서 사람 환장하게 만들죠!

* 시발!! 넘어지라고!!! 
사용자 삽입 이미지

반대로 아주 지랄맞은 감독은(안노히데 아키) 자신만의 문법으로 "결"부분을 완전히 결단을 내버리기도 합니다.

* 이게 뭐임? 안노 ㅅㅂㄻ!!!
사용자 삽입 이미지

다시 말해, 우리의 뇌는 우리가 받아 들이기 쉬운 형태의 문법을 선호하고 그것이 몇 천년동안 가공되어 왔다고 할때, 최근에는 한층 더 쎄련되면서 다음과 같이 가공되기도 했습니다.
그예가 바로 "3줄 요약!" 주저리 주저리 블라 블라 하고 나서 마지막에 "3줄 요약"

이렇게 함으로써 자신의 글 솜씨도 숨기고 하고 싶은 말은 다 합죠. 네넵. (한국인의 낮은 독해능력을 파고드는 방법입니다.)

그렇다면 노래는 어떨까요? 
네! 있습니다. 노래는 제가 잘 모르는 분야이지만 흔히들 "Code"라는 문법이 존재하더군요!

* YES24에서 절찬 판매중...
사용자 삽입 이미지


그렇다면 그림은 어떨까요?
이쪽은 더 잘 모르겠지만, 우리는 이미 학교 다닐때, 회화풍이 어쩌구... 저쩌구... 황금비율이 어쩌구 저쩌구하면서 이미 많은 지식을 머리속에 담고 있습니다.
하나의 예를 들어보면... 모더니즘 미술과 근대미술을 나누는 과정에서도 클래식과 현대 음악과 같은 뚜렷한 차이가 존재합니다.
아래의 추상화 패턴만해도 어떤 규칙을 가지고 있지요.
사용자 삽입 이미지
따라서, 회화 역시 문법이 존재한다는 심증을 가지고 있습니다.

다시말해 모든 Contents는 문법이 있습니다. 
그런데, 게임쪽은 희안하게도 종종 아주 자주 이러한 문법이 무시됩니다.
문법이란 인간의 뇌가 받아 들일 수 있는 규격임에도 그것이 무시됩니다. 아주 무섭고도 놀라운 일이죠.

흔히, 우리가 게임이라 하면, 화투나 포커같은 보드게임에서 부터, 당구, 야구, 축구, 연말평가 등등 이기고 지는 것에 대한 것을 게임이라 합니다.
광의의 의미에서 선거조차 게임입니다. 전쟁은 두말나위 없는 게임입니다. 나아가 시험도 게임입니다.

즉, 게임의 가장 고전적인 문법은 다음과 같습니다.

"플레이어가 OOO해서 OOO 보상을 받아, OOO 했다."

* 이걸 업계용어로 "Core Loop"라합니다.
사용자 삽입 이미지
모든 게임은 Core loop의 문법이 통용됩니다.

예를 들어, 최초의 오락실 게임인 핀볼을 예를 들면,
"볼을 쳐내서 많은 점수를 받고 Rank를 올렸다"

* 흔한 핀볼게임. Rule은 볼을 쳐내서 떨어트리지 않는 것이고 목적은 오로지 점수 올리는 것입니다.
사용자 삽입 이미지


이 문법을 그대로 수 많은 오락실 게임에 가져다 놓으면,
"적을 때려잡아서 많은 점수를 받고 몇 판 깼다"

* 팩맨과 갤러그... Rule은 다르지만, 친구들에게 "몇 판깼어!"하는 걸로 자랑하던 몇 판 깨기 목적 지향의 게임
사용자 삽입 이미지


다시 말해 게임의 기본 문법구조는 다음과 같습니다.
"XX규칙으로 OO을 달성하고 ZZ한다"

RPG역시 이러한 문법에 따릅니다.
- 몹많이 때려잡아서 보상을 많이 모아 Level업 한다."
물론 Level업하면 더 많은 지역을 갈 수 있고 (확장) 더 좋은 아이템이 떨어지는 던젼을 탐험 할 수 있습니다.(또 확장)

시뮬레이션 게임 역시 마찬가지 입니다.
- 유닛 많이 뽑아서 상대를 때려잡으면 승률이 올라가고 승률이 올라가면 더 놓은 리그에서 경기한다.
이 역시 같은 문법으로 이루어져 있습니다.


궁극적으로 평타 게임이란 이러한 문법에 충실한 게임입니다.
새로운 게임이란 이러한 문법을 벗어난 게임입니다. 그 일을 징가가 해냈죠!
사용자 삽입 이미지
팜빌 역시 같은 문법으로 이루어져 있습니다만, 확장의 방향이 조금 달랐습니다.
"농장물 잘 키워서 잘 팔고 남는 이윤으로 영토를 확장한다"가 기본 문법이지만, 이들이 취한 또 하나의 확장은 "친구의 확장"입니다.

그걸 옆나라에서 보고 있던 이들이 만든 문법은 조금 다릅니다.
"친구를 포함한 덱 잘만들어서 몹 때려잡으면 그 보상으로 더 상위 던전으로 진출하고 친구도 얻는다."
사용자 삽입 이미지
소셜로의 확장을 기본으로 하는 게임에서는 당연히 취해야 할 문법이라 봅니다.
이러한 문법이 깨졌을때 게이머는 화를 냅니다.

예를 들어, 
- 규칙이 안보이거나 규칙을 알 수가 없을때, (게이머가 OO해서 라는 부분이 졸라 복잡한거죠...)
- 게이머가 즉시 힘을 가상세계로 투사할 수 없을때, (크래쉬나 뻑이 난다던가.. 입력 반응이 느리다던가...)
- 목적을 알 수 없을때 (도대체 이 게임을 왜하는건지 감정이입조차 안되는 경우)
- 보상이 생각이하로 작다거나... 너무 크거나...
- 확장이 어렵다던가... 혹은 확장이 너무 쉽다던가..

이러한 경우는 우리는 "망작"이라 합니다.

기본적으로 게임은 Loop이기 때문에 기승전결의 구조를 작은 틀에서 가질 수 없습니다.
큰 틀에서 기승전결을 가지되 작은 스테이지 개념에서는 이러한 Loop 구조를 가져야 제대로된 게임이라 할 수 있습니다.

문제는 Animation 회사라면 추구할 (그래픽의 퀄이라던가.. 애니메이션의 퀄이라던가..) 내용에 힘을 쏟거나...
시뮬레이션 회사라면 추구할 (물리의 퀄이라던가.. 타격에 따른 반동의 퀄이라던가..) 내용에 힘을 쏟게 되면,

그야말로 있는 돈 다 쓰고 나 앉게 되는 것이죠.

그래서 게임에서는 가장 중요한 것이. 바로 Loop의 설계입니다. 
Loop의 설계가 제대로 되면 나머지는 "진짜 그런것이 아니라 그럴싸 한것으로 채워집니다."

* 물론 설계된 Loop가 제대로 된 것인지 검증을 해야합니다.(검증이 완료되면 그 때 만들면 되요)
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지


영화 인셉션의 기승전결의 문법이 성립되고나니 그 안의 모든 것이 그럴싸 한것으로 채워져도 진짜로 인식되거나 영화 인터스텔라의 기승전결의 문법이 성립되고나니 그 안의 모든것이 그럴싸 한걸로 채워져도 진짜로 인식되는 같은 이유입니다.

제발 게임 개발자 여러분.
게임의 문법을 먼저 생각하고 먼저 계획하시기 바랍니다.
여러분들의 투자자와 사장님은 눈물흘려요.
2015/01/03 20:12 2015/01/03 20:12
MS가 인터넷 회사로 Positioning하기 시작한 느낌입니다.
Sway를 사용해 게임개발 접근법이란 주제로 포스팅해보았습니다.

https://sway.com/fx6-n0TpBBv9lWuM

계속 업데이트해볼 생각입니다. ㅋ
2014/12/17 03:38 2014/12/17 03:38
1:17에서 부터 시작하는 Snapsh-OO-t 을 만들었습니다.
제대로 고객의 의도를 이해하지 못했구요.
Version 2.0 기획이 아마도 내일쯤 끝나서 다음달 초에는 2.0 업데이트 할 수 있을 것 같습니다.
죄송하고 송구스럽네요. 
추구하는 Value를 이제야 이해했네요 T_T

2014/11/13 16:38 2014/11/13 16:38
배포시 가장 큰 골치덩어리중 하나는 AndroidManifest.xml 파일 수정문제일 것이다.
Android Plugin을 만들어서 넣자니 짜증나고... 그럴때 간단하게 AndroidManifest.xml 파일을 수정할 수 있는 방법을 공개한다.

프로젝트 Root폴더에 보면 "Temp" 폴더가 생성되어 있을텐데 거길 가만히 보면 "StagingArea"라는 폴더가 보인다.
여기로 들어가면 다음과 같이 폴더가 구성되어 있다.

사용자 삽입 이미지
빌드에서 사용될 각종 Resource 파일들이 보일텐데 이중에 필요한건 
AndroidManifest.xml 파일과 res 폴더 두개이다. 이 2개를 선택해서 CTRL+C 해서 복사하고 
유니티로 돌아와서 "Plugins" 폴더를 만든다음 다시 "Android"폴더를 만들고 거기에 복사해 넣자.
사용자 삽입 이미지
이제 복사한 AndroidManifest.xml 파일을 열어서 마음대로 주무르면 됨. 끝!


2014/10/26 16:21 2014/10/26 16:21
최근에 모 대기업 스마트폰에 Preinstall 하는 프로젝트에 참여하면서 영혼이 갈려 나가고 있습니다.
(8월 23일부터 처음 코딩들어가기 시작했으니 벌써 2달이 가까워지네요.)

TDD와 같이 개발하고 Fix Patch하면서 하나하나 고쳐나가다보니 별별 문제를 다 만납니다.

현재환경 : Unity3D 4.5.4
Vuforia : 3.09

가장 큰 문제는 Vuforia의 카메라를 On/Off 할때 Object (특히 GUI)가 많이 떠 있으면 Crash 가 발생합니다. 
이건 답이 없어서 On/Off하는 상황에서 GUI를 꺼주고 Object들도 다 꺼주고 다시 카메라를 Turn On할때는 카메라가 들어오는걸 확인하고 다시 다 띄워줍니다. (이런 미친...)

정리하자면, 전면카메라와 후면카메라 전환시 카메라 Turn Off -> Turn On 되는데, 이때 

- CameraDevice.instance.stop()
- 모든 Object 제거
CameraDevice.instance.start()
- Object 재생성

이렇게 해야 반복적인 On/Off문제에서 해결이 가능하더군요. (Fucking Vuforia)

그리고, Unity3D 4.5.4f1 버전에서 안드로이드 커버를 덥었다 열었다를 반복하면 먹통이 되는 현상이 발생됩니다.
이 경우는 Unity3D 4.5.4 Patch 3 또는 4.5.5로 업데이트 / 업그레이드하면 많은 부분이 해소됩니다만, 
위의 Vufoira Crash 대응작업을 위해서는 Queue를 사용해서 중간에 들어온 Events를 무시하는 겁니다.

예를 들어, Pause Event에서는 
- CameraDevice.instance.stop()
- 모든 Object 제거
를 해야하고 Resume Event에서는 
CameraDevice.instance.start()
- Object 재생성
를 수행해야하는 상황이라면, 다음과 같이 Queue를 처리 할 수 있습니다.


* 다음은 대소문자 무시하고 기억나는대로 Typing한겁니다.

//먼저 List객체로 만들 Class를 하나 선언합니다.
public class Queue {
     public bool PauseType;
     public float EventTime;
}

//List를 하나선언합시다. using System.Collection.Generic; 선언 잊지 맙시다.
List<Queue> _q = new List<Queue>();
void OnApplicationPause(_paused){
    //Pause 또는 Resume Event가 들어오면 Queue에다 넣어둡니다.
     _q.add ( new Queue { PauseType = _paused, EventTime = Time.realtimeSinceStartup } );
   // 처음 들어온 Event는 일단 Pause이므로 처리하도록 합시다.
     if (_q.Count <= 1)  SetPause();
}

void FixedUpdate(){
    if (_q.Count < 1) return; //비어있을때는 무시
    //큐의 마지막이 Resume 이면서 반복 입력이 1초이상 없으면 Resume 실행
    if (_q[_q.Count -1].
PauseType == false && _q[_q.Count -1].EventTime + 1f <  Time.realtimeSinceStartup) {
       SetResume();
       _q.Clear()
    }
}

만들어 놓고 보니 굳이 List 객체로 처리해야하는지 조금은 궁금증이 들기는 하지만, 조금이라도 안드로이드 덮개 때문에 고통받는 개발자들과 나누고 싶네요.
(참고로 삼성제품에서는 괜찮다고 하더라구요. T_T)
2014/10/18 14:33 2014/10/18 14:33
Unity3D의 신묘한 기능중에 하나는 안드로이드 SDK를 C#으로 불러서 쓸수 있다는 점.
그걸 이용해서 Soft Navigation bar를 없애보았다.

* 게임할때  겁나 걸리적 거리는 요녀석!
사용자 삽입 이미지

* 원문은 여기
아래 "2"가 왜 "2"인지에 대한 자료는 여기
 
 
#if UNITY_ANDROID
 // 안드로이드 자바오브젝트를 3개 선언한다.
 static AndroidJavaObject activityInstance;
 static AndroidJavaObject windowInstance;
 static AndroidJavaObject viewInstance;
 //중요한건 바로 여기 "2"로 설정된 "SYSTEM_UI_FLAG_HIDE_NAVIGATION"값이 중요

 const int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 2;
 const int SYSTEM_UI_FLAG_LAYOUT_STABLE = 256;
 const int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 512;
 const int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 1024;
 const int SYSTEM_UI_FLAG_IMMERSIVE = 2048;
 const int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 4096;
 const int SYSTEM_UI_FLAG_FULLSCREEN = 4;
 
 public delegate void RunPtr();
 
 public static void Run()
 {
 if (viewInstance != null)
 {
 viewInstance.Call("setSystemUiVisibility",
 SYSTEM_UI_FLAG_LAYOUT_STABLE
 | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
 | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
 | SYSTEM_UI_FLAG_HIDE_NAVIGATION
 | SYSTEM_UI_FLAG_FULLSCREEN
 | SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
 }
 
 }
 #endif
 


일단 이렇게 선언이 끝났으면 다음의 코드를 추가한다.

 public static void DisableNavUI()
 {
 if (Application.platform != RuntimePlatform.Android)
 return;
 using (AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
 {
 activityInstance = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");
 windowInstance = activityInstance.Call<AndroidJavaObject>("getWindow");
 viewInstance = windowInstance.Call<AndroidJavaObject>("getDecorView");
 
 AndroidJavaRunnable RunThis;
 RunThis = new AndroidJavaRunnable(new RunPtr(Run));
 activityInstance.Call("runOnUiThread", RunThis);
 }
 }
 


이제 이녀석을 호출할 녀석을 추가한다.
 void Start()
 {
 DisableNavUI();
 }
 

이제 상단 실행시켜보면 상단 또는 하단 엣지 부분을 가운데 방향으로 드레그 하기전에는 메뉴가 보이지 않는다.
물론 단점도 존재한다.

- 화면해상도 새로 잡아야 한다. T_T 
- 지금까지 알려진 해상도가 아니라는 점...
2014/09/02 10:46 2014/09/02 10:46
너무나 정신없어서 블로그 관리도 못하고 있네요.
그럼에도 블로그 방문해주신 대부분의 Bot 여러분 및 소수의 열성 독자 여러분께 감사드립니다. (it's joke~!)
Unity3D 에서 안드로이드 개발할때 간혹 다른 앱을 실행하고자 할 때가 있습니다.
물론 이클립스 열어서 플러그인을 만들거나 혹은 쿵짝 쿵짝하는 경우가 있지만, 여기에서는 기본 C#코드로만 하는 방법을 설명할께요.

본 예제는 Android 기본 갤러리를 여는 예제입니다.
 
void LaunchGallery () { 
   AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); 
   AndroidJavaObject jo = jc.GetStatic("currentActivity"); 
   AndroidJavaObject pm = jo.Call("getPackageManager"); 
   AndroidJavaObject intent = pm.Call("getLaunchIntentForPackage", "com.android.gallery3d");
   jo.Call("startActivity", intent); 
}
 


처음부터 보자면, 예전 포스팅 (http://www.wolfpack.pe.kr/860)에서 밝혔던, Static 은 AndroidJavaClass, instance는 AndroidJavaObject 원칙에 따라 Class를 먼저 호출했습니다.
그리고나서, 현재 Activity를 호출했구요.
다음줄 부터는 Android API에 따라서,
getPackageManager (상세 여기참조) 와 getLaunchIntentForPackage (상세 여기참조)을 호출하면서 getLaunchIntentForPackage에 인자값으로 패키지명인 "com.android.gallery3d"을 넣어 줬습니다.
이제 준비가 다 끝나고 마지막으로 준비된 과정을 한꺼번에 부어서...
currentActivity Object에서 startActivity로 실행했습니다.
Intent는 다른 앱을 실행하고나서의 통신을 설정하는 부분인데 Intent 정의를 따로 하지 않았으니 통신하지 않겠다는 의미입니다. =)

그럼 수고하세요.
2014/08/19 21:44 2014/08/19 21:44
일전에 NGUI 관련해서는 기초적인 내용부터 강좌한 적이 있어서 기초 내용은 생략합니다.
최근 버전업데이트된 NGUI를 사용하다보니 Scroll부분의 Script 파일명이나 방법들이 바뀌어 있어서 이렇게 포스팅합니다.

우선 사용되는 스크립트는 다음과 같습니다.
- 빨간색 : Panel
- 파란색 : Grid
- 녹색 : Item
사용자 삽입 이미지
생소하다면 생소하겠지만... 예전강좌에서 다룬 부분이므로 참고 이미지만 넣고 넘어가겠습니다.
사용자 삽입 이미지
이제 Panel 부분의 Script설정입니다.
사용자 삽입 이미지
Grid 부분은 다음과 같이 설정합니다.
사용자 삽입 이미지
마지막으로 아이템부분입니다.
사용자 삽입 이미지
바뀐부분에 대해 예전 강좌로 잘 안되시는 분들은 참고하세요 =)
2014/04/20 17:54 2014/04/20 17:54