데님 파웰
접속 : 4123   Lv. 50

Category

Profile

Counter

  • 오늘 : 4 명
  • 전체 : 18133 명
  • Mypi Ver. 0.3.1 β
[SRPG를 만들자!!] SRPG를 만들자!!! #10 이벤트 씬용 스크립트 (3) 2015/09/06 PM 07:19

1. iTween으로 된 애니메이션을 거의 대부분 FFani.Tween로 바꾸었다.

2. FFani.Tween을 이용하여 이벤트 씬 (컷씬) 애니메이션의 스크립트 파써를 만들어서 플레이하도록 하였다.

3. 승리조건의 표시


2. 만 설명

이벤트 씬 스크립트의 기본 동작은 다음과 같음.

  2.1 저장 포맷은 JSON으로 함.

    2.1.1 이벤트씬용 스크립트 포맷

{
    meta{},
    eventScenes: [
        {
            id: "#0",
            actors{
                "bak": {
                    target: "/bak",
                    name: "도적"
                }
            },
            actions: [
                {
                    actor: "bak",
                    title: "도적",
                    text: ["뭐야완전 초짜 꼬맹이들이잖아!\n후훗오늘은 일진이 좋구만!",
                            "어떠냐얘들아.\n이 꼬맹이들만 처치하고 낼름 도망가자!",
                            "꼬맹이라고   필요 없어!\n한 명도 남김없이 죽여버리자구!"
                    ]
                    
                    orbitX300,
                    orbitY40
                }
            ]
        },

...

}


  2.2 현재는 캐릭터간 대화 기능만 지원

    2.2.1 다이얼로그 창을 연다.

    2.2.2 텍스트를 표시한다.

    2.2.3 텍스트가 두 줄 이상일 경우 현재 텍스트를 지우고 다음 텍스트를 표시한다.

    2.2.4 다이얼로그 창을 닫는다.

    2.2.5 다음 대화를 파싱한 후 2.2.1을 실행

    2.2.6 표시도중 화면 아무곳을 클릭하면 스킵 기능이 있다.


스킵기능을 지원하기 위해 FFaniStepAnimation이라는 클래스를 작성하였다.  그룹 애니메이션의 일종으로 Next()를 호출하면 현재 실행중인 애니메이션을 complete상태로 변환하고 다음 애니메이션을 실행시킨다.


실제 동작 화면


신고

 

니나가라군대    친구신청

캐릭터 이미지 택티스 오거 아닌가요?

아무렇게나_대충적은_닉네임    친구신청

파판택 같네요

가디언히어로즈    친구신청

테스트인것 같은데요 괜찮아 보이네요
[SRPG를 만들자!!] SRPG를 만들자!!! #9 iTween을 대체할 애니메이션 툴킷 개발 (5) 2015/07/06 AM 12:24

iTween은 상당히 강력한 기능을 가지고 있으나, 아래와 같은 문제가 있다.

1. 사용가능한 컴포넌트가 제한
2. 불편한 콜백
3. 코드 가독성이 안좋음
4. 순차 애니메이션 설정이 힘듬


위와 같은 문제를 해결하기 위해 iTween과 비슷하면서도 보다 편리한 기능의 애니메이션 툴킷을 직접 만들었다.  (이것도 요새 루리웹 유행인 없만루에 껴주나요???)

FFani.Tween
FFani는 Fire and Forget animation의 약자로 iTween같이 onUpdate가 필요하지 않고 start명령으로 애니메이션이 실행되는 구조를 fire and forget이라고 많이 부르는 모양인데, 이러한 기능을 보다 깜끔하게 지원하기 위한 툴킷을 직접 개발하였다.  API사양과 설계는 QML이라는 언어의 애니메이션 프레임워크를 많이 참조하였다.

상세 설명

1. 사용가능한 컴포넌트
안타깝게도 iTween은 애니메이션 타겟 종류가 제한되어 있다. Transform, Renderer같은 대표적인 컴포넌트만 지원하며 4.6부터 등장한 New UI의 컴포넌트들을 애니메이션 시킬 수 없다는 것은 너무나 치명적인 문제점이었다.
단 이를 해결하기 위해 몇 가지 범용 기능을 제공하기는 한다.  예를 들어, Fade-in 애니메이션을 위해서는 UI 오브젝트의 Image컴포넌트의 color.a값을 매 프레임마다 바꾸어주어야 하며 이를 위해 iTween.ValueTo를 사용하였다.

    private void FadeIn()
    {
        fadeScreen.SetActive (true);
        Hashtable tweenParams = new Hashtable();
        tweenParams.Add ("from"1.0f);
        tweenParams.Add ("to"0.0f);
        tweenParams.Add ("time"2.0f);
        tweenParams.Add ("onupdate""OnOpacityUpdated");
        iTween.ValueTo(gameObjecttweenParams);
    }

    private void OnOpacityUpdated(float opacity)
    {
        Color color = fadeScreen.GetComponent<Image>().color;
        color.a = opacity;
        fadeScreen.GetComponent<Image>().color = color;
        if (opacity < 0.01f) {
            fadeScreen.SetActive (false);
        }
    }

이 코드의 핵심은 매 프레임마다 OnOpacityUpdated라는 함수를 호출하여 opacity를 갱신하는 데에 있다.  이처럼 지원하지 않는 컴포넌트는 매 번 불편하게 ValueTo + 콜백을 써야한다.
 
새로운 툴킷을 사용하여 FadeIn 메서드를 아래와 같이 수정하였다. 

    private void FadeIn()
    {
        fadeScreen.SetActive(true);
        FFani.Tween (
            targetfadeScreen.GetComponent<Image>(),
            propertyName"color.a",
            from1.0f,
            to0.0f,
            duration2.0f
        ).Start();
    }

fadeScreen의 Image.color.a에 접근 가능하기 때문에 OnOpacityUpdated 메서드는 이제 필요가 없어졌다. UI를 애니메이션 시킬때마다 콜백을 하나씩 만들어야 했던 고통에서 벗어나게 되었다.


2. 콜백

애니메이션이 종료한 후에 바로 다른 코드를 실행시키기 위해서는 콜백을 설정해 주어야 한다.  예를 들어 현재 개발중인 SRPG의 경우 시작시 Fade-in과 함께 카메라 애니메이션이 시작되며 이것이 종료되면 엔트리 픽 모드로 들어간다.  엔트리 픽 모드로 들어 갈 때 약간의 카메라 줌인이 필요하며 이를 위해 아래와 같이 구현했었다.

    public void onEntryPickMode()
    {
        // 초기 실행 부분 생략

        Hashtable tweenParams = new Hashtable();

        tweenParams.Add ("time"3.0f);
        tweenParams.Add ("p-osition", originPosition);
        // 애니메이션 종료시 실행할 콜백을 여기서 설정한다.
        tweenParams.Add ("oncomplete""onActivateEntryPick");
        tweenParams.Add ("oncompletetarget"gameObject);
        iTween.MoveFrom(GameObject.Find ("CamPivot"), tweenParams);
    }
    
    public void onActivateEntryPick()
    {
        // 실제 중요한 코드는 여기 다 있다.
    }

단지 3초간의 카메라 애니메이션을 위해서 코드가 두 개로 분리되어있다.  onActivateEntryPick은 다른 곳에서는 호출되지 않으므로 굳이 나눠줄 필요가 없지만 iTween에서 반드시 콜백 함수의 이름을 넘겨 주어야 콜백이 되기 때문에 애니메이션 종료 후 실행할 코드를 별도의 메서드로 만들어야 했다.

위의 코드를 아래와 같이 수정한다.

    public void onEntryPickMode()
    {
        // 초기 실행 부분 생략

        FFani.Tween(
            targetGameObject.Find ("CamPivot").transform,
            propertyName"p-osition",
            fromoriginp-osition,
            duration3.0f,
            easingCurveFFaniEasing.OutCubic 
        ).Remind (
            () => {
                // 
onActivateEntryPick()의 코드를 여기로 옮김.
            }
        ).Start(); 
    }

콜백 함수를 람다로 전달받으므로 따로 메서드를 만들 필요 없이 애니메이션 종료 후 실행할 코드를 Remind()내부에 넣으면 된다. (주의!! 현재 애니메이션 실행시 화면이 깜빡이는 버그가 있다.)


3. 가독성

iTween를 사용할 때의 문제점은, 코드를 위에서 아래로 읽으면 파라미터를 먼저 읽고 제일 중요한 정보인MoveTo인지 MoveFrom인지, 대상 오브젝트가 무엇인지를 나중에 알게 된다는데에 있다. 

        Hashtable tweenParams = new Hashtable();
        tweenParams.Add ("from"1.0f);
        tweenParams.Add ("to"0.0f);
        tweenParams.Add ("time"2.0f);

        // 제일 중요한 정보를 제일 나중에 알 수 있다.
        iTween.ValueTo(gameObjecttweenParams);

위와 똑같은 동작을 아래와 같이 표기한다.

        FFani.Tween (
            targetfadeScreen.GetComponent<Image>(),
            propertyName"color.a",
            from1.0f,
            to0.0f,
            duration2.0f
        ).Start();

대상 컴퍼넌트와 프로퍼티 이름을 맨 위에서 명확히 하였고 그 후에 from, to, duration 정보가 온다.  파라미터의 순서 자체는 코드의 동작에 전혀 문제가 없지만, 위와 같은 순서로 할 경우 가독성이 확실히 좋아진다. 또한 Hashtable API를 귀찮게 이용하지 않아도 되기 때문에 작성하기에도 훨씬 편하다.


4. 순서대로 애니메이션 플레이

iTween에서는 두 개의 애니메이션을 순서대로 플레이 시키기 위해서 delay를 이용해 애니메이션을 시간차를 두고 플레이시키는 편법을 사용하였다.

아래 코드는 장면전환시 사용하도록 fade-out -> fade-in을 순차적으로 실행하는 애니메이션이다.  이경우 fade-in은 fade-out의 플레이시간에 맞춰 delay를 주어서 애니메이션의 순서를 맞추었다.

        // fade-out
        
Hashtable tweenParams = new Hashtable();
        tweenParams.Add ("from"0.0f);
        tweenParams.Add ("to"1.0f);
        tweenParams.Add ("time"2.0f);
        iTween.ValueTo(gameObjecttweenParams);
        
        // fade-in
        Hashtable tweenParams2 = new Hashtable();
        tweenParams2.Add ("from"1.0f);
        tweenParams2.Add ("to"0.0f);
        tweenParams2.Add ("time"2.0f);
        tweenParams2.Add ("delay"2.0f);
        iTween.ValueTo(gameObjecttweenParams2);


이 경우에는 뒤에 연결되는 애니메이션이 하나밖에 없으므로 별 문제가 없으나 여러 개가 연결된 애니메이션을 delay로만 연결시킬 경우, 앞의 애니메이션의 플레이 시간이 변경되면 뒤따라 오는 애니메이션의 delay 파라미터를 전부 재계산해 주어야 하는 문제점이 있다.

위의 코드를 아래와 같이 고칠 수 있다.

        FFani.Serial (
            FFani.Tween ( // fade-out
                targetfadeScreen.GetComponent<Image>(),
                propertyName"color.a",
                from1.0f,
                to0.0f,
                duration2.0f
            ),
            FFani.Tween ( // fade-in
                targetfadeScreen.GetComponent<Image>(),
                propertyName"color.a",
                from0.0f,
                to1.0f,
                duration2.0f
            )
        ).Start ();

두 개의 FFani.Tween을 FFani.Serial로 묶어줌으로써 순서대로 애니메이션을 실행 시킬 수 있다.  뒤의 애니메이션은 앞의 애니메이션이 끝나면 자동으로 실행된다.  앞의 애니메이션의 플레이시간 (duration)이 바껴도 뒤의 애니메이션이 이를 의식할 필요가 없다.


현재 내가 직접 작성한 코드는 iTween을 없애고 FFani.Tween으로 대체할 계획이다.  아직은 지원되지 않는 기능도 있고 테스트도 충분히 하지 못했기 때문에 당분간은 FFani.Tween의 완성도를 높이는 데에 주력해야 될 듯 싶다.

신고

 

케이스-0    친구신청

좋은 정보 감사합니다 *_*/

케르발    친구신청

흠 저도 마이피에 개발 일기를 쓰고 있지만...
글 읽다가
블렌더 로 모델링 한다는거 알고
샘플만들때 그걸 저도 써야 겠네요..

데님 파웰    친구신청

혹시 UI 관련해서 생긴 문제점을 정확하게 알려주신다면, 아는 범위 내에서 알려드리겠습니다. 회사에서 유니티 사용중에 UI쪽으로 삽질을 너무 많이 해서 이제는 웬만하면 다 적응할 것 같더군요.

케르발    친구신청

정확히는 카메라에 피사계심도(DOF) 를 적용해서 배경 블러처리로 분위기를 내는것을 했었는데
그렇게 하니까 3D텍스쳐가 아닌 스프라이트 이미지 들이 블러가 안먹는 상황이었습니다.
다행이 유니티 엔지니어 분이 답변해주셨었는데
-------------------------------------------------
3D공간에 그리고 있는 UI들은 DOF의 블러 영역에서 흐려지는 거는 어쩔 수 없어요. DOF는 뎁스덱스쳐(버퍼)에 있는 정보를 가지고 원경 블러 처리를 하는데, 보통 UI는 뎁스버퍼에 그리지를 않으니 제대로 처리가 안되요. 3D공간의 위치를 2D로 투영해서 2D 처리해서 그리는게 현실적으로 가장 좋은 대안일거예요
-------------------------------------------------
하고 하네요

데님 파웰    친구신청

허걱 저도 몰랐던 내용이군요. 당장 담주부터 캐릭터 머리 위로 UI 만들어야 했는데 좋은 정보 감사합니다.
[SRPG를 만들자!!] SRPG를 만들자!!! #8 Scene의 흐름을 구성 (2) 2015/05/31 AM 08:02

주요 변경점

이번에는 씬의 흐름을 구성하는 데에 중점을 두고 개발하였음.

1. 전투 맵에서 실제 엔트리 픽 모드를 구현

2. 전투맵 설정 모드를 구현

3. 모든 UI는 터치/마우스에 최적화될 수 있도록 변경하였음.

4. 필요한 데이터를 JSON형식으로 저장/불러오기



상세 설명

1. 전투 맵에서 엔트리 픽 모드를 구현

FFT를 플레이하면서 가장 맘에 안들었던 것이, 전투 맵 상에 적이 누가 어디에 있는지 모른 채 별도의 엔트리 화면에서 아군의 엔트리를 설정해야 한다는 것이었음.  그래서 언제나 플레이할 때 1. 일단 아무렇게나 엔트리를 설정 2. 플레이 시작후 적들의 상태와 위치를 확인 3. 리셋후 다시 엔트리 설정 이라는 번거로운 과정을 거쳐야 했음.  그래서 이번 리메이크때는 이러한 불편을 없애고 새로운 방법으로 씬을 구성하였음.


오리지널 FFT의 경우

엔트리 구성 화면과 전투 화면이 분리

엔트리 픽 화면     ->    전투 화면


My FFT Remake의 경우

전투 맵상에서 엔트리 구성이 가능. 이 때 화면을 움직여서 적들의 위치와 상태를 파악 가능(아직 미구현).

엔트리 구성 모드    ->    전투 모드



2. 전투맵 설정 모드를 구현

맵 상에서 적 유닛을 설정하고 아군의 엔트리 포인트를 설정할 수 있는 모드를 구현

적 유닛 설정


아군의 엔트리 포인트 설정



3. 모든 UI는 터치/마우스에 최적화될 수 있도록 변경하였음.

엔트리 픽, 설정 모드 전부 파레트 창에서 선택 가능한 아이템을 표시하여 파레트 창에서 아이템 선택 -> 맵에서 타일을 선택 하는 방식으로 바꿨음.


4. 필요한 데이터를 JSON형식으로 저장/불러오기

아군 유닛 / 적군 유닛 정보는 모두 JSON으로 파일에 저장됨.

아군 유닛 리스트의 JSON 파일 펼쳐 보기


   { 
      "unitID": "0",
      "name" : "Ramza", 
      "prefabTypeName" : "unitRamza",
      "operationMode" : "manual"
   },
   {
      "unitID": "1",
      "name" : "Delita", 
      "prefabTypeName" : "unitRamza",
      "operationMode" : "guest"
   }, 
   { 
      "unitID": "2",
      "name" : "Deecon", 
      "prefabTypeName" : "unitRamza",
      "operationMode" : "manual"
   }, 
   { 
      "unitID": "3",
      "name" : "Brad", 
      "prefabTypeName" : "unitRamza",
      "operationMode" : "manual
   }, 
   { 
      "unitID": "4",
      "name" : "Lambert", 
      "prefabTypeName" : "unitRamza",
      "operationMode" : "manual"
   }, 
   { 
      "unitID": "5",
      "name" : "Mago", 
      "prefabTypeName" : "unitRamza",
      "operationMode" : "manual"
   }, 
   { 
      "unitID": "6",
      "name" : "Cosmos", 
      "prefabTypeName" : "unitRamza",
      "operationMode" : "manual"
   }, 
   {
      "unitID": "7",
      "name" : "Jessica", 
      "prefabTypeName" : "unitRamza",
      "operationMode" : "manual"
   }

] 

