실전 Unity3D Engine Programing 과정 3일차 (2013.07.24 (수)) 


어제 만든 것을 3D로 변경 한다.


asset에 새로운 리소스 임포트한다.





1.신만든다. 이름은 NewGame으로 한다.

2. 메인 카메라 값을 변경한다.




3. 라이트 추가한다.

4. Assets _Object에 있는 SpaceCraftBox 하이어라키에 추가한다

- 에니메이션은 리무브 컴포넌트한다.

- PlayControl 스크립트를 추가한다.

- PlayControl 스크립트 드래그해서 오른쪽에 추가한다.



PlayControl스크립트 수정

void Update () {

float moveAmt = Input.GetAxis ("Horizontal") * Speed * Time.deltaTime;

float moveAmt2 = Input.GetAxis("Vertical") * Speed * Time.deltaTime;

Vector3 moveVector = Vector3.right * moveAmt + Vector3.up * moveAmt2;

transform.Translate(moveVector);

if(Input.GetKeyDown(KeyCode.Space)){

audio.Play();

Instantiate(bullet, transform.position, transform.rotation);

}

}


5. Assets _Object에 있는 missileFBX를 하이어라키에 추가한다.

- 에니메이션 제거

-   scale 은 5, 5, 2변경한다.

- 충돌을 위해서 리디지바디를 추가한다.

   그라비티  언체크

- 충돌시 캡슐 콜리더를 추가한다. Capsul Collider

  -  센터는 0 0 0

  - 트리거 체크

   - 각도.. 0.06 높이 0.42 축 z-Axis

-  BulletScript를 추가한다.

- 스크립트를 다음과 같이 수정

using UnityEngine;

using System.Collections;


public class BulletControl : MonoBehaviour {


public float Speed = 20f;

// Update is called once per frame

void Update () {

float moveAmt = Speed * Time.deltaTime;

transform.Translate(Vector3.forward * moveAmt);

if(transform.position.z > 35.0f){

Destroy(gameObject);

}

}

- 파티클을 추가하자.

   Standard Assets, Particles , small flames 하이어키에 추가하자.

   - Particle animator의 force값 수정 0.0.-5

   - Ellipsoid Particle Emitter Local velocity, Rnd Velocity를 모두 0으로 준다.

                                        사이즈를 모두 줄인다 1/2


미사일를 비행체 자식으로 바꿔준다.

하이얼리키에서 옮긴다.



그리고 불을 미사일 꽁무니에 옮겨준다. 신화면에서





Prefabs에서 MeshBulletfabs를 만들고 미사일FBX을 끌어다 놓는다. 그리고 미사일 FBX는 제거한다.




[적군을 만들자]

새로 asset에 있는 오브젝트에서 sunRingFBX  하이어라키에 추가한다.

- 에니메이션 리무브

- 메슈콜라이더삭제

- 메뉴 콤포넌트 피직스 shhere collider추가 (크기가 비스하게 들어간다.)

- EnemyControl 스크립트 드래그 드랍으로 추가

   - 

- 오디오 소스 추가. way on awake 언체크, 히트오디오 추가



- EnemyControl 수정

void Update () {

float moveAmt = Speed * Time.deltaTime;

transform.Translate(Vector3.forward * moveAmt);

if(transform.position.z < -7.0f)

{

InitPosition();

}

}

void InitPosition()

{

transform.position = new Vector3(

Random.Range(-10.0f,10.0f),

   Random.Range(-10.0f, 10.0f),

35.0f);

}



- sunRingFBX에서 포지션 0, 0, 35, Rotation 0, 180, 0 수정

sunRingFBX 추가로 2개 복재한다.  x 값을 수정해서 나란히 한다.


- prefabs의 MeshgBulletPrefab Tag를 bullet으로 수정한다.




[배경을 넣자]

assets -> import package -> skybox를 추가한다.


 내용을 놓쳤다...  ㅜ ㅜ





#스크립트에 대해서 배우자. Scripting Overview 파일을 연다.

- www.unity3d.com > community > Document / Go to document  > 우측의 script탭을 누른다. ( Wiki 열어보면 스크립트가 많이 있다. )

  (유니티 IDE에 메뉴에 있는 script help는 옛날 것이다.)

  상기에 스크립트 최신 정보를 볼 수 있다.

  독일 쪽에 스크립트 최신 정보를 찾아 볼 수있고, 구글에서 검색해 본다.

  에러 발생시 서치해 본다.

