황현동 블로그 개발, 인생, 유우머

260205 Unity 수학연산 유틸리티 완벽가이드

Tags:

🛠️ 260205 Unity Vector, Matrix, Math 수학 연산 유틸리티 완벽 가이드

Unity에서 제공하는 수학 연산 유틸리티를 체계적으로 정리했습니다. 게임 개발에 필수적인 벡터, 행렬, 수학 함수부터 고급 기능까지 다룹니다.


📚 목차

  1. 전반적인 유틸리티 소개
  2. 필요성
  3. 장단점
  4. Vector 연산 기능
  5. Matrix 연산 기능
  6. Math 연산 기능
  7. 자주 사용하는 기능
  8. 강력한 고급 기능

🧭 1. 전반적인 유틸리티 소개

Unity는 게임 개발에 필요한 다양한 수학 연산 도구를 제공합니다.

🏗️ 수학 유틸리티 전체 구조

┌─────────────────────────────────────────────────────────────────────┐
│                    Unity Math Utilities                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐│
│  │   Vector    │  │   Matrix    │  │  Quaternion │  │    Mathf    ││
│  │  Vector2    │  │  Matrix4x4  │  │  Rotation   │  │  Functions  ││
│  │  Vector3    │  │             │  │  Euler      │  │  Constants  ││
│  │  Vector4    │  │             │  │  Slerp/Lerp │  │             ││
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘│
│                                                                      │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐│
│  │  Geometry   │  │ Interpolation│ │    Color    │  │ Mathematics ││
│  │  Bounds     │  │ AnimationCurve│ │   Gradient │  │  (Package)  ││
│  │  Ray/Plane  │  │ Lerp/SmoothDamp│ │            │  │  float4/int4││
│  │  Collider   │  │              │  │             │  │  SIMD/Burst ││
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────────┘│
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

🔹 주요 네임스페이스

네임스페이스 설명
UnityEngine Vector2/3/4, Matrix4x4, Quaternion, Mathf 등 기본 타입
Unity.Mathematics SIMD 최적화 수학 라이브러리 (float4, int4 등)
System Math 클래스 (double 정밀도)

🎯 2. 필요성

🧠 게임 개발에서 수학이 필요한 영역

┌────────────────────────────────────────────────────────────────┐
│                      게임 개발 수학 활용                        │
├────────────────────────────────────────────────────────────────┤
│                                                                 │
│   [이동/물리]          [카메라]           [AI]                 │
│   ├─ 속도 계산         ├─ 뷰 행렬         ├─ 경로 탐색         │
│   ├─ 충돌 감지         ├─ 투영 행렬       ├─ 시야 범위         │
│   ├─ 중력/힘 적용      ├─ 프러스텀 컬링   └─ 거리 계산         │
│   └─ 궤적 예측         └─ 스크린 좌표                          │
│                                                                 │
│   [애니메이션]         [렌더링]           [UI]                  │
│   ├─ 보간 (Lerp)       ├─ 조명 계산       ├─ 레이아웃          │
│   ├─ 곡선 (Curve)      ├─ 노말 벡터       ├─ 앵커 포인트       │
│   └─ 블렌딩            └─ UV 매핑         └─ 스케일링          │
│                                                                 │
└────────────────────────────────────────────────────────────────┘

🎯 왜 Unity 내장 수학 도구를 사용해야 하는가?

  1. 성능 최적화: Native 코드로 구현되어 순수 C# 보다 빠름
  2. GPU 친화적: 쉐이더와 동일한 수학 모델 사용
  3. 정밀도 보장: 게임에 최적화된 float 정밀도
  4. 편의성: 자주 쓰는 연산이 이미 구현되어 있음

⚠️ 3. 장단점

🧠 Unity 기본 수학 라이브러리

구분 내용
장점  
✅ 사용 편의성 직관적인 API, 풍부한 문서
✅ 에디터 통합 Inspector에서 직접 편집 가능
✅ 범용성 대부분의 게임 개발 요구 충족
✅ 안정성 오랜 기간 검증된 코드
단점  
❌ SIMD 미지원 Vector3 등은 자동 SIMD 최적화 안됨
❌ Burst 비호환 기본 타입은 Burst 컴파일러 최적화 제한
❌ GC 발생 가능 일부 연산에서 힙 할당 발생