적 유닛 리스트의 JSON 파일 펼쳐 보기

   { 
      "unitID": "10000",
      "name" : "Silvia", 
      "prefabTypeName" : "unitEnemy",
      "portrait": "FFT_Squire_Female_Portrait"
   },
   {
      "unitID": "10001",
      "name" : "Barinton", 
      "prefabTypeName" : "unitEnemy",
      "portrait": "Squire4M"
   }, 
   { 
      "unitID": "10002",
      "name" : "Katsu", 
      "prefabTypeName" : "unitEnemy",
      "portrait": "Squire4M"
   }, 
   {
      "unitID": "10003",
      "name" : "Benedict", 
      "prefabTypeName" : "unitEnemy",
      "portrait": "Squire4M"
   }, 
   {
      "unitID": "10004",
      "name" : "Samson", 
      "prefabTypeName" : "unitEnemy",
      "portrait": "FFT_Chemist_Male_Portrait"
   }
]


현재는 가장 간단한 정보밖에 없음.  추후 실제 유닛의 능력치들도 저장할 예정



실제 구현 영상

(업로드 제한이 10M라서 작은 이미지로 올림)








신고

 

피떡    친구신청

와.. 카메라가 잘 쫓아 댕기네요..

가디언히어로즈    친구신청

오 감사합니다 찾고 있던 정보인데
[SRPG를 만들자!!] SRPG를 만들자!!! #7 캐릭터 이동 (3) 2015/03/21 AM 01:04

