2021. 12. 2. 23:39ㆍ유니티 & C# 공부
1.애니메이션
1) 애니메이션의 종류
Lagacy - 이전의 방식. 빠르고 라이트함. 코딩만 해서 유지보수가 까다롭다. Animation컴포넌트사용
---------------------------------------------------
Mecanim Animation Animator컴포넌트사용
레거시에 비해 살짝 느리나, 노드와 시각적 설계로 개발이 편리
1) Generic - 인체형 모델 아닌 3D모델, 2족 보행 외 사물, 동물, 차 등
2) Humanoid - 인체형, 2족 보행, 15개 필수관절이 모델에게 셋팅,
리타겟팅 Retargeting(모션캡쳐 그대로 다른 애니메이션을 가져와서 사용)
2) 애니메이션 클립 미리 보기 / Warp Mode속성
Warp Mode - 레거시 애니메이션의 재생 옵션
once 한번만 동작 Loop 반복 PingPong 마지막 프레임까지 동작 후 반대로 동작
Clamp Forever는 마지막 프레임까지 동작 후 마지막 프레임에서 고정유지, 정지
3) Animation 컴포넌트 (레거시)
프로퍼티 Animation - 기본 디폴트defult 동작
Animations 배열에 있는 애니메이션만 사용 가능
Play Automatically 시작 시 자동으로 애니메이션을 실행
4) Animation 블렌딩 (애니메이션 부드럽게 교차)
anim.CrossFade("에니메이션 클립 이름똑같이", 교차시간 0.2~0.3이 무난, 모드는 생략가능)
예시
[SerializeField] //어트리뷰트, private 변수를 인스펙터에서 보이게 하면서 수정 보호.
Animation anim;
Void Start()
{ }
Void Update()
{ float h, float, float mouse;
h = Input.GetAxis("Horizontal");
v = Input.GetAxis("Vertical");
mouse = Input.GetAxis("Mouse X"); //좌우로 회전 하는거(y축은 밑에 vecter3.up으로 함)
Vector3 Movedir = (Vector3.right * h) + (Vector3.forward * v);
// Vector3 Movedir = new Vector3(h, 0, v).normalized;
transform.Translate(Movedir.normalized * speed * Time.deltaTime);
transform.Rotate(Vector3.up* _turnSpeed * mouse* Time.deltaTime);
PlayerAnimation(h, v); //플레이어 애니메이션
}
void PlayerAnimation(float h, float v) >> update의 h,v값을 받아서 작동시킴.
{
//전진 후진 할 때 에니메이션
if (v>= 0.1f)
{
// 전진. 0으로 두면 애매
anim.CrossFade("RunF",0.3f);
}
기타 등등
}
5) 휴머노이드 아바타 본, 근육 움직임 확인
1) 모델 아바타 - Rig탭 - 휴머노이드, apply 후 Configure 버튼 활성화 되면 매핑 정보 확인 가능
( 버그로 Configure 버튼 바로 활성화 안 될 수 있으므로 다른 아무거나 선택 먼저 하면 활성화됨)
아바타 에셋 (Asset)
휴머노이드만 해당
모델 Bone 구조의 매핑 정보를 저장하는 에셋
Mapping
실선 원 > 15개 필수 본 구조
점선 원 > 옵션
Muscles & Setting
Muscle Group Preivew > 미리 움직임 범위 확인
Per - Muscle Settings > 관절 움직임 제한
(너무 범위 클 경우)
Mapping 화살표 > Clear
관절 구조 끊기게 됨.
* 이름이 잘못 되어 모델의 관절이 끊어져 있다면
Mapping을 AutoMapping으로, Pose를 Enforce-T pose로 변경하여
강제 연결 시킬 수 있다.
6) 애니메이션 리타겟팅 Retartgeting
외부 애니메이션 클립을 임포트, 선택 후 모델을 인스펙터 뷰의 하위 preview창에 드래그 앤 드롭
모델 Rig탭의 애니메이션 타입 부터 설정해야함.
Animation Type 동일해야 함. 각 애니메이션에 Loop time걸기 가능하다고 함.
7) 애니메이터 컨트롤러 - 큰 단원 2유한생터머신과 같이 작업 들어감.
A키 (시험x) - 전체 스테이트를 뷰에 딱 맞춤(Fit)
클립을 애니메이터 뷰로 드래그, 첫번째는오렌지 색상 스테이트로 변경 > 기본 스테이트 Defult
Exit State는 죽어도 다시 총 맞는 것처럼, 다른 스테이트를 다시 탈 수 있음
대처 예) FSM유한상태 머신 때, 거리로만 기준 삼아서 코루틴을 돌려
몬스터가 총 맞아 죽었다면
> 코루틴을 멈추고(yield break; 마지막에) + 콜라이더 비활성화(총알 충돌 방지)
Any State는 단방향만 됨. 양방향 안됨.
어떤 상태이든 실행가능하며(예- 총맞기, 죽기)
이후 IDLE, WALK, ATTACK등 기존 스테이트와 연결 필요함
달성 조건으로 trigger를 쓴다면,
Any State로 올 때 Has Exit Time 자체 비설정 하지만,
IDLE, WALK 같은 기존 스테이트로 되돌아갈 때는
Has Exit Time을 켜야 작동 안하는 것을 방지함.
Has Exit Time 해제 - 애니메이션 다 실시 안하고도
중간에 다른 애니메이션으로 전환
각 애니메이션 클립을 조건에 맞춰 연결해줄 때(스테이트 전이)
파라미터(bool,trigger,int등) 사용
trigger 파라미터는 이벤트를 위해 한번 호출 후 사라짐
8) 스테이트 전이(Transition)
스테이트로 전이하기 위해 Transition을 연결하여 화살표 연결함.
마우스 우클릭 - Make Transition클릭
9) 파리미터 / 해쉬테이블 / 애니메이션 퍼포먼스를 위한 관리법
전이를 위해 조건(Float, int, bool, Trigger 타입) 파라미터를 지정함
파라미너 끝/중간에 space 적용x (주의!!)
유니티 5 이전은 모두 네모박스 아이콘이었음. 이후
trigger 파라미터는 동그라미아이콘, Bool은 네모로 변경됨
유니티 파라미터는 유니티 내부에서 해쉬 테이블Hash Table로 관리한다.
즉, 중복 없이, 고유한 키 값으로 2차원 테이블 형태로 저장, 관리함.
Bool로 애니메이션 전환 하기 위해 스크립트로 작성한다면
Animation anim
void start(anim = getcomponent<Animation>();)
애니메이션 전환하는 스크립트 안에
anim.Setbool( int나 string..., ture) 하는데 그냥 하면
퍼포먼스에 그다지 효율적이지는 않다
예 anim.SetTrigger("PlayerDie"); //해쉬값 안받고 바로 파라미터 trigger이름 그대로
}
그래서 "Trigger 이름"을 int에 미리 변수로 뽑아서 담은 후에
int hashTrace = Animator.StringToHash("IsTrace"); // "Trigger 이름"을
anim.Setbool(hashTrace, true); 로 하는 게 좋음.
trigger 파라미터는 이벤트를 위해 한번 호출 후 사라짐
bool처럼 condition true/ false 같은 파라미터 x,
Any State로 올 때 Has Exit Time 자체 비설정
IDLE, WALK 같은 기존 스테이트로 되돌아갈 때는
Has Exit Time을 켜야 작동 안하는 것을 방지함.
Has Exit Time 해제 - 애니메이션 다 실시 안하고도 중간에 다른 애니메이션으로 전환
10) 애니메이션 인스펜트 창에서...
Has Exit Time 해제
- 애니메이션 다 실시 안하고도 중간에 다른 애니메이션으로 전환
Settings
(1) Exit Time 시험
- 0.5 = 50% 를 수행 한 후, 다음 애니메이션을 수행한다.
(2) Fixed Duration 체크 한다면
- Transition Duration 0.25초 동안 애니메이션하고
다음 애니메이션으로 넘어감
Transsition Duration은 전 애니메이션과 다음 애니메이션이 섞이는 거
11) 루트 모션의 보정(모델아바타의 발 높이 조정)
모션캡쳐으로 만든 애니메이션은 위치 변화 값도 기록되는데, 발이 지면보다 떠서
안맞는다면 Y축 기준점을 조정할 수 있음
모델 하위 오브젝트인 애니메이션 Clip의 인스펙터 창에서,
(1)Based Upon(at Start)속성을 Feet으로 변경하고,
(2)중심좌표를 캐릭터의 발 관절 높이로 설정
12) 사용하지 않는 Bone 최적화법 (하이어라키에 다 노출 되면 최적화 감소)
1) 모델을 프리펩화 하기 전에 해야 함
2) 원본모델의 인스펙터 창 Rig에서 Optimize Game Object 체크
3) 하단에 생기는 Extra Transform To Expose로 하이어라키에 표시할 것만 체크 후 Apply
> 나머지 관절들은 숨겨짐
2.유한 상태머신 FS
NPC(Non Play Character) 인공지능을 구현하는 방식, AI구현 방식 중 하나
HFSM, BT라는 다른 유형도 있음.
방법은 다양한데, Enum으로 몬스터 등 npc의 여러 상태를 먼저 설정 한 후
2. Switch, 코루틴 등을 활용하여 특정 조건일 때 상태를 변경하고 (걷기 > 공격하기 등)
애니메이션도 전환함
여기서는 코루틴과 while문으로 하되, 빠져나올 bool 조건 값을 주고,
main loop에 갈 수 있도록 yeild return new waitforSeconds을 무조건 사용함.
bool은 처음부터 긍정으로 생각할 것. isDie를 긍정으로 생각하면
while(!isDie) = 죽은 상태가 아닌건가?(False) 로 해석 할 수 있음
3.가비지 콜렉션 GC
가비지 컬렉션 : 사용하지 않는 메모리를 사용할 메모리로 바꿔주는 작업.
메모리를 파악하고 관리하는 프로세스
유니티는 닷넷 프레임워크를 사용하기 위한 프로젝트로 mono기반으로 돌아가는데,
mono자체가 자동으로 메모리를 관리하며, 프로그램 작동 시 필요한 메모리가 있다면 미사용된 힙 메모리 영역으로 제공해야 하며, 이전에 할당햇으나 더이상 유효하지 않는 영역은 개발자가 직접 메모리에서 내릴 수 없고 "사용하지 않음" 영역을 설정 할 수 잇음
메모리 관리자에서 특정조건(메모리 한계,잦은 요청)과 상황에 따라 유효하지 않는 영역을 정리
유니티의 가비지컬렉션 GC은 뵘-멀스-버드바이져(Boehm–Demers–Weiser) 가비지 컬렉션을 사용하며,
Stop the world 방식으로 사용되는데, GC이 유효한 메모리를 수집할 때, 프로그램 코드 실행 중지,
가비지 컬렉션 작업 이후 다시 실행(현재는 유니티에서 이렇게 하지 않음. 많은 시간 소비)
되므로, 기존 메모리 정리 까지 들어가서 느리게 된다. (코드로는 system.gc.collect())
2019년 이전 버전까지는 유니티의 가비지 컬렉션 시 속도가 저하됬었으나, 19 이후 버전은 좀 개선되었으며 (만족할 수준은 아니라고 함) 과거 구버전 mono 시 사용된 GC을 사용하고 있고 개선을 노력하고 있다고 함
정리할 메모리 용량이 아닌, 힙에 할당된 메모리가 기준으로
힙에 100m가 할당되었다면, GC가 작동 시 70ms이며, 어느 시점에서 프레임이 튀어오르게 됨. 플랫폼별 환경, GC 할당 빈도 등 따라서 프레임이 튀어오르게 되고 렉이 발생할 수 있음
언제 발생할 지 모르기에 아예 발생하지 않게 하는 게 좋음.
GC 대처법
방법 1. if,조건절에서 문자열 비교== 쓸 경우 별도의 메모리에 저장해서 할당되므로
Tag=="" 보다는, CompareTag("")으로 사용하여 미리 방지
방법 2. 19년도에 도입된 점진적 GC를 사용하면 하나의 작업을 여러 프레임 동안
나눠서 진행되므로, GC에 사용되는 시간 총량이 줄어들고 60fps로 유지가능
Project Setting - Player - Use Incremental GC 활성화
방법 3. 강제적인 GC 방법 >> 씬전환,UI오픈,특정이벤트 시작 등 뭔가 로딩이 있을 때
강제로 좋은 타이멩에 호출하기
방법 4. Resources.UnloadUnsuedAssets()으로 사용하지 않는 리소스를 해제 하는 방법
방법 5. 초기에 힙 메모리를 크게 할당하고, 오브젝트 풀을 사용
방법 6. 레이캐스트 가비지 컬렉션 방지 위해서는 RaycastNonAlloc 사용,
RaycastNonAlloc 미리 결과값을 배열로 만들어두고 배열로 담아서 리턴
단 배열과 개수까지 미리 셋팅 필요함
정해진 개수보다 넘어가면 오류 발생한다!!
Raycast, RaycastAll은 가비지 컬렉션 발생함
기타
애니메이션 모델 사용하지 않는 Bone 최적화법 > 프리펩화 안된 상태에서 인스펙터창 Rig탭에서 설정
(유니티 자격시험 Unity GameDeveloper)4. 애니메이션/유한상태머신/가비지콜렉션 GC (tistory.com)
[참고] 메모리 종류
스택 - 코드 블록 내 선언된 변수가 차례대로 스택에 쌓였다가 코드 블록이 끝나면서 제거,
순서가 있고, 빠름. 제한적임
힙 - 코드 블록이 끝나도 데이터가 제거되지 않음. 랜덤이며, 사이즈 크고 느림.
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=baek2sm&logNo=221129030352
[참고] 오브젝트 풀 - 사용할 데이터를 미리 메모리에 모두 올려서 오버플로우를 방지,
메모리에서 삭제하지 않음
'유니티 & C# 공부' 카테고리의 다른 글
(유니티 자격시험 Unity GameDeveloper)6. 주인공 점수 감소/싱글톤(싱글턴)/발사체/유니티 예약 폴더 (0) | 2021.12.04 |
---|---|
(유니티 자격시험 Unity GameDeveloper) 5. 네비게이션 (0) | 2021.12.04 |
(유니티 자격시험 Unity GameDeveloper)3.이벤트함수/벡터/오일러/법선벡터/충돌/문법/오디오 (0) | 2021.12.01 |
(유니티 자격시험 Unity GameDeveloper) 2. 유니티 기능 (년도 버전차이) (0) | 2021.11.29 |
(유니티 자격시험 Unity GameDeveloper)1. 유니티 기본 단축키(유니티 21년 기능 포함) (0) | 2021.11.29 |