크래프톤 정글 TIL : 1029

lazyArtisan·2024년 10월 29일
0

정글 TIL

목록 보기
121/147

📝 배운 것들


🏷️ nullable reference type

public class Person
{
    public string FirstName;  // null이 아님
    public string? MiddleName; // null일 수 있음
    public string LastName;   // null이 아님
}

C#에서 string?과 같이 타입 뒤에 붙는 물음표(?)는 nullable reference type을 나타냄.
이는 해당 변수나 필드가 null 값을 가질 수 있음을 명시적으로 표시하는 기능.

C# 8.0부터 도입된 이 기능은 코드의 안정성을 높이고,
null 참조로 인한 예외(NullReferenceException)를 방지하는 데 도움을 줌.

🏷️ 프로퍼티

Auto-implemented properties

public class Person
{
    public string? FirstName { get; set; }

    // Omitted for brevity.
}

Get 또는 Set 접근자에서 사용자 정의 로직이 필요 없는 경우 사용하는 간소화된 속성 정의

public class Person
{
    public string FirstName { get; set; } = "";

    // Omitted for brevity.
}

값을 기본값이 아닌 다른 값으로 초기화하려면 중괄호 닫은 후에 명시해주면 된다



👾 나만무


관전 모드 캐릭터 색깔 변경

GameObject.FindGameObjectsWithTag("ScientistOutline");

이거 태그에 오브젝트 얼마 없으면 씬에 오브젝트 많이 있어도 성능 문제 없음?

GameObject.FindGameObjectsWithTag("ScientistOutline")는 해당 태그가 할당된 모든 게임 오브젝트를 한 번에 검색하는 메서드입니다. 검색 대상이 되는 태그를 가진 오브젝트가 많지 않다면, 다른 오브젝트 수가 많더라도 상대적으로 성능에 큰 영향을 주지 않습니다.

    private void Awake()
    {
        spectatorCameraColorChange = GetComponent<SpectatorCameraColorChange>();
        spectatorCameraColorChange.EnableOutlineEffect(); // 아웃라인 효과 활성화
        StartSpectating();
    }

SpectatorManager에서 윤곽선 변경 효과 호출하는거 추가 (팀장님이 만드셨던 셰이더 및 코드 활용)

using System.Collections.Generic;
using UnityEngine;

public class SpectatorCameraColorChange : MonoBehaviour
{
    public Material ScientistOutlineMaterial; // 과학자 아웃라인 머테리얼
    public Material MonsterOutlineMaterial; // 몬스터 아웃라인 머테리얼

    public void EnableOutlineEffect()
    {
        GameObject[] Scientists = GameObject.FindGameObjectsWithTag("ScientistOutline");

        foreach (GameObject obj in Scientists)
        {
            SkinnedMeshRenderer skinnedMeshRenderer = obj.GetComponent<SkinnedMeshRenderer>();

            if (skinnedMeshRenderer != null)
            {
                skinnedMeshRenderer.material = ScientistOutlineMaterial;
            }
        }

        GameObject[] Monsters = GameObject.FindGameObjectsWithTag("MonsterOutline");

        foreach (GameObject obj in Monsters)
        {
            SkinnedMeshRenderer skinnedMeshRenderer = obj.GetComponent<SkinnedMeshRenderer>();

            if (skinnedMeshRenderer != null)
            {
                skinnedMeshRenderer.material = MonsterOutlineMaterial;
            }
        }

        Debug.Log("Outline Effect Enabled");
    }
}

관전 시작되면 머테리얼 바뀐다

새 캐릭터 모델에 관전 머테리얼 적용

아 근데 오늘 모델링을 프로토타입에서 쓰던 거에서 실제 쓸 걸로 바꿨다고 함
이 친구는 기존 로직 작동 안 함
머테리얼을 두 개 갖고 있어서 일부만 적용됨
장화신은 고양이 됨

머테리얼 이거 어디서 적용되는거임 element 0이랑 1이랑 다른 부위를 담당하는데 뭐임 이거

