'유니티'에 해당되는 글 227건

  1. 2014.02.04 반복되는 배경 만들기(무한 스크롤링) - 원경 (6)
  2. 2014.02.04 유니티 창 여러개 띄우기
  3. 2014.02.04 현재 보고 있는 Scene와 똑같이 Game 뷰를 보는 방법
  4. 2014.02.04 스케줄 관리 프로그램 트렐로
  5. 2014.02.04 [펌] MonoBehaviour 오버라이딩 가능 함수 레퍼런스 총 정리
  6. 2014.02.04 샌드박스형 게임이란(마인크래프트 , GTA 등)
  7. 2014.02.03 글자 크기를 점점 커지게 하면서 사라지게 하기
  8. 2014.02.03 게임 매니저에서 FSM 으로 게임 분기 처리하기
  9. 2014.02.03 충돌 처리시 Tag 설정 값 파악하기
  10. 2014.02.03 Quaternion.LookRotation

반복되는 배경 만들기(무한 스크롤링) - 원경

|

무한으로 반복되는 배경 만들기.

Offset를 조절해서 만든다.


배경을 만들때 원근감을 조절하기 위해서 시차스크롤링 기법을 사용한다.

근거리 배경과 원거리 배경의 속도를 달리해서 입체감을 높이는 기법이다.

원거리 배경의 속도는 늦게 , 근거리 배경의 속도는 빠르게 헤보자.


2D 게임을 개발 목적으로 

메인카메라는 Z값 -30 , size 8 , Orthographic로 맞춘다.




배경을 사용되는 오브젝트는 유니티 4.2 부터 생긴 Quad를 사용하자. 정점 개수가 4개인 아주 가벼운 오브젝트다. 2D 게임을 만들때 좋음.




하늘 관련 배경은 구글에서 검색해서 찾아보자. 구글에서 검색시 Sky Texture 등으로 검색하면 빨리 찾을수 있다.

앞으로 사용되는 이미지들은 모두 뒤에 Texture 등을 붙여서 검색해서 찾아보자. 필자는 Sky Sprite로 찾은 이미지중 마음에 드는 이미지 하나를 선택해서

적용 했다.








스케일 20,20,0

위 그림을 덮어씌어줬다.


스크립트를 작성해보자.

스크립트의 이름은 CsSky이다.








메트리얼의 Offset 값을 조절해서 구름의 메트리얼을 움직입니다.
잘보이게 Direction Light 하나 설치해줍니다.
위 스크립트를 Quad 에 붙여줍니다.

실행해봅시다.





Trackback 0 And Comment 6
  1. ch 2014.05.04 19:24 address edit & del reply

    무한 스크롤에 대한 질문이 있는데요;
    Texture 한바퀴 재생하고 나면 그다음부터 이미지가 뭉개지는데 원인이 뭘까요?ㅠ

    • Favicon of https://hyunity3d.tistory.com BlogIcon 히아레인 2014.05.19 08:11 신고 address edit & del

      저도 그런경우는 없어서 자세한 얘기는 해드릴수가 없네요

  2. yo 2014.08.21 11:11 address edit & del reply

    위아래로 스크롤은 어떻게하나요?

  3. k 2015.03.09 18:19 address edit & del reply

    머터리얼을 Sprites/default로 하면 offset이 변경이 안되는데 저만그런건가여? ㅠ

    • y 2015.03.12 08:52 address edit & del

      Sprites/default 메트리얼은 offset 가 없어요

유니티 창 여러개 띄우기

|

다른 소스들이나 스크립트등을 참고할대 여러개의 유니티 창을 띄우고 싶을 때가 있음

1. Edit > Preferences 

2. General > Always Show Project Wizard 체크


확인을 누르고 유니티를 실행하면 어떤 프로젝트를 열지 확인하는 창이 뜬다.




Trackback 0 And Comment 0

현재 보고 있는 Scene와 똑같이 Game 뷰를 보는 방법

|

히어라이키 탭 에서 메인카메라를 선택후 컨트롤 + 쉬프트 + F 를 누르면 현재 Scene에서 보이는 화면이 게임씬에서 똑같이 적용된다.

Trackback 0 And Comment 0

스케줄 관리 프로그램 트렐로

|

게임 개발시 유용한 스케줄 관리 프로그램 트렐로

https://trello.com/


소규모 개발팀에게 적합한 프로그램일듯.

Trackback 0 And Comment 0

[펌] MonoBehaviour 오버라이딩 가능 함수 레퍼런스 총 정리

|

출처 :  http://kimseunghyun76.tistory.com/194


1. MonoBehaviour 
  
모든 스크립트가 상속받는 기본 클래스입니다.
 (Javascript 는 무조건 MonoBehaviour 를 상속받고 C#, Boo 의 경우 명시적으로 상속받아야 합니다.
  C#, Boo 에서 단순 데이터 보관용 클래스, 전역으로 동작하는 매니저 클래스같은 건 상속받지 않고 쓸 수 있습니다.)
  MonoBehaviour 는 Behaviour 클래스를 상속받고 Behaviour 는 Component 를 상속받습니다.
  즉 MonoBehaviour 를 상속받은 클래스는 게임 오브젝트에 component 로 붙일 수 있다는 뜻입니다.(붙일 수 있다는 건 모두 알고 계시죠? ㅎㅎ)
Behaviour 클래스는 enable/disable 가능합니다.
때문에 MonoBehaviour 도 역시 켜고 끌 수 있습니다.
(스크립트를 Inspector 에 붙이면 앞에 체크박스가 나오죠? 그겁니다.)
레퍼런스를 보면 MonoBehaviour,  Behaviour, script 라는 명칭을 혼재해서 쓰는데 혼란을 줄 수 있으니, 앞으로 모두 '스크립트'로 통칭하도록 하겠습니다.

2. 앞에 On 이 붙지 않는 함수

 1) Update

  Update 
함수는 스크립트가 켜져 있을 때(enabled 상태일 때) 매 프레임마다 호출됩니다.
  Update 함수는 스크립트에서 가장 빈번하게 사용되는 함수입니다.
  지나간 시간을 알고 싶으면, Time.deltaTime 을 사용하면 됩니다.
  이 함수는 스크립트가 켜져 있을 때만 불립니다.

 2) LateUpdate

   LateUpdate 
