עצות אופטימיזציה לאחדות

Unity הוא מנוע משחק פופולרי לא רק בקרב מפתחי אינדי אלא גם בקרב חברות גדולות.

הוא כולל ממשק ידידותי למשתמש, צינור עיבוד רב עוצמה, מערכת רכיבים קלה לשימוש, ולבסוף, הוא תומך במגוון עצום של פלטפורמות.

אבל עם ממשק קל לשימוש, זה אפילו יותר קל לסבך את המשחק שלך (למשל על ידי הצבת הרבה אובייקטים מיותרים וכו'), לכן חשוב שיהיה אופטימיזציה לזכור במהלך כל מהלך הפיתוח.

להלן טיפים חשובים עבור 3 הקטגוריות העיקריות (עיבוד, Scripting, ו-Audio) שיעזרו לך לשפר את הביצועים של המשחק שלך:

טִיוּחַ

טיפ 1: השאר את האובייקטים עם רכיב ה-Renderer ללא קנה מידה

אובייקטים לא מותאמים הם אלה שיש להם קנה מידה של (1, 1, 1). במקרה כזה, Unity לא צריך לעשות חישובים נוספים כדי לשנות את קנה המידה של האובייקט בכל מסגרת.

דוגמה: נניח שיש לך דגם של בית גדול מדי או קטן מדי לרמה שלך. הדבר הטבעי לעשות הוא לשנות את קנה המידה כך:

שינוי גודל בניין

לרוב זה בסדר לשנות את קנה המידה של האובייקט בתצוגת הסצנה, אבל אם אתם מתכננים הרבה מופעים משוכפלים של האובייקט הזה, עדיף לשנות את קנה המידה בהגדרות הייבוא.

הדבר הראשון שעליך לעשות הוא לשנות את קנה המידה של המודל עד שהוא יתאים לצרכים שלך (לדוגמה, הבניין שלמעלה הוגדל מ- (1, 1, 1) ל- (0.49482, 0.49482, 0.49482)), ולאחר מכן בחר את הדגם בפרויקט הצג ובהגדרות הייבוא ​​שים לב ל-Scale Factor (בדרך כלל זה 1 או 0.1).

הגדר את הערך החדש, שאמור להיות שווה לגורם קנה המידה המוגדר כברירת מחדל, הכפל בסולם החדש (במקרה שלי זה 1 x 0.49482 = 0.49482), ואז הקש על החל. כעת חזרו לדגם בתצוגת הסצנה והחזירו את קנה המידה ל- (1, 1, 1).

הגדרות גורם קנה המידה של Unity 3D

האובייקט מוגדל כעת כפי שאתה צריך תוך שמירה על קנה המידה של ברירת המחדל (1, 1, 1).

טיפ זה חשוב במיוחד עבור אובייקטים מונפשים המשתמשים ב-SkinnedMeshRenderer, מכיוון שרכיב זה יקר יותר לעיבוד, וקנה המידה של (1, 1, 1) מפשט את תהליך הרינדור.

טיפ 2: השתמש בכמה שפחות אורות

ישנם 3 סוגי אורות ב-Unity (אור כיווני, אור נקודתי וזרקור). מבחינת ביצועים אור כיווני הוא הזול ביותר לעיבוד, לאחר מכן Point, ולבסוף ה-Spotlight.

בדרך כלל, אינך רוצה שיהיו יותר מאור כיווני אחד לכל סצנה, ולאורות הנקודה והנקודה נסו להכיל כמה שפחות (או אף אחד בכלל).

במונחים של צללים בזמן אמת, בעוד שהוא משפר את ההיבט הוויזואלי של המשחק, יש לו תקורה בעלת ביצועים גבוהים, כך שבאופן כללי, עדיף להשבית אותם או לאפות אותם ב-lightmaps ו-light בדיקות.

טיפ 3: השתמשו ב-Shaders שקוף בזהירות

השתמש רק בשקופים או בהצללות חלקיקים על משטחים שצריכים להיות שקופים (למשל גדרות, חלקיקי עשן וכו')

אובייקטים עם שקיפות דורשים מעבר עיבוד נוסף שעלול להפחית את הביצועים, במיוחד בפלטפורמות עם משאבים מוגבלים, כגון נייד או אינטרנט.

סקריפטים

טיפ 1: שמור תמיד הפניות לרכיבי מטמון

עליך תמיד לשמור הפניות של רכיבים במטמון אם אתה מתכנן לגשת אליהם בכל עדכון.

לדוגמה, בדוק את הסקריפט שלהלן:

רַע

using UnityEngine;

public class Script1 : MonoBehaviour
{
    float someValue = 0;

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

כאן יש לנו Script1 שמקבל את המשתנה "someValue2" מ-Script2 ומקצה אותו למשתנה מקומי.

כעת, קריאה אחת בלבד של 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.FindWithTag ו-GameObject.FindGameObjectsWithTag מאפשרים לך לחפש במהירות את האובייקטים בסצנה. שיטות אלו איטיות בהרבה מ-GetComponent ויש להשתמש בהן רק במהלך האתחול.

טיפ 4: הימנע משימוש ב-OnGUI

מבחינה היסטורית OnGUI הייתה הדרך היחידה ליצור תפריטים ב-Unity. אבל מאז, נוספה אלטרנטיבה בשם UI Canvas שהיא הרבה יותר טובה מבחינת ביצועים ומציעה הרבה יותר פונקציונליות.

עם זאת, OnGUI עדיין נותרה דרך קיימת ליצור ממשק משתמש ב-Unity ואם אתה בהחלט צריך להשתמש בו, זכור ש-OnGUI נקרא לפחות פעמיים לכל מסגרת (פי שניים מעדכון ו-LateUpdate) אז אל תשתמש בו עבור כל חישוב מלבד ממשק משתמש.

דבר אחד שאתה יכול לעשות הוא שיהיה לך סקריפט נפרד שיש בו רק 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
        }
    }
}

Script1.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

Profiler הוא אחד הכלים החשובים ביותר בכל הנוגע לזיהוי צווארי בקבוק וירידות fps, מה שמקל על מציאת הסיבה המדויקת לביצועים הנמוכים.

שֶׁמַע

ניתן לבצע אופטימיזציה של קטעי אודיו על ידי הקפדה על הגדרות הייבוא ​​שלהם נכונות.

הגדרות ייבוא ​​שמע אופטימליות יהיו תלויות באורך האודיו, תדירות ההשמעה ופלטפורמת היעד.