1. Visual Studio Tools for Unity


통칭, UnityVS

유니티5.2이상 권장.

 

 Visual Studio 2015 Tools for Unity

 호환버전

> Visual Studio 2015 Community

> Visual Studio 2015 Professional

> Visual Studio 2015 Enterprise

 Visual Studio 2013 Tools for Unity

 호환버전
> Visual Studio 2013 Community
> Visual Studio 2013 Professional
> Visual Studio 2013 Enterprise

 Visual Studio 2012 Tools for Unity

 호환버전
> Visual Studio 2012 Professional
> Visual Studio 2012 Enterprise

 Visual Studio 2010 Tools for Unity

 호환버전

> Visual Studio 2010 Professional

> Visual Studio 2010 Enterprise


단축키

> F5: 중단점 단위로 이동

> F10: 중단점부터 순차적으로 로그추적이 가능.






2. CMD & adb logcat


* 안드로이드 SDK경로

> D:\dev_lib\android_sdk windows


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
 
C:\Users\ANALOG-GREEN>cd /d D:\dev_lib\android_sdk windows\platform-tools
 
D:\dev_lib\android_sdk_windows\platform-tools>adb logcat Unity:I Native:I *:S
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
I/Unity   (14112): onPause
I/Unity   (14112): windowFocusChanged: false
I/Unity   (15349): splash_mode = 0 (integer)
I/Unity   (15349): useObb = False (bool)
I/Unity   (15349): onResume
I/Unity   (15349): onPause
I/Unity   (15349): onConfigurationChanged
I/Unity   (15349): windowFocusChanged: true
I/Unity   (15349): onResume
... ... ...
cs


 adb logcat

 디바이스 자체에 발생하는 모든 로그를 모니터링

 adb -e logcat

 녹스 앱플레이어등 안드로이드 에뮬쪽 로그만 모니러팅

 adb logcat -s Unity

 유니티에서 발생하는 모든 로그를 모니터링

 adb logcat Unity:I Native:I *:S

 유니티 스크립트의 로그만 걸러서 보는데 유용.


버그가 나는 위치를 찾기 쉽게끔 Debug.Log를 구간별로 넣고 빌드&실행을 해야 합니다.






3. 유니티 스크립트 디버깅


* 케이블 연결상태가 좋지 않거나 로그캣이 번번히 끊길경우에 유용합니다.


1
2
//    [*.cs]
Log.log("unity src debug sample");
cs



실행후
(내외장 메모리)/android/(패키지명)/logs를 확인.






4. 녹스 앱플레이어 디버깅


0) 녹스 개발자 권한
안드로이드 스튜디오 NOX 연결(연동)하는 방법!!!



1) 연결

1
2
3
4
5
6
7
8
PS D:\nox\Nox\bin> ./nox_adb connect 127.0.0.1:62001
adb server version (39) doesn't match this client (36); killing...
* daemon started successfully *
connected to 127.0.0.1:62001
PS D:\nox\Nox\bin> ./adb devices
List of devices attached
127.0.0.1:62001 device
xxxxxxxxxx        unauthorized
cs



2) 디버깅 시작

1
2
PS D:\nox\Nox\bin> cd D:\dev_lib\android_sdk_windows\platform-tools
PS D:\dev_lib\android_sdk_windows\platform-tools> ./adb -e logcat
cs







기타.


Unity Remote 5 (앱)




 

 

 

참조자료.

 

Visual Studio Tools for Unity 시작

UnityVS 사용법 | Blue Water

Unity3D :: 유니티 안드로이드 디버깅 방법

Mr. 후크의 잡동사니 :: Unity에서 폰으로 디버그 하기( Unity Remote )

 

nox adb 연결



 


 

기타. 변경이력


일자

변경이력

2016-11-24

 초안

2018-08-13

 녹스기반 디버깅 추가 자료 추가

'프로그래밍note > 엔진 관련' 카테고리의 다른 글

유니티: 디버깅 방식  (0) 2018.08.13
Box2d: 요약 및 정리  (0) 2017.08.30
오픈소스 게임엔진  (0) 2017.04.11
유니티: 개발팁 및 최적화  (0) 2016.08.17
유니티: NGUI 2.7 튜토리얼&샘플  (0) 2016.04.09
유니티: 안드로이드 API 플러그인  (0) 2016.04.08


* 용어는 가급적 원어를 한글로 옮긴방식을 쓰고 있지만, 발음표기상 생소한건(주관적 기준) 참조자료등의 번역을 사용했습니다.






0. 준비


* 공식페이지: Box2D | A 2D Physics Engine for Games


1) 필요한 파일

파일명

예시 경로

 Box2d 프로젝트파일

Box2D_v2.3.0.7z

Box2D-master.zip

 (해당사항 없음)

 Visual Studio Community [#]

 (설치시 기본경로)



2) 목차

상위

하위

 1. 용어

 1) 주요용어
 2) 모듈
 3) 유닛
 4) 팩토리&정의

 2. 기본용법

 1) 월드
 2) 그라운드 박스

 3) 다이나믹 body

 4) 시뮬레이팅

 5) 클린업

 3. Common 1) 설정
 2) 메모리 관리
 3) 수학
 4. 충돌 모듈(Collision Module)

 1) Shape

 2) 레이캐스트(RayCast)

 3) 쌍방함수    

 4) 다이나믹 트리(Dynamic Tree)     

 5) Broad-phase

 5. 다이나믹 모듈

 1) Body
 2) Fixture

 6. 조인트(Joint) 1) 정의
 2) 사용 절차
 7. Contacts 1) 클래스
 8. 월드 클래스 1) Creating and Destroying
 2) Using
 3) Simulation
 4) Exploring the World
 5) Ray Cast
 6) 회전 및 이동
 7) AABB Queries






1. 용어


* 참조

> Box2D_v2.3.0\Box2D\Documentation\manual.docx

: 1.5 Core Concepts


1) 주요용어

용어

-

 쉐이프(shape)

 2D상의 기하학적인 오브젝트
> 예. 원[O]   구[X, 3D]

 rigid body

 번역시 '강체'로 표기.

 물리적으로 단단한 오브젝트.

 fixture

 밀도, 마찰력, 콜라이더등의 속성을 가지게 함.
> body가 부모라는 전제가 필요.

> 어찌보면 body의 하위에 있는 물리적 요소 집합체격?

 constraint

 a physical connection that removes degrees of freedom from bodies.

 2D body has 3 degrees of freedom (two translation coordinates and one rotation coordinate, 이동축 2개+회전축 1개).

 contact constraint designed to prevent penetration of rigid bodies and to simulate friction and restitution.
> RigidBody끼리 뚫고 지나가지 않게 하고, 마찰등의 물리법칙을 작용케함.
 조인트(joint) 다수의 몸체(body)를 연결
 박스2d에서 지원하는 조인트
> revolute, prismatic, distance
 조인트 리밋(joint limit)

 인간의 관절처럼 회전각도등에 제한값을 두는것.

 조인트의 자유도를 제한하는격.

 조인트 모터(joint motor)

 (허용된 제한값내에서) 조인트를 움직인다.

 world

 오브젝트가 위치해있고, 물리가 작용하는 세계.

 solver The physics world has a solver that is used to advance time and to resolve contact and joint constraints. The Box2D solver is a high performance iterative solver that operates in order N time, where N is the number of constraints.
 continuous collision

 The solver advances bodies in time using discrete time steps. Without intervention this can lead to tunneling.
> 선형보간법이 엮인 충돌처리?



2) 모듈

Box2d 모듈들 = Common + Collision + Dynamics


 Common
 (= Common module)

 수학 및 설정관련 모듈
 Collision shape, 충돌함수관련 정의
 Dynamics world, body, fixture, joint 관련



3) 유닛

> 물체의 이동단위 0.1~10m로 유지하라고 명시됨.

> 라디안[ (π/180)*x ]을 각도로 사용. [호도법]

> 각도조절시, b2Body::SetAngle 사용.



4) 팩토리&정의

1
2
3
4
5
6
7
8
9
b2Body* b2World::CreateBody(const b2BodyDef* def)
b2Joint* b2World::CreateJoint(const b2JointDef* def)
 
void b2World::DestroyBody(b2Body* body)
void b2World::DestroyJoint(b2Joint* joint)
 
b2Fixture* b2Body::CreateFixture(const b2FixtureDef* def)
void b2Body::DestroyFixture(b2Fixture* fixture)
b2Fixture* b2Body::CreateFixture(const b2Shape* shape, float32 density)
cs

> b2Body 또는 b2Joint 생성시, 팩토리 함수를 사용. 메모리 관리상 다른 방법은 금지하는쪽으로 다뤄짐.







2. 기본용법


* 순서상, 세상-땅-땅위에 있는 무언가(body 오브젝트)로 연상가능.


1) 월드

> Box2D 프로그램은 b2World 오브젝트 생성으로 시작됨.

> 스탭/힙 혹은 데이터 섹션에 물리 월드를 할당 가능.