함수는 스크립트가 켜져 있을 때 매 프레임마다 호출됩니다.
   LateUpdate 함수는 모든 Update 함수가 호출된 후 호출됩니다.
   이것은 스크립트의 실행 순서를 정하는 것에 도움이 됩니다.
   예를 들어 따라다니는 카메라는 언제나 LateUpdate 를 구현해야 하는데, 그 이유는 이 카메라가 따라가는 오브젝트들은
   Update 함수 안에서 움직일 가능성이 있기 때문입니다. 이 함수는 스크립트가 켜져 있을 때만 불립니다.

 3) FixedUpdate

   FixedUpdate 함수는 스크립트가 켜져 있을 때 매 프레임마다 호출됩니다.
   FixedUpdate 함수는 Rigidbody 를 다룰 때 Update 대신에 사용됩니다.
   예를 들어 rigidbody에 일정한 힘을 가할 때, FixedUpdate를 구현하여 매 fixed frame 마다 힘을 가해주어야 합니다.
   ※ FixedUpdate 는 매 프레임마다 호출되지만 한 프레임에 여러번 호출될 수도 있습니다. ??
  

* FixedUpdate 는 매 프레임마다 호출됩니다. 그런데 한 프레임에 여러번 호출될 수도 있습니다. 사실 이거 거짓말입니다.
   그냥 알기 쉽게 하려고 이렇게 적어넣은 것이고... 정확히 하면 'FixedUpdate 는 1초에 50번 매 0.02초마다 호출됩니다

   그러니까 실제 렌더링 프레임 사이에 여러번 호출될 수도 있습니다
.
   Update 는 실제 렌더링 프레임 기반으로 동작하지만 FixedUpdate 는 고정 프레임(아마 50fps)으로 다른 쓰레드에서
 
   동작한다고 생각하시면 됩니다
.

   이렇게 나뉘어져 있는 이유는 주로 '물리 연산 중의 충돌 체크 및 정확한 움직임 처리의 근사' 때문입니다
.
   물체는 곡선운동도 하고 회전운동도 하므로 그 궤적이 항상 직사각형이나 실린더 모양이라고 생각할 수 없습니다
.
   물리 공식에 의해 곡선으로 움직이는 궤적도 계산해 낼 수 있고, 궤적 사이에 충돌 체크를 할 수도 있겠지만 여기에는
 
   막대한 CPU 자원이 들어갈 것입니다. (사실 3차원 곡면 사이의 충돌 검출이라.... 생각하는 것만으로도 머리 아퍼
)
   그래서 대체로 물리 엔진은 시간을 아주 짧게 잘라서 물체를 이동시키고 충돌 체킹을 하게 됩니다
.

   3D 에서 평면 폴리곤으로 곡면을 표현하는 걸 생각하시면 될 것 같네요

   잘게 자르면 자를 수록 점점 원하는 모양에 근사시킬 수 있죠
?
  즉, 전체적인 모습을 보면 곡선의 움직임이지만 자세히 들여다 보면 직선 움직임의 덩어리라는 것이죠
.
  계산상으로 직선을 처리하는 것 (1차 방정식) 과 곡선 (2차 이상의 방정식 or 심하면 음함수 그래프 같은 움직임까지)을
 
  처리하는 것은 넘사벽의 차이가 있습니다
.
  어쨌든 계산을 빠르고 편하게, 하지만 나름 정확하게 하기 위해 이런 방식을 씁니다
.
  (제가 예전에 담당하고 있던 라이브 게임에도 이펙트 코드에 가끔씩 이전 프레임과의 시간 차이를 계산한 후에
 
  더 자잘하게 잘라서 실제 처리하는 함수를 여러번 호출하는 루틴도 있었습니다
.)
  
   참고로 테스트 해 보니 아무런 조작도 없을 때 FixedUpdate 실행 주기는 0.02 초 정도인 듯 합니다
.
   (위에서 50fps 라고 적은 이유
)
   
   사실 스크립트 짜는 데 아무런 도움도 안될 것 같은 느낌이 드는데 그냥 '이런 저런 사정 때문에 이런 함수가 있고

   이렇게 동작한다.' 정도만 아시면 될 것 같습니다.


   

 // 매 프레임마다 rigid body 에 위로 향하는 힘을 가해준다.
 // 즉 이 예는 등가속 운동입니다. (Vector3.down 하면 중력을 받는 것과 동일하다는 뜻입니다
.)
function FixedUpdate()
 {
     rigidbody.AddForce(Vector3.up);
 }

 

4) Awake

  Awake 
함수는 스크립트 객체가 로딩될 때 호출됩니다.
  Awake 함수는 게임이 시작하기 전에 변수나 게임 상태를 초기화하기 위해 사용합니다.
  Awake 함수는 스크립트 객체의 라이프타임 동안 단 한번만 호출됩니다.
  
Awake 함수는 모든 오브젝트가 초기화된 후 호출되기 때문에, 다른 오브젝트에 메시지를 날리거나GameObject.FindWithTag 같은 함수를 안전하게 사용할 수 있습니다.
이런 이유로 Awake 함수에서 스크립트를 레퍼런싱한 후, Start 함수에서 필요한 정보를 넘겨받거나 넘겨줄 수 있습니다.
Awake 함수는 언제나 Start 함수 전에 호출됩니다. 이것은 스크립트의 초기화 순서를 정할 수 있게 합니다.
Awake 함수는 coroutine 으로 동작할 수 없습니다.

 5) Start

  Start 
함수는 Update 함수가 처음 호출될 때 Update 함수 직전에 호출됩니다.
  Start 함수는 스크립트가 동작하는 라이프타임 동안 단 한번만 호출됩니다.
  Awake 함수와의 차이는 Start 함수는 스크립트가 켜져있을 때만 호출된다는 것입니다.
  이것은 정말로 필요할 때까지 초기화 코드 실행을 연기시킬 수 있습니다.
  Awake 함수는 언제나 Start 함수가 호출되기 전에 호출됩니다. 이것은 스크립트의 초기화 순서를 정할 수 있게 합니다.
  Start 함수는 모든 스크립트 객체의 Awake 함수가 호출된 후에 호출됩니다.

 6) Reset

  기본값으로 리셋합니다.
  Reset 함수는 유저가 Inspector의 context menu 에서 Reset 버튼을 눌렀을 때나, 게임 오브젝트에 스크립트를 처음 붙였을 때 호출됩니다. 이 함수는 에디터 모드에서만 호출됩니다.
