250425

lililllilillll·2025년 4월 25일

개발 일지

목록 보기
152/350

✅ What I did today


  • Prototyping
  • R&D : Voxel
  • Art Practice : Drawing


📝 Things I Learned


🏷️ How to debug easily

https://github.com/JohnBaracuda/com.baracuda.runtime-monitoring?tab=readme-ov-file

  • Asset Store에서 등록해놨으니 PackageManager에서 설치
  • Tools에서 세팅하기
  • using Baracuda.Monitoring;
  • 인스턴스는 시작할 때 this.StartMonitoring()

🏷️ Unity Input System

🧱 1. InputAction이 뭔데?

InputAction입력을 정의한 개별 명령 단위임.

예:

  • "Move"라는 이름의 InputAction 하나 → WASD or Gamepad 스틱을 통해 Vector2 값을 받음
  • "Jump"라는 InputAction → Spacebar를 누르면 이벤트 발생

InputAction = "입력 이름 + 어떤 키를 쓸지 + 어떤 타입인지" 다 정의한 객체

📁 2. InputActionAsset이 뭔데?

.inputactions 파일 = InputActionAsset
→ 여러 개의 InputAction들을 그룹으로 묶은 것
PlayerAction, UIAction, GameplayAction 같은 Action Map으로 분류됨

즉:

InputActionAsset
├── ActionMap: "Player"
│   ├── Action: "Move" (2D Vector)
│   ├── Action: "Jump" (Button)

🔗 3. InputActionReference는 뭐냐?

  • .inputactions 파일에 있는 "Move" 같은 액션을 Script에서 참조할 수 있게 만든 ScriptableObject
  • Drag&Drop으로 연결해서 바로 가져다 쓸 수 있음

🎮 4. PlayerInput이 하는 일

PlayerInput 컴포넌트는 다음을 자동으로 해줌:

✅ 역할 1: InputActionAsset 로드

playerInput.actions = InputActionAsset

✅ 역할 2: Default Map 활성화

playerInput.actions.FindActionMap("Player").Enable()

✅ 역할 3: 내부 액션들 Enable

PlayerActionMap["Move"].Enable();
PlayerActionMap["Jump"].Enable();


💡 Prototyping


Player Move

public class PlayerMove : MonoBehaviour
{
    [SerializeField] float moveSpeed;
    [SerializeField] InputActionReference inputAction;
    CharacterController cc;

    void Start()
    {
        cc = GetComponent<CharacterController>();
    }

    void Update()
    {
        Vector2 moveInput = inputAction.action.ReadValue<Vector2>();
        Vector3 moveDirection = new Vector3(moveInput.x, 0, moveInput.y).normalized;
        cc.Move(moveDirection * moveSpeed * Time.deltaTime);
    }
}
  1. Player Input이 알아서 InputActionReference에 할당된 input action에 플레이어 입력 받아서 값 입력
  2. 할당해놓은 InputActionReference을 읽으면 플레이어가 입력 했는지 안 했는지 알 수 있다

input system에는 누르고 있는 이벤트 없음. update()는 항상 돌려야 함.

isGrounded는 안정적이지 않다고 함

  1. 프레임 타이밍 문제
    Move()를 호출하기 전에는 isGrounded가 이전 프레임 기준 값일 수 있음
  2. 높은 곳에서 떨어지는 중인데 false로 바뀌는 타이밍이 늦거나 애매함
    예: 경사면, 둥근 지형, 모서리 등에선 정확하지 않음
  3. 바닥과 닿아도 움직이지 않으면 감지 안 될 수도 있음
    실제로 Raycast보다 덜 정확한 경우가 존재함


🛠️ R&D


Voxel