> 중력가속도는 9.8㎨이지만, 계산상 편의를 위해 10이 표준격.

1
2
3
4
5
6
7
//setp 1.
//중력벡터 선언, sleep여부 지정가능
2Vec2 gravity(0.0f, -10.0f);
 
//setp 2.
//월드객체 생성
b2World world(gravity);
cs



2) 그라운드 박스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//setp 1.
//body정의: with position, damping, etc.
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0.0f, -10.0f);
 
//setp 2.
//월드객체를 이용한 body생성
b2Body* groundBody = world.CreateBody(&groundBodyDef);
 
//setp 3.
//fixtures정의: with a shape, friction, density, etc.
b2PolygonShape groundBox;
groundBox.SetAsBox(50.0f, 10.0f);
 
//setp 4.
//body에 fixtures생성.//body의 하위가 fixtures
groundBody->CreateFixture(&groundBox, 0.0f);
cs



3) 다이나믹 body

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//setp 1.
//body생성.
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;//외력(?)등에 반응하게 할 경우.
bodyDef.position.Set(0.0f, 4.0f);
b2Body* body = world.CreateBody(&bodyDef);
 
//setp 2.
//shape
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(1.0f, 1.0f);
 
//setp 3.
//주의. 밀도 기본값이 0이라, 1로 설정필요.
body->CreateFixture(&fixtureDef);
cs



4) 시뮬레이팅

> integrator: Box2D에서 사용하는 계산 알고리즘으로, time step를 별도로 설정할 필요가 없게한다.

1
2
3
4
//sample.
//속도와 정확도는 개발목적에 맞게 조절
int32 velocityIterations = 6;
int32 positionIterations = 2;
cs



5) 클린업

> 메모리 관리관련.

> delete시킨 body/fixture등등도 null 초기화 필요(?)






3. Common


* Common (= Common module)은 설정/메모리관리/벡터관련 처리.


1) 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//(Box2D_v2.3.0)\Box2D\Box2D\Common\b2Settings.h
Type
> (기성_자료형)+(숫자)로 조합된 변수명으로 조합됨.
 
Constants
> b2_xxx식으로 명명법 사용.
> 쓸일이 별로 없다고 한다.(원문. Normally you do not need to adjust these constants.)
 
Allocation wrappers
> 메모리 관리 관련
> b2Alloc, b2Free를 활용.
void* b2Alloc(int32 size);
void b2Free(void* mem);
 
Version
> b2Version구조체 참조.
cs



2) 메모리 관리

> Box2D는 다량의 작은객체를 할당하는 경향O

> SOA(Small Object Allocator)

: b2BlockAllocator를 통해 사용가능

: 다량의 가변크기를 가진 pool보유. 요청받은 크기에 맞는 메모리 블럭을 할당해주고, 해당 블럭을 해제하면 pool에 반환되는데, 이 연산들은 빠르고 힙 트래픽이 최소화 가능.

: 이 방식때문에 body/fixture/joint에 메모리 할당&삭제 사용금지.  (body에 직접연결된 오브젝트들?)

: b2World를 통해서 할당해야.

> stack allocator

: b2StackAllocator를 통해 사용가능.

: time step이 실행되는 과정에서 매 단계마다 힙에 할당되는걸 막기 위해 약간의 임시 메모리 공간을 제어.



3) 수학

> 간단한 벡터/배열 모듈이 포함됨.






4. Collision Module


1) Shape

> 충돌이 가능한 영역. 

> Box2D에서는 쉐이프 충돌시 1개 이상의 볼륨(volume)이 있어야 처리가 가능.

  (원형, 폴리곤에도 볼륨 존재)

> 엣지 쉐이프: 엣지에는 볼륨이 없음. 즉 볼륨이 없는 엣지끼리는 충돌불가.

> 체인 쉐이프

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
① 원형 쉐이프
b2CircleShape circle;
circle.m_p.Set(2.0f, 3.0f);
circle.m_radius = 0.5f;
 
--------------------------------------------------
② 폴리곤 쉐이프(Polygon Shapes, 다각형 쉐이프)
// This defines a triangle in CCW order.
b2Vec2 vertices[3];
vertices[0].Set(0.0f, 0.0f);
vertices[1].Set(1.0f, 0.0f);
vertices[2].Set(0.0f, 1.0f);
int32 count = 3;
 
b2PolygonShape polygon;
polygon.Set(vertices, count);
 
void SetAsBox(float32 hx, float32 hy);
void SetAsBox(float32 hx, float32 hy, const b2Vec2& center, float32 angle);
 
--------------------------------------------------
③ 엣지 쉐이프(Edge Shapes)
b2Vec2 v1(0.0f, 0.0f);
b2Vec2 v2(1.0f, 0.0f);
 
b2EdgeShape edge;
edge.Set(v1, v2);
 
// This is an edge shape with ghost vertices.
b2Vec2 v0(1.7f, 0.0f);
b2Vec2 v1(1.0f, 0.25f);
b2Vec2 v2(0.0f, 0.0f);
b2Vec2 v3(-1.7f, 0.4f);
 
b2EdgeShape edge;
edge.Set(v1, v2);
edge.m_hasVertex0 = true;
edge.m_hasVertex3 = true;
edge.m_vertex0 = v0;
edge.m_vertex3 = v3;
 
--------------------------------------------------
④ 체인 쉐이프(Chain Shapes)
// This a chain shape with isolated vertices
b2Vec2 vs[4];
vs[0].Set(1.7f, 0.0f);
vs[1].Set(1.0f, 0.25f);
vs[2].Set(0.0f, 0.0f);
vs[3].Set(-1.7f, 0.4f);
 
b2ChainShape chain;
chain.CreateChain(vs, 4);
 
// Install ghost vertices
chain.SetPrevVertex(b2Vec2(3.0f, 1.0f));
chain.SetNextVertex(b2Vec2(-2.0f, 0.0f));
 
// Create a loop. The first and last vertices are connected.
b2ChainShape chain;
chain.CreateLoop(vs, 4);
 
// Visit each child edge.
for (int32 i = 0; i < chain.GetChildCount(); ++i)
{
b2EdgeShape edge;
chain.GetChildEdge(&edge, i);
}
cs



2) 레이캐스트(RayCast)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
b2Transfrom transform;
transform.SetIdentity();
b2RayCastInput input;
input.p1.Set(0.0f, 0.0f, 0.0f);
input.p2.Set(1.0f, 0.0f, 0.0f);
input.maxFraction = 1.0f;
int32 childIndex = 0;
b2RayCastOutput output;
bool hit = shape->RayCast(&output, input, transform, childIndex);
if (hit)
{
  b2Vec2 hitPoint = input.p1 + output.fraction * (input.p2 – input.p1);
  …
}
cs



3) 쌍방함수

① 오버랩(Overlap)

> 2개의 쉐이프 영역이 겹치는지 체크


② 광범위 접촉(Contact manifolds)

> 보통은 직접처리할 필요가 없다.(원문.you don’t need to compute contact manifolds directly)

1
2
3
4
5
6
7
8
b2WorldManifold worldManifold;
worldManifold.Initialize(&manifold, transformA, shapeA.m_radius,
                         transformB, shapeB.m_radius);
for (int32 i = 0; i < manifold.pointCount; ++i)
{
  b2Vec2 point = worldManifold.points[i];
  …
}
cs


③ 거리(Distance)




④ 타임 오브 임팩트(Time of Impact)

> b2TimeOfImpact클래스 참조.

: Box2D_v2.3.0\Box2D\Box2D\Collision\b2TimeOfImpact.cpp

> 시간 및 경로상, 2개 이상의 shape가 충돌하는걸 계산해내서 오브젝트가 통과되지 않게 하는 목적.

> shape의 회전각이 너무 크면 오차가 발생할수 있다고 함.



4) 다이나믹 트리(Dynamic Tree)

          

> 계층적 AABB트리(Axis-Aligned Bounding Box)

> 직접사용할수는 없고, b2World로 사용이 가능.



5) Broad-phase

> b2BroadPhase클래스로 

> 프로그래머가 직접 관여친 못한다.





5. 다이나믹 모듈


> Box2D에서 가장 복잡한 파트

> 다이나믹 모듈에 포함된 클래스들

: 해당 클래스들간에는 많은 의존성이 있어서 다른 클래스 참조없이 명시가 어려움.

 fixture class [1.1) 주요용어 참조]
 rigid body class [1.1) 주요용어 참조]
 contact class 
 joint classes [1.1) 주요용어 참조]
 world class [1.1) 주요용어 참조]
 listener classes 



1) Body

① 종류

> 위치와 속도값을 가진다.

 b2_staticBody

 속도를 내지 않는다.(원문. has zero velocity.)
 시뮬레이션에서는 움직이지 않고, 사용자에 의해서 이동가능.

 다른 static or kinematic와는 충돌하지 않음.

 b2_kinematicBody

 시뮬레이션에서 자체속도에 맞춰 이동.

 다른 static or kinematic와는 충돌하지 않음.

 b2_dynamicBody

 모든 타입의 body와 충돌이 가능.
 부피가 0이 아닌 유한값을 가짐.
 강체 하나에 2개의 fixture가 붙어있으면, 움직이지도 충돌처리도 안 된다.


