在遊戲中有時候會需要撥放一些影片動畫當作過場,或者撥放媒體有控制上的需求,本篇就記錄一下「影片撥放器」的作法。
界面準備
首先,我們先利用UNITY的UGUI做出一個進度條(使用Scroll Bar製作),和兩個按鈕(Button)分別是撥放/暫停按鈕和停止按鈕。結構如下。
最外層分別是,主攝影機(MainCamera)、UI畫布(Canvas)、和事件系統(EventSystem建立畫布自動產生),Canvas內又包含了UGUI的ScrollBar和兩個Button。
程式腳本
程式分為兩部分,主控程式和時間進度的手把拖曳的行為偵測。
ScrollBar中的Handle要裝上以下程式,並繼承實作IPointerDownHandler, IDropHandler兩個界面的功能,點手把的時候暫停撥放,拖曳放開後恢復撥放。方法內呼叫的VideoPlayerCtrl就是主控端。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; //繼承兩個UNITY的事件,並實作界面 public class ScrollHandleChecker : MonoBehaviour, IPointerDownHandler, IDropHandler { public void OnDrop(PointerEventData eventData) { VideoPlayerCtrl.ctrl.Play(); } public void OnPointerDown(PointerEventData eventData) { VideoPlayerCtrl.ctrl.Pause(); } } |
主控程式VideoPlayerCtrl就加到Canvas上即可,腳本加入時會自動帶入Unity的VideoPlayer和AudioSource方便撥出影像和聲音。主控程式上只要選擇好VideoRenderMode為CameraFarPlane或者CameraNearPlane,然後VideoAudioOutputMode 為AudioSource即可(其他撥出方式可以另行增加)。要撥放的影片放到VideoClip中,啟動時要不要撥放和背景執行可自選,最後就是UI用的元素要指定到對應欄位,PlayBtnText是放Play按鈕中的文字,這部分也是依照做法可以修改,如果按鈕是用文字顯示箭頭或是暫停符號的話可以用這個做文字替換。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.Video; public delegate void ButtonFunction(); [RequireComponent(typeof(VideoPlayer))] [RequireComponent(typeof(AudioSource))] public class VideoPlayerCtrl : MonoBehaviour { public static VideoPlayerCtrl ctrl; public VideoRenderMode renderMode = VideoRenderMode.CameraFarPlane; public VideoAudioOutputMode audioOutputMode = VideoAudioOutputMode.AudioSource; public VideoClip videoClip; public bool playOnAwake, runInBackground = true; public Scrollbar timeBar; public Text playBtnText; private ButtonFunction btnFunction; private VideoPlayer videoPlayer { get{ return GetComponent<VideoPlayer>(); } } private AudioSource audioSource { get { return GetComponent<AudioSource>(); } } public bool isPause = true; private void Awake() { ctrl = this; } void Start () { SetMode();//設定初始狀態 } void SetMode() { //參數設定 Application.runInBackground = runInBackground; videoPlayer.playOnAwake = false; audioSource.playOnAwake = false; videoPlayer.clip = videoClip; videoPlayer.audioOutputMode = audioOutputMode; //聲音撥放設定 if (audioOutputMode == VideoAudioOutputMode.AudioSource) { videoPlayer.EnableAudioTrack(0, true); videoPlayer.SetTargetAudioSource(0, audioSource); } //影像魔是設定 videoPlayer.renderMode = renderMode; if (videoPlayer.renderMode == VideoRenderMode.CameraFarPlane || videoPlayer.renderMode == VideoRenderMode.CameraNearPlane) { videoPlayer.targetCamera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>(); } StartCoroutine("VideoPrepare");//準備影片 } IEnumerator VideoPrepare() { videoPlayer.Prepare();//讀取素材影片 while (!videoPlayer.isPrepared) { Debug.Log("Preparing Video"); yield return null; } Debug.Log("Video is Prepared"); if(playOnAwake) Play();//是否直接撥放 } //撥放功能鈕 public void ButtonFN() { btnFunction = videoPlayer.isPlaying ? (ButtonFunction)Pause : (ButtonFunction)Play; btnFunction(); } public void Play() { videoPlayer.Play(); isPause = false; } public void Pause() { videoPlayer.Pause(); isPause = true; } //停止 public void Stop() { videoPlayer.Stop(); timeBar.value = 0; } void Update () { if (timeBar) { if (videoPlayer.isPlaying && !isPause) { //時間條同步 timeBar.value = (float)(videoPlayer.time / videoPlayer.clip.length); } else { //拖曳改變影片時間 videoPlayer.time = videoPlayer.clip.length * timeBar.value; } } } } |
其中,ButtonFN()要指定給Play按鈕,Stop()指定給停止按鈕就大功告成了。