GameForFun

블로그 이미지
by PforPepsi

TAG CLOUD

  • Total hit
  • Today hit
  • Yesterday hit

'[Unity3D]'에 해당되는 글 39건

  1. 2012.05.03
    커스터마이징 기능 구현하기 2. 데이터의 저장.
  2. 2012.05.02
    커스터마이징 기능 구현하기 1. Serialize란...
  3. 2012.04.03
    앵그리버드 만들기 1탄.
  4. 2012.03.25
    [Unity] Network 정리 2
  5. 2012.03.25
    [Unity] 정리들
  6. 2012.03.24
    [Unity] 최적화 1
  7. 2012.03.24
    [Unity] Ray의 사용
  8. 2012.03.24
    [Unity] 인자 전달 방법
  9. 2012.03.24
    [Unity] 시작

http://answers.unity3d.com/questions/42095/unity3-can-i-serialize-non-pod-types-color-vector3.html

http://answers.unity3d.com/questions/8480/how-to-scrip-a-saveload-game-option.html

먼저 이 글은 위의 두 자료를 참고해서 만든 것입니다.

지난번 글에서는 serialize에 대해 살펴보았다.
간단히 정리하자면, serialize를 통해 자체적으로 정의한 클래스를 inspector창에 나타나게 하여 즉각즉각 수정할 수 있도록 설정하는 것이었다. 또한 serialize를 통해 데이터들을 저장, 로드할 수 있다고 언급하였는데, 이 글에서는 저장/로드 에 대해 적어볼려고 한다.

그 전에 프로그램들은 서로 어떻게 데이터를 주고 받는가에 대한 질문부터 해결해보자.
데이터는 0과 1의 2진수로 구성된 하나의 문자열이라 생각할 수 있고, 이러한 문자열을 프로그램간에 주고 받는다면, 그것이 프로그램간의 데이터 통신이 있다는 것을 의미할 것이다.

이와 마찬가지로 저장/로드도 동일하게 0과 1으로 구성된 문자열을 적절한 방식으로 쪼개(Parsing) 원하는 데이터를 저장/얻어오게 할 수 있다. 
자세한 작동 방식은 나도 잘 모르기때문에 이해 할 수 있는 부분만 설명하도록 하겠다.

우리가 필요한 것을 나열해 보도록 하자.
1. 저장할 데이터(Non-Binary.. 맞는 표현인가?  우리가 알아 볼 수 있는 데이터)
2. 저장할 파일
3. BInary로 구성된 데이터(컴퓨터가 알아 볼 수 있는 데이터/. 대충 알아들으시면 감사. 정확한 표현이 아니라는것도 알아두세요. )