🔹 Unity.Mathematics 패키지

구분 내용
장점  
✅ SIMD 최적화 하드웨어 벡터 명령어 직접 활용
✅ Burst 완벽 호환 8-17% 추가 성능 향상
✅ 쉐이더 친화적 HLSL/GLSL과 동일한 API
✅ 제로 GC 모든 타입이 구조체
단점  
❌ 학습 곡선 새로운 API 학습 필요
❌ 에디터 지원 부족 Inspector 표시 불편
❌ 추가 패키지 Package Manager 설치 필요

⚡ 성능 비교

┌────────────────────────────────────────────────────────────────┐
│  성능 비교 (상대적 속도, 높을수록 좋음)                         │
├────────────────────────────────────────────────────────────────┤
│                                                                 │
│  순수 C# Math          ████████░░░░░░░░░░░░░░░░░░░░  (기준)    │
│  UnityEngine.Vector3   ██████████████░░░░░░░░░░░░░░  (+40%)    │
│  Unity.Mathematics     ████████████████░░░░░░░░░░░░  (+60%)    │
│  Mathematics + Burst   ██████████████████████████░░  (+200%)   │
│                                                                 │
└────────────────────────────────────────────────────────────────┘

📌 4. Vector 연산 기능

🧭 Vector 타입 개요

┌─────────────────────────────────────────────────────────────────┐
│  Vector Types                                                    │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Vector2 (x, y)                                                  │
│  ├─ 2D 위치, 방향                                               │
│  ├─ 텍스처 좌표 (UV)                                            │
│  └─ UI 좌표                                                      │
│                                                                  │
│  Vector3 (x, y, z)           [가장 많이 사용]                   │
│  ├─ 3D 위치, 방향                                               │
│  ├─ 회전 (오일러 각)                                            │
│  └─ 스케일                                                       │
│                                                                  │
│  Vector4 (x, y, z, w)                                           │
│  ├─ 동차 좌표계 (Homogeneous)                                   │
│  ├─ 쉐이더 파라미터                                             │
│  └─ 메쉬 탄젠트                                                  │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

🏗️ 중요: Vector는 구조체(Struct)

// Vector3는 값 타입 - 힙 할당 없음
Vector3 pos = new Vector3(1, 2, 3);  // 스택에 저장
Vector3 copy = pos;                   // 값 복사 (참조 아님)
copy.x = 10;                          // pos.x는 여전히 1

🔹 주요 정적 프로퍼티

// 방향 벡터 (정규화됨)
Vector3.up       // (0, 1, 0)
Vector3.down     // (0, -1, 0)
Vector3.left     // (-1, 0, 0)
Vector3.right    // (1, 0, 0)
Vector3.forward  // (0, 0, 1)
Vector3.back     // (0, 0, -1)

// 특수 벡터
Vector3.zero     // (0, 0, 0)
Vector3.one      // (1, 1, 1)

// Vector2 전용
Vector2.positiveInfinity  // (∞, ∞)
Vector2.negativeInfinity  // (-∞, -∞)

🔹 핵심 연산

▫️ 크기와 정규화

Vector3 v = new Vector3(3, 4, 0);

// 크기 (길이)
float mag = v.magnitude;           // 5.0 (√(3² + 4²))
float sqrMag = v.sqrMagnitude;     // 25.0 (제곱근 생략 - 더 빠름)

// 정규화 (단위 벡터로 변환)
Vector3 dir = v.normalized;        // (0.6, 0.8, 0) - 길이 1
v.Normalize();                     // 원본 수정

▫️ 거리 계산

Vector3 a = new Vector3(0, 0, 0);
Vector3 b = new Vector3(3, 4, 0);

float dist = Vector3.Distance(a, b);  // 5.0

