레이블이 유니티인 게시물을 표시합니다. 모든 게시물 표시
레이블이 유니티인 게시물을 표시합니다. 모든 게시물 표시

2016년 9월 27일 화요일

벡터 크기 비교

단순히 두 벡터의 크기를 비교할 때
Vector3.sqrMagnitude를 사용하는 것이 좋다.

이유는 Vector3.Distance 함수는 제곱근의 연산(벡터의 길이를 구하기 위해)이 들어가는데

sqrMagnitude는 제곱근을 계산하지 않고 제곱한 값끼리 비교하므로 제곱근의 연산을 줄일 수 있기 때문

2016년 9월 26일 월요일

부동소수점 연산 오류

부동소수점 연산은 치명적인 오류가 있습니다.













위에서 보다시피 0.1만 더했는데 엉뚱한 값들이 나오게 됩니다.

 


부동소수점 오류의 발생 이유는
컴퓨터에서 10진수를 2진수로 변화할 때 발생하는 구조적인 문제이죠

이렇기 때문에 float값을 0과 비교하거나
Float형 값들을 비교할 때는 아래와 같은 방법을 쓰게 됩니다.

0과 비교할 때는

if (sw * sw > Mathf.Epsilon)
두수의 제곱근을 구해 Mathf.Epsilon과 비교

Mathf.Epsion은 0과 매우 가까운 값입니다.
즉
( 값 + Epsilon = 값 ) 이 되지만
( 0 + Epsilon = 0 )이 되지요

Float 형끼리 비교할 때는

Mathf.Approximately(1.0F, 10.0F / 10.0F))


※ 부동 소수점은 부정확하기에 비교를 위해서 등호(=) 연산자를 사용하는 것을 추천하지 않습니다.
(즉, 1.0 == 10.0 / 10.0 은 true를 반환하지 않을수도 있습니다.)








2015년 3월 8일 일요일

유니티 2개 띄우기

전에는 유니티를 2개 띄우기 위해서

바로가기 아이콘의 속성을 편집했었는데요

업데이트 된건지;; 제가 모르고 있었던건지;;

이제는 아래와 같이 툴에서 간단한 체크를 하면 되는 것 같습니다.


Edit -> Preferences -> General 에서

Always Show Project Wizard 를 체크하면 됩니다.

기본적으로 비활성화 되어있습니다.

2015년 3월 6일 금요일

내부 클래스를 인스펙터에서 접근하기




내부 클래스를 아래의 인스펙터 창에서 처럼 접근할 수 있게 하는 방법입니다.
해당 클래스 위에
[Syste.Serializable] 코드를 넣고

해당 클래스의 객체를 Public으로 선언하면 됩니다.



2015년 3월 5일 목요일

Animation Clip 이름 수정 시 정상 작동


기존 Animation Clip을 사용하기 가장 꺼림직했던 이유 중 하나는

애니메이션 클립의 이름을 변경하면 작업하던 애니메이션 클립이 제대로 불러와 지지 않는 버그 인데요 ( 이거 때문에 정말 몇번을 작업하다가 엎었는지 .ㅠ.ㅠ)

이제는 이 부분에 대해 수정이 된 듯 합니다.

작업도중 애니메이션 클립의 이름을 변경해도 정상 작동하는군요(유니티 점점 좋아집니다 .ㅠ.ㅠb)

위의 이미지는 최초 로그인 시 나오는 "화면을 터치하세요"텍스트의 페이드 인 아웃을 구현하는 애니메이션 클립니다.

물론 스크립트로 구현하거나

ITween을 사용하거나

PlayMaker로 구현하는 등등의 방법이 있겠지만

저는 개인적으로 유지보수가 쉬운 애니메이션 클립 작업을 선호합니다.

※ Text.Color를 제어해서는 게임 플레이 시 이벤트가 연출되지 않습니다;; 에디터 모드에서만 되는군요;;


Canvas Group 컴포너트를 제어해야 정상적으로 작동합니다.

2015년 2월 28일 토요일

Unity Sprite Packer

스프라이트 패커 정리


스프라이트 그래픽작업을 위한 아틀라스 관리


기존의 아틀라스 관리 플러그인과는 개념이 다릅니다.

NGUI의 경우 아틀라스 메이커를 통해 다양한 스프라이트를 하나의 아틀라스에 넣어, 만들어진 아틀라스를 직접 관리 및 적용 했다면,

스프라이트 패커는 아틀라스를 만들긴 하는데 해당 아틀라스를 직접 관리 및 적용을 하진 못합니다.

즉 만들어진 아틀라스를 통해 관리하는 것이 아닌

해당 텍스처를 직접 관리 한 부분이 아틀라스에 적용되며, 이 적용된 아틀라스는 에디터 모드에서 작동하지 않고 플레이 모드에서 작동하게 됩니다.

(그래서 스프라이트 패커로 만들어도 에디터 모드의 Draw Call은 감소하지 않습니다. 플레이 버튼을 눌러야 감소한 Draw Call을 확인할 수 있습니다.)

약간 생소한 개념인데

Unity Docmentation을 참조하면

Atlases are cached in Project\Library\AtlasCache.

