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

2016년 10월 11일 화요일

벡터 크기 비교(sqrMagnitude)

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

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

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

2015년 11월 11일 수요일

유니티 3D Max 축 변환 부분



3D Max 에서 Unity로 데이터를 가져올 때의 문제는 축 설정이 꼬인다는 것이다.

이는 3D Max와 Unity의 좌표체게가 달라서 생기는 문제인데;;(유니티는 왼손 좌표계 맥스는 오른손 좌표계를 쓴다.)

위에서 나온 것처럼 수정하면 된다.

다른 하나의 방법으로는 

페어런츠 오브젝트를 두어 부모 오브젝트를 제어하는 방법이 있다.

2015년 10월 11일 일요일

Update, FixedUpdate

참조 : https://www.youtube.com/watch?v=ZukcUv3pyXQ

Update()
> Called Every Frame
> Used for regular updates such as :
    Moving Non-Physic objects
    Simple Timers
    Receiving Input
>Update interval times vary

FixedUpdate()
> Called Every Physics Step
> Fixed Update intervals are consistent
> Used for regular updates such as:
   Adjusting Physics (Rigidbody) object


유니티 실행 순서

참조 : http://docs.unity3d.com/kr/current/Manual/ExecutionOrder.html

2015년 8월 3일 월요일

유니티 메카님 강좌

유니티 공식 강좌
https://www.youtube.com/watch?v=BStXjU-mJvk

이재현님 강좌
https://www.youtube.com/watch?v=wq5x2xArSzc

작은서기님 강좌
https://www.youtube.com/watch?v=ddtLqFPoPA0

[추천] 유니티 최적화 관련 글들


"14일만에 0에서 60프레임 만들기" Unity3D를 사용하여 우리의 게임을 최적화시키면서 배웠던 것들"

출처 : http://unityindepth.tistory.com/30

추천 : ★★★☆

유명한 최적화 글을 번역한 블로그 입니다. 번역 참 어려운데요 수고와 노력에 박수를 보냅니다.



[Unity] 유니티 프로그래머가 알아야 할 최적화 스크립트 코드 작성법

출처 : http://geekcoders.tistory.com/entry/Unity-%EC%9C%A0%EB%8B%88%ED%8B%B0-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EA%B0%80-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-%EC%BD%94%EB%93%9C%EC%9E%91%EC%84%B1%EB%B2%95

추천 : ★★★★★

꼭 보시면 좋을 듯 합니다.

하나하나 테스트를 거쳐서 올린듯 보이며

이런글이 진정 개발자의 성지가 되어야 한다고 생각합니다.



[유니티] 그래픽 성능 최적화

출처 : http://docs.unity3d.com/kr/current/Manual/OptimizingGraphicsPerformance.html

유니티 공식 문서입니다.

추천 : ★★★★★

2015년 7월 29일 수요일

유니티 메모리 관련 정리 글

유니티 메모리 관련 정리 글 링크 입니다.

http://unityindepth.tistory.com/9

아래는 위 링크를 기반으로 정리한 것입니다.

변수는 스택에 저장된다.

new로 생성된 객체는 힙에 저장된다.

힙에 저장되는 형식은

