[Unity] 고급 주제와 기술 정리

네,가능합니다 ㅣ 2024. 12. 19. 14:33

Unity에서 멀티스레딩 구현 방법

  • Unity는 기본적으로 메인 스레드에서 실행되며, 멀티스레딩은 C# Task, Thread, 또는 Unity의 Job SystemBurst Compiler를 통해 구현할 수 있음.

멀티스레딩 구현 방식:

  1. C# Task:
    • 간단한 비동기 작업에 적합.
    async void Start()
    {
        await Task.Run(() => {
            // 비동기 작업 수행
        });
    }
    
  2. Unity Job System:
    • Unity 엔진과 통합된 고성능 멀티스레딩 도구.
    • 데이터 중심의 작업 분할에 적합함.
    using Unity.Jobs;
    
    struct MyJob : IJob
    {
        public void Execute()
        {
            // 작업 로직
        }
    }
    
    void Start()
    {
        MyJob job = new MyJob();
        JobHandle handle = job.Schedule();
        handle.Complete();
    }
    
  3. Burst Compiler:
    • Unity Job System과 함께 사용하여 CPU 성능을 극대화함.

CPU와 GPU의 작동 차이

  • CPU: 논리 연산과 제어 작업에 최적화된 장치로, 복잡한 작업을 처리함.
  • GPU: 대규모 병렬 연산에 최적화된 장치로, 그래픽 렌더링 및 데이터 병렬 처리를 담당함.
특징 CPU GPU
작업 성격 직렬 연산(순차적) 병렬 연산
용도 게임 로직, AI 처리 렌더링, 대량 데이터 처리
코어 수 적은 수의 고성능 코어 많은 수의 저전력 코어

 

월드 스페이스(World Space)와 로컬 스페이스(Local Space)의 차이

  • 월드 스페이스: 객체가 전체 세계 좌표계에 상대적으로 위치함.
  • 로컬 스페이스: 객체가 부모 객체의 좌표계에 상대적으로 위치함.

차이점:

  • 월드 스페이스는 절대적인 좌표를 사용하며, 씬 전체의 위치를 나타냄.
  • 로컬 스페이스는 객체의 부모-자식 관계를 기반으로 좌표를 나타냄.

예시 코드:

Vector3 worldPosition = transform.position; // 월드 스페이스 위치
Vector3 localPosition = transform.localPosition; // 로컬 스페이스 위치

 

 

벡터의 내적과 외적 사용 상황

  • 내적(Dot Product):
    • 두 벡터의 방향이 얼마나 유사한지 계산.
    • 주로 광원 계산, 시야 체크 등에 사용됨.
    float dot = Vector3.Dot(vectorA, vectorB);
    if (dot > 0) Debug.Log("같은 방향");
    
  • 외적(Cross Product):
    • 두 벡터의 수직 벡터를 계산.
    • 주로 회전 축 계산, 평면 법선 벡터 등에 사용됨.
    Vector3 cross = Vector3.Cross(vectorA, vectorB);
    

쿼터니언을 사용하는 이유

  • **쿼터니언(Quaternion)**은 회전을 나타내는 데이터 구조로, Gimbal Lock 문제를 방지하고 효율적인 회전 연산을 가능하게 함.
  • Unity에서 회전은 Quaternion을 사용하며, EulerAngles와 호환 가능함.

예시 코드:

// 객체를 회전
transform.rotation = Quaternion.Euler(0, 90, 0);

 

 

네트워크 프로토콜(IP, TCP, UDP)

  • IP(Internet Protocol): 데이터를 네트워크를 통해 전달하는 프로토콜.
  • TCP(Transmission Control Protocol): 신뢰성을 보장하는 연결 기반 프로토콜.
  • UDP(User Datagram Protocol): 속도를 우선시하는 비연결형 프로토콜.

TCP와 UDP의 차이:

특징 TCP UDP

연결 연결형 비연결형
신뢰성 보장 보장하지 않음
속도 느림 빠름
사용 예시 파일 전송, 채팅 스트리밍, 실시간 게임

렌더링 파이프라인(Rendering Pipeline)

  • 렌더링 파이프라인은 3D 데이터를 화면에 렌더링하는 과정으로, 주요 단계는 다음과 같음:
    1. Application 단계: 게임 로직 실행.
    2. Geometry 단계: 객체의 변환 및 조명 계산.
    3. Rasterization 단계: 3D 객체를 2D 픽셀로 변환.

3D 오브젝트의 픽셀 표현 과정

  • 모델링: 3D 객체가 폴리곤으로 정의됨.
  • 월드 변환: 객체가 월드 좌표계로 변환됨.
  • 뷰 변환: 카메라 좌표계로 변환됨.
  • 투영 변환: 3D 좌표를 2D 화면으로 변환함.
  • 래스터화(Rasterization): 픽셀로 변환되고 셰이더를 통해 색상 계산.

셰이더를 활용한 경험

  • HLSL 셰이더를 사용하여 스킬 연결 효과를 구현한 적이 있음. 스크립트를 참고하여 아래와 같은 셰이더를 작성함.

코드 설명:

Shader "Custom/SkillConnectionLine"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        _FlowSpeed ("Flow Speed", Float) = 1
        _FlowIntensity ("Flow Intensity", Range(0,1)) = 0.5
        _GlowIntensity ("Glow Intensity", Range(0,2)) = 1
        _IsActive ("Is Active", Float) = 0
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        Blend SrcAlpha OneMinusSrcAlpha
        ZWrite Off
        Cull Off
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float4 color : COLOR;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float4 color : COLOR;
            };

            sampler2D _MainTex;
            float4 _Color;
            float _FlowSpeed;
            float _FlowIntensity;
            float _GlowIntensity;
            float _IsActive;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                o.color = v.color;
                return o;
            }

            float4 frag (v2f i) : SV_Target
            {
                float2 flowUV = i.uv;
                flowUV.x += _Time.y * _FlowSpeed * _IsActive;
                float4 col = tex2D(_MainTex, flowUV) * _Color * i.color;
                if (_IsActive > 0)
                {
                    float flow = sin(flowUV.x * 6.28318 + _Time.y * _FlowSpeed) * 0.5 + 0.5;
                    flow *= _FlowIntensity;
                    float glow = 1 - abs