  - 서치에서 monobehaviour를 친다.  



  


MonoBehaviour

Description

MonoBehaviour is the base class every script derives from.

Using Javascript every script automatically derives from MonoBehaviour. When using C# or Boo you have to explicitly derive from MonoBehaviour.

Note: The checkbox for disabling a MonoBehavior (on the editor) will only prevent Start(), Awake(), Update(), FixedUpdate(), and OnGUI() from executing. If none of these functions are present, the checkbox is not displayed.

See Also: The chapter on scripting in the manual.
Variables

useGUILayout

Disabling this lets you skip the GUI layout phase.
Functions

CancelInvoke

Cancels all Invoke calls on this MonoBehaviour.

Invoke

Invokes the method methodName in time seconds.

InvokeRepeating

Invokes the method methodName in time seconds.

IsInvoking

Is any invoke on methodName pending?

StartCoroutine

Starts a coroutine.

StopAllCoroutines

Stops all coroutines running on this behaviour.

StopCoroutine

Stops all coroutines named methodName running on this behaviour.
Static Functions
printLogs message to the Unity Console. This function is identical to Debug.Log.
Messages

Awake

Awake is called when the script instance is being loaded.

FixedUpdate

This function is called every fixed framerate frame, if the MonoBehaviour is enabled.

LateUpdate

LateUpdate is called every frame, if the Behaviour is enabled.

OnAnimatorIK

Callback for setting up animation IK (inverse kinematics).

OnAnimatorMove

Callback for processing animation movements for modifying root motion.

OnApplicationFocus

Sent to all game objects when the player gets or loses focus.

OnApplicationPause

Sent to all game objects when the player pauses.

OnApplicationQuit

Sent to all game objects before the application is quit.

OnAudioFilterRead

If OnAudioFilterRead is implemented, Unity will insert a custom filter into the audio DSP chain.

OnBecameInvisible

OnBecameInvisible is called when the renderer is no longer visible by any camera.

OnBecameVisible

OnBecameVisible is called when the renderer became visible by any camera.

OnCollisionEnter

OnCollisionEnter is called when this collider/rigidbody has begun touching another rigidbody/collider.

OnCollisionExit

OnCollisionExit is called when this collider/rigidbody has stopped touching another rigidbody/collider.

OnCollisionStay

OnCollisionStay is called once per frame for every collider/rigidbody that is touching rigidbody/collider.

OnConnectedToServer

Called on the client when you have successfully connected to a server.

OnControllerColliderHit

OnControllerColliderHit is called when the controller hits a collider while performing a Move.

OnDestroy

This function is called when the MonoBehaviour will be destroyed.

OnDisable

This function is called when the behaviour becomes disabled () or inactive.

OnDisconnectedFromServer

Called on the client when the connection was lost or you disconnected from the server.

OnDrawGizmos

Implement this OnDrawGizmos if you want to draw gizmos that are also pickable and always drawn.

OnDrawGizmosSelected

Implement this OnDrawGizmosSelected if you want to draw gizmos only if the object is selected.

OnEnable

This function is called when the object becomes enabled and active.

OnFailedToConnect

Called on the client when a connection attempt fails for some reason.

OnFailedToConnectToMasterServer

Called on clients or servers when there is a problem connecting to the MasterServer.

OnGUI

OnGUI is called for rendering and handling GUI events.

OnJointBreak

Called when a joint attached to the same game object broke.

OnLevelWasLoaded

This function is called after a new level was loaded.

OnMasterServerEvent

Called on clients or servers when reporting events from the MasterServer.

OnMouseDown

OnMouseDown is called when the user has pressed the mouse button while over the GUIElement or Collider.

OnMouseDrag

OnMouseDrag is called when the user has clicked on a GUIElement or Collider and is still holding down the mouse.

OnMouseEnter

OnMouseEnter is called when the mouse entered the GUIElement or Collider.

OnMouseExit

OnMouseExit is called when the mouse is not any longer over the GUIElement or Collider.

OnMouseOver

OnMouseOver is called every frame while the mouse is over the GUIElement or Collider.

OnMouseUp

OnMouseUp is called when the user has released the mouse button.

OnMouseUpAsButton

OnMouseUpAsButton is only called when the mouse is released over the same GUIElement or Collider as it was pressed.

OnNetworkInstantiate

Called on objects which have been network instantiated with Network.Instantiate.

OnParticleCollision

OnParticleCollision is called when a particle hits a collider.

OnPlayerConnected

Called on the server whenever a new player has successfully connected.

OnPlayerDisconnected

Called on the server whenever a player disconnected from the server.

OnPostRender

OnPostRender is called after a camera finished rendering the scene.

OnPreCull

OnPreCull is called before a camera culls the scene.

OnPreRender

OnPreRender is called before a camera starts rendering the scene.

OnRenderImage

OnRenderImage is called after all rendering is complete to render image.

OnRenderObject

OnRenderObject is called after camera has rendered the scene.

OnSerializeNetworkView

Used to customize synchronization of variables in a script watched by a network view.

OnServerInitialized

Called on the server whenever a Network.InitializeServer was invoked and has completed.

OnTriggerEnter

OnTriggerEnter is called when the Collider other enters the trigger.

OnTriggerExit

OnTriggerExit is called when the Collider other has stopped touching the trigger.

OnTriggerStay

OnTriggerStay is called once per frame for every Collider other that is touching the trigger.

OnValidate

This function is called when the script is loaded or a value is changed in the inspector (Called in the editor only).

OnWillRenderObject

OnWillRenderObject is called once for each camera if the object is visible.

Reset

Reset to default values.

Start

Start is called just before any of the Update methods is called the first time.

Update

Update is called every frame, if the MonoBehaviour is enabled.
Inherited members
Variables

enabled

Enabled Behaviours are Updated, disabled Behaviours are not.

animation

The Animation attached to this GameObject (null if there is none attached).

audio

The AudioSource attached to this GameObject (null if there is none attached).

camera

The Camera attached to this GameObject (null if there is none attached).

collider

The Collider attached to this GameObject (null if there is none attached).

constantForce

The ConstantForce attached to this GameObject (null if there is none attached).

gameObject

The game object this component is attached to. A component is always attached to a game object.

guiText

The GUIText attached to this GameObject (null if there is none attached).

guiTexture

The GUITexture attached to this GameObject (Read Only). (null if there is none attached).

hingeJoint

The HingeJoint attached to this GameObject (null if there is none attached).

light

The Light attached to this GameObject (null if there is none attached).

networkView

The NetworkView attached to this GameObject (Read Only). (null if there is none attached).

particleEmitter

The ParticleEmitter attached to this GameObject (null if there is none attached).

particleSystem

The ParticleSystem attached to this GameObject (null if there is none attached).

renderer

The Renderer attached to this GameObject (null if there is none attached).

rigidbody

The Rigidbody attached to this GameObject (null if there is none attached).

tag

The tag of this game object.

transform

The Transform attached to this GameObject (null if there is none attached).

hideFlags

Should the object be hidden, saved with the scene or modifiable by the user?

name

The name of the object.
Functions

BroadcastMessage

Calls the method named methodName on every MonoBehaviour in this game object or any of its children.

CompareTag

Is this game object tagged with tag?

GetComponent

Returns the component of Type type if the game object has one attached, null if it doesn't.

GetComponentInChildren

Returns the component of Type type in the GameObject or any of its children using depth first search.

GetComponents

Returns all components of Type type in the GameObject.

GetComponentsInChildren

Returns all components of Type type in the GameObject or any of its children.

SendMessage

Calls the method named methodName on every MonoBehaviour in this game object.

SendMessageUpwards

Calls the method named methodName on every MonoBehaviour in this game object and on every ancestor of the behaviour.

GetInstanceID

Returns the instance id of the object.

ToString

Returns the name of the game object.
Static Functions

Destroy

Removes a gameobject, component or asset.

DestroyImmediate

Destroys the object obj immediately. You are strongly recommended to use Destroy instead.

DontDestroyOnLoad

Makes the object target not be destroyed automatically when loading a new scene.

FindObjectOfType

Returns the first active loaded object of Type type.

FindObjectsOfType

Returns a list of all active loaded objects of Type type.

Instantiate

Clones the object original and returns the clone.
Operators

bool

Does the object exist?

operator !=

Compares if two objects refer to a different object.

operator ==

Compares if two objects refer to the same.


이들 내용중에 on으로 시작하는 것은 꼭 달달 외워야 한다.

transform와 Translate를 찾아보라..


Scripting Overview 파일은 아래 내용을 붙였다..


많이 물어보는 내용으로 설명해 본다.


##. GameObject를 찾는 방법

Find  (찾는 것 최상에 것이 찾아진다.) 빠름2

FindWithTag    빠름 1

FindGameObjectWithTag (전부 다찾는것) 빠름3

FindObjectOfType 빠름 4  <== 쓰지 마라 느리다.. 

FindObjhectsOfType 빠름 5 <== 절대 코드에 적용하지 마라 매우 느리다.


GameObject로  찾아보라..



빠르고 느린지를 확인하는 방법...

Play해보고 아래 것을 열어 보면  overview을 알 수 있다. 

메뉴 > 윈도우 > 프로파일러

CPU, Render등이 나온다. 


이제 문서를 보자.

## Update...


Unity 한 Frame의 의미는?

GameObject의 upate가 동작하

~~~~~~~~~~~~~ <= update시작

스크립트의 내용

 - preupdate update lateUdate

 - 이것을 모든 scene에서 돈다.

update 호출 

<== 이것은 눈에 보이지 않고 느린 주범이다. 코더의 수정 부분 코딩은 잘해야 한다.


그리고 preRender Render PostRender가 있다.

