網頁

2019年7月14日 星期日

Unity 程式設計教學 - 當沒偵測到辨識圖時,audio 和 video 組件停止播放

問題:
在 「Unity的應用 - 使用 Vuforia AR 套件,設計2個按鈕分別是 「生日快樂」和「女孩跳舞」 」此篇文章,設計出來的 App。仍有些問題,要解決。
因為 AudioSource 和 VideoPlayer 的 「Play on Awake」都要打勾,造成執行此App,一開始就有聲音播放,離開辨識圖片也不會停止。而且2個聲音都出現,也造成困擾。
解決方式: 使用 Script(腳本),也就是你要寫程式來控制。
新增 Script
由於1 個專案,可能有很多個 Scripts(腳本程式),為了在 assest(資源)資料夾,將各種資源分門歸類,所以新增1個資料夾專門放 Script。
在 Project 視窗,選 Assests,按右鍵 選  Create / Folder。
在 Project 視窗,選 Assests/Script ,按右鍵, 選 Create / C# Script。
選 「NewBehaviourScript」此 Script ,按右鍵 選 Rename。將 NewBehaviourScript 更名為 GirlTrackedScript。(第 1 個字大寫,因為進入 Visual Studio 預設為大寫)
開始編輯程式
選  GirlTrackedScript,按右鍵, 選 「Open C# Project」。 (對 GirlTrackedScript 連續按二下也可以)
進入到 Visual Studio。
將原來 class  NewBehaviourScript 更名為  GirlTrackedScirpt ,讓 檔名和  class name 同名
檔名 和 class name 若不同,將 script 拖曳到 物件上,會有錯誤訊息,如下 :
程式碼如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
using UnityEngine.Audio;
using Vuforia;

public class GirlTrackedScript : MonoBehaviour, ITrackableEventHandler
{
    //宣告要控制的對象物件或組件
    //Audio
    private AudioSource audioSource;

    TrackableBehaviour TB
    {
        get
        {
            return GetComponent();
        }
    }
    // Use this for initialization
    void Start()
    {
        //如果將 下列二條敘述移到 if (TB)的後面,執行有誤
        GameObject target_unitychan = GameObject.Find("Target_unitychan");
        audioSource = target_unitychan.GetComponent<UnityEngine.AudioSource>(); 
      
       if (TB)
        {
            TB.RegisterTrackableEventHandler(this);
        }
    }

    public void OnTrackableStateChanged(TrackableBehaviour.Status previousStatus, TrackableBehaviour.Status newStatus)
    {
               
        if (newStatus == TrackableBehaviour.Status.TRACKED || newStatus == TrackableBehaviour.Status.DETECTED || newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
        {
           //target tracked 
           audioSource.Play();
          
        }
        else
        {
            //target lost
            audioSource.Stop();
           
        }
    }
}

程式碼的意義:
在 OnTrackableStateChanged 此程序內,若偵測到辨識圖,則播放聲音(audioSource.Play),否則就停止播放聲音(audioSource.Stop)。
有關 Unity 、Vuforia 的Scripting API 的用法和 C# 的語法 請自行使用 Google 搜尋其意義。
按「附加至Unity」鈕,檢查程式有無錯誤。
狀態列出現「就緒」,錯誤清單沒有錯誤。
切回 Unity,結果如下:
選 Target_unitychan ,在 Inspector 視窗往下拉看到 Audio Source。
將 GirlTrackedScript 拖曳到 Audio Source 的下面放下。
結果如下:
Target_unitychan 的 Audio Source 之 「Play On Awake」 取消打勾。避免手機還沒拍到 unitychan 辨識圖,就開始播放聲音。
按 「Play」鈕播放,下面狀態列沒有出現問題,出現 Trackable unitychan found,這是正常的。
再按 「Play」鈕結束播放。
切回到 Visual Studio,按「停止偵錯」鈕 。
新增 BirthTrackedScript
切回 Unity,參考上述方法,新增 BirthTrackedScript 。
進入到 Visual Studio。
程式碼如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
using UnityEngine.Audio;
using Vuforia;

public class BirthTrackedScript : MonoBehaviour, ITrackableEventHandler
{
    //宣告要控制的對象物件或組件
    private GameObject video;

    //Video
    private VideoPlayer videoPlayer;

    //Audio
    private AudioSource audioSource;

    TrackableBehaviour TB
    {
        get
        {
            return GetComponent();
        }
    }

    // Use this for initialization
    void Start()
    {
        //如果將下列三條敘述移到 if (TB)的後面,執行有誤
        video = GameObject.Find("video_plane");
        videoPlayer = video.GetComponent<UnityEngine.Video.VideoPlayer>();
        audioSource = video.GetComponent<UnityEngine.AudioSource>();

        if (TB)
        {
            TB.RegisterTrackableEventHandler(this);
        }

    }
    public void OnTrackableStateChanged(TrackableBehaviour.Status previousStatus, TrackableBehaviour.Status newStatus)
    {

        if (newStatus == TrackableBehaviour.Status.TRACKED || newStatus == TrackableBehaviour.Status.DETECTED || newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
        {
            //target tracked 
            videoPlayer.Play();
            audioSource.Play(); 
        }
        else
        {
            //target lost
            videoPlayer.Stop();
            audioSource.Stop();
        }
    }
}
按「附加至 Unity」鈕,檢查有無錯誤。
狀態列出現「就緒」,錯誤清單沒有錯誤。
選 Target_birth ,在 Inspector 視窗往下拉。
將 BirthTrackedScript 拖曳到 Image  Target  Mesh127 的下面放下。

錯誤做法
如果把 BirthTrackedScript 拖曳到 Target_birth / video_plane  的 Video Player下面放下。
執行結果,將看不到影片。因為 BirthTrackedScript 是要綁定到 辨識圖(Target Image)物件,當偵測到辨識圖才有作用。
video_plane 的 Audio Source 之 「Play On Awake」 取消打勾。
video_plane 的 Video Source 之 「Play On Awake」 取消打勾。
避免手機還沒拍到 birth 辨識圖,就開始播放聲音和影片。
按 「Play」鈕播放,下面狀態列沒有出現問題,出現 Trackable unitychan found,這是正常的。
女孩跳舞和生日快樂影片皆沒問題。
建置發佈App
選功能表的 File/Build Settings... 。按「Build」。
Building 過程如下:
若不會發佈 App ,請參考本人的文章 「將 Unity 專案 發佈成 App 程式,以便使用手機執行」。
最後產生 「dance_birth.apk」 此檔案,可傳到手機上執行。(先上傳到雲端硬碟,再從手機下載或用 usb 連接線傳到手機)
切回到 Visual Studio,按「停止偵錯」鈕 。
檔案/全部儲存,把 所有 Scripts 全部儲存。