class
object
string (string은 변수가 아닌 Class String이다.


가비지 컬렉션

1. 가비지 컬렉션은 시스템이 연산을 위해 메모리가 충분치 않다고 판단될 때 일어난다.
> 버려진 객체가 상당한 기간 동안 수거되지 않을 수 있다.
2. 가비지 컬렉션은 매우 비싼 연산이다.
>레벨 로드, 일시정지 등에서 수동적인 가비지 컬렉션을 작동시키는 것이 좋다.
> System.GC.Collect(); 명령어를 통해 수동으로 가비지 컬렉션을 작동시킬 수 있다.
3. 스택에 할당된 값에는 일어나지 않는다. 즉 Class는 가비지 컬렉션이 일어나지만, 구조체는 일어나지 않는다.

값 전달
1. =, 함수의 인자로 값을 전달할때 스택에 할당된 메모리가 복사된다.
2. int a = int b 일 때 b에 할당된 값이 a에 복사된다.
3. class a = class b 일 때는 스택에 할당된 a와 b의 힙 메모리 주소가 복사된다.

클래스 vs 구조체
1. 클래스는 참조 타입이고(힙에 할당되며, 힙의 메모리 주소는 스택에 저장된다.)
2. 구조체는 값 타입이다.(스택에 할당된다.)
3. 구조체는 값에 의한 전달이기 때문에 =, 인자로 값을 전달할 때 메모리가 증가한다.
4. 클래스에 의한 전달은 힙에 생성된 객체를 스택에서 메모리 주소로 할당되어 있기 때문에 메모리가 주소값을 저장하는 변수의 크기만큼만 늘어난다.
5. 클래스는 메모리를 절약하지만, 속도는 값이 스택에 저장되는 구조체가 빠르다.
6. 그러나 구조체의 데이트가 거대할 경우, 복사하는 시간이 걸리기 때문에 이 부분도 고려해야 한다.
7. 구조체는 가비지 컬렉션을 유발하지 않는다.
8. Vector3, RayCastHit은 자주 할당되고 오래사용하지 않기 때문에 구조체로 되어 있다.
9. 물론 ref, out을 사용하여 구조체의 값을 참조하여 변화시킬 수 있다.

스태틱
1. .Net의 정적 변수는 High Frequency Heap라고 불리는 Heap의 특별 공간에 저장된다.

정적 클래스
1. 오직 하나의 객체(사용하기 위한)만을 힙에 할당한다.
2. 다른 객체는 만들 수 없다.
3. 객체의 생성은 첫번째 호출에서 생성되며, 프로그램이 끝날 때 파괴된다.
> Scene이 종료되도 파괴되지 않기 때문에 사용 시 주의해야 한다.
> 여러씬에서 사용되는 클래스를 정적으로 만드는 것이 좋다.
> 객체 생성이 첫번째 호출에서 생성되기 때문에, 호출되지 않는 정적 클래스는 객체를 만들지 않는다.

정적 변수
1. 객체안의 정적 변수는 객체가 아닌 클래스에 속해있다.
2. 객체가 생성될 때 할당되지 않으며, 호출될 때(정적 클래스와 마찬가지로) 객체화 된다.
3. 즉 모든 객체안의 정적변수 객체는 단 하나이며 모든 객체는 이 클래스에 속한 정적 변수를 공유한다. (하나의 객체에서 값을 변경하면 다른 객체도 영향을 받는다. 힙에 할당되어 스택의 메모리 주소만 공유하기 때문)
4. 당연히 씬이 파괴되더라도 이 정적 변수는 살아있다.(정적 객체는 프로그램이 종료될 때 파괴된다.)

정적 함수
1. 일반 클래스에서 구현할 수 있다.
2. 단 정적 함수에 사용하는 변수는 정적 변수이어야 한다.

힙 파편화
1. 힙은 데이터가 무작위로 저장되어 있는 거대한 메모리 공간이다.
2. 유니티에서는 .Net managed 메모리를 사용하기 때문에 C처럼 파편화 현상이 일어나지 않지만 공간을 확보하기 위한 가비지 컬렉션의 과도한 사용은 절대로 효율적이지 않다.(버벅거림)

오브젝트 풀링
1. 오브젝트의 생성 제거에 의한 힙 파편화에 의한 과도한 가비지 컬렉션 사용을 막기위해 사용된다.
2. 재사용될 객체(총알, 몬스터, 이펙터 등)를 파괴하지 않고 비활성 시켜 놓는다.
 > Instanitate와 Destroy를 사용하지 않아도 된다!!

2015년 6월 30일 화요일

유니티 Android Studio SDK 설치 관련

출처 : http://gamedev.stackexchange.com/questions/93209/how-would-i-find-the-sdk-folder-for-android-studio-so-i-can-build-my-unity-proje


the sdk may be hidden in the AppDatafolder (the folder itself was hidden).
If you want to look for AppData, but can't find it, open explorer and type %appdata%, press enter. It will show the hidden files. Path will look like this; C:\Users\Your.name\AppData\Local\Android\sdk1 Now that you have found the sdk, go back in to unity and click EDIT / Preferences / External Tools. You will see a field for Android SDK location - enter the path in that field.

익스플로어 창에 %appdata%를 입력하면 경로가 나옵니다.

"C:\Users\Your.name\AppData\Local\Android\sdk" 경로를 확인해서 

유니티의 EDIT / Preferences / External Tools 에 설정하면 됩니다.


2015년 6월 2일 화요일

유니티 이펙트 렌더링 문제

유니티에서 2D Sprite에 가려 위치 상으로는 위에 있지만 이펙트가 보이지 않는 경우가 있습니다.

이럴 경우에는 스프라이트를 정렬(Sort)처럼 이펙트도 정렬할 수 있는데요

해당 이펙트를 선택하고

프로퍼티 창의

SortingLayer 를 조정해주면 됩니다.


만약 동일한 레이어라면

Order in Layer 에서 번호를 넣어 렌더링 순서를 정해줄 수 있습니다.

2015년 5월 9일 토요일

UnityEngine.UI.dll is in timestamps but is not known in assetdatabase

이 에러가 뜨면 정식이 아늑해 지죠 ㄷㄷ;
포럼에 가서 초반부를 보면 공포에 휩싸일 수 있습니다.(해결 방법이 없;;;;;)

하지만 다행히도 해결되어 있군요

출처 : http://forum.unity3d.com/threads/unityengine-ui-dll-is-in-timestamps-but-is-not-known-in-assetdatabase.274492/

I may have found a workaround. The idea is to totally remove the UI System from Unity then put it back. Unity should reload its modules.

I wrote a full walktrough but overall it is very simple. It is better than a full reimport.
  1. Remove the UI System
    1. Close Unity
    2. Access on Unity's installation folder on Explorer or Finder on mac (On mac rightclick on the App and click on ShowPackageContent).
    3. Locate the folder named "UnityExtensions/Unity". (On Mac: "Content/UnityExtensions/Unity".
    4. In this folder you will notice a folder named "GUISystem"
    5. Move this folder from the installation folder (you may need administrator rights). Yes, right. Do not just rename it or move it out the "Unity" folder, Unity will find it... I assure you...
  2. Have Unity notice the change
    1. Open Unity again in the project you had the issue
    2. You may have an error "GameObject (named 'Canvas') references runtime script in scene file. Fixing!"
    3. Close Unity, DO NO SAVE ANY SCENE
  3. Restore the UI System
    1. Make sure Unity is closed
    2. Restore the "GUISystem" to its previous location
    3. Open Unity again
    4. Unity will compile script
    5. You will see the warning "Timestamps (19) and assets (21) maps out of sync." and the errors "Asset '' is in assets but has no assettimestamp..." just ignore them
    6. Everything should be ok again

간략 해석

1. 유니티를 닫고
2. 유니티가 설치되어 있는 폴더에서 "UnityExtensions/Unity"를 찾습니다.
3. 여기에 "GUISystem" 폴더가 있는데
4. 이 것을 완전하게 (저는 바탕화면에다가 뺏습니다.) 잘라서 외부 폴더에 붙여놓습니다.

1. 다시 유니티를 열고
2. 유니티가 에러가 나거나 그냥 닫힙니다.
3. 만약 유니티가 닫혀있지 않다면
4. 유니트를 종료하고

1. "GUISystem" 폴더를 제자리에 갖다 놓습니다.
2. 그럼 정상적으로 작동될것입니다.

2015년 5월 4일 월요일

Android Native Plugin 버그 관련 SIGN_IN_REQUIRED


http://forum.unity3d.com/threads/released-android-native-plugin.201468/page-16

링크에서 보시면 아시겠지만

만약 세팅을 제대로 한 상태에서도 해당 오류가 계속 나온다면

아래와 같이 해주시면 됩니다.



1. Window -> Android Native -> EditSetting 으로 위의 창을 엽니다.
2. 그리고 사용하지 않는 Lib를 비활성화해줍니다.
 - 저는 Social, Camera 부분을 비활성 시켰습니다.
3. Facebook SDK를 삭제했습니다. 이 SDK가 어떠한 영향을 주는지는 정확하게 알지 못하지만 Facebook 설정을 하지 않으면 빌드시 오류가 나더군요 현재 Facebook 계획이 없기 때문에 삭제했습니다.


2015년 3월 31일 화요일

uGUI 애니메이션 추가 방법


해당 오브젝트에 Animator나 Animation을 직접적으로 추가하면 여러가지 경고창이 뜹니다.

uGUI 오브젝트에 애니메이션 추가 순서는

1. 해당 오브젝트를 선택하고
2. Animaition 윈도우에서 AddCurve를 선택하고, 해당 애니메이션 클립을 저장하면
3. Animator 컴포넌트가 선택된 오브젝트에 자동으로 생성됩니다.

2015년 3월 17일 화요일

Unity 5 AssetBundle 주의할 부분

문서 : http://docs.unity3d.com/Manual/BuildingAssetBundles5x.html

1. 문서에 나온 스크립트중에서 using UnityEditor;가 있다면 반드시 Editor 폴더에 넣어야 합니다.

2. AssetLabel(오브젝트를 클릭하면 Inspector 하위단에 나오는)에서 AssetBundle 이름을 입력할 때 /를 입력하면 폴더로 구분되어 집니다. character/player는 character 폴더가 생성됩니다.

동일한 입력으로 에셋번들을 정의 했을 경우


위의 이미지와 같이 해당 ManifestFile파일에 Assets로 추가됩니다.

2015년 3월 16일 월요일

유니티 5.0 도입, 에셋 번들 작업, 다음작업

유니티 5.0 도입

에셋 번들 작업을 위해 유니티 스크립트 문서를 보는 중에
유니티 5.0에서 변경된 에셋 번들을 보게 되었습니다. 확인해본 결과 조금 더 편하게 관리가 가능할 것 같아 이참에 유니티 5.0으로(차후 애니메이션 관련해서 어짜피 업데이트 해야 하기 때문) 업데이트 했습니다.

에셋 번들 작업

에셋 번들 관련 작업을 진행했습니다. 사용자가 만들어 놓은 에셋 번들 데모가 있어서 분석을 해봤는데요, 저는 간단하게 사용할 거라서 직접 유니티 스크립트 문서를 참조해서 만드는 걸 고려하고 있습니다.

다음작업

에셋 번들 작업
유니티 5.0에 소스 이식

2015년 3월 15일 일요일

Unity Script Execution Order

Awake, OnEnable and Update의 다른 스크립트와의 실행 순서를 결정합니다.

다른 스크립트와의 Awake 실행 순서로 고민하신 경험이 있다면

강력하게 추천하는 기능인데요

아래의 이미지와 같이 에디터 상에서 실행 순서를 정할 수 있습니다.

menu:Edit -> Project Settings -> Script Execution Order



스크립트는 Apply 버튼위에 있는 + 버튼을 누르면 리스트로 나옵니다(깜짝 놀랐다는 ㅎㅎ;)
리스트에 나온 스크립트를 선택하면 위의 화면처럼 스크립트가 등록됩니다.

그리고 스크립트 이름 우측에 실행순서를 나타내는 숫자가 나오는데요

입력된 숫자의 순서대로 자동 정렬됩니다.

혹은 스크립트 이름이 나와있는 Bar를 누르고 드래그앤 드롭으로도 정렬이 가능합니다.

매우 유용한 기능이니 한번 써보시길 추천드립니다.

전 Unity3d Log Viewer 설치하면서 알게 되었네요

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);