  Render는 카메라에 붙어 있는 모든 Render를 호출한다. pre와 postRender로 한다. 

<== 이미지 개선이 가능한 부분 디자이너의 개선 부분

~~~~~~~~~~~~<- 여까지가 한프레임이...(폴리콘.. 카운트 )


따라서 코더는 스크립트의 단위 테스트로 문제점 시간 등을 확인해야 한다.


** 스크립트는 80line을 넘지말다 (최대 120line) / 스크립트는 하나의 함수라고 생각해야 한다.

** 스크립트가 많아지면 언떻게 해야 파라메터 차이로 스크립트 늘어나는 것을 줄일 수 있다.

** 간결하게 쓰고 이중 포문 쓰지 마라, 

** 펑션콜을  줄인다...


update는 빠른 컴퓨터는 빠르고, 느리다.

- deltaTime

fixedUpdate 는 정해진 시간에 업데트된다. 

- TimeManger를 가봐라..

- 이것은 물리에만 사용해야 하낟.

- fixedDeltaTime


##숏컷



##get하는 방법

-함수를 불러오는 방법

  playercontrol 스크립트 안에 있는 함수를 찾는다.

  GameObject.Find("player").GetComponet<playercontrol>().함수명();


   스크립트내에서 찾을 때 소문자. 소문자는 자기것을 의미함

   gameObjct.GetComponent<playControl>().함수명();


   tranform.FindChild("player").gameObject.

- 중복된 스크립트는 어떻게 가져 오나?  더비부모를 만들고 거기에 넣어서 더미부모를 가져 오게 한다. 이때 응답은 배열이다. 또는 Tag검색하라.


## 스크립트의 동작순서

1) Awake <== 딱 한번 호출 FInd 함수 되도록이면 쓰지마라. 참조해서 사용해라

2) Start <== 딱 한번 호출 FInd 함수 되도록이면 쓰지마라. 참조해서 사용해라

    생성하고 꺼놓으다가 다시 호출해도 호출되지 않는다. Inspector에서 스크립트 체크박스를 언체크...하면 끄는 것이다. 

3) update() == OnGUI()

    업데이트도 껐다 키면 호출 안된다. 

4) lateUpdate


## 인스턴스

as는 타입케스팅이다.

인스턴스를 통해서 원하는 컨포넌트를 불러올 수 있다.



## Corote..

직접예제...


## 상속

초기화 Awake, 

클래스와 파일이름은 동일하게


## 

namespace는 사용마라..


## 생성자는 못쓴다. 모노비해뷰어에 상속받은 놈은



## Use STatic Typing

자바스크립트보다 C# 스크립트가 훨 빠르다..

Var 타입때문에 매우 드리다.

이것은 모든 타입을 모두 담을 수 있다. 따라서 동적으로 타입케스팅된다. 



## 스크립트를 빠르게 쓸 수 있는 방법

ArrayList.add(모든타입)...

따라서 배열크기가 일정하지 않아서 검색시 느리다.

타입이 하나라면,

Vector[] 형태로 배열로 사용하는 것이 훨씬 빠르다. 17.5배 빠르다.

이렇게 하면 메모리 각 크기가 동일하기에 빠른 것이다.



## 컴포넌트 캐싱

미리 담아 둔다는 의미..

최신 숏컷으로 대신하기에 별로 사용하지 않는다...

소문자 transform으로 자신의 것을 지정할 수 있다.



## 이팩트 사용시 화면이 멈칫하는 것 막는 방법

1) 생성후 저멀리 위치 옮겨 놓을 것을 위치를 옮기를 형태로 한다. 

2) 스크립트에서 원하는 해당 콤포넌트를 하나씩 AddComponet하는 방법이 있다.

    - 한꺼번에 넣어 놓으면 느리다. 코드로 단계별로 호출하는 방식이 빠르다.

3) 화면에 보이지 않으면 업데이트 하지 마라..



## 카메라 들어올때만 업데이트하라

- 스크립트를 언체크한다. (끈다)



## 컴파일 순서

Assets 내용에 있는것을 본다.

- Startd Assets을 1차 

- Editor 폴더

- Plugin 폴더 (외부 것.. C++, DLL)

* 상기 3가지는 다른 것에서 불러 올수 없다. (컴파일시)


[Scripting Overview 파일]

번역/수정/추가 주세영

 

Scripting Overview  

유니티 내부의 스크립팅은 Behaviours(동작들)라고 불리는 스크립트 개체를 게임 오브젝트에 붙임 으로써 시작된다고 할 수 있습니다. 스크립트 개체의 내부 함수들은 특정 이벤트 상에서 호출이 되는데 가장 많이 사용되는 함수는 아래와 같습니다.

Update

이함수는 하나의 프레임이 렌더링되기 전에 호출된다. 물리코드를 제외한 대부분의 게임 동작 코드가 실행되는 곳입니다.

FixedUpdate

물리 동작의 매 스텝마다 호출됩니다. 물리학 기반의 게임 동작들을 실행 할 수 있는 곳입니다.

Code outside any function

오브젝트들이 로드될 때 함수 외부의 코드들이 실행 됩니다. 이것은 스크립트의 상태를 초기화 하는데 사용될 수 있습니다.

 

일반적인 동작들

대부분의 게임 오브젝트에 대한 조작은 게임오브젝트의 Transform 이나 Rigidbody를 통해 이루어 집니다. 이것은 Monobehaviour를 상속받은 스크립트 안에서 접근 할 수 있는데, 사용법은 대충 아래와 같습니다.

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Update() {
        transform.Rotate(0, 5, 0);
    }
}

만약 오브젝트를 움직이고 싶다면

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Update() {
        transform.Translate(0, 0, 2);
    }
}

 

Overview: Keeping Track of Time  

Time 클래스는 deltaTime이라 불리는 매우 중요한 클래스 변수를 갖고 있다. 이 변수는 Update또는 FixedUpdate 함수가 마지막으로 호출된 이후 경과한 시간의 양을 저장한다. (Update 함수 내부와 FixedUpdate 함수 내부랑은 다르다)

그래서 앞의 예제를 일정한 속도로 회전하도록 만들기 위해 다음 처럼 수정한다.

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Update() {
        transform.Rotate(0, 5 *
Time.deltaTime, 0);
    }
}

오브젝트 이동:

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Update() {
        transform.Translate(0, 0, 2 *
Time.deltaTime);
    }
}

만약 당신이 프레임마다 값을 더하거나 뺀다면 Time.delTaTime 곱해야 한다.

다른 예로 만일 당신이 시간에 따라 빛의 범위를 증가시키고 싶다면 아래와 같이 변경하면 되는데 아래 구문은 초당 2유닛 만큼씩 반경을 변경시킬 것이다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Update() {
        light.range += 2.0F *
Time.deltaTime;
    }
}

Forces를 통해 Rigidbody를 조작할때는, 엔진이 이미 그것을 처리해 주므로 일반적으로 Time.deltaTime을 곱할 필요는 없다.

Overview: Accessing Other Components  

 

컴포넌트들은 게임 오브젝트에 Attack 된다. 하나의 Renderer 컴포넌트를 게임 오브젝트에 붙이는 것은 그것을 스크린 상에 그려지도록 만드는 것이고, Camera를 붙이는 것은 그것을 카메라 오브젝트로 변환하는 것이다. 모든 스크립트들은 컴포넌트들이므로 그것들은 게임 오브젝트들에 붙일수 있다(Monobehaviour를 상속받았다면)

대부분의 일반 컴포넌트들은 간단한 멤버변수들로 액세스 할 수 있다.

Component

Accessible as

Transform

transform

Rigidbody

rigidbody

Renderer

renderer

Camera

camera (only on camera objects)

Light

light (only on light objects)

Animation

animation

Collider

collider

... etc.

 