② 정의

> Damping

: 공기저항처럼 body의 속도에 영향을 주는 요소.

: Damping parameters should be between 0 and infinity, with 0 meaning no damping, and infinity meaning full damping. Normally you will use a damping value between 0 and 0.1

> Bullets

: Box2D에서는 dynamic 바디와 static바디하고의 터널링을 방지하기 위해 CCD를 기본으로 사용하나, dynamic 바디사이의 충돌에는 사용되지 않습니다.

(Box2D uses continuous collision detection (CCD) to prevent dynamic bodies from tunneling through static bodies. Normally CCD is not used between dynamic bodies.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bodyDef.type = b2_dynamicBody;
 
bodyDef.position.Set(0.0f, 2.0f);   // the body's origin position.
bodyDef.angle = 0.25f * b2_pi;      // the body's angle in radians.
 
bodyDef.linearDamping = 0.0f;      //no damping
bodyDef.angularDamping = 0.01f;    //damping value between 0 and 0.1
 
// Set the gravity scale to zero so this body will float
bodyDef.gravityScale = 0.0f;
 
bodyDef.allowSleep = true;
bodyDef.awake = true;
 
bodyDef.fixedRotation = true;
 
bodyDef.bullet = true;    //dynamic바디와 static바디간 터널링 방지
 
bodyDef.active = true;    //충돌체크 및 레이캐스트등이 적용되는 옵션
 
b2BodyDef bodyDef;
bodyDef.userData = &myActor;    //User data is a void pointer
cs



2) Fixture

> body하나에 0개 혹은 1개 이상의 fixture보유.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//생성
b2FixtureDef fixtureDef;
fixtureDef.shape = &myShape;
fixtureDef.density = 1.0f;
b2Fixture* myFixture = myBody->CreateFixture(&fixtureDef);
 
//소멸
myBody->DestroyFixture(myFixture);
 
//밀도(Density)
fixture->SetDensity(5.0f);//0 ~ +N
body->ResetMassData();
 
//마찰(Friction)
float32 friction;
friction = sqrtf(fixtureA->friction * fixtureB->friction);
 
//탄성(튕김 혹은 반발력, Restitution)
//restitution value is usually set to be between 0 and 1
//b2Contact::SetRestitution를 재정의 가능(원문. You can override the default mixed restitution using b2Contact::SetRestitution)
float32 restitution;
restitution = b2Max(fixtureA->restitution, fixtureB->restitution);
 
//필터링
playerFixtureDef.filter.categoryBits = 0x0002;
monsterFixtureDef.filter.categoryBits = 0x0004;
playerFixtureDef.filter.maskBits = 0x0004;
monsterFixtureDef.filter.maskBits = 0x0002;
 
//센서(Sensor)
/*
    Sensors do not generate contact points. There are two ways to get the state of a sensor
    > b2Contact::IsTouching
    > b2ContactListener::BeginContact and EndContact 
*/
cs






6. 조인트(Joint)


1) 정의

Many joint definitions require that you provide some geometric data. Often a joint will be defined by anchor points. These are points fixed in the attached bodies. Box2D requires these points to be specified in local coordinates.



2) 사용 절차

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*
    Joint Factory
    Don't try to create a joint on the stack or on the heap using new or malloc.
    Joints are destroyed when an attached body is destroyed.
*/
b2RevoluteJointDef jointDef;
jointDef.bodyA = myBodyA;
jointDef.bodyB = myBodyB;
jointDef.anchorPoint = myBodyA->GetCenterPosition();
b2RevoluteJoint* joint = (b2RevoluteJoint*)myWorld->CreateJoint(&jointDef);
... do stuff ...
myWorld->DestroyJoint(joint);
joint = NULL;
 
 
/*
    Using 
*/
b2Body* GetBodyA();
b2Body* GetBodyB();
b2Vec2 GetAnchorA();
b2Vec2 GetAnchorB();
void* GetUserData();
 
b2Vec2 GetReactionForce();
float32 GetReactionTorque();
 
 
/*
    Distance Joint
    > 충돌이 일어나지 않을정도로 떨어진 body들이 body내 anchor로 연결됨.
*/
b2DistanceJointDef jointDef;
jointDef.Initialize(myBodyA, myBodyB, worldAnchorOnBodyA, worldAnchorOnBodyB);
jointDef.collideConnected = true;
jointDef.frequencyHz = 4.0f;
jointDef.dampingRatio = 0.5f;
 
 
/*
    Revolute Joint
    > 겹쳐있는 body들이 body내 anchor로 연결됨.
*/
b2RevoluteJointDef jointDef;
jointDef.Initialize(myBodyA, myBodyB, myBodyA->GetWorldCenter());
... ... ...
b2RevoluteJointDef jointDef;
jointDef.Initialize(bodyA, bodyB, myBodyA->GetWorldCenter());
jointDef.lowerAngle = -0.5f * b2_pi; // -90 degrees
jointDef.upperAngle = 0.25f * b2_pi; // 45 degrees
jointDef.enableLimit = true;
jointDef.maxMotorTorque = 10.0f;
jointDef.motorSpeed = 0.0f;
jointDef.enableMotor = true;
float32 GetJointAngle() const;
float32 GetJointSpeed() const;
float32 GetMotorTorque() const;
... ... ...
void SetMotorSpeed(float32 speed);
void SetMaxMotorTorque(float32 torque);
... Game Loop Begin ...
float32 angleError = myJoint->GetJointAngle() - angleTarget;
float32 gain = 0.1f;
myJoint->SetMotorSpeed(-gain * angleError);
... Game Loop End ...
 
 
/*
    Prismatic Joint
*/
b2PrismaticJointDef jointDef;
b2Vec2 worldAxis(1.0f, 0.0f);
jointDef.Initialize(myBodyA, myBodyB, myBodyA->GetWorldCenter(), worldAxis);
jointDef.lowerTranslation = -5.0f;
jointDef.upperTranslation = 2.5f;
jointDef.enableLimit = true;
jointDef.maxMotorForce = 1.0f;
jointDef.motorSpeed = 0.0f;
jointDef.enableMotor = true;
 
float32 GetJointTranslation() const;
float32 GetJointSpeed() const;
float32 GetMotorForce() const;
void SetMotorSpeed(float32 speed);
void SetMotorForce(float32 force);
 
 
/*
    기타 조인트들
    Pulley Joint
    Gear Joint
    Mouse Joint
    Wheel Joint
    Weld Joint
    Rope Joint
    Friction Joint
    Motor Joint
*/
cs






7. Contacts


Contacts are objects created by Box2D to manage collision between two fixtures.


1) 클래스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
b2Manifold* GetManifold();
const b2Manifold* GetManifold() const;
 
void GetWorldManifold(b2WorldManifold* worldManifold) const;
 
bool touching = sensorContact->IsTouching();
 
b2Fixture* fixtureA = myContact->GetFixtureA();
b2Body* bodyA = fixtureA->GetBody();
MyActor* actorA = (MyActor*)bodyA->GetUserData();
 
 
/*
    Accessing Contacts
    Accessing contacts off b2World and b2Body may miss some transient contacts that occur in the middle of the time step.
    Use b2ContactListener to get the most accurate results.
*/
for (b2Contact* c = myWorld->GetContactList(); c; c = c->GetNext())
{
  // process c
}
 
for (b2ContactEdge* ce = myBody->GetContactList(); ce; ce = ce->next)
{
  b2Contact* c = ce->contact;
  // process c
  // stored in a graph using a contact edge structure.
}
 
 
/*
    Contact Listener
*/
class MyContactListener : public b2ContactListener
{
    public:
    void BeginContact(b2Contact* contact)
      { /* handle begin event */ }
 
      void EndContact(b2Contact* contact)
      { /* handle end event */ }
 
      void PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
      { /* handle pre-solve event */ }
 
      void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
      { /* handle post-solve event */ }
};
cs






8. 월드 클래스


1) Creating and Destroying

1
2
3
b2World* myWorld = new b2World(gravity, doSleep);
... do stuff ...
delete myWorld;
cs



2) Using

> b2World에는 body와 joint가 포함되어 있고, 이걸 생성 및 파괴할 factory도 포함되어 있다.



3) Simulation

1
2
3
4
5
6
7
float32 timeStep = 1.0f / 60.f;
int32 velocityIterations = 10;
int32 positionIterations = 8;
myWorld->Step(timeStep, velocityIterations, positionIterations);
 
//After stepping, you should clear any forces you have applied to your bodies.
myWorld->ClearForces();
cs



4) Exploring the World

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//too simple code(with awake)
for (b2Body* b = myWorld->GetBodyList(); b; b = b->GetNext())
{
    b->SetAwake(true);
}
 
 
//    sample 1.
for (b2Body* b = myWorld->GetBodyList(); b; b = b->GetNext())
{
    GameActor* myActor = (GameActor*)b->GetUserData();
    if (myActor->IsDead())
    {
        myWorld->DestroyBody(b); // ERROR: now GetNext returns garbage.
    }
}
 