우리가 필요한 것은 위의 3가지로 나뉘게 된다. 저장할 데이터, 사용자가 알아 볼 수 있는 데이터들을 컴퓨터가 알아 볼 수 있는 데이터로 변경시킨 뒤에, 파일에 저장을 해야 할 것이다
저장할 데이터 -> 변환 -> Binary 데이터( -> 파일에다 저장
위의 과정을 통하여 저장이 이뤄질 것인다. 반대로 로드는 다음과 같은 과정으로 이뤄질 것이다.
파일 -> Binary -> 변환 -> 우리가 알아 볼 수 있는 데이터
이러한 과정을 생각해보고 다음 코드를 봐보자.

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
using UnityEngine;
using System;
using System.Collections;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Reflection;
 
public class MonoDerivedClass : MonoBehaviour{
    public ClassINeed INeed;
}
 
[System.Serializable]
public class ClassINeed{
    public string name;
    public float kkk;
     
    //기본 생성자.
    public ClassINeed(){
    }
    //직접적인 사용이 아니라. 프로그램 상에서 자동적으로 불러주는 생성자이기 때문에 꼭 선언해야한다.
    public ClassINeed(SerializationInfo info, StreamingContext ctxt){
        name = (string)info.GetValue("MyName",typeof(string));
        MyColor = (float)info.GetValue("MyFloat",typeof(float));
    }
    //저번에 설명한 SerializtionInfo에 데이터를 집어넣는 방법.
    public void GetObjectData(SerializationInfo info, StreamingContext ctxt){
        info.AddValue("MyName",name);
        info.AddValue("MyFloat",kkk);
    }
    public void SavePlayerData(){
        ClassINeed data = new ClassINeed();
         
        //새로 생성한 데이터에 값을 넣어준다.
        data.name = name;
        data.MyFloat = MyFloat;
         
        //저장할 파일을 연다.
        Stream stream = File.Open("Assets/Resources/Player/PlayerData.game",FileMode.Create);
        //요놈이 우리가 알아 볼 수 있는 데이터를  컴퓨터가 알아 볼 수 있도록 바꿔줄 것이다.
        BinaryFormatter bformatter  = new BinaryFormatter();
        //여기는 모르겠다.
        bformatter.Binder = new VersionDeserializationBinder();
        Debug.Log ("Saving");
        //데이터를 변환시키고 파일에 저장시켜주는 방법 (추측임)
        bformatter.Serialize(stream,data);
        stream.Close();
    }
     
    public void LoadPlayerData(){
        PlayerData data = new PlayerData();
        Stream stream = File.Open("Assets/Resources/Player/PlayerData.game",FileMode.Open);
        BinaryFormatter bformatter = new BinaryFormatter();
        bformatter.Binder = new VersionDeserializationBinder();
        Debug.Log ("Reading Data");
        //파일에서부터 읽어온 데이터를 다시 번역해서, 우리가 알아 볼 수 있도록 해준다.
        data = (PlayerData)bformatter.Deserialize(stream);
        stream.Close();
         
        name = data.name;
        MyFloat = data.MyFloat;
    }      
}
 
public sealed class VersionDeserializationBinder : SerializationBinder
{
    public override Type BindToType( string assemblyName, string typeName )
    {
        if ( !string.IsNullOrEmpty( assemblyName ) && !string.IsNullOrEmpty( typeName ) )
        {
            Type typeToDeserialize = null;
 
            assemblyName = Assembly.GetExecutingAssembly().FullName;
 
            // The following line of code returns the type.
            typeToDeserialize = Type.GetType( String.Format( "{0}, {1}", typeName, assemblyName ) );
 
            return typeToDeserialize;
        }
 
        return null;
    }
}
위의 코드를 잘 살펴보고 아~ 대충 이런 식으로 흘러가는구나를 알았으면 좋겠다....(나도 모름)

AND

여기서 다룰 것은 , Editor와 같은 커스터마이징이 아닌, 플레이어의 색상을 커스터마이징 하는 방법을 다뤄보겠다. 

게임을 하다 보면, 플레이어는 자유롭게 갑옷의 색상을 정할 수 있는 게임이 존재하는데, 이러한 기능을 구현한다고 생각하면 된다.

그런데 이러한 기능을 구현하기 위해서는 먼저 Serialize에 대해 공부해야 한다.

Unity의 Inspector창에는 Transform의 position을 지정할 수 있고, rotation도 지정할 수 있으며, 그 외의 다른 컴포넌트를 붙였을 때는 그 컴포넌트들의 속성을 고칠 수 있게 된다. 그러나 이러한 기능들은 모두 MONOBEHAVIOR를 직접적으로 상속 받은 클래스에서만 가능한 얘기이다.

그 말은 즉,

1
2
3
4
public class MonoDerivedClass : MonoBehaviour{
    public string name;
    public float kkk;
}
위의 스크립트를 작성하고, 게임 오브젝트에 부착시켰을 때 name과 kkk는 각자의 변수에 알맞게 입력될 수 있도록 자동적으로 생성이 된다는 것이다.

반면 다음과 같은 스크립트를 부착시켰을 때는 위와 다른 결과를 얻게 될 것이다.

1
2
3
4
5
6
7
8
public class MonoDerivedClass : MonoBehaviour{
    public ClassINeed INeed;
}
 
public class ClassINeed{
    public string name;
    public float kkk;
}
그대로 적은 뒤에 게임 오브젝트에 장착시켰다면 위와는 다르게 name과 kkk를 직접 입력 할 수 없게 될 것이다.

자체적인 클래스(Monobehavior를 상속 받지 않는)를 제작하지 않는다면 이러한 문제는 아무런 문제가 없을테지만... 우리는 가끔 자체적인 클래스를 적지 않는가..
여튼 이러한 문제를 해결해주는 것이 Serialize라는 것이다.

먼저 해결책을 보자면 다음과 같다.

using UnityEngine;
using System;
using System.Collections;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Reflection;
 
 
public class MonoDerivedClass : MonoBehaviour{
    public ClassINeed INeed;
}
 
[System.Serializable]
public class ClassINeed : ISerializable{
    public string name;
    public float kkk;
     
    public void GetObjectData(SerializationInfo info, StreamingContext ctxt){
        info.AddValue("MyName",name);
        info.AddValue("MyFloat",kkk);
    }
}
위의 using문들은 나중에 데이터를 저장/로드 하기 위해 필요한 것들을 모두 적어놓은 것이다.
창에 보여주기 위해서는 꼭 GetObjectData를 Overriding해 줘야 된다.
//Overriding이란 부모에 존재하는 함수를 자식함수에서 다시 구현한다는 것입니다.
GetObjectData는 ISerializable에 존재하는 함수고, 그 안에서 SerializationInfo.AddValue를 통해 내가 정의한 변수들을 Inspector 창에서 보여지도록 할 수 있다.
Unity 공식 홈페이지에서도 자료를 찾아볼 수 없으니까 일단 추측글을 한번 써보도록하자.
Unity 내부적으로 MonoBehavior를 상속받은 클래스들을 판단을 해서 자동적으로 Serialization이 되어 Inspector창에 보이는 것이고, 그 외의 클래스들은 멤버 변수들을 수동으로 serialize를 시켜 줘야 inspector창에 보이게 되는 것이다.

즉, MonoBehavior는 SerializationInfo를 가지고 있고 Inspector는 그 SerializtionInfo를 바탕으로 정보를 표시하는 것이다
따라서 AddValue로 SerializationInfo를 추가해줌으로써 내가 원하는 정보들도 Inspector 창에 띄울 수 있다는 결과를 얻게 된다고 본다.

여튼.. Serialize는 원래 직렬화라는 용어로 변수들을 binary로 변환시켜 저장하거나, 로드할 때 필요한 것이라고 보면 된다. 

AND

Unity를 이용하여 앵그리버드 만들기 1탄.

먼저 2D 게임을 만들기 위해서는 적절한 카메라 세팅이 필요.

Camera의 속성중 Projection의 속성을 Orthographic으로 설정해준다.

이렇게 설정해주면 카메라와의 거리와 상관 없이, 한 평면의 점은 모두 위치가 같아보인다. (원근법을 제거해버리는것)


여튼...


앵그리버트의 특징은 앵그리버드는 물리게임이라는것.

다행이도 Unity에서는 RigidBody라는 물리 Component를 제공한다.

단 주의해야할 것은 다음과 같다.

1. 우리의 오브젝트는 z값을 0으로 설정하고, z값이 변하지 않는다.

-> 이것은Rigidbody의 속성중 Contraints의 Freeze Position Z를 체크해주면 된다.

2. 우리의 오브젝트는 돌되, X축과 Y축의 방향으로는 돌지 않는다.

-> 마찬가지로 Rigidbody의 속성 중 Contraints의 Freeze Rotation의 x,y를 체크해준다.


이게 기본적인 물리 세팅이 된다.

'[Unity3D]' 카테고리의 다른 글

커스터마이징 기능 구현하기 2. 데이터의 저장.  (0) 2012.05.03
커스터마이징 기능 구현하기 1. Serialize란...  (0) 2012.05.02
[Unity] Network 정리  (2) 2012.03.25
[Unity] 정리들  (0) 2012.03.25
[Unity] 최적화  (1) 2012.03.24
AND
http://unity3d.com/support/documentation/Components/net-HighLevelOverview.html

권한 2가지 방식

1. Authoriative
-
 방법은 서버에서 클라이언트에 정보를 지속적으로 넘겨주어 클라이언트의 변화를 허락하는 방식이다. 사용자가 입력하면 서버에거 입력을 받고, 그에 맞는 처리를 한다음에 다시 사용자에게 돌려주게된다.

모든 처리를 서버에서하게 됨으로 공격을 받을일이 거의 없지만, 서버에서 처리하는 내용이 많아서 비효율적일수도 있다.
따라서 부분적으로 클라이언트에 권한을 넘겨줘서 클라이언트가 처리하도록 할 수 있는 방법도 존재한다.

2. Non-Authoriative 
- 클라이언트에서 대부분의 로직을 처리하고, 서버에게 처리된 로직을 넘겨줘서 클라이언트간의 데이터를 싱크하는 방식이다.


통신의 방법

1. RPC (Remote Procedure Calls)
- 이 방법은
서버, 클라이언트에서 반대방향(클라이언트, 서버)에 존재하는 함수를 실행하는 방법이다. 

2. State Synchronization
- 이 방법은 자동적으로 데이터들을 맞춰주는 것이다. 플레이어들의 위치, 몬스터의 위치 등을 이것으로 설정해준다면, 자동적으로 맞춰줄 것이다.

서버와 클라이언트 연결하기
- IP주소를 알아야하며, 방화벽 설정을 해줘야한다.  
 

네트워크 함수들

1.Network.Instantiate()
- 연결되어 있는 모든 클라이언트에게 Instantiate명령을 내려주는 작업이다.

2.Network.LoadLevel()
  
 

'[Unity3D]' 카테고리의 다른 글

커스터마이징 기능 구현하기 1. Serialize란...  (0) 2012.05.02
앵그리버드 만들기 1탄.  (0) 2012.04.03
[Unity] 정리들  (0) 2012.03.25
[Unity] 최적화  (1) 2012.03.24
[Unity] Ray의 사용  (0) 2012.03.24
AND
1. FBX를 통해 케릭터 모델을 로딩할때, 한 FBX파일에 애니메이션을 몰아 넣어놓고Split Animation을 통해 애니메이션들을 수동으로 쪼갤 수 있다.

2. FBX를 통해 캐릭터 모델을 로딩할때, Generate  Collider를 On으로 설정해주면 Mesh 그대로 Collision을 체크해준다.  단!. 지형에만 쓸것을 추천하고 움직일것이라면 OFf로 지정, 일반 Collider들을 사용하는것을 추천
 

'[Unity3D]' 카테고리의 다른 글

앵그리버드 만들기 1탄.  (0) 2012.04.03
[Unity] Network 정리  (2) 2012.03.25
[Unity] 최적화  (1) 2012.03.24
[Unity] Ray의 사용  (0) 2012.03.24
[Unity] 인자 전달 방법  (0) 2012.03.24
AND
http://unity3d.com/support/documentation/ScriptReference/index.Performance_Optimization.html 
참고.

1.  
private 변수의 사용
 꽤나 쇼크인 내용.

유니티에서는 게임오브젝트의 컴포넌트를 항상 getcomponent로 찾는 모양입니다.
public class example : MonoBehaviour {
void Update() {
transform.Translate(0, 0, 5);
}
}
해당과 같이 바로 transform을 사용하게 되면. trasnform을 바로 뱉어내는게 아니고, 한번 찾아서 뱉어낸다고 하는군요. 따라서 이 방법보다는
public class example : MonoBehaviour {
private Transform myTransform;
void Awake() {
myTransform = transform;
}
void Update() {
myTransform.Translate(0, 0, 5);
}
}
요것과 같이 내부에 private 변수를 따로 두어 변경해주는것이 더욱 좋다고 합니다.

 

'[Unity3D]' 카테고리의 다른 글

[Unity] Network 정리  (2) 2012.03.25
[Unity] 정리들  (0) 2012.03.25
[Unity] Ray의 사용  (0) 2012.03.24
[Unity] 인자 전달 방법  (0) 2012.03.24
[Unity] 시작  (0) 2012.03.24
AND

Unity에서는 ray라는것을 제공합니다.  ray를 사용하면 내가 화면에서 어떤 아이템을 클릭했는가를 쉽게 알 수 있게 해줍니다.


그럼 먼저


Ray 란 무엇인가?

-> Ray를 번역하면 '광선'이죠?  ray는 말 그대로 광선을 뜻합니다.


시작점 : Origin

방향 : Direction


이 두가지를 가진 오브젝트로써, 시작점으로부터 방향으로 쭉 선을 그어주는 놈입니다.


Ray의 사용

-  ray는 다음과 같은 곳에 쓰일 것입니다. 

1. 게임에서 내 캐릭터를, 내가 클릭한 곳으로 이동시키고 싶다

2. 게임 화면에서 어떤 오브젝트를 클릭했는지 알고 싶다.

----------------------------------제가 현재까지 사용한 정도------------------------------------------------------------------


Ray 관련 중요 메쏘드

- 그럼 Ray와 관련된 중요 메쏘드들을 살펴봅시다.


1. Camera.ScreenToRay(pixelwidth, pixelHeight)  //(http://unity3d.com/support/documentation/ScriptReference/Camera.ScreenPointToRay.html)

- 이 메쏘드는 카메라를 origin으로 삼고, 인자로 받을 픽셀로부터 자동으로 방향을 결졍해주는 함수입니다.


즉, 이 메쏘드는 위에서 언급한 2가지의 경우를 처리하기 위해 필수인 요소입니다.



2. Plane.Raycast(Ray _r, out float _f) //(http://unity3d.com/support/documentation/ScriptReference/Plane.Raycast.html)

- 이 메쏘드는 특정 평면과 Ray와의 충돌을 체크하여  Ray의 Origin으로부터 충돌지점까지의 거리를 _f에 저장하여 줍니다.


응용.

- 위의 두가지를 응용하면 Ray의 사용 1번을 구현할 수 있습니다.

1
2
3
4
5
6
7
8
9
Plane zeroPlane = new Plane(Vector3.up, Vector3.zero);
float distance;
Vector3 pos;
Ray ray = MainCamera.ScreenPointToRay(Input.mousePosition);
 
if(zeroPlane.Raycast(ray,out distance))
{
pos = ray.origin + ray.direction * distance;
}


위의 코드를 살펴보면, zeroPlane이라는 y축의 값이 0인 평면과, MainCamera에서 쏜 Ray를 

zeroPlane.Raycast(ray,out distance))를 통해 처리하고있습니다.