만일 게임오브젝트가 당신이 얻고자 하는 컴포넌트를 갖고 있지 않다면, 변수들은 null 셋팅된다.

게임 오브젝트에 attach 어떤 컴포넌트나 스크립트는 GetComponent 통해서 access 있다.

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Awake() {
        transform.Translate(0, 1, 0);
        GetComponent<
Transform>().Translate(0, 1, 0);
    }
}

 

transform Transform 사이의  /소문자 차이에 주의해야한다. 전자는 변수이고 후자는 하나의 클래스 똔느 스크립트의 이름이다. 이 대/소문자는 클래스/스크립트이름과 변수이름을 구별하게 해준다.

우리가 배운 것을 적용해 이제 우리는 GetComponent를 사용해 동일한 게임오브젝트에 붙은 다른 스크립트 또는 builtin 컴포넌트들을 찾을 수 있다. 다음의 예제를 작동시키려면 DoSomething함수를 가진 OtherScript 라는 스크립트가 필요하다. OtherScript는 게임오브젝트에 attach되어야 한다.

 

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Update() {
        OtherScript otherScript = GetComponent<OtherScript>();
        otherScript.DoSomething();
    }
}

 

Overview: Accessing Other Game Objects 

 

대부분의 게임코드는 단 하나의 오브젝트만 다루지 않는다. 유니티 스크립팅 인터페이스는 다른 게임 오브젝트들과 그 내부의 컴포넌트들을 찾아서 접근하기 위한 다양한 방법들을 제공한다.

다음의 코드에서 우리는 Scene내에 게임 오브젝트들에 붙여진 OtherScript 라는 이름의 스크립트가 있다고 가정한다.

.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Update() {
        OtherScript otherScript = GetComponent<OtherScript>();
        otherScript.DoSomething();
    }
}

1.     Inspector를 통한 참조

Inspector를 통해서 변수에 할당된 컴포넌트에 접근할 수 있다.

:

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    public
Transform target;
    void Update() {
        target.Translate(0, 1, 0);
    }
}

 

또한 다른 오브젝트에 대한 참조들을 inspector에 노출 시킬 수 있는데 Inspector의 타겟 슬롯위로 다른 스크립트를 가지고 있는 게임 오브젝트를 드래그 할 수 있다.

 

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    public OtherScript target;
    void Update() {
        target.foo = 2;
        target.DoSomething("Hello");
    }
}

2.     오브젝트 계층을 통한 위치 찾기

오브젝트의 Transform 컴포넌트를 통해 기존 오브젝트의 Child Parent 오브젝트를 찾을 수 있다.

 

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Awake() {
        transform.Find("Hand").Translate(0, 1, 0);
    }
}

일단 Hierarchy에서 transform을 찾으면, 타 스크립트들에 접근해서 GetComponent함수를 사용할 수 있다.

 

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Awake() {
        transform.Find("Hand").GetComponent<OtherScript>().foo = 2;
        transform.Find("Hand").GetComponent<OtherScript>().DoSomething("Hello");
        transform.Find("Hand").rigidbody.AddForce(0, 10, 0);
    }
}

모든 Child 들을 순환하면서 접근할 있다.

:

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Awake() {
        foreach (
Transform child in transform) {
            child.Translate(0, 10, 0);
        }
    }
}

3.     이름과 Tag를 통해 접근하기

GameObject.FindWithTag GameObject.FindGameObjectsWithTag 사용해서 어떤 tag들로 게임 오브젝트들을 찾을 있다GameObject.Find  이용해서 이름으로 찾을수 있다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Start() {
       
GameObject go = GameObject.Find("SomeGuy");
        go.transform.Translate(0, 1, 0);
       
GameObject player = GameObject.FindWithTag("Player");
        player.transform.Translate(0, 1, 0);
    }
}

찾은 게임 오브젝트를 통해 GetComponent들을 사용할 있다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Start() {
       
GameObject go = GameObject.Find("SomeGuy");
        go.GetComponent<OtherScript>().DoSomething();
       
GameObject player = GameObject.FindWithTag("Player");
        player.GetComponent<OtherScript>().DoSomething();
    }
}

메인 카메라 같은 특별한 오브젝트들은  Camera.main. 같은 단축어를 있다.

4.     파라미터를 통해서 위치 찾기

어떤 이벤트 메시지들은 이벤트에 대한 자세한 정보를 담는다. 예를 들어 Trigger 이벤트들은 핸들러 함수에 충돌 오브젝트의 Collider 컴포넌트를 넘겨 준다. OnTriggerStay 함수는 Collider 대한 참조를 제공해 준다. Collider로부터 그것에 Attach rigidbody 얻을 있다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void OnTriggerStay(
Collider other) {
        if (other.rigidbody)
            other.rigidbody.AddForce(0, 2, 0);
       
    }
}

또는 Collider 동일한 게임오브젝트에 붙여진 다른 컴포넌트들을 얻을 있다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void OnTriggerStay(
Collider other) {
        if (other.GetComponent<OtherScript>())
            other.GetComponent<OtherScript>().DoSomething();
       
    }
}

샘플에서 Other 변수 뒤에 접미사를 붙임으로써 충돌 오브젝트 안의 다른 컴포넌트를 액세스 있다.

 

5. 특정 타입의 스크립트들

 Object.FindObjectsOfType 사용해 특정 타입의 어떤 오브젝트나 스크립트들을 찾거나 Object.FindObjectOfType. 사용해 특정 타입의 첫번째 오브젝트를 찾을 있다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Start() {
        OtherScript other = FindObjectOfType(typeof(OtherScript));
        other.DoSomething();
    }
}

Overview: Vectors

유니티는 모든 3차원 벡터를 표현하기 위해 Vector3 클래스를 사용한다. 3차원 벡터의 성분들은 x,y,z 멤버 변수들을 통해 접근 있다.

 

Vector3 aPosition;

aPosition.x = 1;

aPosition.y = 1;

aPosition.z = 1;

 

벡터의 모든 성분들을 한번에 초기화하기 위해 Vector3 생성자를 사용할 있다..

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    public
Vector3 aPosition = new Vector3(1, 1, 1);
}

Vector3  또한 공통적으로 많이 사용하는 값들을 정의해놓은 공통 변수들을 통해 셋팅할 있다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    public
Vector3 direction = Vector3.up;
}

벡터 상에서의 연산들은 아래와 같은 방식으로 접근 된다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    void Awake() {
        SomeVector.Normalize();
    }
}

또한 여러 개의 벡터들에 대한 연산들은 Vector3 클래스 함수들을 사용한다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    public
Vector3 oneVector = new Vector3(0, 0, 0);
    public
Vector3 otherVector = new Vector3(1, 1, 1);
    public float theDistance =
Vector3.Distance(oneVector, otherVector);
}

또한 벡터들을 다루기 위해 일반 수학 연산자들을 사용할 있다.

vectors: combined = vector1 + vector2;

사용 가능한 연산들과 속성들의 전체 리스트는 Vector3 클래스 참조 문서를 참고하기 바란다.

 

Overview: Member Variables & Global Variables

 

함수 외부에서 정의된 변수는 하나의 멤버 변수로 정의된다. 멤버 변수들은 유니티 내의 Inspector를 통해 접근 될 수 있다. 또한 멤버 변수에 저장되는 어떤 값은 프로젝트와 함께 자동으로 저장된다.

 

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    public float memberVariable = 0.0F;
}

 

