Unity Engine2012.06.27 19:43

Fruit Ninja 를 플레이 해 보시면, 손가락을 사용해 터치 디바이스에 드래그를 하면 칼날을 휘두른 것 같은 효과가 납니다. 물론, Fruit Ninja 뿐만 아니라 많은 스마트폰 디바이스용 어플에서 볼 수 있는 효과입니다. 이것을 어떻게 구현할까 싶어 알아보니, Trail Renderer 를 사용하면 쉽게 구현이 가능하더군요. (Sword 효과라고 명명 된 것은 아니고, 정확히 어떤 명칭을 붙여야 하는지 모르겠어서 그냥 Sword 효과라고 이름을 붙였습니다.)

 

TrailRenderer 는 Unity3D Document 에서 이렇게 설명합니다.

 

"The Trail Renderer is used to make trails behind objects in the scene as they move about."

 

Scene 내에서 GameObject 가 이동 시, 이동한 흔적(Trail)을 남기고자 할 때 사용되는 것이죠.

 

그럼, Sword 효과를 내기 위해 Trail Renderer 를 어떻게 사용하면 될까요?

방법은 아주 간단합니다.

 

1. GameObject 를 두고, Trail Renderer 컴포넌트를 추가

  - Hierarchy 에 Empty GameObject 를 추가. (TrailObject 라고 이름을 변경 했습니다.)

  - 추가 된 GameObject 를 선택하고 Trail Renderer 컴포넌트 추가 (Component - Effects - Trail Renderer) 

 

  - Trail Renderer 컴포넌트의 속성 설정. 

저는 간단히 Material 을 Unity에서 제공하는 Fire Smoke 로 설정하고, Start Width, End Width 만 살짝 바꿔봤습니다. (입맛에 맞게 설정하시면 됩니다.)

 

 

2. Input 클래스를 사용하여 Move 발생 시 마다 GameObject 의 Transform 을 변경

  - Scene 에서 발생하는 이벤트를 처리하기 위한 Script 를 추가. (mainSceneScript.cs)

    + Trail Renderer 컴포넌트가 추가 된 GameObject 를 할당 할 변수 추가

public GameObject TrailObject;

 

    + Inspector 에서 변수 할당 

(MainCamera 도 변수 선언을 해서 할당 했습니다.)

 

 

  - Script 에 터치 이벤트 처리하여 Move 발생 시에 GameObject 의 Transform 변경.

TrailObject.transform.position =
    MainCamera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 1));

 

 

결과 화면 

 

 

 

요약.

1. GameObject 를 두고, Trail Renderer 컴포넌트를 추가.

2. Input 클래스를 사용하여 Move 발생 시 마다 GameObject 의 Transform 을 변경.

Posted by Min-gu, Kim
Unity Engine2012.06.20 11:21

1. FSM 구현을 위해 Unity3D engine 이 제공하는 StartCoroutine 메서드 활용.

Unity > Support > Script Reference > MonoBehaviour.StartCoroutine 참고

Unity3D engine 에서 제공하는 MonoBehaviour 객체의 StartCoroutine 메서드는 매 프레임 마다 지정 된 콜백함수를 실행합니다.

Debug.Log 를 찍어서 확인 해 보시면, Update, StartCoroutine 에서 지정 된 콜백함수 순으로 실행이 됩니다.

이때 지정 된 콜백 함수가 IEnumerator 를 반환하는 형태이기 때문에 while 문과 yield 키워드를 통해 FSM 을 구현 할 수 있습니다.

 

2. State 정의 및 IEnumerator 를 반환하는 State 별 함수 구현.

  - State 정의

    우선, FSM 이 되는 객체에 State 를 정의 합니다. (귀찮아서 세밀하게 구현 하는 것보단 심플하게 어떻게 동작하는지 보여드리는게 더 효과적일 것 같아서 Init, Idle, Move 로만 정의했습니다.)

 

public enum DudeState {
    Init,
    Idle,
    Move
}

 

  - State 별 함수 구현

    FSM을 구현하기 위해 3가지의 메서드가 필요합니다. (State 최초 진입 시 실행 될 메서드, 매 프레임마다 실행 될 메서드, State 종료시 실행 될 메서드)

    만약, StartCoroutine 메서드가 없다면 각 메서드를 구현 해 주고, State 변경 메서드를 따로 두어 관리해야 하겠지만, Unity3D engine 을 사용 시에는 더욱 더 편하게 3개의 메서드를 하나로 통합 할 수 있으며, 클래스 상속을 통해 메서드를 상속, 오버라이드 하여 유연하게 구현하는 장점이 생기죠.

방법은 다음과 같습니다.

 