// 성능 팁: 거리 비교 시 sqrMagnitude 사용
float threshold = 10f;
if ((b - a).sqrMagnitude < threshold * threshold)  // 제곱근 계산 생략
{
    // 범위 내
}

▫️ 내적 (Dot Product)

        B
       /
      / θ
     /_____ A

    A · B = |A| × |B| × cos(θ)
    정규화된 벡터: A · B = cos(θ)
Vector3 forward = transform.forward;
Vector3 toTarget = (target.position - transform.position).normalized;

float dot = Vector3.Dot(forward, toTarget);

// dot > 0  → 전방 (0~90도)
// dot = 0  → 직각 (90도)
// dot < 0  → 후방 (90~180도)
// dot = 1  → 정확히 같은 방향
// dot = -1 → 정반대 방향

// 활용: 시야 범위 체크
if (dot > 0.5f)  // cos(60°) = 0.5 → 전방 60도 이내
{
    // 타겟이 시야 내에 있음
}

▫️ 외적 (Cross Product)

        C = A × B
        ↑
        │
        │  B
        │ /
        │/_____ A

    결과 C는 A와 B 모두에 수직
Vector3 a = Vector3.right;    // (1, 0, 0)
Vector3 b = Vector3.forward;  // (0, 0, 1)

Vector3 c = Vector3.Cross(a, b);  // (0, 1, 0) = up

// 활용: 법선 벡터 계산
Vector3 edge1 = p2 - p1;
Vector3 edge2 = p3 - p1;
Vector3 normal = Vector3.Cross(edge1, edge2).normalized;

// 활용: 회전 방향 판단 (왼손/오른손 법칙)

▫️ 각도 계산

Vector3 from = transform.forward;
Vector3 to = (target.position - transform.position).normalized;

// 0~180도 사이 각도 반환
float angle = Vector3.Angle(from, to);

// 부호 있는 각도 (-180 ~ 180)
float signedAngle = Vector3.SignedAngle(from, to, Vector3.up);

▫️ 투영 (Projection)

        B
       /│
      / │
     /  │ Proj
    /   │
   A────┴────→

   Proj = A 방향으로 B를 투영한 벡터
Vector3 a = new Vector3(3, 0, 0);  // 투영할 축
Vector3 b = new Vector3(2, 2, 0);  // 원본 벡터

// a 방향으로 b 투영
Vector3 proj = Vector3.Project(b, a);  // (2, 0, 0)

// 평면에 투영 (법선 방향 성분 제거)
Vector3 planeNormal = Vector3.up;
Vector3 projOnPlane = Vector3.ProjectOnPlane(b, planeNormal);  // (2, 0, 0)

▫️ 반사 (Reflect)

// 거울 반사
Vector3 inDirection = new Vector3(1, -1, 0).normalized;
Vector3 normal = Vector3.up;

Vector3 reflected = Vector3.Reflect(inDirection, normal);
// 입사각 = 반사각

🔹 벡터 타입 변환

// Vector2 ↔ Vector3 (암시적 변환)
Vector2 v2 = new Vector2(1, 2);
Vector3 v3 = v2;        // (1, 2, 0) - z는 0
Vector2 back = v3;      // (1, 2) - z 버려짐

// Vector3 → Vector4
Vector4 v4 = new Vector4(v3.x, v3.y, v3.z, 1f);

// 명시적 변환
Vector3 explicit3 = (Vector3)v4;  // w 버려짐

📌 5. Matrix 연산 기능

🏗️ Matrix4x4 구조

┌─────────────────────────────────────────────────────────────────┐
│  Matrix4x4 (4x4 행렬) - Column Major                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌─────────────────────────────────────────────────────┐        │
│  │  m00  m01  m02  m03  │   [X축]  [Y축]  [Z축]  [위치] │        │
│  │  m10  m11  m12  m13  │                               │        │
│  │  m20  m21  m22  m23  │                               │        │
│  │  m30  m31  m32  m33  │   [0]    [0]    [0]    [1]    │        │
│  └─────────────────────────────────────────────────────┘        │
│                                                                  │
│  Column 0-2: 회전/스케일 (3x3 부분행렬)                         │
│  Column 3: 이동 (Translation)                                   │
│  Row 3: 동차 좌표 (보통 0,0,0,1)                                │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