위의 변수는 inspector 안에서 Member Variable 이라는 하나의 수치 속성으로서 보여지게 된다.

만일 변수 타입을 컴포넌트 타입(Transform, RigidBody, Collider,스크립트이름)으로 셋팅한다면, Inspector안에서 게임 오브젝트들을 위로 드래깅함으로써 그것들을 셋팅할 있다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    public
Transform enemy;
    void Update() {
        if (
Vector3.Distance(enemy.position, transform.position) < 10)
            print("I sense the enemy is near!");
       
    }
}

또한 Private 멤버 변수들을 생성할 있다. Private 멤버 변수들은 스크립트 외부에서는 보이지 않아야 하는 State 저장하는 유용하다. Private 멤버 변수들은Disk 저장되지 않으며 Inspector에서 Edit 없다. 그것들은 Debug 모드일 Inspector 안에서 있다. 이것은 실시간 Updating Debugger 처럼 Private 변수들을 사용할 있게 해준다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    private
Collider lastCollider;
    void OnCollisionEnter(
Collision collisionInfo) {
        lastCollider = collisionInfo.collider;
    }
}

전역변수

Static 키워드를 사용해 전역 변수를 생성 있다.

아래 스크립트는 someGlobal 이라는 전역 변수를 생성한다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    public static int someGlobal = 5;
    void Awake() {
        print(someGlobal);
        someGlobal = 1;
    }
}

다른 스크립트에서 그것을 액세스 하기 위해서는 스크립트명.전역변수명을 사용할 필요가 있다.
TheScriptName.someGlobal = 10;

Overview: Instantiate  

Instantiate는 한 오브젝트를 복제(Duplicate)한다. 모든 Attach 된 스크립트들과 전체 Hierarchy를 포함한다. 그것은 예상되는 그대로의 Reference들을 유지한다. 복제된 Hierarchy의 외부 오브젝트들에 대한 참조들은 Untouched 상태로 되고 , 내부 오브젝트들에 대한 참조들은 복제된 오브젝트에 매핑될 것이다.

 

Instantiate는 믿기지 않을 만큼 빠르고 용도도 매우 많다. 유니티를 최대로 활용하기 위해서는 필수적이다.

 

아래의 간단한 예제 스크립트는 Collider를 가진 rigidbody attach 되었을때 자신을 Destroy하고 대신 explosion 오브젝트를 Spawn할 것이다.

 

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    public
Transform explosion;
    void OnCollisionEnter() {
        Destroy(gameObject);
       
Transform theClonedExplosion;
        theClonedExplosion = Instantiate(explosion, transform.position, transform.rotation) as
Transform;
    }
}

Instantiate 흔히 Prefab.들과 결합되어 사용된다.

Overview: Coroutines & Yield  

 

게임 코드를 작성할 , 하나의 이벤트 시퀀스를 스크립트해 필요를 자주 느끼게 된다. 그것은 다음 코드와 같을 것이다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    private int state = 0;
    void Update() {
        if (state == 0) {
            state = 1;
            return;
        }
        if (state == 1) {
            state = 2;
            return;
        }
    }
}

yield문을 사용하는 것이 좀더 편리할 때가 종종있다. Yield 문은 return 특수한 종류이고, next time 호출될 yield 다음 라인으로부터 함수가 계속됨을 보장해 준다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    IEnumerator Awake() {
        while (true) {
            yield return null;
            yield return null;
        }
    }
}

 

또한 어떤 이벤트가 발생할 때까지 Update 함수의 실행을 지연시키기 위해 특별한 값들을 Yield 문에 전달 있다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    IEnumerator Awake() {
        yield return new
WaitForSeconds(5.0F);
    }
}

 

아래 예제는 Do 실행하지만 호출한 즉시 계속해서 다음이 실행될 것이다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    IEnumerator Do() {
        print("Do now");
        yield return new
WaitForSeconds(2);
        print("Do 2 seconds later");
    }
    void Awake() {
        Do();
        print("This is printed immediately");
    }
}

예제는 Do 실행하고, 실행을 계속하기 전에 Do 끝날 때까지 기다릴것이다.

C#

using UnityEngine;
using System.Collections;

public class example :
MonoBehaviour {
    IEnumerator Do() {
        print("Do now");
        yield return new
WaitForSeconds(2);
        print("Do 2 seconds later");
    }
    IEnumerator Awake() {
        yield return StartCoroutine("Do");
        print("Also after 2 seconds");
        print("This is after the Do coroutine has finished execution");
    }
}

이벤트 핸들러들 역시 coroutine 있다.

 

Update FixedUpdate 함수 안에서는 Yield 사용할 없다는 것에 주의하라, 하지만 당신은 StartCoroutine 하나의 함수를 시작하기 위해 사용할 있다.

 

많은 정보는  YieldInstructionWaitForSecondsWaitForFixedUpdateCoroutine and MonoBehaviour.StartCoroutine  참조하기 바란다.

Overview: Writing Scripts in C# & Boo

 

Syntax 별개로 하고 C#이나 Boo 스크립트를 작성할 몇가지 차이점이 있다.

1. MonoBehaviour 부터 상속

모든 게임오브젝트 동작 스크립트들은 Monobehaviour로부터 상속을 받아야 한다. (직접또는 간접적으로) 이것은 자바스크립트 안에서는 자동적으로 일어나지만 C#이나 Boo 스크립트들에서는 명시적이어야 한다. 만일 유니티에서 Asset -> Create -> C Sharp/Boo Script  통해 스크립트를 생성한다면, 생성된 템플릿은 이미 필요한 정의를 포함하고 있을 것이다.

public class NewBehaviourScript : MonoBehaviour {...} // C#

class NewBehaviourScript (
MonoBehaviour):  ... # Boo

2. 초기화는  Awake 또는 Start 함수에서 하라

자바스크립트에서는 함수들 외부에 놓는 것들을, C#이나 BOO 에서는 Awake 함수나 Start함수에 놓는다.

Awake Start 차이점은 Awake 씬이 로드될 실행되고 , Start Update FixedUpdate 처음 호출되기 직전에 호출된다. 모든 Awake함수들은 Start 함수들이 호출되기 이전에 호출된다.

3. 클래스 이름은 파일이름과 일치해야 한다..

클래스 이름과 파일이름이 다르면 GameObject에서 제대로 스크립트 컴포넌트로써 인식을 못한다.

4. C# 에서 Coroutines 들은 다른 syntax 갖는다..

Coroutines  IEnumerator 타입을 리턴해야하고  yield  대신  yield return ... ;  사용해야한다.

using System.Collections;
using UnityEngine;
public class NewBehaviourScript :
MonoBehaviour {
   
// C# coroutine
    IEnumerator SomeCoroutine () {
       
// Wait for one frame
        yield return 0;
       
       
// Wait for two seconds
        yield return new WaitForSeconds (2);
    }
}

5. namespaces 사용하지 말라.

유니티는 아직 namespace안에 당신의 스크립트들을 놓는 것을 지원하지 않는다. 제한은 차후 버전에서는 제거 것이다.

6. 오직 멤버 변수들만 serialized  되고 Inspector 에서 보여진다.

Private protected 멤버 변수는 Debug Mode에서만 보일것이다.  Properties 들은 serialized 되지 않거나, 또는 inspector에서 보이지 않을 것이다.