실제 충돌 좌표를 구하는 작업은  8번째 줄입니다.

Vector3 pos에 ray의 원점, 그리고 ray의 방향(노말 벡터)에 거리를 곱해서 구한 것입니다.


3. Physics.Raycast  //http://unity3d.com/support/documentation/ScriptReference/Physics.Raycast.html

- 이 함수는 오버로딩(?)이 되어있습니다. 함수는 기본적으로 충돌하면 참을 반환합니다.

1. (vector3 중심, vector3 방향, float 최대 거리, layermask(?)) (Ray ray, float 거리, layermask)

-> 이 함수는 최대 거리 안에 Collider와 충돌을 하면 true값을 반환해 줍니다.

2. (vector3 중심, vector3 방향, out RaycastHit _r, float 거리, layermask), (Ray ray,out RaycastHit _r, float 거리, layermask)

-> 이 함수를 사용하여 어떤 오브젝트에 가장 먼저 충돌했는지 알 수 있습니다. 그리고 이것을 이해하기 위해서는 

RaycastHit이라는 놈을 알아야 합니다.


RaycastHit //http://unity3d.com/support/documentation/ScriptReference/RaycastHit.html

ray와 충돌한 오브젝트의 정보를 담기 위한 자료입니다.

이를 통해, 

충돌한 지점 point, 