//    sample 2.
b2Body* node = myWorld->GetBodyList();
while (node)
{
    b2Body* b = node;
    node = node->GetNext();
    
    GameActor* myActor = (GameActor*)b->GetUserData();
    if (myActor->IsDead())
    {
        bool otherBodiesDestroyed = GameCrazyBodyDestroyer(b);
        if (otherBodiesDestroyed)
        {
            node = myWorld->GetBodyList();
        }
    }
}
cs



5) Ray Cast

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// This class captures the closest hit shape.
class MyRayCastCallback : public b2RayCastCallback
{
public:
    MyRayCastCallback()
    {
        m_fixture = NULL;
    }
    
    float32 ReportFixture(b2Fixture* fixture, const b2Vec2& point,
                        const b2Vec2& normal, float32 fraction)
    {
        m_fixture = fixture;
        m_point = point;
        m_normal = normal;
        m_fraction = fraction;
        return fraction;
    }
    
    b2Fixture* m_fixture;
    b2Vec2 m_point;
    b2Vec2 m_normal;
    float32 m_fraction;
};
 
MyRayCastCallback callback;
b2Vec2 point1(-1.0f, 0.0f);
b2Vec2 point2(3.0f, 1.0f);
myWorld->RayCast(&callback, point1, point2);
 
 
/*
    Caution
    Due to round-off errors,
    ray casts can sneak through small cracks between polygons in your static environment.
    If this is not acceptable in your application, please enlarge your polygons slightly.
*/
void SetLinearVelocity(const b2Vec2& v);
b2Vec2 GetLinearVelocity() const;
void SetAngularVelocity(float32 omega);
float32 GetAngularVelocity() const;
cs



6) 회전 및 이동

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
    Forces and Impulses
*/
void ApplyForce(const b2Vec2& force, const b2Vec2& point);
void ApplyTorque(float32 torque);
void ApplyLinearImpulse(const b2Vec2& impulse, const b2Vec2& point);
void ApplyAngularImpulse(float32 impulse);
 
if (myBody->IsAwake() == true)
{
    myBody->ApplyForce(myForce, myPoint);
}
 
 
/*
    Transformations
*/
b2Vec2 GetWorldPoint(const b2Vec2& localPoint);
b2Vec2 GetWorldVector(const b2Vec2& localVector);
b2Vec2 GetLocalPoint(const b2Vec2& worldPoint);
b2Vec2 GetLocalVector(const b2Vec2& worldVector);
 
for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext())
{
    MyFixtureData* data = (MyFixtureData*)f->GetUserData();
    ... do something with data ...
}
cs



7) AABB Queries

> b2World class has a fast log(N) method for this using the broad-phase data structure. You provide an AABB in world coordinates and an implementation of b2QueryCallback.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class MyQueryCallback : public b2QueryCallback
{
public:
    bool ReportFixture(b2Fixture* fixture)
    {
        b2Body* body = fixture->GetBody();
        body->SetAwake(true);
        
        // Return true to continue the query.
        return true;
    }
};
 
...
 
MyQueryCallback callback;
b2AABB aabb;
aabb.lowerBound.Set(-1.0f, -1.0f);
aabb.upperBound.Set(1.0f, 1.0f);
myWorld->Query(&callback, aabb);
cs






기타. 참조자료


소난의 실험실 :: '컴퓨터/Box2D' 카테고리의 글 목록

하얀기적이 있는 곳.. :: IOS Cocos2d 물리엔진 Box2d 번역






기타. 변경이력


일자

변경이력

2017-08-30

 초안 작성 시작

2018-04-03

 초안 공개

'프로그래밍note > 엔진 관련' 카테고리의 다른 글

유니티: 디버깅 방식  (0) 2018.08.13
Box2d: 요약 및 정리  (0) 2017.08.30
오픈소스 게임엔진  (0) 2017.04.11
유니티: 개발팁 및 최적화  (0) 2016.08.17
유니티: NGUI 2.7 튜토리얼&샘플  (0) 2016.04.09
유니티: 안드로이드 API 플러그인  (0) 2016.04.08