올려주신 스크린샷은 Unity에서 Skinned Mesh Renderer 컴포넌트가 설정된 게임 오브젝트의 모습입니다. Skinned Mesh Renderer의 Materials 섹션에서 Element 0과 Element 1은 서로 다른 머티리얼이 적용된 부분을 나타냅니다.

Materials 섹션의 Element 항목이 의미하는 것

  1. Element 0과 Element 1

    • Element 0과 Element 1은 메시에 서로 다른 머티리얼이 할당된 부분을 나타냅니다.
    • Element는 메시에 있는 특정 서브메시 또는 서브머티리얼 슬롯을 의미하며, 이는 모델링 도구에서 설정된 메시의 재질 슬롯에 따라 결정됩니다.
  2. 각 Element의 적용 위치

    • Element 0과 Element 1이 서로 다른 머티리얼을 할당받았다는 것은, 이 메시가 두 개의 다른 재질 구역을 가지고 있다는 것을 의미합니다.
    • 예를 들어, Element 0(Ch11_body1 머티리얼)은 캐릭터의 특정 부위(예: 몸통), Element 1(Ch11_body 머티리얼)은 다른 부위(예: 머리나 팔)와 같은 방식으로 메시의 서로 다른 부분에 할당될 수 있습니다.
  3. 모델링 도구에서 설정된 서브메시

    • 이 설정은 3D 모델링 도구(예: Blender, Maya)에서 모델을 제작할 때, 각 부위에 서로 다른 머티리얼 슬롯을 할당함으로써 이루어집니다. Unity에서는 이러한 머티리얼 슬롯을 각 Element로 구분하여 적용합니다.
  4. 어떤 부위에 적용되는지 확인하는 방법

    • Unity에서 메시의 특정 부분에 머티리얼이 어떻게 적용되는지 확인하려면, 3D 뷰에서 해당 오브젝트를 선택하고 각 머티리얼을 변경하면서 메시의 어떤 부분이 바뀌는지 확인할 수 있습니다.
    • 또는, 3D 모델링 도구에서 메시의 각 서브메시가 어떤 부위에 해당하는지 확인할 수 있습니다.

요약

  • Element 0과 Element 1은 모델링 도구에서 설정된 서브메시 또는 서브머티리얼 슬롯을 나타냅니다.
  • 각 Element는 서로 다른 머티리얼이 메시의 특정 부위에 적용되는 방식으로, Element 0이 특정 부위, Element 1이 다른 부위에 적용됩니다.
  • 정확한 부위는 Unity에서 머티리얼을 변경하면서 확인하거나, 3D 모델링 도구에서 확인할 수 있습니다.