어셋스토어에서 구매한 내비게이션 기능은 FFT를 구현하기에는 빠진 기능이 많음.  패스파인딩 관련 소스를 수정하였음.


수정하여 구현한 기능

1. 고저차를 고려한 패스파인딩

2. 적, 아군을 구별하여 패스파인딩

3. 지형을 고려한 이동 애니메이션

4. 가장중요! 건너 뛰기 가능

5. 최단 + 게으른 거리 계산


원래는 상용소스 빼고 소스를 깃헙에 통째로 올리려고 했는데 상용소스를 수정할 수밖에 없게됨.  안타깝지만 그냥 프라이빗 리포에 저장할 수밖에.

예상외로 쉽지 않은 부분이 있음.  이동 가능한 타일을 계산하는 부분과 실제 이동시의 최단거리 계산부분이 분리되어 있기 때문에 두 곳 다 같은 파라미터 / 조건을 넣어 주어야 할 필요가 있음.  이런 식으로 분리하는 것이 최선이었나? 하는 의문.  


상세 내용


1. 고저차를 고려한 패스 파인딩

  특정 높이차 이상의 노드는 패스파인딩 제외함. 아래와 같이 밑으로 떨어질 것 같거나 혹은 너무 높은 곳은 이동 불가.


물론 이동이 가능하다고 해서 한 칸 옆으로 바로 뛰어내리면 안되는 경우도 있음.