7. 생성자 사용을 피하라.

어떤값도 생성자에서 초기화 하지 말라. 대신 Awake Start 사용해야 한다. 유니티는 Edit Mode에서 조차도 생성자를 자동으로 Invoke한다. 이것은 종종 스크립트를 컴파일한 즉시 발생하는데, 생성자는 스크립트의 Default Value들을 Retrieve하기 위해서 Invoked 필요가 있기 때문이다. 생성자는 예기치 않은 순간에 호출될 수도 있을 뿐만 아니라, prefabs Inactive 게임오브젝트들을 위해서 호출될 수도 있다.

예를 들어 생성자를 사용하는 singleton 패턴의 경우에 위함한 결과를 야기할 있고, random Null reference Exception 에러로 이어질 있다.

 

그러므로 만일 SingleTon 패턴을 구현하고 싶다면 생성자 대신 Awake 사용하라. 실제로 Monobehavior로부터 상속받은 클래스의 생성자 안에 어떤 코드를 넣을 일은 없다.

Overview: The most important classes  

Global functions accessable in javascript or the base class in C#

Moving / Rotating objects around

Animation System

Rigid bodies

FPS or Third person character controller

 

Overview: Performance Optimization  

1. Use Static Typing

자바스크립트를 사용할 때 가장 중요한 최적화는 동적 타입 대신에 정적 타입을 사용하는 것이다. 유니티는 별도의 작업없이 자바스크립트 구조체들을 정적 타입 코드로 변환해주는 자바스크립트 타입 참조 라는 테크닉을 사용한다.

C#

*JavaScript

*C#

*Boo

var foo = 5;

using UnityEngine;
using

System.Collections;

public class example :
MonoBehaviour {
public int foo =5;
}

import

UnityEngine
import

System.Collections

class example(
MonoBehaviour):

public foo as int = 5

Var foo = 5;

위의 예제에서 foo 자동으로 integer 값으로 추론이 된다. 그러므로 유니티는 비싼 동적으로 변수 찾기없이 많은 컴파일 타임 최적화를 적용할 있다. 이것이 유니티의 자바스크립트가 다른 자바스크립트 구현들 보다 20 빠른 이유이다.

유일한 문제는 때때로 타입의 추론이 모두 적용되지 않아서 유니티가 동적 타입으로 되돌아 가는 것이다. 동적 타이핑으로 돌아가면 자바스크립트 코드 작성은 더 간단하다. 하지만 또한 코드가 더 느리게 실행되게 된다.

Let's see some examples.

C#

*JavaScript

*C#

*Boo

function Start () {
var foo =

GetComponent(MyScript);
foo.DoSomething();
}

using UnityEngine;
using

System.Collections;

public class example :
MonoBehaviour {
void Start()

{
MyScript foo = GetComponent<MyScript>();
foo.DoSomething();
}
}

JavaScript

Function Start()

{

Var foo = GetComponent(MyScript);

foo.Dosomething();

}

import

UnityEngine
import

System.Collections

class example(
MonoBehaviour):

def Start():
foo as MyScript = GetComponent[of

MyScript]()
foo.DoSomething()

여기서 foo 동적으로 타입이 정해지므로 DoSomething 함수 호출은 필요 이상으로 오래 걸린다. 이유는 foo 타입은 var , unknown 이기 때문에 그것이 DoSomething 함수를 지원하는지를 확인해야 하고 만일 그렇다면 함수를 호출한다.

C#

*JavaScript

*C#

*Boo

function Start () {
var foo :

MyScript = GetComponent(MyScript);
foo.DoSomething();
}

using UnityEngine;
using

System.Collections;

public class example :
MonoBehaviour {
void Start()

{
MyScript foo =

GetComponent<MyScript>();
foo.DoSomething();
}
}

JavaScript

function StarT()

{

Var foo : MyScript = GetComponent(MyScript);

Foo.DoSomething();
}

import

UnityEngine
import

System.Collections

class example(
MonoBehaviour):

def Start():
foo as MyScript = GetComponent[of

MyScript]()
foo.DoSomething()

여기서 우리는 foo 강제로 특정 타입으로 만들었다, 이렇게 하면 좀더 나은 성능을 얻을 있는 것이다.

2. Use #pragma strict

문제는 당신이 동적타이핑을 사용할 때 보통 알아 차리지 못하고 있다는 것인데, 이것을 알려주는 것이 #pragma strict 이다 . 간단히 스크립트의 맨위에 #pragma strict 를 추가하면 유니티는 그 스트립트에서 동적 타이핑기능을 꺼버리고, 정적 타이핑만 사용하도록 강제할 것이다. 타입을 알지 못할 때마다, 유니티가 컴파일 에러를 리포트를 할 것이다. 그래서 이 경우에서는 컴파일시 foo에서 에러가 날 것이다.

C#

*JavaScript

*C#

*Boo

#pragma strict
function Start ()

{
var foo : MyScript = GetComponent(MyScript)

as MyScript;
foo.DoSomething();
}

using UnityEngine;
using

System.Collections;

public class example :
MonoBehaviour {
void Start()

{
MyScript foo = GetComponent<MyScript>() as

MyScript;
foo.DoSomething();
}
}

JavaScript

#pragma strict

{

var foo = GetComponent(MyScript);

foo.DoSomething();

}

import

UnityEngine
import

System.Collections

class example(
MonoBehaviour):

def Start():
foo as MyScript = GetComponent[of

MyScript]()
foo.DoSomething()

3. component 캐싱

또 다른 최적화는 컴포넌트의 캐싱이다. 이 최적화는 약간의 코딩이 요구되고 항상 가치가 있는 것은 아니다. 하지만 정말 자주 사용되는 스크립트에서 최적화의 마지막 방법으로 유용하다.

GetComponent 나 액세스 변수를 통해 하나의 컴포넌트를 액세스할 때 마다, 유니티는 게임 오브젝트로부터 올바른 컴포넌트를 찾아야 하는데 private 변수에 컴포넌트에 대한 참조를 캐싱함으로써 쉽게 저장해서 찾는 시간을 줄일 수 있다.

간단히 다음을:

C#

*JavaScript

*C#

*Boo

function Update () {
transform.Translate(0, 0, 5);
}

using UnityEngine;
using

System.Collections;

public class example :
MonoBehaviour {
void Update()

{
transform.Translate(0, 0, 5);
}
}

import

UnityEngine
import

System.Collections

class example(
MonoBehaviour):

def Update():
transform.Translate(0, 0, 5)

아래와 같이

C#

*JavaScript

*C#

*Boo

private var myTransform : Transform;
function

Awake () {
myTransform =

transform;
}

function Update () {
myTransform.Translate(0, 0, 5);
}

using UnityEngine;
using

System.Collections;

public class example :
MonoBehaviour {
private
Transform myTransform;
void Awake()

{
myTransform = transform;
}
void Update() {
myTransform.Translate(0, 0,

5);
}
}

import

UnityEngine
import

System.Collections

class example(
MonoBehaviour):

private myTransform as
Transform

def Awake():
myTransform = transform

def Update():
myTransform.Translate(0, 0, 5)