Reset은 Inspector에 초기 값을 설정할 때 가장 자주 사용하는 함수입니다.

 
 7 ) Awake, Start, Update, LateUpdate 순서도

'A,  B, C 라는 게임 오브젝트가 있고, A, B 에 스크립트가 하나씩 붙어있습니다. B는 스크립트가 비활성화 되어 있습니다.'
 라는 상황을 가정하겠습니다.

 1. 게임이 로딩되면 우선 A, B, C 모든 게임 오브젝트가 초기화 됩니다.
 
 2. 이후 A, B 에 붙어있는 스크립트의 Awake 함수가 호출됩니다.
   (이 상황에서도 이미 A, B, C 게임 오브젝트와 구성 컴포넌트는 모두 메모리에 들어있는 상태이므로 null 체크 
   이런 거 없이 안심하고 데이터 전달 등을 할 수 있습니다.)

 3. 이후 A 의 Update 함수가 호출되려고 합니다. B 는 스크립트가 비활성화 상태이기 때문에 동작하지 않습니다.

 4. A 의 Update 함수가 호출되려고 하는데, 이번이 첫번째 호출이네요! 우선 Start 가 호출됩니다.

 5. A 의 Start 가 호출되었으니 Update 가 호출됩니다. 앞으로 매 프레임마다 호출되겠네요.

 6. A 의 LateUpdate 도 호출됩니다. 역시 앞으로 매 프레임마다 호출됩니다.

 - 여기서 B의 스크립트를 활성화시켰습니다.

 7. B 의 Update 함수도 호출되기 시작합니다. 제일 처음 Update 호출될 때 역시 Start 가 우선 한 번 호출됩니다.

 8. A, B 의 Update 함수가 모두 호출된 후 A, B 의 LateUpdate 가 호출됩니다.

 - 여기서 C에 스크립트 컴포넌트를 붙였습니다.

 9. C 에 스크립트가 붙자 C의 Awake 가 호출됩니다.

 10. A, B, C 의 Update 차례. C의 경우 처음 Update 호출이라서 그전에 Start 함수가 우선 호출됩니다.

 11. A, B, C 의 LateUpdate 차례. A, B, C 의 모든 Update가 끝나면 호출되기 시작합니다.

 

 


3. On~ 
계열 함수

 1) OnMouse~ 함수군

  
마우스와 GUIElement, Collider 사이의 인터랙션에 관련한 함수 집합입니다.
  게임 오브젝트가 Ignore Raycast 레이어에 속해있으면 호출되지 않습니다. (내부적으로 Raycast 를 하는 듯.)
  이 함수들은 co-routine 으로 사용할 수 있습니다. (yield 사용 가능.)
  이 이벤트는 GUIElement, Collider 에 붙어있는 모든 스크립트에 전달됩니다.

  OnMouseEnter - 마우스가 처음 오브젝트 위로 올라왔을 때 호출.
  OnMouseOver - 마우스가 오브젝트 위에 있을 경우 매 프레임마다 호출.
  OnMouseExit - 마우스가 처음 오브젝트 밖으로 나갔을 때 호출.
  OnMouseDown - 오브젝트 위에서 마우스 버튼을 눌렀을 때 호출.
  OnMouseUp - 오브젝트 위에서 마우스 버튼을 땠을 때 호출. 눌렀을 때의 오브젝트와 같은 오브젝트일 때만 호출됨.
  OnMouseDrag - 오브젝트 위에서 마우스 버튼을 누른 상태로 있을 때 매 프레임마다 호출.

  여기서 Drag 는 일반적으로 생각하는 드래그가 아니라 그냥 꾸욱 누르고 있는 상태를 나타냅니다. 
 (물론 그 상태로 마우스를 움직이면 드래그지만..)
  그리고 오브젝트 위에 마우스를 올려놓고 누르고 있으면 Over와 Drag 가 매 프레임마다 호출됩니다. 
  Drag 호출된다고 Over 호출 안된다거나 하는 거 없습니다. *ㅅ*

  스크립트가 enable / disable 과 상관없이 호출됩니다.
  즉 Inspector 에서 체크박스를 해제해도 스크립트가 붙어있다면 무조건 호출됩니다.
  앞으로 '스크립트가 켜져있을 때만 호출된다.' 는 말이 없으면 기본적으로 비활성화 상태에서도 호출된다고 생각하세요.

 2) OnTrigger~(other : Collider), OnCollision~(collisionInfo : Collision) 함수

  OnTrigger~, OnCollision~ 은 모두 충돌 관련 함수입니다.
  충돌이 일어나려면 두 오브젝트 모두 Collider 를 가져야 하고 둘 중 하나는 Rigidbody 를 가져야 합니다.
  그리고 Rigidbody 를 가진 쪽이 움직여서 서로 만날 경우만 이벤트가 일어납니다. 물론 둘 다 움직이고 있어도 됩니다.
  (그러니까 Rigidbody 를 가진 녀석은 가만히 있는데 그냥 Collider 가 아무리 와서 들이박아도 아무런 일도 생기지 않는다는 겁니다. ==> 중요한것입니다.)

  Trigger 는 Inspector 창에서 Collider 의 Is Trigger 속성이 켜져있을 때 발생합니다.
  Trigger 가 켜져있을 때는 Collision 관련 함수는 호출되지 않습니다.
  Trigger 가 켜져있을 때는 두 오브젝트 사이에 물리 계산이 이루어지지 않습니다.
   그래서 Trigger 는 단순한 '영역' 으로 이해하는 것이 좋습니다.

  Collision 은 두 오브젝트 중 적어도 하나가 Inspector 창에서 Rigidbody 의 Is Kinematic 속성이 꺼져있을 때 발생합니다.
   (Is Kinematic 이 켜져있으면 이 오브젝트는 내부 물리연산을 하지 않기 때문에 부딪쳐도 그냥 뚫고 지나갑니다.)
  두 오브젝트 모두 Kinematic 속성이 켜져있으면 어느 쪽이 움직여서 겹치더라도 물리 연산이 이루어지지 않기 때문에 
  충돌 함수가 호출되지 않습니다.

  Trigger 는 함수의 파라메터로 Collider 변수가 들어옵니다. 이것은 자신과 접촉한 오브젝트의 Collider 입니다.
  Collision 은 함수의 파라메터로 Collision 변수가 들어옵니다. 이것은 접촉에 대한 여러가지 정보를 담고 있는 클래스입니다.

  relativeVelocity - 두 오브젝트의 상대 속도입니다. 충격량이라는 느낌일까요? (읽기 전용)
  rigidbody - 자신과 접촉한 Rigidbody 입니다. 
                  만약 상대가 Rigidbody 가 없는 Collider 라면 이 값은 null 입니다. (읽기 전용)
  collider - 자신과 접촉한 Collider 입니다. (읽기 전용)
  transform - 자신과 접촉한 오브젝트의 Transform 정보입니다. (읽기 전용) 
  gameObject - 자신과 접촉한 오브젝트입니다. (읽기 전용)
  contacts - 물리 엔진에서 연산한 접촉 포인트 정보입니다. ContactPoint 의 배열입니다.