충돌한 지점의 노말 벡터 ,normal

거리 ,distance

충돌된 오브젝트, collider ->요놈이 필요해요

rigidbody

transform


위의 것 외에도 더 있지만, 제가 모르기에 설명 안합니다.


응용

-> 이제 1번과 3번을 응용하여 내가 어떤 오브젝트를 선택했는지 알 수 있습니다.

1
2
3
4
5
6
7
Ray ray = MainCamera.ScreenToRay(Input.mouseposition);
RaycastHit hit;
 
if(Physics.Raycast(ray,out hit))
{
 Debug.Log(hit.collider.name);
}


위의 코드를 그대로 해보면 자신이 클릭한 collider의 이름이 출력되는것이 보일것입니다.


 ---------------------------------------------------------------------------------------------------------------------------------------

저는 카메라에만 사용하였지만, ray는 특정 방향으로 오브젝트가 충돌했을 경우를 체크하기에 유용함으로 쓰기 나름입니다.

 


'[Unity3D]' 카테고리의 다른 글

[Unity] Network 정리  (2) 2012.03.25
[Unity] 정리들  (0) 2012.03.25
[Unity] 최적화  (1) 2012.03.24
[Unity] 인자 전달 방법  (0) 2012.03.24
[Unity] 시작  (0) 2012.03.24
AND