즉 아래의 이미지처럼 아틀라스를 만들어도 NGUI 처럼 Assets 안에 존재하지 않으며 에디터 상에서 파일을 확인할 수 없습니다.


하지만 AtlasCache 폴더안에 저장되기 때문에 실제로는 파일이 존재하게 되며, 유니티를 실행하게 되면 아틀라스를 쓰는 가장 큰 이유인


  • 메모리 절약
  • Drawo Call 감소


의 장점을 동일하게 사용할 수 있습니다.

아틀라스 만들기



선택한 텍스처의 Inspector창에서
Packing Tag에 Tag를 넣습니다.

이 Tag는 아틀라스의 이름역할을 합니다.



좌측 위의 Pack 버튼을 누르면 위에서 입력했던 같은 Tag 이름으로 묶인 아틀라스를 생성합니다.

단 해당 텍스처의 파일포멧에 따라 다른 그룹(같은 이름인데 그룹이 분리되는)이 생성되며 다른 그룹일 경우 Draw Call이 증가합니다.

만약 2048*2048의 해상도가 넘어가게 된다면 페이지(Page 1, Page 2 등)생성되며 생성된 페이지는 스프라이트 패커의 상단에서 선택할 수 있습니다.

(PC에서 테스트해본 결과 Page에 따른 DrawCall은 증가하지 않았습니다)

만들어진 아틀라스 사용?


개발단에서는 위에서 만든 아틀라스를 사용하지 않습니다.

이 부분에서 저도 많이 헷갈렸는데요;;

중요한 부분은

개발과 최적화가 분리되어 있다는 겁니다.

즉 개발은 Sprite로 변환시킨 텍스처를 드래그앤 드랍이나 코드를 통해 사용하고

이 Sprite를 단지 스프라이트 패커를 통해 Pack 만 시킨다면

유니티의 빽단에서 최적화 하는 방식입니다.

그냥 임포트한 Sprite를 사용하면 됩니다.

다만 메로리 및 Draw Call 최적화를 하기 위해 스프라이트 패커를 통해 아틀라스를 만들어야 하는 것이지요

2015년 2월 19일 목요일

Unity WWWForm.AddField 주의해야 할 부분

WWWForm 에서

public void AddField(string fieldName, string value);

로 PHP에 쿼리를 날릴 경우 주의해야 하는 부분은

value에 null이 들어가면

오류가 납니다 ㅡㅡ;;

이거 약간 난감한데요

클라이언트에서 서버로 키, 벨류 값을 보낼때

의도적으로 해당키에 null 값을 보내는 경우가 있고

이 부분을 디버그 모드에서 확인하는게 깔끔한데요

에러를 뿜으니;;

디버그 모드에서는 해당 키에 null 값이 들어있다는 것을 보여주지만

서버에는 전송되지 않았다는 것을 알려야죠(잊어먹을 수 있으니 .ㅠ.ㅠ)

코드를 추가해줘서

약간 깔끔하지 못한;; 코드를 만들었습니다.


        foreach (KeyValuePair<string, string> post_arg in data)
        {
#if UNITY_EDITOR    // 에디터에서 확인할 통신 메세지

            // Form의 value값이 null일 때를 구분해 준다.(안해주면 오류 발생)
            if (post_arg.Value != null)
            {
                formMessage = Edit_Text.AddString(formMessage, post_arg.Key.ToString(), " : ", post_arg.Value.ToString(), "\n");
                m_Form.AddField(post_arg.Key, post_arg.Value);
            }
            else
            {
                formMessage = Edit_Text.AddString(formMessage, post_arg.Key.ToString(), " : ", "null", "    <--[ value가 null일 경우 서버에 전송되지 않습니다 ]\n");
            }
#endif
        }

#if UNITY_EDITOR
        Debug.Log("- WWWForm_Send [ RequestID : " + requestID + " ] (세부정보를 보려면 터치하세요)\n\n" + formMessage);
#endif
        m_WWW = new WWW(url, m_Form);




2015년 2월 11일 수요일

Unity WWW 다운드된 바이너리 파일 읽기

처음에는

File.WriteAllBytes(filePath, m_WWW.bytes);

로 리소스 폴더의 바이너리 파일을 수정한 다음

m_Textasset = Resources.Load("ClientDB") as TextAsset;

로 다시 읽었는데요

계속 기존의 바이너리 파일을 읽어들이더군요

그래서 알아봤더니

AssetDatabase.Refresh


로 리소스를 다시 읽어야 한다더군요


그런데 AssetDatabase의 네임스페이스가

Namespace: UnityEditor

로 되어 있습니다.;;

즉 에디터 상에서만 된다는 것인데요

한참 헤메다가

stream = new MemoryStream(lWWW.bytes);

코드로 해결했습니다.

www.bytres로 바로 MemoryStream에 올리면 되더군요 .ㅠ.ㅠ

전체 코드는 아래와 같습니다.

MemoryStream stream;

        if (lWWW != null)
        {
            stream = new MemoryStream(lWWW.bytes);
        }
        else
        {
            if (!(Table.Data_ConquerorLevel == null)) return;

            m_Textasset = Resources.Load("ClientDB") as TextAsset;
            stream = new MemoryStream(m_Textasset.bytes);
        }

       m_TableDataBinary = new BinaryReader(stream);