두 종류 모두 ~Enter, ~Stay, ~Exit 함수를 제공합니다.

Enter 는 접촉을 시작했을 때 호출,
Stay 는 접촉 중일 때 매 프레임마다 호출,
Exit 는 접촉이 끝났을 때 호출됩니다.

두 함수군 모두 yield 사용 가능합니다.


 * Mesh Collider 관련해 추가 설명 

기본 도형으로 이루어진 Collider 이외에 실제 모델같은 Mesh Collider 를 붙일 수도 있습니다. (알고 계시겠죠? ㅎ)
그런데 기본적으로 Mesh Collider 는 다른 Mesh Collider 와 충돌 계산이 이루어지지 않습니다.
아마 계산이 오래 걸리기 때문에 막아놓은 것으로 보입니다. 기본 도형은 대체로 방정식 몇번 풀면 체크 끝나지만, Mesh 는... 모든 폴리곤을 순회하면서 체크해야 하니까요.
그래도 하고 싶은 사람을 위해 준비된 Inspector 창의 Mesh Collider 의 Convex 속성을 켜면 다른 Mesh Collider 와 충돌 계산을 합니다. 단, Convex 속성을 켜기 위해서는 Mesh Collider 의 폴리곤 개수가 255개를 넘으면 안됩니다.
이런 제한이 있습니다~ 간단한 게임이나 계산 파워가 부족한 iphone 게임을 만들 때는 굳이 Mesh Collider 쓸 필요는 없을 것 같습니다.

3) OnControllerColliderHit(hit:ControllerColliderHit)
 CharacterController 가 Move 함수로 이동하는 도중 다른 Collider 와 충돌했을 때 호출됩니다.
 (CharacterController 가 붙어있는 gameObject 를 Translate 로 움직여서 충돌할 때는 호출되지 않습니다. 
  무조건 CharacterController 의 Move 함수로 움직일 때만 호출됩니다.)
CharacterController 는 이전 충돌 함수 때처럼 따로 Rigidbody, Collider 가 필요없습니다.

4) OnJointBreak(breakForce:float)
게임 오브젝트에 붙어있는 조인트가 끊어질 때 호출됩니다.
조인트에 설정된 breakForce 보다 높은 힘이 가해지면 조인트는 끊어집니다.
조인트가 끊어질 때 주어진 힘이 파라메터로 들어옵니다.
조인트가 끊어지고 OnJointBreak 가 호출된 후 조인트는 자동적으로 게임 오브젝트에서 지워집니다.

5) OnParticleCollision(other:GameObject)
파티클이 Collider 와 충돌했을 때 호출됩니다.
WorldParticleCollider 와 충돌한 Collider 에 붙어있는 모든 스크립트에 호출됩니다.
Inspector 창에서 WorldParticleCollider 의 sendCollisionMessage 속성을 켜야지 호출됩니다.
 (즉, 기본적으로 WorldParticleCollider 가 붙어있어야 합니다.)
Collider 는 따로 Rigidbody 일 필요 없습니다. yield 사용 가능합니다.

6) OnBecameVisible / OnBecameInvisible
 renderer 가 어떤 카메라에 보이기 시작할 때, 보이지 않기 시작할 때 호출됩니다.

레퍼런스 설명은 위와 같은데, '어떤' 카메라라는 것은 여러대의 카메라가 있을 때 그 중 하나라도 보이기 시작하면 Visible, 모두 보이지 않을 때 Invisible 이라는 것이며, 단, 카메라가 있어도 비활성화 상태이거나 화면에 보이지 않을 경우 (즉 View Port Rect 의width, height 가 0일 때) 는 '어떤' 카메라에 포함되지 않습니다.
오브젝트의 renderer 컴포넌트를 꺼도 마찬가지로 Invisible 입니다.

그러니까 단순히 말해서  어쨌든 화면에 보이기만 하면 Visible, 안보이면 Invisible 입니다.

renderer 에 붙어있는 모든 스크립트에 호출됩니다.
화면에 보일 때만 스크립트가 처리되도록 할 때 유용합니다.
yield 사용 가능합니다.

 // 화면에 보일 때만 스크립트 활성화.
function OnBecameVisible ()
 {
     enabled = true;
 }
 function OnBecameInvisible()
 {
     enabled = false;
 }


주의점이 있습니다. 툴에서 작업할 때 Scene View 에도 동일하게 동작합니다.
Game View 에서 안보여도 Scene View 에서 보이고 있는 상태라면 Invisible 호출이 안됩니다.