1. C#


 Duality 
 [#net] [#github]

 2D Game Development Framework

 Duality is a modular 2D game engine that provides its own visual editor. It's highly extensible, written entirely in C# and backed by OpenGL.

 -

 OpenRA
 [#net] [#github]

 provides a common platform for rebuilding and reimagining classic 2D and 2.5D RTS games (the OpenRA mods)
 it can be used as a general purpose RTS game engine.
 -

 MonoGame

 [#net] [#github]

 One framework for creating powerful cross-platform games.

 We currently support iOS, Android, MacOS, Linux, all Windows platforms, OUYA, PS4, PSVita, and Xbox One with more platforms on the way.

 -

 Xenko
 [#com] [#github]

 Next-Level C# Game Engine

Xenko is an open-source C# game engine designed for the future of gaming. It comes with a full toolchain and is especially well suited to create realistic games but allows you much more!

 C# 6.0 scripting
 Windows Desktop, Phone & Xbox One / Xamarin for Android, iOS & Linux / macOS and PlayStation 4 coming soon!
 Graphics: 2D, 3D & VR
 파티클, 포스트 이펙트 지원
 Fully-featured Engine: 멀티스레딩, 물리, 오디오, 애니메이션, 이벤트 시스템






2. C++


 CRYENGINE
 [#com]  [#github]

 The most powerful game development platform is now available to everyone. Full engine source code. All features. No royalties. No obligations. No license fee.

 100% royalty-free
 Users can commercialize any games they develop using CRYENGINE as they choose, without being tied to any distribution platforms or middleware services.

 godot
 [#org] [#github]
 Godot is an advanced, feature-packed, multi-platform 2D and 3D open source game engine

 MULTI-PLATFORM EDITOR 지원
 쇼케이스에서 해당 엔진이 사용된 게임들 소개.

 Torque2D/3D
 [#2D]
 [#3D, org]  [#3D, github]

 MIT Licensed

 Torque 2D Forum: [#Beginner]  [#Professional]


 3D, wiki: [#Artists]  [#Scripters]  [#Coders]

 Simple custom startup sequence - Torque 3D

 Spring RTS Engine
 [#com] [#github]

 A powerful free cross-platform RTS game engine
 developed for Windows, Linux and Mac OS X
 Cocos2d-x
 [#org] [#github]
 Cocos2d-x is a suite of open-source, cross-platform, game-development tools used by thousands of developers all over the world.

 Cocos2d-x Programmers Guide
 API Reference
 Developers Manual(Wiki)
 Get Started

 GamePlay
 [#io] [#github]

 Open-source, cross-platform, C++ game framework/engine for creating 2D/3D mobile and desktop games.

 100% written in C++ and provides Lua bindings. Providing a very fast

 윈도우, MacOSX, 리눅스 지원

 openage

 [#mx] [#github]

 Free (as in freedom) open source clone of the Age of Empires II engine

 rewriting its engine in C++14 from scratch (GPLv3+). Including "modern" technologies like OpenGL and GLSL

 -
 Box2d
 [#Google Code Archive]
 A 2D Physics Engine for Games

 물리엔진 기초를 배우는데도 최적화

 Allegro
 [#org] [#sourceforge]
 Allegro is a cross-platform library intended for use in computer games and other types of multimedia programming.
 Supported on Windows, Linux, Mac OSX, iPhone and Android
 Hardware accelerated bitmap and graphical primitive drawing support (via OpenGL or Direct3D)






3. JAVA


 jMonkeyEngine

 [#org]  [#github]

 A cross-platform game engine for adventurous Java developers.

 조명, 쉐이더, 메테리얼, 필터 및 이펙트 지원

 유틸리티: 물리, 지형, 시네마틱, NW, GUI

 [#위키

 libgdx
 [#com]  [#github]

 Publish your games on Windows, Mac, Linux, Android, iOS, BlackBerry and HTML5, all with the same code base.

 licensed under Apache 2.0

 작성시점으로 4156개의 게임을 갤러리를 통해 열람 가능.






4. Python


 Panda3D

 [#org] [#github]

 Panda3D is a game engine, a framework for 3D rendering and game development for Python and C++ programs.

 갤러리에서 랜더링 샘플 열람 가능.

 Blender
 [#org]
 Blender is the free and open source 3D creation suite. It supports the entirety of the 3D pipeline—modeling, rigging, animation, simulation, rendering, compositing and motion tracking, even video editing and game creation.

 무료 3D 모델링 툴과 동일.






기타. 참조자료


Game Engines · GitHub






기타. 변경이력


일자

변경이력

2017-04-11

 초안

'프로그래밍note > 엔진 관련' 카테고리의 다른 글

유니티: 디버깅 방식  (0) 2018.08.13
Box2d: 요약 및 정리  (0) 2017.08.30
오픈소스 게임엔진  (0) 2017.04.11
유니티: 개발팁 및 최적화  (0) 2016.08.17
유니티: NGUI 2.7 튜토리얼&샘플  (0) 2016.04.09
유니티: 안드로이드 API 플러그인  (0) 2016.04.08




3. 최적화


[데브루키/141206 박민근] 유니티 최적화 테크닉 총정리

[160404] 유니티 apk 용량 줄이기

Unity3D :: 게임 최적화 기법 - VallistA






기타. 변경이력


일자

변경이력

2016-08-17

 초안

'프로그래밍note > 엔진 관련' 카테고리의 다른 글

Box2d: 요약 및 정리  (0) 2017.08.30
오픈소스 게임엔진  (0) 2017.04.11
유니티: 개발팁 및 최적화  (0) 2016.08.17
유니티: NGUI 2.7 튜토리얼&샘플  (0) 2016.04.09
유니티: 안드로이드 API 플러그인  (0) 2016.04.08
유니티: 구글 애드몹  (4) 2016.04.05

Sample_NGUI.zip






0. 필요한 파일


파일명

예시 경로

 NGUI 2.0.7c (free version) [#]

 (해당사항 없음)

 유니티(5.3.1f1)

 (설치 기본경로)


Just note that in order to use it for professional purposes you must fall under the same conditions as Unity Free: “free version may not be licensed by a commercial entity with annual gross revenues (based on fiscal year) in excess of US$100,000, or by an educational, non-profit or government entity with an annual budget of over US$100,000.”

* 해석한게 맞다면, 2.7 무료버전의 경우 유니티 프리버전과 같은 라이센스 정책이라고 합니다.

[#링크]






1. NGUI 설치







2. 카메라


1) 생성

NGUI - Open the UI Wizard

지금상태로는 Scene에서 편집한 내용중 일부를 Game window(Ctrl+2)에서 볼수 없습니다.

패널내 스프라이트들의 Depth가 음수인 경우 Clipping Planes>Near를 0이하로 하면 Game window에도 출력이 됩니다.

* 캡쳐상 bg_common, blind는 제가 추가한것이라 UI 최초생성시에는 없는겁니다.


그리고 인스펙터에서 Tag를 MainCamera로 설정해줍니다.


입문시 봤던 튜토리얼의 경우,

씬 생성시 기본제공하는 카메라를 지우라길래 그에 따랐지만 

적지 않은 튜토리얼이나 개발자 게시판을 보면 카메라는 2개 존재하는게 일반적이라고 하는글도 있어서 이 부분은 case by case같습니다.






3. UI 구성


1) Maker

① Atlas maker

SkyBaby의 살아가는 그 이유 ! :: [Unity3D] Atlas Maker로 Atlas 이미지 만들기 (NGUI)

에러: NGUI altas 알파영역 노이즈


② Font

> NGUI에서 사용할 Bitmap Font 제작 (BM Font Maker) : 네이버 블로그

Think Different :: [Unity3D] NGUI와 BMFont를 이용한 데미지(숫자) 폰트 만들기


③ 기타

보금자리 :: [ NGUI ] ScrollView 만들기

> 씬관리

   File - Build Settings에서 씬을 드래그 앤 드랍등으로 등록시킵니다.

   불필요해진 씬은 파일과 해당 메뉴에서 삭제해주면 됩니다.






4. 입력 처리


* 예시로 사용한 제어 스크립트는 Panel에 붙인 상태입니다.

* 카메라의 인스펙터에서 Tag를 MainCamera로 설정해줘야 합니다.


1) 인스펙터



2) 스크립트(C#)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
... ... ...
void Update () 
{
    if (Input.GetMouseButtonDown(0))
    {
        DoClick();
    }
}
 
private void DoClick()
{
    string colliderName = null;
 
    Vector2 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    RaycastHit2D hit = Physics2D.Raycast(worldPoint, Vector2.zero);
 
    if (hit.collider != null)
    {//Box Collider 2D
        colliderName = hit.collider.name;
        //Debug.Log("DoClick, hit.collider.name=" + colliderName);
    }
    else if (UICamera.lastHit.collider != null)
    {//레이캐스트가 먹통일 경우. [인스펙터==Box Collider]
        colliderName = UICamera.lastHit.collider.name;
    }
    
    if (colliderName == "btn_menu0")
    {
        Destroy(gameObject);
        Application.LoadLevel("Scene_B");
    }
    else if (colliderName == "btn_menu1")
    {
        //
    }
    else if (colliderName == "btn_quit")
    {
        Application.Quit();
    }
}
... ... ...
cs






5. 오브젝트 접근 및 제어


* 예시로 사용한 제어 스크립트는 Panel에 붙인 상태입니다.

* Scene_B에서 UI Grid를 이용한 예제입니다.



1) 화면 리사이즈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using UnityEngine;
using System.Collections;
 
public class BaseHandler : MonoBehaviour
{
    //================================================================================
    //  PROTECTED, SYS
    //================================================================================
    protected virtual void Start()
    {
        UIRoot root = GameObject.Find("NGUI_ROOT").GetComponent<UIRoot>();
        root.automatic = true;
        root.manualHeight = 480;
        root.minimumHeight = 480;
        root.maximumHeight = 1440;//2560 x 1440
 
        //RESIZE.
        float perx = 1920.0f / Screen.width;
        float pery = 1080.0f / Screen.height;
        //카메라
        //Camera camera = GameObject.Find("NGUI_Camera").GetComponent<Camera>();
        Debug.Log(this.transform.parent.name);
        Debug.Log(this.transform.parent.transform.parent.name);
        Camera camera = this.transform.parent.transform.parent.GetComponent<Camera>();
        camera.orthographicSize = (perx > pery) ? perx : pery;
    }
}
cs



2) 씬 핸들러

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
using UnityEngine;
using System.Collections;
 
public class ScneneB_Handler : BaseHandler
{
    protected override void Start()
    {
        base.Start();
        
        UIGrid grid = this.transform.Find("UI_Grid").GetComponent<UIGrid>();
        //UIGrid grid = GameObject.Find("UI_Grid").GetComponent<UIGrid>();
        
        for (int idx = 0; idx<10; idx++)
        {
            GameObject listChild = Resources.Load("Prefabs/UI_Listchild"as GameObject;
            
            int tmp = idx+1;
            listChild.transform.FindChild("idx").GetComponent<UILabel>().text = tmp.ToString();
            tmp = Random.Range(0100);
            listChild.transform.FindChild("content").GetComponent<UILabel>().text = "random_num="+tmp.ToString();
 
            NGUITools.AddChild(grid.gameObject, listChild);
        }
    }
 
    void Update () 
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            DoBack();
        }
        else if (Input.GetKey(KeyCode.Escape))
        {
            DoBack();
        }
        else if (Input.GetMouseButtonDown(0))
        {
            DoClick();
        }
    }
    
    private void DoBack()
    {
        Destroy(gameObject);
        Application.LoadLevel("Scene_main");
    }
    
    private void DoClick()
    {
        string colliderName = null;
 
        Vector2 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        RaycastHit2D hit = Physics2D.Raycast(worldPoint, Vector2.zero);
 
        if (hit.collider != null)
        {//Box Collider 2D
            colliderName = hit.collider.name;
            //Debug.Log("DoClick, hit.collider.name=" + colliderName);
        }
        else if (UICamera.lastHit.collider != null)
        {//레이캐스트가 먹통일 경우.
            colliderName = UICamera.lastHit.collider.name;
        }
        
        if (colliderName == "sample_author")
        {
            Application.OpenURL("http://analog-green.tistory.com/");
        }
    }
}
cs


Panel 제어 스크립트 붙인 이유이기도 합니다.

NGUITools.AddChild사용이나 오브젝트 접근시 무난한 위치이기 때문입니다.






6. 애니메이션


1) 단일 스프라이트 애니메이션

유니티 NGUI 버튼 애니메이션 만들기 : 네이버 블로그

유니티 애니메이션 만들고 재생하기~!

NGUI – POPUP 애니메이션 효과주기 // TweenScale방식


2) 그외

03. Live2D 실습 강좌 - Live2D Cubism 2 한글매뉴얼






기타. 참조자료


스마트아카데미 :: APP 개발 온라인 강좌 제4강 [4-5.2.1] - NGUI 구성

[Unity3d] 카메라 2개 동시에 보기 :: JENEMIA






기타. 변경이력


일자

변경이력

2016-04-09

 초안

2017-06-26

 애니메이션 항목추가.


* Unity 5.3.1f1 기준으로 작성됐습니다.

* 이클립스 기준입니다.






0. 필요한 파일


파일명

예시 경로

 classes.jar

(아래의 경로들에서 찾을수 있습니다.)

 (...Unity설치경로...)\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes

 (...Unity설치경로...)\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Release\Classes

 (...Unity설치경로...)\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Development\Classes

 (...Unity설치경로...)\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Development\Classes

 이클립스

 (생략)






1. 이클립스에서


1) 프로젝트 설정

> 프로젝트 생성시, 유니티에서 사용중인 패키지명과 동일하게 합니다.

> (프로젝트 우클릭)-Properties-Java Build Path


앞서 명시해둔 경로를 사용해서 classes.jar을 연결.



2) JAVA코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.xxxxxx.xxxxxx;//Unity 프로젝트와 동일한 패키지
 
import com.unity3d.player.UnityPlayerActivity;
 
import android.os.Bundle;
import android.widget.Toast;
 
 
public class JavaNative extends UnityPlayerActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate( savedInstanceState );
        //setContentView( R.layout.activity_main );
    }
    
    public void SetToast(final String msg)
    {
        this.runOnUiThread(new Runnable() {
                public void run() {
                    Toast.makeText( JavaNative.this, msg, Toast.LENGTH_LONG ).show();
                }
            });
    }
}
cs



3) AndroidManifest.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xxxxxx.xxxxxx"
    android:installLocation="internalOnly"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <application
        android:theme="@android:style/Theme.NoTitleBar" 
        android:icon="@drawable/icon"
        android:label="MY_APP_NAME"
    >
        <activity
            android:name="com.unity3d.player.UnityPlayerActivity"
            android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
            android:label="MY_APP_NAME"
            android:screenOrientation="landscape" >
 
        </activity>
        <activity android:name="com.xxxxxx.xxxxxx.JavaNative" 
            android:label="MY_APP_NAME"
            android:icon="@drawable/icon"
            android:screenOrientation="landscape"
            android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
            <!--android:launchMode="singleTask"-->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
        <activity
            android:name="com.unity3d.player.UnityPlayerNativeActivity"
            android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
            android:label="MY_APP_NAME"
            android:screenOrientation="landscape" >
        </activity>
                <activity
            android:name="com.unity3d.player.UnityPlayerProxyActivity"
            android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
            android:label="MY_APP_NAME"
            android:screenOrientation="landscape" >
        </activity>
    </application>
 
</manifest>
cs


(프로젝트 우클릭)-Export






2. 유니티에서


1) 파일배치

> 전 단계의 프로젝트내 res폴더, AndroidManifest.xml, jar파일을

   (...유니티 프로젝트...)\Assets\Plugins\Android에 복사합니다.



2) C#

1
2
3
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
jo.Call("SetToast""THIS IS ANDROID API");
cs






기타. 참조자료


유니티 - 매뉴얼: Android 플러그인 빌드

How To Use Android Plugins in Unity Apps | Vuforia Library Prod






기타. 변경이력


일자

변경이력

2016-04-08

 초안







0. 필요한 파일


파일명

예시 경로

 GoogleMobileAds.unitypackage

 [#]

 (해당사항 없음)

 android-sdk

 C:\android-sdk-windows







1. 애드몹 가입 및 광고 ID생성


참조: 안드로이드: 구글 애드몹, 1. 애드몹 가입 및 광고 ID생성






2. 유니티, import






3. 유니티, 구현


* 마켓에서 'Device ID'로 검색하면 디바이스 아이디 검출앱이 꽤 많습니다.
물론 이미 알고 있는 경우 생략 가능합니다.


1) 스크립트, 배너

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
... ... ...
using GoogleMobileAds.Api;
 
public class SampleHandler : MonoBehaviour
{
    private BannerView adBannerView = null;
 
    void Start ()
    {
        if (adBannerView == null)
        {
            AdRequest.Builder builder = new AdRequest.Builder();
            adRequest = builder.Build();
            //adRequest = builder.AddTestDevice(AdRequest.TestDeviceSimulator).AddTestDevice("MY_DEVICE_ID").Build();//FOR TEST
            adBannerView = new BannerView("ca-app-pub-xxxxxxxxxxxxx", AdSize.Banner, AdPosition.BottomLeft);
            adBannerView.LoadAd(adRequest);//해당 함수로 광고 요청 반복 가능.
        }
    }
 
    ... ... ...
    private void DoAD()
    {
        adBannerView.Show();
    }
}
cs



2) 스크립트, 전면광고

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
... ... ...
using GoogleMobileAds.Api;
 
public class SampleHandler : MonoBehaviour
{
    private InterstitialAd adInterstitial = null;
    private AdRequest adRequest = null;
 
    void Start ()
    {
        if (interstitialAd == null)
        {
            adRequest = builder.Build();
            //adRequest = builder.AddTestDevice(AdRequest.TestDeviceSimulator).AddTestDevice("MY_DEVICE_ID").Build();//FOR TEST
            adInterstitial = new InterstitialAd("ca-app-pub-xxxxxxxxxxxxx");
            adInterstitial.AdClosed += AdListener;//전면광고를 종료시 이벤트 추가.
            adInterstitial.LoadAd(adRequest);
        }
    }
    ... ... ...
    private void DoAD()
    {
        if(adInterstitial.IsLoaded())
        {
            adInterstitial.Show();
        }
    }
 
    private void AdListener(object sender, System.EventArgs args)
    {
        adInterstitial.LoadAd(adRequest);
    }
}
cs






기타. 참조자료


예제.

애드몹(광고) 붙이기


기타

Unity - Scripting API: ADBannerView

> Banner Ads  |  AdMob for Android  |  Google Developers

unity - ResolutionException: Cannot find candidate artifact for com.google.android.gms:play-services-games:8.1+ - Game Development Stack Exchange






기타. 변경이력


일자

변경이력

2016-04-05

 초안

  1. 유니티 초보 2017.01.20 03:46

    interstitial.AdClosed += EventAdClose;
    이함수가 작동을 하지 않는데무슨 오류가 뜨거든요 대체 함수나 그런게 없을까요 한번 실행시키고 백키로뒤로 가면 다시 온 gui가 작동을 안해요 삭제가 안되는거같은뎅..

    • Favicon of https://analog-green.tistory.com BlogIcon MTG 2017.01.20 22:28 신고

      안녕하세요,
      혹시 말씀하신 오류 메시지문을 알수 있을까요?

  2. 초보 2017.07.02 06:48

    진짜 감사합니다 이런 알찬정보공유해주셔서

  3. Favicon of https://analog-green.tistory.com BlogIcon MTG 2017.07.02 19:34 신고

    별 말씀을요.
    불필요한 시간낭비를 줄여서 보다 효율적인 개발에 도움이 된다면 저로써는 포스팅 목적이 달성된거니 기쁠뿐입니다.

* Unity3D 5.3.1f1 기준으로 작성됐습니다.

* 다른버전을 원하시면 유니티 아카이브에서 찾을수 있습니다. [#링크]

* 해당 포스트는 입문자용으로 최소한의 내용으로 구성했기 때문에 난이도가 올라가는 부분은 생략했습니다.


유니티: 입문 및 기초(1)

유니티: 입문 및 기초(2)






0. 프로젝트 구성


이후의 예시등은 아래의 캡쳐기준입니다.


* 프로젝트 파일 용량을 줄이려면 (프로젝트명)\Library\ShaderCache내에 있는 폴더를 다 지워도 괜찮지만 

(프로젝트명)\\Library\metadata에 있는걸 삭제시 프로젝트 자체를 열지 못하게 됩니다.






1. 카메라


1) 2D와 3D 전환

오브젝트 배치보다 순서가 앞서는 이유는 화면상 보이는 방식이 다르기때문입니다.

2D게임을 의도했어도 카메라가 3D기준이면 스프라이트 배치시 좌표를 깔끔하게 맞추는 작업이 비효율적으로 될수도 있습니다.



2) 좌표

> Unity3D :: 유니티 카메라 관련 좌표값 변경 스크립트들



3) 기타

> 2D게임으로 생성했어도 스프라이트 배치와 미리보기가 매끄럽지 못하면 해당 옵션을 확인해봐야 합니다.

  projection에는 2가지 옵션값이 있으며 해당 옵션의 차이는 아래와 같습니다.

perspective도 연출에 따라서 2D게임에도 가능하겠지만, 평면적인 배치에 친화적인건 Orthographic쪽입니다.





2. 씬편집


* 씬이란?

 게임 오브젝트들이 배치된 공간으로 씬의 내용물은 디스플레이로 보여지면 카메라를 이용해서 보여지는 영역이 조절됩니다.

안드로이드 API쪽으로는 액티비티랑 비슷한 개념입니다.

제가 아는 범위에서 차이점을 정리하면 아래와 같습니다.

액티비티=디스플레이에 존재하는 출력화면

   씬=카메라로 제어되는 시야내 배치된 오브젝트들의 출력화면



1) 계층(Hierarchy)에서

 가급적 연관성이 높은 오브젝트를 빈 오브젝트(Empy Object)를 이용해서 폴더처럼 묶어두는게 좋다고 봅니다.

 가령, 벽돌을 여러개 쌓아서 성을 만들었는데 성을 다른위치로 옮겨야 합니다. 폴더처럼 묶어두었다면 그 덩어리를 통채로 이동시키면 되지만, 성을 쌓은 벽돌들이 개별이라면 어떻게 될까요?

 아니면 캐릭터 머리위에 따라 다니는 체력게이지 혹은 레벨을 표시하는 객체가 있습니다. 그리고 캐릭터에 부속되는 무기 혹은 이펙트 이미지 출력물의 좌표를 매번 지정하지 않는 방법이 있다면?


> UI관련 캔버스의 경우 씬내에서 2개 이상 사용가능하며 UI 컴포넌트 사용시, 캔버스가 필수라고 합니다.

UI 튜토리얼

UNITY IN DEPTH :: [UI] 체력바 HUD 만들기



2) 인스펙터(Inspector)에서

씬에 존재하는 오브젝트를 대상으로 속성을 지정할수 있습니다.

작업 가능한 속성을 크게 분류하면 아래와 같습니다.

 태그

유니티 - 매뉴얼: 태그

> 명명법에 맞춰 태그명을 지정해두면 최적화에도 유용하다는 글이 보이긴 합니다.

 좌표

 Transform

 x,y,z축 방향으로 좌표값 조정.

 계층에서 빈 오브젝트를 생성해도 기본적으로 있는 속성값입니다.

 Scale에 있는 값을 1보다 크게 하면 조정된 값만큼 부피가 증가합니다.

 물리

 Pysics, Pysics 2D

 충돌체크(xxx Collider), 중력등등

 Pysics가 3D기반, Pysics 2D에 2D기반 충돌처리로 구성됐습니다.

 충돌체크의 경우 오브젝트의 형태나 구현하려는 방식에 맞춰서 선택하시면 됩니다.

<- 중력이 필요한 오브젝트 사용

 사운드

 Audio

 효과음이나 배경음을 추가하려면 Audio Source, Audio Listener속성이 필요합니다.

 스크립트

 Script
 메인 스트림은 C#이고 구글링이 가능한 자료도 이쪽이 많기 때문에 C#을 추천드립니다. 몇몇 책자는 자바스크립트기준이더군요.

 스프라이트

 Sprite Renderer

 '3) 스프라이트 관련'항목 참조.

 매쉬

 유니티에서 기본으로 3D object에 있는 세부속성은

 해당 포스트는 목표상 텍스쳐를 적용하는 부분까지만 다루겠습니다.

 이펙트 (해당 포스트에서는 다루지 않습니다.)



3) 스프라이트 관련

(프로젝트명)\Assets\Sprite에 사용할 이미지 파일을 준비해야 합니다.

해당 경로내 이미지 파일은 Sprite Editor에서 스프라이트 시트처럼 이미지 파일내 사물들을 박스로 잘라서 분할처리도 가능합니다.


Sprite항목에서 이미지 파일을 지정해주면 됩니다.






3. 스크립트


1) 씬전환

1
2
3
4
5
6
7
8
9
10
11
12
void Update ()
{
    ... ... ...
    if (Input.GetKeyDown(KeyCode.Space))
    {
        ... ... ...
        Destroy(gameObject);
        Application.LoadLevel("next_sceneFile_name");
        //    (project_name)\Assets\Scenes내에 있는 씬파일(*.unity)
        ... ... ...
    }
}
cs

참고로

couldn't be loaded because it has not been added to the build settings or the AssetBundle has not been loaded. To add a scene to the build settings use the menu File->Build Settings.같은 에러 발생시

필요한 씬을 활성화 시킨채 빌드세팅애서 추가시키면 해결됩니다.

경로: File>Build settings.



2) 오브젝트 제어 관련