이 글에서는 다양한(? 그래봤자 3가지정도)방법을 이용하여 인자를 전달하는 방법을 알아보도록 하겠습니다.

 

1. 그냥 Public  변수의 선언

- 가장 간단한 방법입니다.

스크립트에 public float life; 와 같은것을 해준다면, 게임 오브젝트를 클릭했을 때  Inspector 창에서 수정이 가능한 형태로 나옵니다.


2. SendMessage의 사용

- 별로 추천하지 않는 방법입니다. GameObject.Sendmessage("Method Name",인자); 를 통해 지정한 GameObject가 포함한 스크립트에 MethodName이 있다면 그 함수를 실행합니다..  단점은...... 인자를 한개밖에 못넘겨요..........(틀렸으면 댓글좀요)


예)

Box라는 이름의 게임 오브젝트는 ScriptA라는 스크립트를 컴포넌트로 가지고 있다.

ScriptA라는 스크립트는 Method(float 인자) 라는 함수를 가지고 있다. 


그러면 외부에서 Box에 존재하는 Method를 실행하고 싶다면 다음과 같은 코드를 사용합니다.

1
GameObject.Find("Box").SendMessage("Method", 1.0f);


3. ScriptName을 통해 함수 실행 
-> 이게 개인적으로 제일 좋은것이라 생각함요. 