후자의 코드는 유니티가 매프레임 게임오브젝트에서 transform 컴포넌트를 찾을 필요가 없기 때문에 상당히 더 빠르게 실행될 것이다.transform이나 다른 단축어 속성 대신 GetComponent를 사용하는 스크립트된 컴포넌트들에 모두 똑같이 적용된다.

4. 고유의 배열들 사용

고유 배열들은 빠르다, 매우 빠르다~그러니 그것들을 쓰자.

비록 ArrayList Array 클래스들은 쉽게 성분들을 추가할 수 있어서 사용하기 쉽지만 거의 비슷한 속도를 갖고 있지 않다. 고유 배열들은 고정된 사이즈를 가지지만 대부분의 경우 사전에 최대 사이즈를 알고 있기에 나중에 쉽게 채울 수가 있다. 고유 배열의 가장 좋은 점은 어떤 외부 타입 정보나 오버헤드 없이 하나의 꽉차게 묶여진 버퍼에 구조체 데이터 타입들을 직접 가져온다는 것이다. 그러므로 모든 것이 메모리에서 선형적으로 존재하기 때문에 캐쉬상에서 반복순환 하기가 매우 쉽다.

C#

*JavaScript

*C#

*Boo

private var positions : Vector3[];
function

Awake () {
positions = new
Vector3[100];
for

(var i = 0; i < 100; i++)
positions[i] =
Vector3.zero;
}

using UnityEngine;
using

System.Collections;

public class example :
MonoBehaviour {
private
Vector3[] positions;
void Awake()

{
positions = new
Vector3[100];
int i =

0;
while (i < 100) {
positions[i] =
Vector3.zero;
i++;
}
}
}

import

UnityEngine
import

System.Collections

class example(
MonoBehaviour):

private positions as (
Vector3)

def Awake():
positions = array[of
Vector3](100)
i as int

= 0
while i < 100:
positions[i] =
Vector3.zero
i++

5. 불필요한 함수 호출은 피해라

모든 최적화에서 가장 간단하면서도 최선의 방법은 동작을 최소로 하는 것이다. 예를 들면 , 멀리 떨어져 있는 적의 경우 잠들게 하는 것은 성능 향상에 좋은 기법이다. 잠들게 한다는 것은 플레이어가 가까이 오기 전까지는 잠든 듯이 아무것도 하지 않는 것이다. 이런 상황을 느리게 조종하는 방법은 아래와 같을 것이다.

C#

*JavaScript

*C#

*Boo

var target : Transform;

function Update ()

{
// Early out if the player is too far

away.
if

(Vector3.Distance(transform.position,

target.position) > 100)
return;
// perform real work work...
}

using UnityEngine;
using

System.Collections;

public class example :
MonoBehaviour {
public
Transform target;
void Update() {
if (
Vector3.Distance(transform.position,

target.position) > 100)
return;

}
}

import

UnityEngine
import

System.Collections

class example(
MonoBehaviour):

public target as
Transform

def Update():
if
Vector3.Distance(transform.position,

target.position) > 100:
return

이것은 좋은 방법이 아니다. 왜냐하면 유니티는 매 프레임 Update 함수를 호출해야하기 때문이다. 좀더 나은 해결법은 플레이어가 가까이 올 때 까지 스크립트를 꺼두는 것(disable)시키는 것이다. 이것에는 3가지 방법이 있다.

1. OnBecameVisible OnBecameInvisible 을 사용하는 법. 이 콜백함수 들은 렌더링 시스템에 들어 있다. 어떤 카메라가 그 오브젝트를 볼수 있는 순간 , OnBecameVisible이 호출되고, 어떤 카메라도 그것을 더 이상 보지 않을 때 OnBecameInvisible 이 호출 될 것이다. 이것은 몇가지 경우에 유용하지만 종종 AI상에서는 유용하지 않다. 왜냐하면 카메라를 적들로부터 돌리자마자 꺼지기 때문이다.

C#

*JavaScript

*C#

*Boo

function OnBecameVisible () {
enabled =

true;
}

function OnBecameInvisible () {
enabled = false;
}

using UnityEngine;
using

System.Collections;

public class example :
MonoBehaviour {
void OnBecameVisible()

{
enabled = true;
}
void OnBecameInvisible() {
enabled = false;
}
}

import

UnityEngine
import

System.Collections

class example(
MonoBehaviour):

def OnBecameVisible():
enabled = true

def OnBecameInvisible():
enabled = false

2. triggers 사용 , 하나의 간단한 구형 트리거로 놀라운 일을 할수 있는데 , 원하는 영향 범위에서 벗어날 때 OnTriggerEnter/Exit 함수가 호출된다.

C#

*JavaScript

*C#

*Boo

function OnTriggerEnter (c : Collider) {
if

(c.CompareTag("Player"))
enabled =

true;
}

function OnTriggerExit (c :
Collider) {
if

(c.CompareTag("Player"))
enabled = false;
}


using UnityEngine;
using

System.Collections;

public class example :
MonoBehaviour {
void OnTriggerEnter(
Collider c) {
if (c.CompareTag("Player"))
enabled = true;

}
void OnTriggerExit(
Collider c) {
if (c.CompareTag("Player"))
enabled = false;

}
}

import

UnityEngine
import

System.Collections

class example(
MonoBehaviour):

def OnTriggerEnter(c as
Collider):
if

c.CompareTag('Player'):
enabled = true

def OnTriggerExit(c as
Collider):
if

c.CompareTag('Player'):
enabled = false

3. Coroutines을 사용. Update함수에서의 문제는 매프레임 호출된다는 것이다. 플레이어와의 거리 체크는 5초마다 수행할 수도 있을 것이다. 이것은 처리 시간을 많이 Save해준다.

Overview: Script compilation (Advanced)  

유니티는 모든 스크립트들을 .NET DLL 파일들로 컴파일 한다. DLL파일들은 런타임에 JIT(Just In Time) 컴파일 될 것이다.

이것은 믿기 어려울 만큼 빠르게 스크립트를 실행 할수있게 해준다. 그것은 전통적인 자바 스크립트보다 20배 더 빠르고 native C++코드보다 약 50% 더 느리다 . 스크립트를 저장할 때 유니티는 모든 스크립트를 컴파일하고 잠깐의 시간이 걸린다. 만일 유니티가 여전히 컴파일 중이라면 유니티의 메인 윈도우의 오른쪽 구석에서 프로그레스바가 도는 것을 볼수 있다.

스크립트 컴파일은 4단계로 수행된다.

1. "Standard Assets", "Pro Standard Assets" 또는 "Plugins" 안의 모든 스크립트들이 먼저 컴파일된다.

이 폴더들 안의 스크립트 들은 폴더 밖의 다른 스크립트들을 직접 액세스 할 수 없다.

클래스나 변수들을 참조할 수 없지만, GameObject.SendMessage를 통해서 통신은 할 수 있다.

2. "Standard Assets/Editor", "Pro Standard Assets/Editor" 또는 "Plugins/Editor" 안의 모든 스크립트들이 먼저 컴파일 된다.

만약에 UnityEditor 네임스페이스를 사용하고 싶다면 당신의 스크립트들을 이 폴더들에 넣어야 한다. 예를 들면 메뉴 아이템 추가나 커스텀 창들을 만들기 위해서는 스크립트들을 이 폴더들 안에 넣어야 한다. 이 스크립트들은 앞의 그룹의 스크립트들을 액세스 할 수 있다.

 

