Unity 최적화 팁

Unity 인디 개발사뿐만 아니라 대기업에서도 인기가 높은 게임 엔진입니다.

사용자 친화적인 인터페이스, 강력한 렌더링 파이프라인, 사용하기 쉬운 구성 요소 시스템을 갖추고 있으며 마지막으로 다양한 플랫폼을 지원합니다.

그러나 사용하기 쉬운 인터페이스를 사용하면 게임을 지나치게 복잡하게 만들기가 훨씬 더 쉽기 때문에(예: 배치 불필요한 개체를 많이 배치하는 등) 최적화를 갖는 것이 중요합니다. 개발 과정 전반에 걸쳐 염두에 두어야 합니다.

다음은 게임 성능을 향상시키는 데 도움이 되는 3가지 주요 범주(렌더링, 스크립팅,오디오)에 대한 중요한 팁입니다.

표현

팁 1: 렌더러 구성 요소가 포함된 개체의 크기를 조정하지 않은 상태로 유지

크기 조정되지 않은 개체는 크기가 (1, 1, 1)인 개체입니다. 이 경우 Unity은 각 프레임에서 개체의 크기를 조정하기 위해 추가 계산을 수행할 필요가 없습니다.

예: 레벨에 비해 너무 크거나 작은 집 모델이 있다고 가정해 보겠습니다. 자연스러운 일은 다음과 같이 크기를 조정하는 것입니다.

건물 크기 조정

대부분의 경우 장면 뷰에서 개체의 크기를 조정하는 것이 좋지만 해당 개체의 복제 인스턴스를 많이 만들 계획이라면 가져오기 설정에서 크기를 변경하는 것이 좋습니다.

가장 먼저 해야 할 일은 필요에 맞을 때까지 모델의 크기를 조정하는 것입니다(예: 위의 건물은 (1, 1, 1)에서 (0.49482, 0.49482, 0.49482)로 크기가 조정되었습니다). 그런 다음 프로젝트에서 모델을 선택합니다. 보기를 클릭하고 가져오기 설정에서 배율 인수(보통 1 또는 0.1)를 확인하세요.

기본 배율 인수에 새 배율을 곱한 값(제 경우에는 1 x 0.49482 = 0.49482)과 같아야 하는 새 값을 설정한 다음 적용을 누릅니다. 이제 장면 보기의 모델로 돌아가서 배율을 다시 (1, 1, 1)로 설정합니다.

Unity 3D 스케일 팩터 설정

이제 기본(1, 1, 1) 배율을 유지하면서 필요한 방식으로 개체의 배율이 조정됩니다.

이 팁은 SkinnedMeshRenderer를 사용하는 애니메이션 개체에 특히 중요합니다. 이 구성 요소는 렌더링하는 데 더 많은 비용이 들고 (1, 1, 1)의 배율을 사용하면 렌더링 프로세스가 단순화되기 때문입니다.

팁 2: 조명을 최대한 적게 사용하세요

Unity에는 3가지 유형의 조명이 있습니다(방향 조명, 포인트 조명, 스포트라이트). 성능 측면에서 보면 방향성 조명이 렌더링에 가장 저렴하고 그 다음이 포인트, 마지막으로 스포트라이트입니다.

일반적으로 장면당 방향성 조명이 1개 이상 있는 것을 원하지 않으며 스폿 및 포인트 조명의 경우 가능한 적은 수(또는 전혀 포함하지 않음)를 사용합니다.

실시간 그림자의 경우 게임의 시각적 측면을 향상시키지만 고성능 오버헤드가 있으므로 일반적으로 비활성화하거나 라이트맵라이트에 굽는 것이 좋습니다. 프로브.

팁 3: 투명 셰이더를 주의해서 사용하세요

투명해야 하는 표면(예: 울타리, 연기 입자 등)에만 투명 또는 파티클 셰이더를 사용하세요.

투명도가 있는 개체에는 특히 모바일이나 웹과 같이 리소스가 제한된 플랫폼에서 성능을 저하시킬 수 있는 추가 렌더링 패스가 필요합니다.

스크립팅

팁 1: 항상 구성 요소 참조를 캐시하세요.

업데이트할 때마다 구성 요소 참조에 액세스하려면 항상 구성 요소 참조를 캐시해야 합니다.

예를 들어 아래 스크립트를 확인하세요.

나쁜

using UnityEngine;

public class Script1 : MonoBehaviour
{
    float someValue = 0;

    // Update is called once per frame
    void Update()
    {
        someValue = GetComponent<Script2>().someValue2;
    }
}

여기에는 Script2에서 변수 "someValue2"을 가져와 이를 지역 변수에 할당하는 Script1이 있습니다.