🔹 변환 행렬 생성

// 개별 변환 행렬
Matrix4x4 translateMat = Matrix4x4.Translate(new Vector3(10, 0, 5));
Matrix4x4 rotateMat = Matrix4x4.Rotate(Quaternion.Euler(0, 45, 0));
Matrix4x4 scaleMat = Matrix4x4.Scale(new Vector3(2, 2, 2));

// TRS: 이동, 회전, 스케일을 한번에
Matrix4x4 trs = Matrix4x4.TRS(
    position,           // Vector3
    rotation,           // Quaternion
    scale               // Vector3
);

// 단위 행렬
Matrix4x4 identity = Matrix4x4.identity;

🔹 행렬 연산

// 행렬 곱 (변환 결합)
Matrix4x4 combined = translateMat * rotateMat * scaleMat;
// 적용 순서: Scale → Rotate → Translate (오른쪽에서 왼쪽)

// 역행렬
Matrix4x4 inverse = combined.inverse;

// 전치 행렬
Matrix4x4 transposed = combined.transpose;

// 행렬식 (Determinant)
float det = combined.determinant;

🔹 점/벡터 변환

Matrix4x4 mat = Matrix4x4.TRS(pos, rot, scale);

// 점 변환 (위치 - w=1로 취급)
Vector3 worldPoint = mat.MultiplyPoint(localPoint);

// 점 변환 (3x4 연산 - 더 빠름, 투영 없을 때)
Vector3 worldPointFast = mat.MultiplyPoint3x4(localPoint);

// 벡터 변환 (방향 - w=0으로 취급, 이동 무시)
Vector3 worldDir = mat.MultiplyVector(localDir);

🔹 Transform과 Matrix4x4

// Transform → Matrix4x4
Matrix4x4 localToWorld = transform.localToWorldMatrix;
Matrix4x4 worldToLocal = transform.worldToLocalMatrix;

// 좌표 변환
Vector3 worldPos = localToWorld.MultiplyPoint3x4(localPos);
Vector3 localPos = worldToLocal.MultiplyPoint3x4(worldPos);

// Matrix4x4 → Transform 분해
Vector3 position = matrix.GetColumn(3);
Quaternion rotation = matrix.rotation;
Vector3 scale = matrix.lossyScale;

🔹 뷰/투영 행렬

// 카메라 행렬
Camera cam = Camera.main;
Matrix4x4 viewMat = cam.worldToCameraMatrix;
Matrix4x4 projMat = cam.projectionMatrix;

// 커스텀 투영 행렬
Matrix4x4 ortho = Matrix4x4.Ortho(left, right, bottom, top, near, far);
Matrix4x4 persp = Matrix4x4.Perspective(fov, aspect, near, far);

// LookAt 행렬 생성
Matrix4x4 lookAt = Matrix4x4.LookAt(eyePos, targetPos, upDir);

📌 6. Math 연산 기능

🧭 Mathf 클래스 개요

UnityEngine.Mathf는 게임 개발에 필요한 수학 함수들을 제공합니다. 모든 함수가 float 타입으로 최적화되어 있습니다.

🔹 상수

Mathf.PI           // 3.14159265359...
Mathf.Deg2Rad      // PI / 180 (도→라디안)
Mathf.Rad2Deg      // 180 / PI (라디안→도)
Mathf.Epsilon      // 가장 작은 float 값
Mathf.Infinity     // 양의 무한대
Mathf.NegativeInfinity  // 음의 무한대

🧠 기본 수학 함수

// 절대값, 부호
Mathf.Abs(-5f);        // 5
Mathf.Sign(-5f);       // -1 (음수:-1, 0:0, 양수:1)

// 최대/최소
Mathf.Min(3f, 7f);     // 3
Mathf.Max(3f, 7f);     // 7
Mathf.Min(1f, 2f, 3f); // 1 (여러 개 가능)