"Space.Self/World" using transform.Translate in #unity3d. #unitytips #gamedev #indiedev

Unity에서 게임오브젝트 접근하는 방법에 대해..

다른 오브젝트 접근하기 | SMART UNITY

> 계층을 통해 씬에 배치한 오브젝트에 스크립트파일을 드래그 앤 드랍시키면,

   해당 오브젝트에 스크립트 연결이 됩니다.

Inspector에서 변수값이나 오브젝트 변경을 쉽게 하려면 클래스 멤버의 접근제한자를 public으로 해야 합니다.

   클래스 멤버 자료형이 맞으면 계층에 있는 UI 구성 혹은 prefabs등을 드래그 앤 드랍으로 연결이 가능합니다.

> (2D기준)총알처럼 다수로 일회성으로 사용되는건 계층에 배치하지 않고,

  Prefabs로 하나 만들어서 다연발이 가능합니다.(Shot, ShotMove)

유니티 - 매뉴얼: 런타임에서의 프리팹의 인스턴스화


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using UnityEngine;
using System.Collections;
 
public class Motin : MonoBehaviour
{
    public float gap = 0.06F;
    public float motionSpeed = 0.002F;
    
    bool isUp = true;
    private Vector3 pos;
    private float orig_y = 0.0F;
    private float max_y = 0.0F;
    