1
2
3
4
var Script : ScriptName;
 
Script = GetComponent(ScriptName);
Script.Method();

이 방식을 통해서 해당 게임 오브젝트에 존재하는 스크립트의 함수를 실행 할 수 있다. 

따라서 이를 응용하여 다른 게임 오브젝트의 함수를 실행한다고 치자. 

상황

-  총알(Trigger)이 날아가 어떤 플레이어를 맞춘다 그리고 총알을 맞은 플레이어는 죽는다.. 

알아둘 것 

1. 총알은 Trigger이므로 OnTriggerEnter에 처리를 한다. 
2. 플레이어의 메쏘드 IsDead()는 플레이어의 상태를 죽음으로 바꿔주고, State라는 스크립트 파일의 메쏘드이다. 

1
2
3
4
5
6
7
//script for 총알
void OnTriggerEnter(Collider col)
{
 GameObject player = col.gameObject// 맞은 플레이어는 col로 받아들여진다. col.gameObject 를 통해 해당 플레이어의 게임 오브젝트를 player에 저장한다.
 State Script = player.GetComponent<State>();
 Script.IsDead(); //플레이어의 상태가 죽음으로 바뀜
}
이러한 방법으로 게임오브젝트에 다가가 특정스크립트의 메쏘드를 실행 할 수 있다.