3. "Editor" 밖의 모든 스크립트들이 그 다음 컴파일 된다.

“Editor”폴더와 그 서브 폴더를 제외한 모든 스크립트들이 컴파일 된다.

이 단계의 스크립트들은 이전 단계의 스크립트들을 액세스 할 수 있다. 이것은  다른 언어로 짜여진 스크립트들을 얻을수 있도록 해준다. 예를 들면, C#스크립트 를 사용하는 자바스크립트를 만들길 원한다면 , C#스크립트는 Standard Assets 폴더에 놓고 자바스크립트는 Standard Assets 폴더 바깥에 놓는다면 그 자바스크립트는 C#스크립트를 직접 참조 할수 있다.

첫번째 그룹안에 놓인 스크립트들이 컴파일되면 세번째 그룹도 재컴파일 되어야 하므로 컴파일에 시간이 더 걸릴 것이다. 따라서 컴파일 시간을 단축시키고 싶다면 덜 바뀌는 스크립트들을 첫번째 그룹으로 옮기고 많이 바뀌는 것은 3번째 그룹으로  옮겨라

 

4. "Editor" 안의 스크립트들이 가장 마지막에 컴파일된다.

만약 UnityEditor 네임스페이스를 쓰고 싶다면 이 폴더에 넣어야 한다. 예를 들면 menu 아이템들을 추가하거나 custom wizards를 작성하기 위해서는 스크립트들을 이 폴더 안에 넣어야 한다.

이 스크립트들은 앞 그룹의 모든 스크립트들을 접근할 수 있다.

 

또한 WebPlayerTemplates이라고 불리는 폴더는 컴파일 되지 않는다..

조건부 컴파일은 유니티 버전에 의존한다.

유니티 2.6버전부터 C# 전처리기 정의가 추가되었다. 이 정의는 사용중인 유니티의 버전을 정의하고 특정 특징들을 조건적으로 액세스할 수 있게 해준다. 예를들면,


// Specific version define including

the minor revision
#if

UNITY_2_6_0
// Use Unity 2.6.0 specific

feature
#endif

// Specific version define not including the minor

revision
#if UNITY_2_6
// Use Unity 2.6.x specific feature
#endif

이 코드는 특정 버전에서만 가능한 game feature들을 활성화 시키는데 사용될 수 있다. 이 정의는 오직 2.6버전부터 제공된다는 것에 주의해라. 앞으로 나올 유니티 버전들은 스크립트 버전을 분별하기 위한 적절한 정의들이 제공될 것이다.

알림 : 플랫폼별 조건부 컴파일에 대해서 좀더 정보가 필요하다면 Platform Dependent Compilation.을 참조해라

Overview: Unity and Mono compatibility  

유니티를 위하여 당신의 스크립트 안에서 닷넷 라이브러리를 사용할 수있다. 당신 프로젝트 안에서 닷넷 호환성 레벨을 선택한 것에 따라 달라지고, 유니티를 풀클래스 라이브러리들보다 좀더 많거나 적게 제공하고 있다. 어떤 특정한 세팅들과 함수 호환성을 체크하고 싶다면 .Net Compatibility page.

 








3_MonoBehaviourAndUnityScripting20111215 파일을 연다.

Object <- Componet <- Behaviour  형태로 상속 받았다. 함수를 모두 사용할 수 있다.

이렇게 상속받아서 솟컷이 가능하다..



## 해당 이벤트 발생 처리


## 객체가 접근

## Component  접근

## Debugging  <== 실습하자..



## Send Message 방법을 알아보자.

GO.SendMessage("함수이름");

GO.SendMessage("함수이름, 인자");

이것은 프라이빗 함수라도 호출 가능하다. (인자도 특정한 것으로 정해져 있다.) 

펑션콜보다 센드메시지가 훨 빠를 때가 있다.


이것을 쓰면 메신저에 쌓아두고 나중에 여유가 되면 겟해서 실행한다.

- 시간에 관계없이 여유될 때 사용하게 하려면 이렇게 해서 처리해 두면 좋다.

- RPC로 다른 함수를 호출시 이해가 쉽다.

  이것은 패킷 필요없고 함수 호출로 동작이 가능하다. 

  이것의 시작점이 sendmessage이다. 통신도 편하게 사용할 수 있다.

  이것은 퍼블릭함수만 호출가능하다.





[delegate를 설명하자.]

- 활용하기에 유용하다. C# 스럽다.

새로 new Scene

스크립트 DelegateTest 스크립트 추가. 


using UnityEngine;

using System.Collections;

using System;

using System.Collections.Generic;

using System.Text;


delegate void dele1();

delegate int dele2(int a, int b);

public class DelegateScript : MonoBehaviour {

public class MathClass

{

public void Intor()

{

Debug.Log("Start the Intro~");

}

public int Sum(int a, int b)

{

return a+b;

}

}

// Use this for initialization

void Start () {

MathClass mclass = new MathClass();



dele1 intro = new dele1(mclass.Intor);

dele2 sum = new dele2(mclass.Sum);

intro();

int result = sum(-10, 90);

Debug.Log("result : " + result.ToString());

}


}


그리고 메인카메라에 스크립트를 추가한다.




using UnityEngine;

using System.Collections;

using System;

using System.Collections.Generic;

using System.Text;


//사용법


delegate void deleMath(int Value);



public class MathClass

{

public int number;

public void plus(int Value)

{

number = number + Value;

}

public void Minus(int Value)

{

number = number - Value;

}

public void Multiply(int Value)

{

number = number * Value;

}

}


public class DelegateTest : MonoBehaviour {

void Start() 

{

MathClass MClass = new MathClass();

deleMath Math = new deleMath(MClass.plus);

Math += new deleMath(MClass.Minus);

Math += new deleMath(MClass.Multiply);

//result

MClass.number = 10;

Math(10);

Debug.Log("result : "+MClass.number.ToString());

// delegate remove

Math -= new deleMath(MClass.Minus);

//result

MClass.number = 10;

Math(10);

Debug.Log("result : "+MClass.number.ToString());

}

}


/*

delegate void dele1();

delegate int dele2(int a, int b);

public class DelegateScript : MonoBehaviour {

public class MathClass

{

public void Intor()

{

Debug.Log("Start the Intro~");

}

public int Sum(int a, int b)

{

return a+b;

}

}

// Use this for initialization

void Start () {

MathClass mclass = new MathClass();

dele1 intro = new dele1(mclass.Intor);

dele2 sum = new dele2(mclass.Sum);

intro();

int result = sum(-10, 90);

Debug.Log("result : " + result.ToString());

}

// Update is called once per frame

void Update () {

}

}

*/



c#은 모두 콜백이.. 레퍼런스로 사용가능하다.
delegate는 한사람만 사용해야 한다. 또는 자기것만 사용한다.
결과는 run해서 consol에서 확인 가능하다.
result : 100
UnityEngine.Debug:Log(Object)
DelegateTest:Start() (at Assets/Scripts/DelegateTest.cs:41)
result : 200
UnityEngine.Debug:Log(Object)
DelegateTest:Start() (at Assets/Scripts/DelegateTest.cs:50)




내일은 슈팅게임을 다시 만든다..
2D슈팅게임 한다.
마무리하고 보강한다..

캐릭터한다.

오늘은 3D로 움직인다.라는 것.