    void Start()
    {
        pos = transform.position;
        orig_y = pos.y;
        max_y = orig_y + gap;
    }
 
    void Update ()
    {
        pos = transform.position;
        
        if(isUp == true)        {            pos.y += motionSpeed;        }
        else if(isUp == false)    {            pos.y -= motionSpeed;        }
        
        if(pos.y < orig_y)
        {
            isUp = true;
            pos.y = orig_y;
        }
        else if(pos.y > max_y)
        {
            isUp = false;
            pos.y = max_y;
        }
        
        transform.position = pos;
    }
    
    public Vector3 getPosition()
    {
        Vector3 tmpPos = transform.position;
        
        return tmpPos;
    }
}
cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
 
public class ControlCharacter : MonoBehaviour
{
    public Text nameTxt;
    public string nameStr = "Insert_name";
 
    public Text hpText;
    public int hp = 0;
    public int hpMax = 100;
 
    private Vector3 pos;
    //private bool _isEnd = false;
    private Shot obj_shot;
    private Motion motion;
 
    void Start()
    {
        nameTxt = nameTxt.GetComponent<Text>();
        nameTxt.text = nameStr;
        hpText = hpText.GetComponent<Text>();
 
        obj_shot = GetComponent<Shot>();
        //motion = GetComponent<Motion>();
 
        SetText();
    }
 
    void Update()
    {
        if (Input.touchCount == 1)
        {
        }
    }
 
    private Vector3 tmpPos;
    void FixedUpdate()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (obj_shot != null)
            {
                tmpPos = transform.position;//motion.getPosition();
                obj_shot.doShot(true, tmpPos.x, tmpPos.y);
                GetComponent<AudioSource>().Play();
            }
        }
        
        SetText();
    }
 
    void SetText()
    {
        hpText.text = "HP: " + hp.ToString() + " / " + hpMax.ToString();
    }
}
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using UnityEngine;
using System.Collections;
 
public class Shot : MonoBehaviour
{
    public Transform PrefabShot;
    public float shootingRate = 0.25f;
    
    private float shootCooldown;
    private Vector3 pos;
 
    void Start()
    {
        shootCooldown = 0f;
    }
    
    void Update()
    {
        if (shootCooldown > 0)
        {
            shootCooldown -= Time.deltaTime;
        }
    }
    
    public void doShot(bool isShot, float argX, float argY)
    {
        shootCooldown = shootingRate;
 
        var shotTransform = Instantiate(PrefabShot) as Transform;
        pos.x = argX;
        pos.y = argY;
        shotTransform.position = pos;//argPos;//transform.position;
 
        ShotMove beam = shotTransform.gameObject.GetComponent<ShotMove>();
        if (beam != null)
        {
            beam._isShot = isShot;
        }
    }
}
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using UnityEngine;
using System.Collections;
 
public class ShotMove : MonoBehaviour
{
    public int damage = 10;
    public bool _isShot = false;
    public int startX, startY;
    public string tag = "ATK_to_Enemy";/*    ATK_to_enemy
                                            ATK_to_player
                                        */
 
    public Vector2 speed;// new Vector2(6, 4);
    private Vector2 movement;
 
    private Vector3 pos;
    
    void Start ()
    {
        pos.x = startX;
        pos.y = startY;
        transform.position = pos;
        //pos = transform.position;
    }
    
    void Update()
    {
        if(_isShot)
        {
            speed = new Vector2(64);
            pos = transform.position;
            pos.x = pos.x + speed.x;
            pos.y = pos.y + speed.y;
            
            if(pos.y > 40.0F)    {    Destroy(this.gameObject);        }
            //else                {    transform.position = pos;    }//너무 빨라서 조절 안 됨.
            else                {    movement = new Vector2( pos.x, pos.y);    }
        }
    }
    
    void FixedUpdate()
    {
        // Apply movement to the rigidbody
        GetComponent<Rigidbody2D>().velocity = movement;
    }
}
cs



3) 충돌체크






4. 조명


몇몇 용어만 정리해두도록 하겠습니다.


1) 조명의 요소[각주:1]

 환경광
 (Ambient Light)

 다른 표면에서 반사된 빛을 받는것.

 반사된 빛을 비교적 저렴하고 간단하게 구현하는 방법.

 난반사광

 (Diffuse Light)

 모든 방향으로 동일하게 반사되므로 위치와는 관계없이 관찰자의 눈에 빛이 도달하고 관찰자의 위치를 고려할 필요가 없다.

 정반사광

 (Specular Light)

 특정한 방향으로 진행하며, 표면에 닿으면 한 방향으로 강하게 반사하여 특정한 각도에서만 관찰할 수 있다. 관찰자의 시점을 모두 고려해야 한다.



