Unity Wrapper ของฟีเจอร์เล่นเกมของ YouTube รุ่นทดลอง

Wrapper นี้ช่วยให้คุณเข้าถึง YouTube Playables SDK ใน Unity C# ได้ โดยมีปลั๊กอิน .jslib และไฟล์ C# เพื่อช่วยเร่งการพัฒนา นอกจากนี้ยังมีโปรเจ็กต์ตัวอย่างที่แสดงวิธีใช้ปลั๊กอินและไฟล์ดังกล่าวในโปรเจ็กต์ของคุณ

คุณสามารถดาวน์โหลดแพ็กเกจ Unity ได้จากที่เก็บตัวอย่าง Playables sample repo

การใช้งาน

  1. ตรวจสอบว่าแพลตฟอร์มโปรเจ็กต์ Unity ตั้งค่าเป็น WebGL คุณจะดูการตั้งค่านี้ได้ใน Build Settings
  2. ใช้ WebGLTemplate เพื่อสร้างเกมสำหรับเว็บ หรือทำตามส่วน "ใช้ไฟล์ index.html ของคุณเอง" และตรวจสอบ ว่าคุณได้ตั้งค่าและเริ่มต้นใช้งาน Web SDK ในไฟล์index.html แล้ว
    • WebGLTemplate สามารถพบได้ในแพ็กเกจ Google-WebGLTemplate-only.unitypackage หรือ GoogleYTGameWrapper-with-sample.unitypackage หากต้องการตั้งค่าและใช้ เทมเพลตนี้ ให้ทำตามขั้นตอนในส่วน "เทมเพลต WebGL "
    • หากต้องการใช้เว็บและไฟล์ index.html ของคุณเอง คุณจะต้องเพิ่มโค้ด 2 บรรทัดลงในสคริปต์การสร้าง index.html ของ Unity โปรดดูส่วน ใช้ไฟล์ index.html ของคุณเอง สำหรับ การผสานรวม
  3. เปิดโปรเจ็กต์ใน Unity จากนั้นเปิดและนำเข้าแพ็กเกจใดแพ็กเกจหนึ่งลงในโปรเจ็กต์
    • GoogleYTGameWrapper.unitypackage: มีปลั๊กอิน JS สำหรับเชื่อมต่อฟีเจอร์เล่นเกมของ YouTube SDK และ Wrapper C# เพื่อช่วยเชื่อมต่อ SDK นี้กับผลิตภัณฑ์ของคุณ
    • GoogleYTGameWrapper-with-sample.unitypackage: มีเนื้อหาไฟล์เหมือนกับที่พบในแพ็กเกจ GoogleYTGameWrapper และตัวอย่างที่แสดงวิธีใช้ YouTube Playables SDK ใน C#
  4. สำคัญ: สร้างออบเจ็กต์เกมใหม่ในฉากหลักและตั้งชื่อว่า YTGameWrapper ออบเจ็กต์เกมนี้ใช้เพื่อสื่อสารกับ JS Bridge
  5. สำคัญ: เพิ่มโค้ดที่นำเข้า YTGameWrapper.cs เป็นคอมโพเนนต์สคริปต์ ลงใน YTGameWrapper GameObject
  6. หากโปรเจ็กต์มีหลายฉาก ให้เพิ่ม DontDestroyOnLoad ลงในสคริปต์ YTGameWrapper.cs (หมายเหตุ: สคริปต์เวอร์ชันใหม่มีปุ่ม DontDestroyOnSceneChange ซึ่งเปิดอยู่โดยค่าเริ่มต้น) การดำเนินการนี้จะช่วยให้สคริปต์และ GameObject ยังคงอยู่ตลอดทั้งเกม

    GameObject.DontDestroyOnLoad(this.gameObject);
    
  7. คอมโพเนนต์ YTGameWrapper.cs และ YTGameWrapper GameObject ใช้เพื่อเชื่อมต่อกับ SDK ฟีเจอร์เล่นเกมของ YouTube ใช้คอมโพเนนต์และออบเจ็กต์เหล่านี้เพื่อเชื่อมต่อกับ YouTube โดยใช้สคริปต์เพื่อค้นหาออบเจ็กต์และคอมโพเนนต์ หรือเพิ่มออบเจ็กต์และคอมโพเนนต์เหล่านี้ลงในโค้ดเกมด้วยตนเองผ่าน Unity Editor

  8. ตรวจสอบว่าคุณปฏิบัติตามข้อกำหนดทางเทคนิคสำหรับโปรเจ็กต์