그러면 element 0이랑 1에 둘 다 접근해서 머테리얼 바꿔버리려면 어케 함

        // Skinned Mesh Renderer 컴포넌트를 가져옴
        SkinnedMeshRenderer renderer = GetComponent<SkinnedMeshRenderer>();

        if (renderer != null)
        {
            // 현재 할당된 모든 머티리얼을 가져와 배열로 저장
            Material[] materials = renderer.materials;

Unity에서 Skinned Mesh Renderer의 Materials 배열에 접근하여 Element 0과 Element 1에 할당된 머티리얼을 바꾸려면, materials 배열을 사용해 각각의 Element에 접근할 수 있습니다. 이렇게 하면 Skinned Mesh Renderer에 할당된 여러 머티리얼 중 원하는 것을 변경할 수 있습니다.

                for (int i = 0; i < materials.Length; i++)
                {
                    materials[i] = ScientistOutlineMaterial;
                }

foreach로 했었는데 오류 남.
생각해보니까 for문으로 해야 Call by Reference 가능

근데 이렇게 해도 적용이 안됨.
material 배열을 다시 적용을 했어야 됐던거임.

일단 적용은 했는데

왼쪽이 프로토타입 모델링이고
오른쪽이 지금 모델링

왼쪽은 윤곽선'만' 적용이 가능한데
오른쪽은 윤곽선만 적용이 불가능

팀장님께 얘기드렸더니 윤곽선은 중요한게 아니라서
벽 관통 비관통만 만들어놓으라고 하심

비관통용 머테리얼은 기존 머테리얼에서 emission 색깔을 바꾸면 된다고 함

        GameObject[] Scientists = GameObject.FindGameObjectsWithTag("ScientistOutline");

        foreach (GameObject obj in Scientists)
        {
            SkinnedMeshRenderer skinnedMeshRenderer = obj.GetComponent<SkinnedMeshRenderer>();

            if (skinnedMeshRenderer != null)
            {
                Material[] materials = skinnedMeshRenderer.materials;
                materials[1] = ScientistBodyMaterial;
                materials[0] = ScientistBody1Mateiral;
                skinnedMeshRenderer.materials = materials;
            }
        }

바꾸었다

선택지도 많이 만들어놨다

관전 카메라 상하 조절

https://www.youtube.com/watch?v=DXFrfh1oy3M

시네머신은 다양한 효과를 코딩 안 하고도 줄 수 있다
특정 오브젝트를 회전하면서 관찰하게 하거나
카메라의 시야에서 사라지면 다음 번 카메라로 자동 전환되게 하거나
실제 손으로 촬영하는 것처럼 손떨림 기능을 추가하거나
게임에서 자주 보이는 3D 시점 카메라까지

starter tps asset으로 예제 돌릴 건데
핑크색으로 나오면 모든 머테리얼의 셰이더를 Standard로 변경해라

create - cinemachine 보면 종류가 여러가지
1. virtual camera : 이거 설정 건드리면 나머지 다 만들어낼 수 있는데 프리셋처럼 다른 카메라들 미리 만들어져 있는거
2. FreeLock Camera : 플레이어를 중심으로 구에 가까운 궤적을 그리며 카메라 이동시킬 수 있음

https://www.youtube.com/watch?v=P_ibDJhFVMU

카메라에 cinemachine brain 붙이면
1. 버츄얼 카메라의 속성값으로 카메라에 붙어있는 속성값들을 덮어써서 카메라를 조작한다

  • virtual camera는 (주로 빈) 게임 오브젝트에 붙이는 컴포넌트이다.
  1. 씬에 있는 모든 버츄얼 카메라를 추적한다
  2. virtual 중에 한 개를 활성화된 카메라로 선택하고 그 친구의 속성값을 사용하여 cinemachine brain이 달려있는 unity camera을 조작한다

blend 쓰면 카메라의 다양한 각도 사용 가능

cinemachine free lock 카메라 이거 마우스 좌우 반전 푸는 법

  1. Cinemachine FreeLook 카메라를 선택합니다.
  2. Inspector 창에서 Axis Control 섹션을 찾습니다.
  3. X Axis와 Y Axis에 각각 Invert Axis 옵션이 있을 겁니다.
    • X Axis의 Invert Axis 체크박스를 해제하면, 좌우 반전이 꺼집니다.
    • Y Axis의 Invert Axis 체크박스를 해제하면, 상하 반전이 꺼집니다.

cinemachine 공부하다보니 freelock이라는게 있다는 걸 알아냄
일일이 스크립트로 할 필요 없이 이 친구를 이용하면 될듯?

이거 바꾸면 스크롤로 상하 조작 가능하게 만들 수 있다고는 하는데 우선순위 높지 않다고 함
일단 이거 관전 모드에 통합시키고 다른 작업 하러 가기

TargetHead = spectatingTarget.transform.Find("PlayerHead").gameObject; // 관전 대상의 머리 위치 찾기

이거 어떻게 최적화 안되나? find를 바꾼다던가 gameObject를 생략한다던가

  1. 사전에 레퍼런스 저장하기
    관전 대상인 spectatingTarget의 자식 구조가 변하지 않는 경우라면, PlayerHead를 한 번만 찾아서 캐싱해두고, 이후에는 캐싱된 참조를 사용하는 것이 가장 효율적입니다.

  2. Inspector에서 직접 할당 (가능한 경우)
    만약 PlayerHead가 항상 특정 구조에 있는 자식 오브젝트라면, Inspector에서 미리 할당하거나, 스크립트에서 SerializeField로 필드에 할당할 수도 있습니다. 이렇게 하면 Find를 아예 사용하지 않게 되어 성능을 최적화할 수 있습니다.

  3. Tag를 이용한 FindWithTag 활용 (비추천)
    FindWithTag를 사용할 수도 있지만, 같은 태그를 가진 오브젝트가 여러 개 존재할 수 있어, 의도치 않은 결과가 나올 수 있습니다. 따라서 PlayerHead가 고유한 태그로 설정되어 있지 않은 한, 이 방법은 추천하지 않습니다.

  4. GetChild()를 사용하여 자식 인덱스가 고정된 경우 최적화
    만약 PlayerHead가 항상 특정 위치에 있는 고정된 자식이라면, 인덱스를 통해 직접 접근하는 방식으로 최적화할 수도 있습니다.

virtual camera follow를 할 때 y 좌표만 +1.5 시키는 방법 없나?

Cinemachine Virtual Camera의 Follow 기능을 사용할 때, Y 좌표에 오프셋을 추가하는 방법은 Follow Offset 설정을 통해 가능합니다. 이렇게 하면 카메라가 대상의 Y 위치보다 1.5 단위 위에 따라오도록 설정할 수 있습니다.

방법 1: Transposer에서 Follow Offset 설정
1. Cinemachine Virtual Camera를 선택합니다.
2. Inspector 창에서 Body 섹션에 있는 Transposer를 선택합니다.
3. Follow Offset 필드에 오프셋을 설정합니다.

  • 여기서 Y 값에 1.5를 입력하면 카메라가 대상의 Y 좌표보다 1.5 단위 위에 따라오게 됩니다.

PlayerHead라는 오브젝트를 달아서 그거 따라가려다가
player 자체가 필요한 로직 (UI에 현재 플레이어 뿌리는거) 있어서
로직이 살짝 복잡해졌는데 그냥 오프셋 설정하면 끝이었구나

follow offset을 못 찾겠어서
rig의 height만 바꿨더니 결국 바닥을 꼬라봐서 안됨
gpt한테 이거 버츄얼 카메라가 아니라 freelock camera라고 했더니 rig height 올리라고 함

아니 그렇게는 안되는디...

그냥 하려던 대로 Head 만들고 1.5 높이는게 나을듯

    private void FollowAndLookAtTarget(GameObject spectatingTarget)
    {
        TargetHead = spectatingTarget.transform.Find("Head").gameObject; // 플레이어의 머리 위치 찾기
        FreeLockCamera.Follow = TargetHead.transform; // 버츄얼 카메라가 관전 대상의 머리를 따라다니도록 설정
        FreeLockCamera.LookAt = TargetHead.transform; // 버츄얼 카메라가 관전 대상의 머리를 바라보도록 설정
    }

복잡하게 안 하고 그냥 따라가는 요소만 바꿔주니까 됐다
이게 캡슐화의 힘인가?

그런데 이상한 현상 발생.
게임 시작하면 갑자기 아래로 빠져버림.
transform 봐도 그대로임.
콜라이더도 그대로임.

물어보니까 애니메이션 오류라고 함.
내가 망가뜨린거 아니라 다행.



🎮 유니티 공부


📌 animation

animation type

  • generic
    임의의 본 구조를 가진 캐릭터에 적합
    애니메이션을 특정 본 구조에 직접 매핑하여 사용해야 함

  • humanoid
    인간형 캐릭터에 적합
    표준화된 본 구조를 요구
    Unity가 자동으로 본을 매핑해 줌
    IK(Inverse Kinematics) 시스템을 기본으로 지원해서 손이나 발의 위치를 지정 가능

https://www.youtube.com/watch?v=dLomdF5Z0DU

animation type을 humanoid로 바꾸기
기본 스킨 애니메이션 (y bot) 아니면 avatar definition을 전부
copy from other avatar로 바꾸고 y bot 아바타로 바꾸기
바꿀때마다 apply 누르는거 잊지 말기
fbx 파일 임포트 했던 것들에서 삼각형 (animation clips) 들만 따로 빼고
나머지 필요없는 건 지운다 (이건 강의자 본인의 방식)

animation clips 보면 loop time 옵션이 있는데
자동으로 반복할지 결정하는 옵션

animation controller 더블클릭하면 보이는게 Layer
출발하려는 노드에서 우클릭하고 Make Transition 누르고 도착할 노드 지정 가능
끝나면 돌아와야 되니까 반대로도 연결해주자

파라미터에서 어떤 조건일 때 어떤 애니메이션으로 가야할 지 지정 가능
엣지 선택해보면 conditions 리스트 있는데 거기에 파라미터 설정해주면 된다
트리거로 설정했다면 돌아올 때는 따로 설정 안해줘도 됨
엣지에서 has exit time 체크 해제해야 신호 주자마자 애니메이션 중간에 다른 애니로 전환 가능

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            anim.SetTrigger("Magic");
        }
    }