7) OnLevelWasLoaded(level:int)
새로운 레벨(scene)이 로딩되었을 때 호출됩니다.
level 파라메터는 로딩된 레벨의 인덱스를 나타냅니다.
메뉴 File - Build Settings... 에서 레벨과 인덱스를 설정할 수 있습니다.
yield 사용 가능합니다.
레퍼런스에는 적혀있지 않지만 해당 장면의 모든 스크립트에서 호출되는 것 같습니다.

8) OnEnable/OnDisable
스크립트가 켜지거나 꺼졌을 때 호출됩니다.
추가로 OnDisable 의 경우 스크립트가 붙은 게임 오브젝트가 제거될 때도 호출되므로 파괴자로 사용할 수 있습니다.
툴에서 플래이 모드 중에 스크립트를 편집할 경우, 편집이 끝난 후 스크립트가 다시 로딩되면서 OnDisable, OnEnable 이 순차적으로 호출됩니다.
참고로 툴에서 플래이 중 스크립트를 고쳤을 때 고쳐진 스크립트의 Awake, Start 는 호출되지 않습니다.
그리고 OnEnable 은 Awake 함수 바로 다음에 호출됩니다. (켜져있을 경우)

9) OnGUI
 GUI 를 그리거나 이벤트를 처리하기 위해 호출됩니다.
이벤트 처리도 맡고있기 때문에 한 프레임에 여러번 호출될 수 있습니다. (한 이벤트에 한 번) 스크립트가 꺼져있으면 호출되지 않습니다.
OnGUI 함수 안에서 Event.current 를 사용하면 현재 처리하고 있는 이벤트 내용을 알 수 있습니다.
이 때 사용되는 Event 클래스의 내용은 다음과 같습니다.

 type - 이벤트의 타입. (http://unity3d.com/support/documentation/scriptReference/EventType.html)
 mousePosition - 마우스 위치. (Vector2)
 delta - 지난번 처리한 이벤트와 현재 마우스 위치의 차이. (Vector2)
 button - 어떤 마우스 버튼이 눌려졌는지. (int) (0:왼쪽, 1:오른쪽, 2:가운데)
 clickCount - 마우스 클릭 횟수. (int)
 character - 키보드로 입력한 문자. (char)
 commandName - 단축키로 입력된 명령. (string) ("Copy", "Cut", "Paste", "Delete"... 툴에서만 호출.)
 keyCode - 키보드로 입력한 가공되지 않은 키코드.(http://unity3d.com/support/documentation/scriptReference/KeyCode.html)
 shift - 쉬프트 눌려져 있는지.
 control - 컨트롤 눌려져 있는지.
 alt - 알트 눌려져 있는지.
 command - Command(맥)/Windows(윈도우) 키 눌려져 있는지.
 capsLock - CapsLock 켜져있는지.
 numeric - 키패드 입력인지.
 functionKey - 펑션키 입력인지.
 isKey - 키보드 이벤트인지.
 isMouse - 마우스 이벤트인지.

Event 클래스의 기타 함수는 영역이 애매해서 따로 설명하지 않습니다. (http://unity3d.com/support/documentation/scriptReference/Event.html)

10)  OnApplicationPause(pause:bool)
플레이어가 정지/재개될 때 모든 스크립트에서 호출됩니다. yield 사용 가능합니다.

11) OnApplicationQuit 
어플리케이션이 종료되기 직전에 모든 스크립트에서 호출됩니다.

12) OnDrawGizmos 
게임 오브젝트에 기즈모를 추가합니다.
이 기즈모는 선택할 때 사용할 수 있고 언제나 그려집니다.

13) OnDrawGizmosSelected 
게임 오브젝트가 선택되었을 때 기즈모를 그리고 싶을 때 구현합니다. 이 기즈모는 선택에 사용할 수 없습니다.
Gizmos 클래스는 http://unity3d.com/support/documentation/scriptReference/Gizmos.html 에서 사용법을 확인할 수 있습니다.

혹 기즈모가 뭔지 모르시는 분은..
툴의 Scene 뷰에 빛이나 카메라의 위치를 볼 수 있게 해 주는 아이콘이 기즈모입니다.
눈에 보이지 않지만 위치 설정이 필요할 때, 중요한 오브젝트를 보기 좋게 표현하기 위해.. 기타 여러가지 이유로 사용할 수 있습니다. 실제 어플리케이션에는 표시되지 않지만 툴로 작업할 때 여러모로 편하게 해 줍니다.
공동 작업할 때 자주 사용하면 좋을 거라 생각합니다.

4. 렌더링에 관련한 고급 기능

 1) OnPreCull
  
카메라에서 장면을 컬링하기 전에 호출됩니다. 여기서 컬링이란 프러스텀 컬링입니다. (후면 컬링 아님)
  카메라에 붙어있는 스크립트에만 호출됩니다. 
  카메라의 속성을 바꾸고 싶을 때, 이 함수 안에서 하면 좋습니다.
  이 함수가 호출된 후 실제 프러스텀 컬링을 하고 각 오브젝트가 화면에 그려질지 그려지지 않을지 정해집니다.

 2) OnPreRender
  
카메라가 장면을 렌더링하기 전에 호출됩니다.
  카메라에 붙어있는 스크립트에만 호출됩니다.
  yield 사용 가능합니다.

 3) OnPostRender
  카메라가 장면을 렌더링한 후 호출됩니다.
  카메라에 붙어있는 스크립트에만 호출됩니다.
  yield 사용 가능합니다.
  이 함수는 해당 카메라가 모든 오브젝트를 렌더링한 후 호출됩니다.
  만약 '모든' 카메라와 GUI가 렌더링된 후 무언가를 하고 싶으면 WaitForEndOfFrame coroutine 을 사용하면 됩니다.

 4) OnWillRenderObject()
  해당 오브젝트를 렌더링하는 카메라마다 한 번 호출됩니다.
  (세 대의 카메라가 하나의 오브젝트를 보고 있으면 그 오브젝트에 붙어있는 스크립트에서 세 번 불린다는 뜻.)
  (툴에서 작업할 때는 Scene View 카메라도 들어갑니다.)
  이 함수는 렌더링하기 전, 컬링 중에 호출됩니다.
  Camera.current 를 사용하면 현재 어떤 카메라가 렌더링할 것인지 알 수 있습니다.

 5) OnRenderObject(queueIndex:int)
  오브젝트가 렌더링될 때 호출됩니다. queueIndex 는 해당 오브젝트를 렌더링할 때 사용하는 렌더 큐의 값입니다.
  RenderBeforeQueues 속성으로 특정한 렌더링 큐에서 동작하도록 설정할 수 있습니다.
  이 함수도 OnWillRenderObject 함수처럼 각 카메라가 그릴 때마다 한 번 호출됩니다.

 6) OnRenderImage(source:RenderTexture, destination:RenderTexture)
  모든 렌더링이 끝난 후 호출됩니다. 카메라에 붙어있는 모든 스크립트에서 호출됩니다.
  포스트 프로세스 효과를 줄 때 사용합니다. (Pro 전용)
  source 는 렌더링이 끝난 화면이며 destination 텍스쳐에 결과물을 그려주면 됩니다.
  카메라에 여러 이미지 필터가 붙어있을 경우 순차적으로 진행됩니다.