// 반올림
Mathf.Round(2.5f);     // 2 (Banker's rounding)
Mathf.Floor(2.9f);     // 2 (내림)
Mathf.Ceil(2.1f);      // 3 (올림)
Mathf.RoundToInt(2.7f);// 3

// 제곱/루트
Mathf.Pow(2f, 3f);     // 8 (2³)
Mathf.Sqrt(16f);       // 4
Mathf.Exp(1f);         // e¹ ≈ 2.718
Mathf.Log(10f);        // ln(10) ≈ 2.303
Mathf.Log10(100f);     // 2

🔹 삼각함수

// 모든 각도는 라디안!
float rad = 45f * Mathf.Deg2Rad;

Mathf.Sin(rad);        // 0.707...
Mathf.Cos(rad);        // 0.707...
Mathf.Tan(rad);        // 1

// 역삼각함수 (결과는 라디안)
Mathf.Asin(0.5f);      // 0.524... (≈30°)
Mathf.Acos(0.5f);      // 1.047... (≈60°)
Mathf.Atan(1f);        // 0.785... (45°)

// Atan2: 사분면 고려한 각도 계산
float angle = Mathf.Atan2(y, x) * Mathf.Rad2Deg;

🔹 클램핑과 범위

// 범위 제한
Mathf.Clamp(value, 0f, 100f);    // value를 0~100 사이로
Mathf.Clamp01(1.5f);             // 0~1 사이로 (결과: 1)

// 범위 매핑 (정규화)
float t = Mathf.InverseLerp(0f, 100f, 75f);  // 0.75 (75는 0~100의 75%)

// 0~1 사이 체크
bool inRange = (value >= 0f && value <= 1f);

🔹 보간 (Interpolation)

┌─────────────────────────────────────────────────────────────────┐
│  보간 함수 비교                                                  │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Lerp (선형)                                                     │
│  ────────────────────────────→                                  │
│  시작 ──────────────────────→ 끝                                │
│       일정한 속도                                                │
│                                                                  │
│  SmoothStep (부드러운 S커브)                                    │
│         ╭──────────╮                                            │
│        ╱            ╲                                           │
│  시작 ╱              ╲ 끝                                       │
│       천천히→빠르게→천천히                                       │
│                                                                  │
│  SmoothDamp (물리적 감속)                                       │
│  ────────╲                                                      │
│           ╲─────╲                                               │
│                  ╲────→ 목표                                    │
│       관성, 오버슈트 방지                                        │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘
// 선형 보간
float a = 0f, b = 100f, t = 0.5f;
float result = Mathf.Lerp(a, b, t);  // 50

// t는 0~1 범위, 초과해도 됨
Mathf.LerpUnclamped(a, b, 1.5f);     // 150

// 각도 보간 (0-360 wrap around 처리)
float angle = Mathf.LerpAngle(350f, 10f, 0.5f);  // 0 (또는 360)

// 부드러운 보간
float smooth = Mathf.SmoothStep(0f, 1f, t);  // S커브

// 프레임 독립적 부드러운 이동
float velocity = 0f;
float current = Mathf.SmoothDamp(
    current,           // 현재 값
    target,            // 목표 값
    ref velocity,      // 속도 (참조)
    smoothTime,        // 목표 도달 시간
    maxSpeed,          // 최대 속도 (선택)
    Time.deltaTime     // 델타 타임
);

🔹 목표값으로 이동

// 일정 속도로 이동
float current = Mathf.MoveTowards(current, target, speed * Time.deltaTime);

// 각도 이동 (wrap around 처리)
float angle = Mathf.MoveTowardsAngle(current, target, speed * Time.deltaTime);

🔹 각도 유틸리티

// 각도 차이 (-180 ~ 180)
float delta = Mathf.DeltaAngle(30f, 350f);  // -40 (350에서 30까지 최단)

// 각도 반복 (0 ~ 360 사이로)
float wrapped = Mathf.Repeat(angle, 360f);

// 핑퐁 (왕복)
float ping = Mathf.PingPong(Time.time, 1f);  // 0→1→0→1 반복