'[Unity3D]' 카테고리의 다른 글

[Unity] Network 정리  (2) 2012.03.25
[Unity] 정리들  (0) 2012.03.25
[Unity] 최적화  (1) 2012.03.24
[Unity] Ray의 사용  (0) 2012.03.24
[Unity] 시작  (0) 2012.03.24
AND

먼저 유니티란?

- 유니티는 게임 엔진입니다.  


는 장난반, 진담 반.    여튼 CBES의 기법을 사용하여 만든 게임엔진입니다.


CBES(Component Based Entity System)

- CBES란 무엇이냐....

해석해보면,  부품(component)를 중심으로한 개체(Entity) 시스템이라고 합니다.


예를 들어보록 하죠. 레고조립을 예로 들어보죠....

당신이  레고 부품들을 이용해서 로봇을 만든다고 칩시다.


로봇의 큰 부품을   팔, 몸통, 머리, 다리, 무기 크게 분류해보죠.

그럼 당신은 로봇을 어떻게 만듭니까?


각각 부분에 맞는 부품을 넣죠?   

이와 같습니다.


Unity에서는 GameObject라는 그릇에 Component들을 집어넣습니다.

이 오브젝트에는 물리효과가 적용되니까 '물리효과 부품'을 넣자

이 오브젝트는 빛이 나야되니까 '빛을 내는 부품'을 넣도록 하자.


이러한 형식으로 하나의 Game Object를 생성합니다.


Compont의 범위와 종류

 유니티에서 어느 범위까지 Component로 취급하는지, 그리고 무슨 부품들이 존재하는지 알아보도록 하겠습니다.


Transform - 게임 오브젝트의 위치정보를 담는것입니다.

위치를 Vector3에 담아놓고, 방향등의 추가적인 정보도 존재합니다.

이 정보는 무조건들어 있는 정보입니다.

http://unity3d.com/support/documentation/ScriptReference/Transform.html


Collider -  이 부품은 충돌을 체크하기 위한 부품입니다. 

말씀드리지만 "충돌"만입니다.  충돌할 경우의 물리적인 효과는 아무것도 없습니다.

collider와 같이 충돌을 체크하는 것들은 많이 존재함으로, 다음번 글에서 다루도록 하겠습니다.

http://unity3d.com/support/documentation/ScriptReference/Collider.html


Animation - 애니메이션을 플레이해주는 기능을 지닌 부품입니다.


아..... 다 말해줄 수는 없을 것 같아요... 너무 많거든요? 그래서 컴포넌트의 종류는 이만하고 가장 중요한걸 이야기 하도록 하죠.


그것은 바로 Script의 존재입니다.

 Script(스크립트)란 자기가 직접 정의한 부품을 말하는 것입니다.


예를들어, 음..... 나는 이 검에 불효과를 넣겠어!!!!. 라고 하면,  불 효과를 스크립트로 작성하여 게임 오브젝트에 붙여주시면 됩니다.

유니티는 스크립트를 javascript/C#/boo 이 세가지로 제작할 수 있게 하는데.. 저는 C#으로 설명할 것입니다.


Unity는 사용자가 직접 정의한 부품들도 Component로 취급하게 해주어, 아주 대단한 일을 할 수 있게 만들어 줍니다.