https://www.youtube.com/watch?v=EubjobNVJdM&list=PLxI8V1bns4ExV7K6DIrP8BByNSKDCRivo

        public void UploadMesh(bool sharedVertices = false)
        {
            mesh.SetVertices(vertices);
            mesh.SetTriangles(triangles, 0, false);
            mesh.SetUVs(0, UVs);

            mesh.Optimize();

            mesh.RecalculateNormals();

            mesh.RecalculateBounds();

            mesh.UploadMeshData(false);
        }
  • mesh.SetVertices(vertices)

    • vertices 리스트에 저장된 모든 정점(vertex) 데이터를 mesh 객체에 설정합니다.
    • 메시에 대한 정점 배열을 초기화하거나 갱신합니다.
  • mesh.SetTriangles(triangles, 0, false)

    • 삼각형 인덱스 배열(triangles)을 메시에 설정합니다.
    • 0은 서브메시 인덱스(submesh index)를 의미합니다. 여기서는 첫 번째 서브메시를 사용합니다.
    • false는 삼각형 배열을 읽기 전용으로 유지하지 않겠다는 뜻입니다.
  • mesh.SetUVs(0, UVs)

    • UV 맵핑 좌표(UVs)를 메시에 설정합니다.
    • 0은 첫 번째 UV 채널을 사용한다는 의미입니다.
  • mesh.Optimize()

    • 메시에 대해 렌더링 및 메모리 사용 최적화를 수행합니다.
    • 드로우 콜(draw call)을 최적화하고 내부 데이터를 정리합니다.
    • Unity 2020 이후 버전에서는 이 메서드는 Deprecated(사용 중단 예정) 되었고, 대신 MeshUtility.Optimize를 사용하도록 권장합니다.
  • mesh.RecalculateNormals()

    • 정점(vertex)들의 법선 벡터(normals)를 자동으로 재계산합니다.
    • 주로 수동으로 수정된 메시나 노멀 데이터가 없는 메시를 사용할 때 필요합니다.
  • mesh.RecalculateBounds()

    • 메시의 경계 박스(bounds)를 재계산합니다.
    • 정확한 경계 박스는 카메라 클리핑, 광원 계산 등에 필수적입니다.
  • mesh.UploadMeshData(false)

    • CPU 메모리에 있는 메시 데이터를 GPU로 업로드합니다.
    • 매개변수 false는 업로드 후에도 CPU 메모리 상에 데이터를 유지하겠다는 의미입니다.
      • true를 주면 CPU 메모리에서 데이터를 해제하여 메모리를 절약할 수 있으나, 이후 메시 수정이 불가능해집니다.

SetVertices까지만 하면 "어떤 점들이 어디에 있다"는 정보만 메시한테 주는 거다.
하지만 렌더링이 되려면 점만 있어서는 안 된다. 컴퓨터는 "이 점들을 어떻게 이어서 면(face)을 만들고, 빛은 어떻게 반사되고, 물체는 공간 안에서 어디까지 차지하는지"를 알아야 한다.

SetTriangles를 해야 하나?

  • 점만 있으면 그냥 구름처럼 흩어진 포인트밖에 없다.
  • 삼각형(triangles) 은 "이 점, 저 점, 또 다른 점을 연결해서 '면'을 만든다"고 알려주는 데이터다.
  • GPU는 '면'을 기준으로 렌더링하지, '점'을 그냥 그리진 않는다.

SetUVs를 해야 하나?

  • UV는 텍스처(이미지)를 입힐 때 필요하다.
  • "텍스처의 이 부분을 이 면에 매핑해라"는 좌표계다.
  • 안 하면 텍스처가 제대로 입혀지지 않고, 색이나 디테일이 이상하게 보인다.

Optimize를 해야 하나?

  • 최적화를 안 하면, 메시 내부 데이터가 느리거나 비효율적일 수 있다.
  • 꼭 필요한 건 아니지만 성능을 위해 하는 게 좋다. (렌더링 속도, 메모리 사용량 개선)

RecalculateNormals를 해야 하나?

  • 법선(normal)은 "이 면이 어느 방향을 향하고 있는가"를 나타낸다.
  • 광원이 있을 때, 빛이 어떻게 반사되는지 결정하는 데 필요하다.
  • 없으면 조명이 제대로 작동하지 않고 물체가 검게 보이거나 이상하게 빛난다.

RecalculateBounds를 해야 하나?

  • 경계 박스(bounds)는 "이 메시가 어디까지 차지하냐"를 나타낸다.
  • 카메라나 광원, 그림자 시스템은 이 경계박스를 보고 "보여줄지, 아니면 무시할지"를 결정한다.
  • 없으면 메시가 화면에 안 나올 수도 있다.

UploadMeshData를 해야 하나?

  • GPU가 최종적으로 쓸 수 있도록 데이터를 업로드하는 작업이다.
  • 이걸 안 하면 메시가 CPU 쪽에만 남아있고 실제로 렌더링할 때 제대로 쓰이지 않을 수 있다.


🎨 Art Practice : Drawing


  • 테두리 색깔은 무조건 검은색으로 하면 안되고 살짝 연하게
  • 안티앨리어싱은 아예 끄는게 오히려 깔끔


profile
너 정말 **핵심**을 찔렀어

0개의 댓글