스크립트에서 파라미터 지정할 수 있다
이 스크립트는 animation controller에 할당한다

엣지 누르고 다른 애니로 넘어가는 폭 조절하면 전환 속도 조절 가능
자연스럽게 전환되려면 폭 늘리고
전환 속도가 중요하면 폭 좁혀라
애니 바 위치를 바꾸면 어느 부분이랑 전환이 이루어질지 조절 가능

conditions에 여러 조건 넣어놓으면 그 조건들이 다 이뤄져야 해당 애니로 전환됨
근데 조건 다 모이는 케이스 A여도 전환,
그냥 조건 하나만 이뤄져도 전환시키는 Must 케이스 B여도 전환시키고 싶을 수 있음

가장 간단한 방법은 노드를 복사한 뒤에 엣지 condition을 케이스 B로 수정
근데 절대 이렇게 하면 안됨. 가뜩이나 애니메이터 복잡한데 더 복잡해짐.

엣지 inspector 상단에 있는 transition을 추가하면 됨.
추가하는 방법은 Make Transition을 한 번 더 해주는거

사람마다 다른데, 본인은 parameter에서 트리거는 거의 안 쓰고 위 3개만 사용함.
트리거도 체크 가능하고, bool도 체크 가능.
트리거는 한 번 사용되면 꺼지고, bool은 사용돼도 안 꺼짐