ใช้ไฟล์ index.html ของคุณเอง

หากคุณไม่ได้ใช้ตัวอย่าง index.html ที่ให้ไว้ คุณจะต้องเพิ่มโค้ด 2 บรรทัดลงในสคริปต์การสร้าง index.html ของ Unity

ขั้นแรก ให้เพิ่มบรรทัดนี้ในตำแหน่งเดียวกับที่โปรเจ็กต์ตั้งค่าตัวแปรสำหรับคอนเทนเนอร์ Canvas ฯลฯ ของ Unity

    var container = document.querySelector("#unity-container");
    var canvas = document.querySelector("#unity-canvas");

    var unityGameInstance = null; // <-- Add this line >

    ...

จากนั้นให้เพิ่มบรรทัดนี้ลงในฟังก์ชัน createUnityInstance

    createUnityInstance(canvas, config, (progress) => {
        progressBarFull.style.width = 100 * progress + "%";
    }).then((unityInstance) => {

        unityGameInstance = unityInstance; // <-- Add this line >

    ...

ตัวอย่าง

ส่วนนี้มีตัวอย่างวิธีใช้ Wrapper C# แต่ไม่ใช่รายการ API ทั้งหมดที่พร้อมใช้งาน หากต้องการดูรายการ API ทั้งหมดที่พร้อมใช้งาน โปรดดู YouTube Playables SDK

sendScore

ตัวอย่างนี้แสดงการใช้งาน sendScore(int points) ใน C#

...
using YTGameSDK;
...

public YTGameWrapper ytGameWrapper;
public int battleScore = 0;

...

// Update the total score and send this to the YouTube Game Wrapper.
public void UpdateScores(int scoreAmt)
{
    battleScore += scoreAmt;
    // ytGameWrapper should be a reference to your YTGameWrapper component.
    ytGameWrapper.SendGameScore(battleScore);
}

onPause

ตัวอย่างนี้แสดงวิธีที่เกมสามารถรับฟังเหตุการณ์ Pause ที่มาจาก YT Playables เพื่อหยุดชั่วคราวเมื่อจำเป็น

...
using YTGameSDK;
...

public YTGameWrapper ytGameWrapper;
public bool gameIsPaused = false;

...
void Start()
{
    // Sets the OnPause callback with the YT Playables SDK
    ytGameWrapper.SetOnPauseCallback(PauseTheGameCallback);
}

// Pause game callback, will pause the game when called.
public void PauseTheGameCallback()
{
    gameIsPaused = true;
}

saveData

ตัวอย่างนี้แสดงวิธีใช้ saveData เพื่อส่งข้อมูลไปยัง YT Playables SDK

...
using YTGameSDK;
...

public YTGameWrapper ytGameWrapper;

...

// Saves the current score of the game and converts it to a JSON format.
public void SaveScore(int scoreAmt)
{
    SaveGameData("{\"BestScore\": \"" + scoreAmt.ToString() + "\"}");
}

public void SaveGameData(string saveString)
{
    if (string.IsNullOrEmpty(saveString)) return;

    // Sends save data to the YT Playables SDK
    ytGameWrapper.SendGameSaveData(saveString);
}

loadData

ตัวอย่างนี้แสดงวิธีใช้ loadData เพื่อส่งข้อมูลไปยัง YT Playables SDK

...
using UnityEngine;
using YTGameSDK;
...

[Serializable]
public class LoadedScores
{
    public int BestScore;
    public float BestTime;
}

public YTGameWrapper ytGameWrapper;

...

void Start()
{
    ytGameWrapper.LoadGameSaveData(LoadSaveGameDataReturned);
}

public void LoadSaveGameDataReturned(string data)
{
    if (!string.IsNullOrEmpty(data))
    {
        LoadedScores loadedScores = JsonUtility.FromJson<LoadedScores>(data);
        Debug.Log("LoadSaveGameDataReturned > Score <" + loadedScores.BestScore.ToString()
                  +   "> Time <" + loadedScores.BestTime.ToString("0.00"));
    }
}

requestInterstitialAd

ตัวอย่างนี้แสดงวิธีใช้ requestInterstitialAd เพื่อระบุว่าถึงเวลาที่เหมาะสมในการแสดงโฆษณาคั่นระหว่างหน้าแล้ว หากมี เพื่อให้ได้ผลลัพธ์ที่ดีที่สุด ให้เรียกใช้ฟังก์ชันนี้ระหว่างการหยุดพักการเล่นเกม เช่น เมื่อจบด่าน

...
using YTGameSDK;
...

public YTGameWrapper ytGameWrapper;

...

// At the end of a round send a request to show an interstitial Ad, if one is
//  available an Ad will be shown and Pause Game Callback should be called.

// EXAMPLE: send and forget
public void RequestInterstitialAd()
{
    ytGameWrapper.RequestInterstitialAd();
}

// EXAMPLE: send and react to if an Ad was shown
public void RequestInterstitialAd()
{
    int status = ytGameWrapper.RequestInterstitialAd();
    if (status == 0)
    {
        // Ad request was successful, do some action.
    }
}

requestRewardedAd

ตัวอย่างนี้แสดงวิธีใช้ requestRewardedAd ฟังก์ชันนี้ใช้เมื่อผู้ใช้เลือกที่จะดูโฆษณาที่มีการให้รางวัลเพื่อแลกกับรางวัลบางอย่างในเกม หากมีโฆษณา ระบบจะแสดงโฆษณาให้ผู้ใช้เห็น

...
using YTGameSDK;
...

public YTGameWrapper ytGameWrapper;

...

public void RequestRewardedAd()
{
    // Register callback for Rewarded Ads. If an Ad is available one will be
    //  shown. Pause Game Callback should be called. Any ID is fine as long as
    //  its identifyable for your game.
    ytGameWrapper.RequestRewardedAd("my-reward-ad-id-123", (rewardEarned) => {
        if (rewardEarned) {
            // Rewarded Ad is earned, reward the user.
        } else {
            // Rewarded Ad not earned, take the appropriate action
        }
    });
}

วิธีใช้เทมเพลต WebGL ตัวอย่างของ YouTube

ไฟล์ .wasm และ .data ที่สร้างขึ้น ควรมีขนาดไม่เกินขีดจำกัดขนาดไฟล์แต่ละไฟล์ของเรา เว้นแต่ว่าโปรเจ็กต์ Unity ของคุณจะมีขนาดใหญ่มาก ในกรณีนี้ คุณไม่ควรบีบอัดไฟล์เหล่านี้เพิ่มเติม เนื่องจากระบบจะบีบอัดไฟล์เหล่านี้โดยอัตโนมัติเมื่อคุณส่งไฟล์ Playable การบีบอัดอัตโนมัตินี้จะตรวจสอบด้วยว่าไฟล์ .wasm มีขนาดตรงตามข้อกำหนดขนาดแพ็กเกจ เริ่มต้นหรือไม่ ตัวอย่างเช่น ไฟล์ .wasm ขนาด ~25 MiB จะบีบอัดเป็นขนาด ~7 MiB

หากไฟล์มีขนาดเกินขีดจำกัดขนาดไฟล์แต่ละไฟล์สูงสุด คุณควรใช้การบีบอัด ZIP เพื่อตรวจสอบว่าไฟล์มีขนาดไม่เกินขีดจำกัดนี้ การบีบอัด Playable จะไม่บีบอัดไฟล์เหล่านี้อีกครั้ง

เทมเพลต WebGL

  1. ทำตามวิธีการแพ็กเกจ Unity ด้านบนสำหรับการตั้งค่าเริ่มต้น ตรวจสอบว่าคุณใช้ Google-WebGLTemplate-only.unitypackage หรือ GoogleYTGameWrapper-with-sample.unitypackage และนำเข้าไฟล์ทั้งหมดในโฟลเดอร์ WebGLTemplates/YTGameWrapperTemplate/
    • หมายเหตุ: หากยังไม่ได้นำเข้า YTGameWrapper.cs และ UnityYTGameSDKLib.jslib คุณควรนำเข้าไฟล์เหล่านั้นด้วย
  2. ตั้งค่าเทมเพลต WebGL ให้ใช้ YTGameWrapperTemplate คุณจะดูการตั้งค่านี้ได้ใน Edit -> Project settings -> Player -> แท็บ WebGL -> ส่วน Resolution and Presentation
    • หมายเหตุ: เทมเพลตตั้งค่าความกว้างและความสูงของ Canvas เริ่มต้นเป็น 100% ดังนั้นการตั้งค่า Unity เหล่านี้จึงจะไม่ปรับอะไร
  3. ตรวจสอบว่า Compression Format ตั้งค่าเป็น Disabled คุณจะดูการตั้งค่านี้ได้ใน Project settings -> Player -> แท็บ WebGL -> ส่วน Publishing Settings
  4. สร้างสำหรับ WebGL ในหน้าต่าง Build Settings จากนั้นไปที่ขั้นตอนที่ 7 หรือ 5 ขึ้นอยู่กับความต้องการของโปรเจ็กต์
  5. ทำตามขั้นตอนที่ 5 และ 6 เท่านั้นหากใช้การบีบอัด: หลังจากสร้างโปรเจ็กต์แล้ว ให้ไปที่ตำแหน่งโฟลเดอร์ที่สร้างขึ้นและเปิดโฟลเดอร์ Build ค้นหาไฟล์ .wasm หรือ .data ของโปรเจ็กต์ที่ต้องบีบอัดเพื่อให้มีขนาดไม่เกินขีดจำกัด ขนาดไฟล์แต่ละไฟล์ แล้วบีบอัดไฟล์เหล่านี้ อย่าลืมลบไฟล์ต้นฉบับ .wasm/.data ที่บีบอัด เนื่องจากคุณจะต้องส่งไฟล์ *.wasm.zip และ *.data.zip แทน
    • หมายเหตุ: หากใช้ Mac คุณสามารถคลิกขวาที่ไฟล์แล้วเลือก "Compress *" ส่วนใน PC ให้คลิกขวาที่ไฟล์แล้วเลือก "Compress to ZIP file"
  6. ทำตามขั้นตอนนี้เฉพาะในกรณีที่ทำขั้นตอนที่ 5: อัปเดตไฟล์ index.html ที่สร้างขึ้นจาก YTGameWrapperTemplate เพื่อโหลดไฟล์ที่บีบอัดและคลายการบีบอัด
    • คุณจะเห็น Path 1 ใกล้กับส่วนท้ายของไฟล์ index.html และแสดงความคิดเห็นในบรรทัด InitUnitySection();
    • คุณจะเห็น Path 2 ใกล้กับส่วนท้ายของไฟล์ index.html และแสดงความคิดเห็นในบรรทัด loadResources(InitUnitySection);
  7. เมื่อส่งโปรเจ็กต์เพื่อขอการรับรอง คุณจะต้องส่งไฟล์ทั้งหมดที่สร้างขึ้นจาก Unity ไปยังตำแหน่งที่สร้างขึ้นจากขั้นตอนที่ 4 หากทำตามขั้นตอนที่ 5 และ 6 ให้รวมไฟล์เหล่านี้ด้วย

อัปเกรดตัวอย่างที่ให้ไว้เพื่อใช้ Universal Render Pipeline (URP)

ความก้าวหน้าล่าสุดอย่างหนึ่งของ Unity เวอร์ชันใหม่คือการใช้ Universal Render Pipeline (URP) หากต้องการอัปเกรดตัวอย่างเพื่อให้ทุกอย่างแสดงผลอย่างถูกต้อง ให้ทำดังนี้

  1. เริ่มต้นด้วยการนำเข้าแพ็กเกจ GoogleYTGameWrapper-with-sample.unitypackage ลงในโปรเจ็กต์ใหม่หรือโปรเจ็กต์ที่มีอยู่
  2. ไปที่หน้าต่าง Render Pipeline Converter โดยไปที่ Window -> Rendering -> Render Pipeline Converter
  3. เลือก Rendering Settings, Material Upgrade และ Readonly Material Converter
  4. จากนั้นเลือก Initialize and Convert รอให้การดำเนินการนี้เสร็จสิ้น ตัวอย่างควรพร้อมสำหรับ URP

วิธีแยกชิ้นงานในโปรเจ็กต์ Unity (การโหลดแบบ Lazy)

ปัญหาหลักอย่างหนึ่งที่นักพัฒนาแอปเน้นย้ำเมื่อใช้ Unity คือการทำให้ไฟล์มีขนาดไม่เกิน ข้อกำหนดขนาดไฟล์แต่ละไฟล์และข้อกำหนดขนาด แพ็กเกจทั้งหมด

การโหลดชิ้นงานแบบ Lazy เป็นการเพิ่มประสิทธิภาพที่ยอดเยี่ยมสำหรับโปรเจ็กต์ เนื่องจากคุณสามารถโหลดชิ้นงาน ระดับ และข้อมูลได้ตามต้องการ ทีมการรับรองอาจยกเว้นข้อจำกัดขนาดไฟล์โดยรวมหากดำเนินการอย่างถูกต้อง เนื่องจากระบบจะไม่โหลดเกมทั้งหมดล่วงหน้า แต่จะโหลดเมื่อผู้ใช้ไปยังส่วนต่างๆ ของผลิตภัณฑ์

Unity มีวิธีต่างๆ ในการแยกชิ้นงานเพื่อช่วยให้การโหลดเป็นไปอย่างเหมาะสม โดยตรวจสอบว่ากลุ่มชิ้นงานแต่ละกลุ่มมีขนาดไม่เกินขีดจำกัด และคุณโหลดเนื้อหาเมื่อเวลาผ่านไป เราขอแนะนำให้ใช้ Addressables หรือ Asset Bundle

Addressables

Addressables ช่วยให้คุณระบุไฟล์ต่างๆ ที่ควรโหลดด้วยกันได้ และ Unity จะจัดการการแพ็กเกจส่วนใหญ่ให้คุณ นอกจากนี้ Unity ยังมีเครื่องมือบางอย่างในการจัดการขนาดไฟล์และช่วยให้คุณมั่นใจว่าคุณจะไม่ทำซ้ำชิ้นงาน

หากต้องการใช้ Addressables คุณจะต้องนำเข้าแพ็กเกจ Addressables ผ่าน Package Manager ใน Unity จากนั้นแท็กชิ้นงานลงในกลุ่ม Addressable ดูรายละเอียดเพิ่มเติมได้จาก เอกสารประกอบของ Unity

Asset Bundle

Asset Bundle มีประโยชน์เนื่องจากคุณสามารถแยกโปรเจ็กต์และโหลดองค์ประกอบได้ทันที ซึ่งมีประโยชน์สำหรับ DLC, แพ็กระดับ, ตัวละครใหม่ และอื่นๆ Asset Bundle เหมาะสำหรับการโหลดและการจัดกลุ่มเนื้อหาที่จัดการด้วยตนเอง คุณสามารถใช้ Asset Bundle ได้โดยการแท็กชิ้นงานลงใน Bundle ที่เฉพาะเจาะจง จากนั้นโหลด Bundle ตามที่ต้องการ ดูรายละเอียดเพิ่มเติมได้ในเอกสารประกอบ Asset Bundle ของ Unity

ดูเอกสารอ้างอิง YT Playables API ทั้งหมด