게임의 경우 때깔내는데 가장 중요한 포스트 프로세싱 부분이 Pro 전용으로 빠져있습니다.
(그러고 보니 free 에서 렌더 타겟이 사용 불가였으니 당연히 이것도 사용이 불가능하겠네요.)
여기 있는 함수들은 제가 사용해 본 적이 없고, 지금 당장 특별히 어떻게 쓰면 좋을지 잘 모르는 관계로 특별한 부연 설명 없이 레퍼런스를 옮겨적기만 했습니다.

참고로 3.0 부터 이쪽 함수들은 스크립트가 꺼져있으면 동작하지 않는다고 합니다.

5. 네트워킹 관련 함수
점점 써 본적이 없는 함수만 나와서 정말 난감하네요;;;

 1) OnPlayerConnected(player:NetworkPlayer)
   새 유저가 성공적으로 접속했을 경우 서버에서 호출됩니다.

 2) OnServerInitialized
   Network.InitializeServer 를 호출한 후 완료되었을 때 서버에서 호출됩니다.

 3) OnConnectedToServer
   서버에 성공적으로 접속했을 경우 클라이언트에서 호출됩니다.

 4) OnPlayerDisconnected(player:NetworkPlayer)
   유저의 접속이 끊겼을 경우 서버에서 호출됩니다.

 5) OnDisconnectedFromServer(mode:NetworkDisconnection) 
  서버와 접속이 끊기거나 접속을 종료했을 때 클라이언트에서 호출됩니다.

 6) OnFailedToConnect(error:NetworkConnectionError)
  접속 시도가 실패했을 때 클라이언트에서 호출됩니다.

 7) OnFailedToConnectToMasterServer(error:NetworkConnectionError)
  서버나 클라이언트에서 마스터 서버로의 접속에 문제가 있을 경우 호출됩니다.

 8) OnMasterServerEvent(msEvent:MasterServerEvent)
  서버나 클라이언트로 마스터 서버에서 보낸 이벤트를 받았을 때 호출됩니다.

 9) OnNetworkInstantiate(info:NetworkMessageInfo)
  Network.Instantiate 함수로 네트워크를 통해 게임 오브젝트가 생성되었을 때 해당 오브젝트에서 호출됩니다.
  네트워크 상에서 새 게임 오브젝트가 생성되었을 때 다른 사람이 생성했는지 내가 생성했는지에 따라 오브젝트에 특별한 
  처리를 할 때 유용합니다.

 10) OnSerializeNetworkView(stream:BitStream, info:NetworkMessageInfo)
  네트워크 상에서 전달되는 변수들(variables in a script watched by a network view)의 동기화 처리를 커스터마이징할 
  때 사용합니다..
  이 함수는 직렬화된 값 (즉 BitStream으로 바뀐 정보)을 전달할 것인지 받을 것인지에 대해서 자동으로 판단합니다.
 (이 오브젝트를 소유권에 따라서 처리됩니다. 소유자는 보내고 나머지는 받고.)

사실 저같은 경우 tcp, udp 연결이 필요한 게임을 만드는 게 아니라 그냥 WWW 클래스만으로도 충분합니다..

 

Trackback 0 And Comment 0

샌드박스형 게임이란(마인크래프트 , GTA 등)

|

1 개요 

샌드박스 게임. 특정한 게임 장르로 보기는 어려운 부분이 많으나 대체로 일종의 장르로 취급된다.

영어판 위키피디아에선 Open world란 문서명으로 등록되어 있다.

2 특징 

원래 비디오 게임에서 일컫는 샌드박스는, 플레이어의 창조적 욕구에 대한 발현을 중시하는 일부 시뮬레이션 장르의 게임들을 가리키는 단어였으나[1] 21세기 들어서 후술된 내용으로 단어의 의미가 확장되었다. 기존에는 자유도 높은 게임은 그냥 뭉뚱그려서 오픈월드로 불렀지만, 기술의 발전 및 트렌드의 변화로 인해 과거 오픈월드라고 칭하던 게임들 수준의 자유도는 요즘 나오는 웬만한 게임들은 전부 구현하고 있다. 따라서 현재 오픈월드는 '지역 간 이동의 제약이 없는 게임' 정도로 의미가 축소되었고, 반대 급부로 샌드박스라는 단어가 '높은 수준의 자유도를 제공하는 게임'을 칭하는 오픈월드의 하위 개념으로 대체되었다. 다만 동네마다 다른데, 옛날 의미를 고수해서 자유도 높은 게임은 오픈월드, 건물을 짓는 레고 같은 게임은 샌드박스로 구분하는 동네들도 꽤 있다. 주로 서양 쪽 웹, 그 중에서도 PC 게임을 선호하는 커뮤니티에서 이런 분류를 선호한다.

샌드박스 게임은 막강한 자유도를 기반으로 하여, 특정한 목표가 없거나, 목표가 존재하더라도 그 목표를 최소한으로 줄여 사용자가 하고 싶은 대로 플레이할 수 있게 하는 게임이다. 목표를 달성해 성취감을 얻는 전통적인 게임의 전개보다는, 자신의 아바타로 가상의 세계를 탐험하는 가상 체험을 중요시한다. 따라서 게임의 룰 못지않게 생기 넘치는 가상 월드의 구현이 무엇보다 중요하며, 생동감 있는 NPC들의 인공지능, 넓은 세계를 끊김 없이 구현하는 스트리밍 맵 로딩, 다양한 콘텐츠들의 배치 등이 주요한 게임 시스템 요소이다.