2. 적, 아군을 구별하여 패스파인딩

적의 경우에는 장애물로 간주하여 이동/지나가기 불가. 아군의 경우에는 아군의 위치로 이동할 수는 없지만 지나가기는 가능하기 때문에 패스파인딩에 포함시켜야 함.


3. 지형을 고려한 이동 애니메이션

타일 노드간의 애니메이션을 iTween을 통해 이동하게 되어 있음.  계단형일 경우 점프, 평지나 경사일 경우 지형을 타고 넘어가도록 설정함.



4. 건너 뛰기 가능

패스 파인딩 시에는 같은 방향 다다음 링크까지 검색함.

즉,

     O
     O
OOX OO
     O
     O

인접 4칸은 물론 한 칸 건너까지 패스파인딩에 포함. 대각선 타일은 포함 안함.  이 때 인접 타일은 이동불가이면서 다다음 칸은 이동 가능한 경우를 정확하게 판단할 필요가 있음.



5. 최단 + 게으른 거리 계산


밑으로 떨어졌다가 다시 올라가야할 경우에는 그냥 점프해서 건너감.



물론 한칸 건너뛰기로 해결 불가능 할 경우 쓸 데 없이 건너 뛰는 동작을 하지 않음


그나마 난이도 높은 과제를 큰 문제 없이 해결할 수 있어서 다행임.  