🔹 노이즈와 랜덤

// 펄린 노이즈 (0~1)
float noise = Mathf.PerlinNoise(x, y);

// 2D 노이즈 예시 (지형 생성)
float height = Mathf.PerlinNoise(worldX * 0.1f, worldZ * 0.1f) * maxHeight;

⚖️ 근사 비교

// float 비교 (부동소수점 오차 고려)
bool isEqual = Mathf.Approximately(a, b);

// 직접 비교 (권장하지 않음)
// if (a == b)  // 위험!

📌 7. 자주 사용하는 기능

🔹 Quaternion (회전)

⚖️ 오일러 각 vs 쿼터니언

┌─────────────────────────────────────────────────────────────────┐
│  회전 표현 방식 비교                                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Euler Angles (오일러 각)                                       │
│  ├─ (x, y, z) = (pitch, yaw, roll)                              │
│  ├─ 직관적이고 이해하기 쉬움                                    │
│  └─ ⚠️ 짐벌락(Gimbal Lock) 문제 발생 가능                      │
│                                                                  │
│  Quaternion (쿼터니언)                                          │
│  ├─ (x, y, z, w) 4개 요소                                       │
│  ├─ 짐벌락 없음                                                 │
│  ├─ 부드러운 보간 가능                                          │
│  └─ ⚠️ 직관적 이해 어려움                                       │
│                                                                  │
│  ✅ Unity 권장: 내부적으로 Quaternion 사용                      │
│     Euler는 입출력 시에만 사용                                   │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

▫️ 주요 Quaternion 연산

// 생성
Quaternion.identity;                    // 회전 없음
Quaternion.Euler(0, 90, 0);            // 오일러 각에서 생성
Quaternion.AngleAxis(90f, Vector3.up);  // 축-각도에서 생성

// 방향 벡터에서 회전 생성
Quaternion.LookRotation(forward);       // forward 방향을 바라보는 회전
Quaternion.LookRotation(forward, up);   // up 벡터 지정

// 두 방향 사이 회전
Quaternion.FromToRotation(fromDir, toDir);

// 보간
Quaternion.Lerp(a, b, t);   // 선형 보간 (빠름, 일정 속도 아님)
Quaternion.Slerp(a, b, t);  // 구면 선형 보간 (권장, 일정 속도)

// 회전 적용
Vector3 rotatedDir = rotation * direction;  // 벡터 회전
Quaternion combined = rot1 * rot2;          // 회전 결합

// 역회전
Quaternion inverse = Quaternion.Inverse(rotation);

// 각도 계산
float angle = Quaternion.Angle(a, b);

// 오일러 각으로 변환
Vector3 euler = rotation.eulerAngles;

🔹 Bounds (경계 상자)

// AABB (Axis-Aligned Bounding Box)
Bounds bounds = renderer.bounds;  // 월드 공간
Bounds localBounds = mesh.bounds; // 로컬 공간

// 속성
Vector3 center = bounds.center;
Vector3 size = bounds.size;       // 전체 크기
Vector3 extents = bounds.extents; // 반 크기 (size/2)
Vector3 min = bounds.min;         // 최소 코너
Vector3 max = bounds.max;         // 최대 코너

// 포함 여부
bool contains = bounds.Contains(point);

// 교차 검사
bool intersects = bounds.Intersects(otherBounds);

// Ray 교차
float distance;
bool hit = bounds.IntersectRay(ray, out distance);

// 확장
bounds.Encapsulate(point);        // 점을 포함하도록 확장
bounds.Encapsulate(otherBounds);  // 다른 Bounds 포함
bounds.Expand(1f);                // 모든 방향으로 확장

🔹 Ray와 Plane

// Ray (광선)
Ray ray = new Ray(origin, direction);
Ray cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition);

// Plane (무한 평면)
Plane plane = new Plane(normal, point);
Plane groundPlane = new Plane(Vector3.up, 0f);  // y=0 평면

// Ray-Plane 교차
float enter;
if (plane.Raycast(ray, out enter))
{
    Vector3 hitPoint = ray.GetPoint(enter);
}