이런류의 게임은 GTA 이전에도 여럿 있었지만, 샌드박스를 붐으로 이끈 작품은 GTA 시리즈가 가장 큰 영향을 줬다. 물론 성공한 것보다 실패한 게 더 많지만.

목표가 완전히 존재하지 않는 게임(심즈동물의 숲)도 존재하지만, 목표가 존재하고 그 목표를 달성하는 것으로 게임을 시작해, 어느 단계가 넘으면 플레이어의 재량껏 플레이하는 것이 가능한 방식(GTA 시리즈), 본래 가지고 있던 게임의 특성에 샌드박스 요소를 집어넣은 방식(번아웃 시리즈 중 번아웃 파라다이스)도 있다.

어떤 게임들은 '목표' 를 던져주고 그 목표를 달성하기 위한 과정은 완전히 플레이어의 자유에 맡긴다. 예를 들면 암드 어썰트 시리즈나 오퍼레이션 플래쉬 포인트 시리즈 의 경우 임무를 완수하기 위해 어떤 방법으로 진행해도 상관없으며, 시설폭파 임무 등에서는 총 한 발 쏘지 않은 체 메탈기어솔리드 하듯 숨어서 적을 전부 피해서 시설만 폭파해도 상관없다.
또한 이 두 게임은 완벽한 미션 에디터 역시 기본적으로 제공하면서 유저들이 직접 캠페인, 미션 등을 만들 수 있도록 배려하고 있다. 다른 샌드박스 게임에서도 사용자가 직접 콘텐츠를 만드는 '모드'제작이 활발하게 이루어지는편.

샌드박스는 기본적으로 진행의 자유를 가지고 있고 여기서 상호작용을 해야 한다. 주위와 상호작용을 함으로써 유저는 하나의 세계의 구성원이 되는 것이다. 상호작용을 통해서 유저의 행동이 변화를 가져옴으로써 자기가 원하는 방식으로 진행하고 그 안에서 유저가 세계를 체험할 수 있는 게 샌드박스의 요점.

샌드박스 게임류는 개발자의 적이다. 게임에 기본이 되는 시스템(예를 들어 RPG의 전투)에 스토리 같은 덧살을 붙이는 여타 게임과 비교하면, 샌드박스 형식은 게임 내 모든 요소가 수평적으로 연결되어 있기 때문에 요소가 많아질수록 경우의 수가 기하급수적으로 많아진다.

덕분에 이런 경우의 수를 줄이려고 엘더스크롤 5: 스카이림에서의 닭둘기 전설이나 아무리 때려도 죽지 않는 NPC등을 만들어 부자연스럽게 보이기도 한다. 이건 어디까지나 사람의 손으로 처리해야 하므로 어느 정도 이상의 복잡도를 가진 샌드박스 게임이 나오기란 불가능하다. 락스타와 베데스다의 샌드박스 게임들 정도가 사실상 현실적인 한계일 듯하다. 이 이상 가려면 NPC가 스스로 학습하고 배경이 전부 상호작용해야 하는데 하드웨어에서 한계가 있다.

과거에는 심시티로 대표되는 시뮬레이션 게임이 주를 이뤘으나, 최근에는 심즈동물의 숲게리 모드GTA 등 다양한 장르로 발전하여 미래의 게임이 나아가야 할 길 중 하나로 제시되고 있다.

한 가지 문제가 있다면, 이 방식을 취하는 게임은 막장제조 게임이 될 우려가 있다는 것이다. 반대로 굳이 넣을 필요도 없는 콘텐츠를 억지로 집어넣으면 재미는 커녕 플레이어의 짜증을 유도하기도 한다.

샌드박스 요소를 넣어서 재미가 훼손된 대표적인 경우가 울펜슈타인게임 비평가 Yatzhee는 "탐험해봤자 나오는 건 적, 적, 적뿐인데 대체 누가 탐험을 하고 싶겠어요?"라고 깠다.

오픈월드형 샌드박스 게임의 경우, 대부분의 유저가 간과하는 사실이 있는데, 무작정 맵의 크기와 진행의 자유도를 연관지어 생각하는 것이다. 물론 구현된 오픈월드 맵이 크면 클수록 좀 더 자유로운 느낌이 드는 것은 사실이다. 다만, 오픈월드 게임에서의 자유도란 맵의 크기보단 그 맵 속에 구현되어 있는 시설물과 미니게임, NPC의 상호작용 등의 인과관계가 큰 비중을 차지한다. 생각해 보자. 넓디넓은 사막 한가운데에 사람 하나를 떨궈 놓고, 그 속에서 자유를 느껴보라면 말이 되겠는가? 전술한 GTA의 행동의 자유란 단순한 이동의 자유만이 아니라, 오픈월드 내에 녹아 있는 즐길거리, 즉 즐길 자유를 추구했기에 호평받은 것이다.

온라인 게임은 기본적으로 오픈 월드가 구현돼서 샌드박스를 구현하기가 쉬운 편. NPC의 상호작용 한계도 유저들로 대체할 수 있기 때문에 상호작용의 한계도 적다. 가장 큰 예가 시장의 형성. 개발자들이 시장을 만들려고 하면 공급과 수요부터 문제가 되지만 온라인 게임은 진짜 사람들이 하므로 알아서 시장이 형성된다. 그러나 한 유저가 게임에 영향을 주는 게 다른 유저들에게도 영향을 줘서 밸런스를 망칠 수 있기에 실제로 구현하고 운영하는 것은 상당히 힘들다. 예를 들어 길드에게 지도상 영토를 개척하게 해줬다니, 영토 확장한답시고 주변 지역에 있는 플레이어들을 다 죽인다든가 하는식의 문제. 또 흥미로운 내용은 한 사람이 머드게임 시절에 썼던 논문인 온라인 게임 4대 플레이어 유형에서 플레이어가 4가지로 나뉘어 서로 다른 스타일의 플레이를 한다는 것을 느낄 수 있다.