2) 라이팅

> Point Lights / Spot Lights / Directional Lights / Area Lights

  유니티 - 매뉴얼: Lighting Overview

라이트(Light) 사용하기






5. IO


1) 클릭, 버튼 메시지

레이캐스트가 코드나 편집상 깔끔하나
NGUI 습작 초기에 레이캐스트가 먹통이라 임시로 쓰던 방법입니다.

 버튼 메시지는 캡쳐상 포함이긴 하지만,

 NGUI 최신버전에서는 비권장이기도 해서 굳이 쓸 필요는 없습니다.
 실제로도 코드상 버튼 메시지를 활용치 않았습니다.

 참고로 예시의 UI_controller는 계층(Hierarchy)에서 입력제어용 코드를 붙인 오브젝트 이름이고,
 함수명은 아래의 코드와 맞춰주면 됩니다.

MainCamera Culling Mask: Default, TransparentFX, IgnoreRaycast, Water


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
... ... ...
void Update ()
{
    if (Input.touchCount >= 1 || Input.GetKey(KeyCode.Mouse0))
    {
        DoClick();
    }
}
 
void DoClick()
{
    if (UICamera.lastHit.collider != null)
    {
        if (UICamera.lastHit.collider.name == "obj_name")
        {
            ... ... ...
        }
    }
}
... ... ...
cs






기타. 샘플 프로젝트


* 샘플에 포함된 이미지들은 학습용 예제로만 사용했습니다.

sample_proj.7z


Min-gu, Kim :: Physics.Raycast 활용하여 3D 공간에서 충돌 체크하기

> 레이캐스트 샘플






기타. 변경이력


일자

변경이력

2016-01-03

 초안

2016-03-16

 5. IO 추가.

2016-05-11

 Space.Self/World 팁 링크 추가.


  1. DirectX9를 이용한 3D GAME 프로그래밍 입문, pp151-152. [본문으로]
  1. Favicon of https://iwmug.tistory.com BlogIcon 서지웅 2016.01.31 22:58 신고

    혹시 거지키우기만들기 강좌해주실수있나요???
    강좌보고 참고해서 게임한번 제작해보려고 하는데
    거지키우기같은 게임만드는 강좌는 없네요...
    해주시면 저같은 초보제작자들 도움이 많이 될겁니다
    죄송하지만 한번 부탁드려봐요!!

    • Favicon of https://analog-green.tistory.com BlogIcon MTG 2016.02.01 23:56 신고

      안녕하세요?
      말씀하신게 무슨 방향성인지 전혀 모르겠습니다.
      죄송합니다.






1. IDE별 특성 개요


 IDE

 지원되는 개발언어

 개발가능한 모바일 플랫폼

 appmethod [#공식페이지]

 C++

 Android, iOS

 cocos2d-x [#공식페이지]

 C++
 Lua, Javascript// 자매품

 파이썬[#]

 Android, iOS,

 Window phone(파이썬 제외)

 corona [#공식페이지]

 Lua

 Android, iOS, Window phone,

 Kindle Fire

 kivy [#공식페이지]

 파이썬(2.7 & 3.xx)

 Android, iOS

 MS visual studio community

 [#공식페이지]

 C#, C++, Python 등 Android, iOS
 rubymotion [#공식페이지] Ruby Android, iOS
 Unity [#공식페이지] C# (몇몇 언어가 더 있으나 문서 빈약) Android, iOS, Window phone8
 Xamarin [#공식페이지] C# 5.0 Android, iOS, Window phone






2. 튜토리얼


1) appmethod

공식페이지

앱메소드 튜토리얼 : 안드로이드 앱 개발하기(C++)

Android and iOS Tutorials | Appmethod

Tutorials - Appmethod Topics

Build an Android App in 2 Minutes with Appmethod - YouTube



2) cocos2d-x

미분류

게임 개발 포에버 :: cocos2d-x 3.0 beta의 개발 환경 설치 및 빌드 : win32, android

Creating multi-platform games with Cocos2d-x version 3.0 or later | Intel® Developer Zone



3) corona

공식페이지

Getting Started with Corona SDK | Corona Labs

Building and Distribution(안드로이드, 아이폰, 킨들파이어)


Mark Falkland::youtube

Corona SDK - Flappy Bird Code Walk-Through [7]

> Corona SDK Game Tutorial [14편]

> Corona SDK App Creation [5편]



4) kivy

미분류

Accessing Android Sensors with Kivy via Plyer

Kivy with Python tutorial for Mobile Application Development [12편]



5) MS visual studio community

VS2015에서 C++로 안드로이드 앱 개발하기 - Step1

Visual Studio에서 플랫폼 간 개발

Visual C++로 안드로이드 앱 개발하기 .. : 네이버블로그

유튜브

> Building Android and iOS Apps with Visual Studio (Hybrid Applications) - YouTube

Developing Native iOS, Android and Windows Apps In C# With Xamarin & Visual Studio 2015 - YouTube

미분류

하이브리드앱 개발 on Visual Studio #1 | 개밥 먹는 블로그



6) rubymotion

공식페이지

> 개발환경 세팅 매뉴얼[#]



7) Unity

> (유니티의 경우 자료검색이 쉽고 선택지가 많기때문에 생략해두겠습니다.)



8) Xamarin

forenty ::

xamarin에 날개들 달자!! Genymotion 설치 및 설정

> xamarin EditText Button을 이용한 간단한 예제

개밥 먹는 블로그 | 새롭거나 흥미로운 개발 경험 공유하기

Xamarin 앱 개발 테스트 #1

Xamarin 앱 개발 테스트 #2






기타. 읽을거리


Top Game Development Tools: Pros and Cons - Developer Economics

16 top mobile game development tools | Game Development Tools & Tech | Develop

15 essential mobile game development tools | Game Development Tools & Tech | Develop

Cross Platform Mobile Development: 10 Best Tools

Ten of the Best Cross-Platform Mobile Development Tools for Enterprises


Unity vs Xamarin


10 Excellent Platforms for Building Mobile Apps

Best App Maker - App Builders and Creators - Business News Daily






기타. 변경이력


일자

변경이력

2015-11-07

 초안

2016-02-03

 'Visual C++로 안드로이드 앱 개발하기' 링크 추가


* Unity3D 5.3.1f1 기준으로 작성됐습니다.

* 다른버전을 원하시면 유니티 아카이브에서 찾을수 있습니다. [#링크]

* 해당 포스트는 입문자용으로 최소한의 내용으로 구성했기 때문에 난이도가 올라가는 부분은 생략했습니다.


유니티: 입문 및 기초(1)

유니티: 입문 및 기초(2)






0. 설치 및 빌드 관련


다운로드


② 라이센스 선택

 무료판은 PC판으로만 빌드가 가능하고, 모바일로 빌드가 되지 않는다고 한다.

 PERSONAL EDITON

 PROFESSIONAL EDITION

 무료버전

 유료버전






1. 프로젝트 생성/불러오기


1) 생성

중앙의 New project나 상단의 NEW를 누릅니다.

프로젝트명을 입력하면,아래 경로(Location) 하위폴더로 생성이 됩니다.

예. D:\Projects-Unity3D\sample_proj

참고로 경로에 한글을 비권장입니다.



2) 불러오기

OPEN이라는 메뉴를 통해서

위와같이 프로젝트 폴더에 들어가서 '폴더 선택'을 해주면 됩니다.






2. 기본 레이아웃


1) 씬(Scene)

-> 디자인 작업 영역.

-> 우클릭을 한채 도리각으로 화면이 회전하고, 마우스 휠로 거리조절이 가능.

-> 카메라가 (Hierarchy나 씬에서 직접 클릭하는등으로)선택된 상태이면 Inspector영역에 설정하는 메뉴들이 활성화 된다.



2) Console

-> 디버깅 및 에러 메시지 확인용



3) 계층(Hierarchy)

-> 현재 활성화된 씬을 기준으로 존재하는 게임오브젝트 구성원 목록



4) 인스펙터(Inspector)

-> 선택된 객체에 저장된 속성등을 조정할수 있다. (위치/카메라정보 등등)



5) 핫키

-> 씬내 위치이동 / (선택한)객체위치변경 / (선택한)객체 각도 수동조절 / (선택한)크기조절

-> Center or Pivot: 객체의 회전각 수동설정시 회전축을 어느것으로 할것인가

-> Local or Global: DX등에도 나온 로컬스페이스/글로벌 스페이스 쯤?






기타. 참조자료


Game Dev Nation

Creating A 2D Game with Unity | Game Dev Nation

Unity 2D Game Tutorial






기타. 변경이력


일자

변경이력

2013-02-18

 초안. Unity3D 4.0.1 기준.

2015-10-09

 5.2.1f1 기준.

2015-12-25

 5.2.1f1 기준.


+ Recent posts