앞으로의 큰 과제는 1. 적 캐릭의 인공지능, 2.원거리 활공격시의 장애물 판정, 이것 두 개 정도??

신고

 

곰익는 마을    친구신청

오 이런 것 좋네요.
감사히 잘 보겠습니다 :)

아여름은너무덥다    친구신청

감사히 잘보고 친구신청하고 갑니다 ㅎㅎ

나무넷    친구신청

유니티로 제작하시는것 같은데

이번에 언리얼4 엔진이 정말 정말 잘 나왔습니다. 시간 되시면 꼭 한번 설치하셔서 태스트 해보세요

저는 아마도 언리얼4 쪽으로 완전히 넘어 갈것 같습니다.
[SRPG를 만들자!!] SRPG를 만들자!!! #6 레벨 작성 (5) 2015/02/22 PM 11:58

블렌더에서 레벨 작성 -> Unity에서 불러오기 -> Navigation Map 생성까지 완료



아직까지 버그는 많지만 기본적인 뼈대는 대강 완성됨.


여기까지 해 본 소감은....

유니티를 좋게 평가하기가 힘들다.  원래 게임 개발이 이런건가 싶기도 하지만.  기능 하나하나가 꼼꼼히 익히지 않으면 원하는 대로 움직여주지 않는게 많아서 많은 사람들이 이상적이라고 생각하는 "간단하고 쉬운 사용 -> 무궁무진하고 난이도 높은 활용"이 잘 안됨.  이런식으로 계속 개발하는 것이 과연 좋을지에 대한 회의감이 듬.