거기다 상호작용의 주체이자 객체인 유저들이 사람들이다 보니까 통제불능 상황에 빠지면 운영이 무너지기 쉽다. 하우징의 요소가 있는 때는 부동산 문제가 생기고, 자원 채집에서는 자원의 분배와 소모 문제가 생긴다. 기술의 발전으로 여러가지 요소가 들어가지만 초기 온라인 게임에서 샌드박스의 요소는 많이 들어갔지만 2010년에 들어서까지 유지되는 자유도는 제작과 낚시 수준이다.

그리고 한 요소가 증가하면 기존의 모든 요소들과의 상호작용을 디자인하고 버그도 잡아야 해서 골치 아프기도 하다. 한 예로 MMORPG에서 최초로 샌드박스를 구현한 울티마 온라인은 업데이트가 진행되면서 이러한 요소가 많이 퇴색되었다. 국내에선 울티마 온라인과 비슷한 마비노기가 비슷한 경우일 듯. 마비노기도 잡다한 시스템이 잔뜩 있는데, 한번 신기능이 추가되면 버그가 없던 적이 없었다.

2011년 한국의 기대작 아키에이지가 이러한 샌드박스 스타일의 게임이 될것이라 기대했으나, 포장을 열어보니 실상은 리니지3. 본래 광고했던 샌드박스형 게임과는 여러모로 다른 방향의 게임이었다.

3 오픈 월드 

샌드박스의 기본으로 오픈 월드가 깔린다. 오픈 월드는 게임 내 배경이 공간적, 물리적 제약을 벗어던지고 하나의 구성공간으로 상호작용한다. 샌드박스의 기본 배경으로 오픈월드가 중요한 것은 세계가 자유롭지 않은 상황에서 자유도를 넣기가 애매하기 때문이다.

오픈 월드는 기본적으로 이동의 자유를 전제로 하여 다양한 경로를 제시하여 이용자가 자유도를 확실하게 체감할 수 있게 한다. 보통의 RPG와 같이 선형적 구조에서는 길과 막힌 곳이 너무나 뚜렷하지만 오픈 월드에서는 연결만 되면 모두 갈 수가 있다. 이런 연결성은 하나의 세계를 지속해서 연결하여 몰입감을 주고 이동의 자유만큼 자유도를 느끼게 해주므로 가장 기본이 되는 요소이다.

단, 오픈 월드가 다 샌드박스가 되는 것은 아니다. 어쌔신 크리드 시리즈나 L.A. Noire크라이시스는 오픈 월드로 이동의 자유도가 상당히 높지만, 상호작용이 약하고 선형적 구조로 진행되기 때문에 진행의 자유도는 낮다. 반면에 심즈와 심시티는 오픈 월드의 성질은 적지만 진행의 자유도는 높다. 기본적으로 샌드박스는 상호작용과 진행에 대한 자유를 의미하고 여기서 이동의 자유가 큰 비중을 차지하기 때문에 영향을 주는 것이다. 상호작용이 없고, 진행이 고정된다면 오픈 월드라고 해서 반드시 샌드박스라고 할 수는 없다.

오픈 월드를 가장 쉽게 연상할 수 있는건 온라인 게임으로, 배경이 하나의 공간으로 연결이 돼서 그 안에서 이용자들이 상호작용을 할 수 있다.


Trackback 0 And Comment 0

글자 크기를 점점 커지게 하면서 사라지게 하기

|




히어라이키 탭에 "txtMsg" GUI text 생성 해야됨.



Trackback 0 And Comment 0

게임 매니저에서 FSM 으로 게임 분기 처리하기

|
각각의 스크립트가 게임 매니저와 동기를 유지하려면 게임의 상태를 표시하는 변수가 필요합니다. 보통 게임 매니저 스크립트의 위와 같이 변수들을 선언하고 업데이트 문에서 해당하는 변수에 따라 분기 처리를 하여 게임을 관리해줍니다.
Trackback 0 And Comment 0

충돌 처리시 Tag 설정 값 파악하기

|


C# 에서는 스위치 문에서도 string의 사용이 가능합니다.

충돌시 충돌하는 물체에 각각 Tag 값을 넣어서 구별을 할수 있습니다.

만약 


ENEMY, BONUS 등 태그값을 구분하려면 아래 처럼 하면 됩니다.

참고로 태그를 지정하지 않은 값들은 모두 Untagged 값을 가지는데 이것또한 태그값입니다.

마찬가지로 태그로 구별할수 있습니다.


void OnTriggerEnter(Collider coll){

switch(coll.tag)

{

case "ENEMY":

//충돌 처리 로직

break;

cae "BONUS":

//충돌 처리 로직

break;

case "Untagged"

//충돌 처리 로직 (태그값을 지정하지 않은 물체)

break;

    }

}


OnTriggerEnter 는 두 물체 중에 하나가 isTrigger 속성이 On으로 설정이 되어야 하며 두물체중 하나는 리지드바디가 추가되어야 발동되는

함수입니다.


Trackback 0 And Comment 0

Quaternion.LookRotation

|

두 점 사이의 각도를 계산할때 사용하는 API 함수

static Quaternion LookRotation(Vector3 forward, Vector3 upwards = Vector3.up);


forward는 바라보는 물체 

upwards는 기본값이 Vector3.up으로 정의되있음.






Quaternion.LookRotation

static Quaternion LookRotation(Vector3 forwardVector3 upwards = Vector3.up);
Parameters

forwardThe direction to look in.
upwardsThe vector that defines in which direction up is.
Description

Creates a rotation with the specified forward and upwards directions.

Returns the computed quaternion. If used to orient a Transform, the Z axis will be aligned with forward and the Y axis withupwards if these vectors are orthogonal. Logs an error if the forward direction is zero.
using UnityEngine;
using System.Collections;

public class Example : MonoBehaviour {
    public Transform target;
    void Update() {
        Vector3 relativePos = target.position - transform.position;
        Quaternion rotation = Quaternion.LookRotation(relativePos);
        transform.rotation = rotation;
    }
}
See Also: SetLookRotation.


Trackback 0 And Comment 0