Component 관련 함수들(C# 으로 설명합니다)

- 컴포넌트 관련 함수들은 다음과 같은 것들이 존재합니다.


1.GetComponent  //  http://unity3d.com/support/documentation/ScriptReference/Component.html

이는 게임 오브젝트에 속해있는 부품 하나를 가져옵니다.


ex) 현재 오브젝트에 있는 Collider라는 정보를 가져오는 스크립트를 짜봅시다.


1
Collider col = GetComponent<Collider>();


2. GetComponent(s)InChildren

- 괄호친 것은 있어도되고 없어도 됩니다.

하면 복수로 불러와요


예를 봐봅시다


Collider[] col = GetComponentsInChildren<Collider>();

위의 코드를 치면 Collider라는 컴포넌트들을 리스트로 만들어서 반환을 해줍니다.


3. 컴포넌트의 추가와 삭제

- 레고에서 부품을 추가하고 제거 할 수 있듯이, 유니티에서도 부품을 동적으로 추가/제거 할 수 있습니다.

부품을 추가/제거하기 위한 코드는 다음과 같습니다.

1
2
3
4
5
//추가하는 방법
gameObject.AddComponent("Component Name");
 
//제거하는 방법
Destroy(gameObject.GetComponent<Component Name>());


Destroy같은 경우는 모든 파괴에 사용이 됩니다.


Script를 컴포넌트로써 활용하기

- 위에서 언급했듯이  스크립트 또한 하나의 부품으로 취급됩니다.

이 말은 즊!!!!! 한 스크립트에서 다른스크립트의 정보를 가져와 함수를 실행 할 수 있다는 이야기입니다.

뭐 간단히 가정을 하도록하죠.


ScriptA - 나는 플레이어를 죽게 만들 수 있지. 그러나 PlayerHp라는 정보가 필요해

ScriptB - 나는 플레이어의 PlayerHP를 관리하는 스크립트다. PlayerHp는 GetHp()라는 함수로 얻을 수 있어.


지금 상황에서는 ScriptA가 ScriptB의 함수를 실행해야 하는 경우죠. 이런 경우는 다음의 코드로 실행 할 수 있습니다.


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
//ScriptB의 구현
public class ScriptB : MonoBehavior
{
private float PlayerHP;
 
void Update()
{
//hp처리
}
 
public GetHp()
{
return PlayerHp;
}
}
 
//ScriptA 의 구현
 public class ScriptA : MonoBehavior
{
private ScriptB script; //요렇게 자료형을 스크립트 이름으로 해주어야 합니다.
 
void Start()
{
script = GetComponent<ScriptB>();//두 스크립트는 같은 오브젝트의 부품이니까, GetComponent<스크립트 이름>으로 가져옵니다.
}
 
void Update()
{
if(script.GetHp() < 0) // 요렇게 합니다
{
//나 죽었어요 처리
}
}
}


이는 두개의 스크립트가 같은 오브젝트에 있을 경우에만 사용이 가능합니다.

다른 방법으로 스크립트의 함수를 실행 할 수 있지만 다음 글에서 설명하도록 하겠습니다.


http://unity3d.com/support/documentation/ScriptReference/Component.html



'[Unity3D]' 카테고리의 다른 글

[Unity] Network 정리  (2) 2012.03.25
[Unity] 정리들  (0) 2012.03.25
[Unity] 최적화  (1) 2012.03.24
[Unity] Ray의 사용  (0) 2012.03.24
[Unity] 인자 전달 방법  (0) 2012.03.24
AND

ARTICLE CATEGORY

목록들 (118)
[Unity3D] (39)
그래픽관련 (13)
잉여잉여 (25)
프로그래밍 (27)
노래♬ (3)
Game_Design(기획) (3)

RECENT ARTICLE

RECENT COMMENT

RECENT TRACKBACK

CALENDAR

«   2024/05   »
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

ARCHIVE