// 점과 평면 거리
float distance = plane.GetDistanceToPoint(point);
bool isAbove = plane.GetSide(point);  // 평면 앞쪽이면 true

🔹 Color 연산

// Color 생성
Color red = Color.red;
Color custom = new Color(0.5f, 0.5f, 0.5f, 1f);  // RGBA (0~1)
Color32 byte32 = new Color32(128, 128, 128, 255); // RGBA (0~255)

// HSV 변환
Color.RGBToHSV(color, out h, out s, out v);
Color fromHSV = Color.HSVToRGB(h, s, v);

// 보간
Color lerped = Color.Lerp(colorA, colorB, t);

// 연산
Color brighter = color * 1.5f;
Color blended = color1 + color2;

// 감마/선형
Color linear = color.linear;
Color gamma = color.gamma;

🔹 Gradient (그라디언트)

// 코드에서 Gradient 생성
Gradient gradient = new Gradient();
gradient.SetKeys(
    new GradientColorKey[] {
        new GradientColorKey(Color.red, 0f),
        new GradientColorKey(Color.blue, 1f)
    },
    new GradientAlphaKey[] {
        new GradientAlphaKey(1f, 0f),
        new GradientAlphaKey(0f, 1f)
    }
);

// 값 평가
Color colorAtTime = gradient.Evaluate(0.5f);  // t=0.5 위치의 색상

🔹 AnimationCurve

// 기본 커브
AnimationCurve linear = AnimationCurve.Linear(0, 0, 1, 1);
AnimationCurve easeInOut = AnimationCurve.EaseInOut(0, 0, 1, 1);

// 커스텀 커브
AnimationCurve curve = new AnimationCurve();
curve.AddKey(0f, 0f);
curve.AddKey(0.5f, 1.5f);  // 오버슈트
curve.AddKey(1f, 1f);

// 값 평가
float value = curve.Evaluate(0.5f);

// Inspector에서 편집 가능
[SerializeField] AnimationCurve _jumpCurve;

📌 8. 강력한 고급 기능

🔹 Unity.Mathematics 패키지

DOTS/Burst 컴파일러와 함께 사용하면 극대화된 성능을 얻을 수 있습니다.

using Unity.Mathematics;
using static Unity.Mathematics.math;

// 타입 (소문자)
float3 pos = new float3(1, 2, 3);
float4 color = new float4(1, 0, 0, 1);
float4x4 matrix = float4x4.identity;
quaternion rot = quaternion.Euler(0, radians(90), 0);

// SIMD 최적화 연산
float3 result = normalize(cross(a, b));
float d = dot(a, b);
float len = length(a);

// 다양한 수학 함수
float s = sin(angle);
float c = cos(angle);
float3 clamped = clamp(value, min, max);
float3 lerped = lerp(a, b, t);

// 노이즈
float n = noise.cnoise(pos.xy);       // Classic Perlin
float sn = noise.snoise(pos.xyz);     // Simplex
float cn = noise.cellular(pos.xy).x;  // Cellular/Worley

⚡ SIMD 성능 비교

┌─────────────────────────────────────────────────────────────────┐
│  SIMD 연산 비교                                                  │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  일반 연산 (스칼라)                                             │
│  ┌───┐ ┌───┐ ┌───┐ ┌───┐                                       │
│  │ a │ │ b │ │ c │ │ d │  ← 4개 float 개별 연산               │
│  └─┬─┘ └─┬─┘ └─┬─┘ └─┬─┘                                       │
│    ↓     ↓     ↓     ↓     4번의 연산                          │
│  ┌───┐ ┌───┐ ┌───┐ ┌───┐                                       │
│  │ A │ │ B │ │ C │ │ D │                                       │
│  └───┘ └───┘ └───┘ └───┘                                       │
│                                                                  │
│  SIMD 연산 (float4)                                             │
│  ┌───────────────────┐                                          │
│  │  a   b   c   d    │  ← 4개 float를 하나의 레지스터로        │
│  └─────────┬─────────┘                                          │
│            ↓           1번의 연산                               │
│  ┌───────────────────┐                                          │
│  │  A   B   C   D    │                                          │
│  └───────────────────┘                                          │
│                                                                  │
│  → 이론상 4배 빠름 (실제 2~3배)                                 │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