다음 과제

1. 레벨의 텍스쳐

2. 동작 버그의 해결

3. 이동 패스의 최적화

신고

 

잉그람    친구신청

맵 구성이 파이널판타지택틱스의 마법도시 가릴란드 네요.
시작하고 두번째 전투가 벌어지는 곳.

날킥    친구신청

파판택 참 재밌게 즐겼던 게임

케로    친구신청

저도 보고 바로 파판택 생각이 ㅎㅎㅎ

데님 파웰    친구신청

잉그람/케로님, 제가 겜 만드는 거 첨이라서 일단은 마법도시 가릴란드를 그대로 카피해 보는 걸 일차 목표로 하고 있습니다.

잉그람    친구신청

한가지 조언을 드리자면...
요즘 아무리 상용엔진이 잘 나온다고 하더라도, 엔진에서 제공하는 기능만으로는 반드시 한계가 옵니다.
간단한 게임은 무리가 없지만 좀 깊이가 있는 게임을 만들기 위해서는 C++은 꼭 필요합니다.
엔진의 미흡한 부분을 스스로 만들어 엔진에 포팅하여 사용해야 하는 경우가 빈번하기 때문입니다.
아직 C,C++에 미숙하시다면 이 것을 공부하는 것도 염두에 두시기 바랍니다.
1 현재페이지2 3
X