https://www.youtube.com/watch?v=-FhvQDqmgmU&list=PLwyUzJb_FNeTQwyGujWRLqnfKpV-cj-eO

mixamo에서 다운받은 걸로 거의 모든 애니메이션을 구현할 수 있다

그냥 fbx와 fbx for unity의 차이는 텍스처 최적화 차이라고 함
유니티 애니메이션 프로그램은 interpolation을 사용하기 때문에
frames per second는 아무거나 해도 되긴 함. 프레임 높으면 파일 커지니까 30 정도로 해라.
keyframe reduction은 일정 변동 이하면 없는 취급해서 최적화하는거. none으로 해둬라.
in place 체크하면 특정 영역에서만 애니메이션이 재생되고, 체크 해제하면 애니메이션만큼 움직임

믹사모 파일에 들어있는거

set as layer default state로 하면 기본 상태가 바뀜

animator - update mode
1. normal : timescale에 기반하여 애니메이션 스피드 결정
2. animate physics : 내부적으로 애니메이션 로직을 fixed update에서 이루어지게 한다
물리랑 상호작용해야되는 애니메이션 있으면 이걸로 설정하면 됨
3. unscaled time : 애니메이션이 time scale과 독립적으로 이루어짐

animator - culling mode
1. always animate : 카메라에 들어와 있거나 말거나 항상 애니메이션 실행
2. cull update transforms : 카메라에 안 들어왔으면 프레임만 계산함
3. cull completely : 카메라에서 없어졌다가 다시 들어오면 이전 상태 그대로 다시 재생

culling은 카메라에 보이는 것만 렌더링하는 유니티 기능

exit time : 애니메이션 몇 퍼센트 진행돼야 다른 애니메이션으로 전환될 수 있는지 조절

0개의 댓글