🔹 GeometryUtility

// 프러스텀 컬링 (카메라 시야 내 체크)
Plane[] frustumPlanes = GeometryUtility.CalculateFrustumPlanes(camera);
bool isVisible = GeometryUtility.TestPlanesAABB(frustumPlanes, bounds);

// 바운딩 박스 계산
Bounds bounds = GeometryUtility.CalculateBounds(points, matrix);

🧠 수학적 유틸리티 함수들

// 베지어 커브 (직접 구현 필요)
Vector3 QuadraticBezier(Vector3 p0, Vector3 p1, Vector3 p2, float t)
{
    float u = 1 - t;
    return u * u * p0 + 2 * u * t * p1 + t * t * p2;
}

Vector3 CubicBezier(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
{
    float u = 1 - t;
    return u*u*u*p0 + 3*u*u*t*p1 + 3*u*t*t*p2 + t*t*t*p3;
}

// Catmull-Rom 스플라인
Vector3 CatmullRom(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
{
    float t2 = t * t;
    float t3 = t2 * t;
    return 0.5f * (
        (2 * p1) +
        (-p0 + p2) * t +
        (2*p0 - 5*p1 + 4*p2 - p3) * t2 +
        (-p0 + 3*p1 - 3*p2 + p3) * t3
    );
}

// 원 위의 점 계산
Vector3 PointOnCircle(Vector3 center, float radius, float angleDeg)
{
    float rad = angleDeg * Mathf.Deg2Rad;
    return center + new Vector3(
        Mathf.Cos(rad) * radius,
        0,
        Mathf.Sin(rad) * radius
    );
}

// 구 위의 점 계산 (구면 좌표)
Vector3 PointOnSphere(Vector3 center, float radius, float theta, float phi)
{
    return center + new Vector3(
        radius * Mathf.Sin(theta) * Mathf.Cos(phi),
        radius * Mathf.Cos(theta),
        radius * Mathf.Sin(theta) * Mathf.Sin(phi)
    );
}

🔹 Random 유틸리티

// UnityEngine.Random
Random.Range(0, 10);           // int: 0~9 (max 제외)
Random.Range(0f, 10f);         // float: 0~10 (max 포함)
Random.value;                  // 0~1
Random.insideUnitSphere;       // 구 내부 랜덤 점
Random.insideUnitCircle;       // 원 내부 랜덤 점
Random.onUnitSphere;           // 구 표면 랜덤 점
Random.rotation;               // 랜덤 회전
Random.ColorHSV();             // 랜덤 색상

// 시드 설정
Random.InitState(12345);

// Unity.Mathematics.Random (Burst 호환)
Unity.Mathematics.Random rng = new Unity.Mathematics.Random(seed);
float3 randDir = rng.NextFloat3Direction();

⚡ 성능 최적화 팁 요약

┌─────────────────────────────────────────────────────────────────┐
│  수학 연산 성능 최적화 체크리스트                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ✅ 거리 비교 시 sqrMagnitude 사용 (제곱근 회피)               │
│  ✅ 내적은 정규화된 벡터로 계산                                 │
│  ✅ MultiplyPoint3x4 사용 (투영 필요 없을 때)                   │
│  ✅ Quaternion.Slerp 대신 Lerp (속도 중요시)                    │
│  ✅ 매 프레임 행렬 생성 피하기 (캐싱)                           │
│  ✅ DOTS/Burst 환경에서 Unity.Mathematics 사용                  │
│  ✅ float4 타입 선호 (SIMD 최적화)                              │
│  ✅ Mathf.Approximately로 float 비교                            │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

🔗 참고 자료

🔹 Unity 공식 문서

🔹 Unity.Mathematics

🔹 튜토리얼 및 블로그

🧪 소스 코드 참조


작성일: 2026-02-05