IEnumerator MoveState() {
    // Enter
    this.gameObject.animation.Play("Take 001");
    yield return null;

    while (this.State == DudeState.Move) {
        // Excute
        this.gameObject.transform.position +=
            new Vector3(0, 0, Time.deltaTime * moveSpeed);

        if (!moving) {
            this.State = DudeState.Idle;
        }

        yield return null;
    }

    // Exit
    NextState();
}

 

    IEnumerator 를 반환하고 yield 키워드를 사용하는 이유는 이렇습니다.

    StartCoroutine에 콜백함수가 지정되면, 지정 된 콜백함수는 매프레임마다 Update 문 다음에 실행됩니다. 이 때, yield 문을 만나면 콜백함수 내에서 yield 다음 구문을 다음 프레임으로 양보하고 콜백함수가 종료가 됩니다. 그러면 또 다음번 프레임에서는 yield 문 다음 구문이 실행이 되는 것이죠.

 

    그래서 위와 같이 콜백함수를 코딩하면,

      - State 최초 진입 시 실행 되는 블럭 (Enter 부분, while 문 이전까지)

      - 매 프레임 마다 실행 되는 블럭 (Execute 부분, While 문 블럭)

      - State 종료 시 실행 되는 블럭 (Exit 부분, while문 블럭 이하)

    이렇게 구현이 되는 것이죠.

 

3. 각 State 에 맞는 StartCoroutine 의 콜백함수(2.번에서 구현 된)를 지정.

 

protected void NextState() {
    string methodName = State.ToString() + "State";
    System.Reflection.MethodInfo info = GetType().GetMethod(methodName,
        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
    StartCoroutine((IEnumerator)info.Invoke(this, null));
}

 

 

 

 

요약

1. FSM 구현을 위해 Unity3D engine 이 제공하는 StartCoroutine 메서드 활용.

2. State 정의 및 IEnumerator 를 반환하는 State 별 함수 구현.

3. 각 State 에 맞는 StartCoroutine 의 콜백함수(2.번에서 구현 된)를 지정.

 

 

 

Unity 샘플 프로젝트를 첨부합니다.

FSMSample.7z

 

 

Posted by Min-gu, Kim
Unity Engine/Android2012.06.05 12:40

Eclipse 안드로이드 프로젝트로 만든 Activity 를 Unity3D 에서 Main 으로 사용하기 위해서는 다음과 같은 작업을 필요로 합니다.

 

 

1. 새 프로젝트 생성 후 Activity 파일명 변경

  - Eclipse 에서 File > New  > Android Project 생성 

 

  - 생성 된 Activity.java 파일을 선택 후 Refactor > Rename (F2, Alt+Shite+R) CustomUnityPlayerActivity 로 변경 

 

 

 

2. Unity3D 에서 제공하는 classes.jar 프로젝트에 추가

  - 프로젝트 Properties 에서 Java Build Path 탭 선택 후 Add External JARs... 클릭, classes.jar 파일(Path : 유니티설치폴더\Editor\Data\PlaybackEngines\androidplayer\bin)을 선택. 

 

 

 

3. CustomUnityPlayerActivity.java 파일 설정.

 - UnityPlayerActivity.java 소스 파일(Path : 유니티설치폴더\Editor\Data\PlaybackEngines\androidplayer\src\com\unity3d\player) 의 내용을 CustomUnityPlayerActivity.java 에 그대로 복사 (onKeyDown, onKeyUp 등 Activity 메서드가 실행 될 때 UnityPlayer 객체에도 전달 되도록 코드 되 있다.)

 - package명, Activity명 설정, import com.unity3d.player.UnityPlayer 추가. 

 

 

 

4. CustomUnityPlayerActivity.java 파일 선택 후 JAR File 로 Export. 

 

 

 

/** 이제 Unity tool 에서 작업 */

 

5. Unity에서 새 프로젝트 생성 후 Eclipse 에서 Export 된 JAR 파일 복사 (Path : Assets/Plugins/Android)

  - New Unity Project 생성 후 Build Setting 에서 Android platform 으로 switch 후 패키지명 설정 (eclipse 와 동일하게) 

 

  - 4. 에서 Export 된 AndroidPlugin.jar 파일을 Assets/Plugins/Android 에 복사  

 

6. AndroidManifest.xml 생성 후 프로젝트 내 복사

  - 빌드 후 생성 되는 Temp 폴더 내 StagingArea 폴더에서 AndroidManifest.xml 추출하여 (Path : 유니티프로젝트 폴더\Temp\StagingArea) 다음과 같이 수정 

 

  - Assets/Plugins/Android 에 복사 

 

위와 같은 작업을 해 준 뒤에는 Eclipse 에서 Activity 내용이 변경 될 때마다 java 파일을 Export 하여, Unity Project 내에서 jar 파일만 새로 Export 된 파일로 변경 해 주면 됩니다.

 

 

 

* 요약 *

[ Eclipse 내에서 작업 ]

  1. 새 프로젝트 생성 후 Activity 파일명 변경

  2. Unity3D 에서 제공하는 classes.jar 프로젝트에 추가

  3. CustomUnityPlayerActivity.java 파일 설정.

  4. CustomUnityPlayerActivity.java 파일 선택 후 JAR File 로 Export.

[ Unity3D 내에서 작업 ]

  5. Unity에서 새 프로젝트 생성 후 Eclipse 에서 Export 된 JAR 파일 복사 (Path : Assets/Plugins/Android)

  6. AndroidManifest.xml 생성 후 프로젝트 내 복사

Posted by Min-gu, Kim

티스토리 툴바