이제 각 프레임마다 GetComponent 하나만 호출해도 성능에 아무런 영향을 미치지 않습니다. 그러나 자주 사용되는 구성 요소를 캐싱하는 습관을 들여야 합니다.

스크립트에서 구성요소를 캐시하는 방법에는 두 가지가 있습니다. 공용 변수를 생성하여 Inspector 보기에서 할당하거나, 전용 변수를 생성하고 Start 또는 Awake에서 할당하는 것입니다. 아래 예를 확인하세요.

좋은

using UnityEngine;

public class Script1 : MonoBehaviour
{

    float someValue = 0;

    Script2 script2Cached;

    // Use this for initialization
    void Start()
    {
        script2Cached = GetComponent<Script2>();
    }

    // Update is called once per frame
    void Update()
    {
        someValue = script2Cached.someValue2;
    }
}

훨씬 더 나은 점은 이제 성능 오버헤드 없이 각 업데이트에 Script2에 액세스할 수 있다는 것입니다.

BoxCollider, Rigidbody 등과 같은 내장 구성 요소에 대해서도 동일한 작업을 수행합니다. (Transform 및 GameObject를 제외하고 이러한 구성 요소는 기본적으로 이미 캐시되어 있으므로 즉시 액세스할 수 있습니다.)

팁 2: SendMessage를 주의해서 사용하세요

SendMessage를 사용하면 게임 개체에 연결된 모든 MonoBehaviour에서 특정 함수(존재하는 경우)를 호출할 수 있습니다.

예를 들어, 게임에서 무기를 쏠 때 총알이 적에게 닿으면 GetComponent 및 기타 추가 기능을 사용할 필요 없이 빠르게 피해를 입힐 수 있습니다.

그러나 이 메서드는 계산 집약적이므로 너무 자주 호출하면 안 됩니다.

팁 3: GameObject.Find 및 GameObject.FindWithTag를 주의해서 사용하세요.

GameObject.Find, GameObject.FindWithTagGameObject.FindGameObjectsWithTag를 사용하면 장면에서 개체를 빠르게 검색할 수 있습니다. 이러한 메서드는 GetComponent보다 훨씬 느리므로 초기화 중에만 사용해야 합니다.

팁 4: OnGUI 사용을 피하세요

역사적으로 OnGUI는 Unity에서 메뉴를 만드는 유일한 방법이었습니다. 그러나 그 이후로 성능 측면에서 훨씬 더 좋고 더 많은 기능을 제공하는 UI Canvas라는 대안이 추가되었습니다.

그럼에도 불구하고 OnGUI는 여전히 Unity에서 UI를 만드는 실행 가능한 방법으로 남아 있으며 꼭 사용해야 하는 경우 OnGUI는 프레임당 최소 두 번(업데이트 및 LateUpdate의 두 배) 호출된다는 점을 명심하세요. UI 이외의 계산에 사용하세요.

당신이 할 수 있는 한 가지는 OnGUI만 포함하고 필요할 때 활성화/비활성화하는 별도의 스크립트를 갖는 것입니다.

예를 들어:

UIScript.cs

using UnityEngine;

public class UIScript : MonoBehaviour {

    void OnGUI()
    {
        if(GUI.Button(new Rect(5, 5, 125, 25), "Button 1"))
        {
            //Button 1 was pressed, Do Something
        }
        if (GUI.Button(new Rect(140, 5, 125, 25), "Button 2"))
        {
            //Button 2 was pressed, Do Something
        }
    }
}

스크립트1.cs

using UnityEngine;

public class Script1 : MonoBehaviour
{

    UIScript uiScript;

    // Use this for initialization
    void Start()
    {
        uiScript = GetComponent<UIScript>();
        uiScript.enabled = false;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Tab))
        {
            //toggle UIScript when Tab is pressed
            uiScript.enabled = !uiScript.enabled;
        }
    }
}

UIScript와 Script1은 모두 동일한 GameObject에 연결됩니다. Script1은 메뉴를 표시할 시기를 제어합니다.

플레이어가 Tab을 누르면 UIScript가 활성화되어 버튼이 표시됩니다. Tab을 다시 누르면 비활성화되어 버튼이 숨겨집니다.

UIScript가 비활성화되는 동안에는 OnGUI 메서드가 호출되지 않아 성능이 향상됩니다.

팁 5: 프로파일러 사용

Profiler는 병목 현상과 fps 저하를 식별하는 데 있어 가장 중요한 도구 중 하나이므로 성능 저하의 정확한 원인을 더 쉽게 찾을 수 있습니다.

오디오

가져오기 설정이 올바른지 확인하여 오디오 클립을 최적화할 수 있습니다.

최적의 오디오 가져오기 설정은 오디오 길이, 재생 빈도 및 대상 플랫폼에 따라 달라집니다.