質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

1508閲覧

Unity(C#)動画の再生中だけボタンを非表示にする方法

studyUSAAA

総合スコア17

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2022/05/15 15:13

動画の再生中だけボタンを非表示にする方法を教えてください。

Unity初心者です。
Planeオブジェクト一つとボタンA,Bの二つを配置し、
ChangVideoスクリプト(下記参照)でAボタンを押したらAの動画が流れて、Bボタンを押したら動画Bが流れるような仕組みを作ることができたのですが、
動画再生中にボタンを非表示にする方法を教えてください。
(SetActive(bool値)で表示・非常時を制御できることは把握できたのですが、自分のPlaneに付けたChangVスクリプトでどう描けば反映できるのかがわかりません。)

初心質問でお手数をおかけしてしまい、大変申し訳ございませんが、教えていただけますと幸いです。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.Video; 5 6public class ChangV : MonoBehaviour 7{ 8 VideoPlayer vp; 9 void Start() 10 { 11 vp = GetComponent<VideoPlayer>(); 12 //↓VideoPlayerの再生準備ができたとき、OnVideoPlayerPreparedが呼ばれる 13 vp.prepareCompleted += OnVideoPlayerPrepared; 14 } 15 16 void OnVideoPlayerPrepared (VideoPlayer vp) 17 { 18 vp.Play(); 19 } 20 21 public void ChangeVideo (string name) 22 { 23 //既にVideoPlayerに動画が読み込まれている場合 24 if (vp.clip != null) 25 { 26 vp.Stop(); 27 //↓その動画をメモリから解放する 28 Resources.UnloadAsset(vp.clip); 29 } 30 31 //動画をメモリに読み込む 32 vp.clip = Resources.Load<VideoClip>("Videos/" + name); 33 //↓VideoPlayerに再生準備をさせる 34 vp.Prepare(); 35 } 36}

以下はPlaneとボタンの参考画像です。
イメージ説明
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

※末尾に追記しました

下記で対応できると思います。
テストはしていないので問題ありましたら連絡ください。

ChangV.csを変更

中身を下記に書き換えてください。

c#

1using UnityEngine; 2using UnityEngine.Video; 3 4public class ChangV : MonoBehaviour 5{ 6 public VideoPlayer Vp { get; private set; } 7 8 void Start() 9 { 10 Vp = GetComponent<VideoPlayer>(); 11 //↓VideoPlayerの再生準備ができたとき、OnVideoPlayerPreparedが呼ばれる 12 Vp.prepareCompleted += OnVideoPlayerPrepared; 13 } 14 15 void OnVideoPlayerPrepared (VideoPlayer vp) 16 { 17 vp.Play(); 18 } 19 20 public void ChangeVideo (string name) 21 { 22 //既にVideoPlayerに動画が読み込まれている場合 23 if (Vp.clip != null) 24 { 25 Vp.Stop(); 26 //↓その動画をメモリから解放する 27 Resources.UnloadAsset(Vp.clip); 28 } 29 30 //動画をメモリに読み込む 31 Vp.clip = Resources.Load<VideoClip>("Videos/" + name); 32 //↓VideoPlayerに再生準備をさせる 33 Vp.Prepare(); 34 } 35} 36

ボタンにChangVButton.csをアタッチ

※ボタンA,Bがあるとの事なので両方とも下記の対応をお願いします。
PlayTarget(説明は後述)にボタンAで表示したい動画名を。ボタンBで表示したい動画名を設定してください。

四角で囲った部分を「-」ボタンで削除してください。
イメージ説明

下記スクリプトをChangVButtonという名前で保存し、ボタンにアタッチしてください。

PlayTargetを変更する事で違う動画を再生できます。
個人的には、直書きしない方が良いと思いますがテストなので今回はこの形にしました。
イメージ説明
アタッチ後、ChangVをドラッグ&ドロップで設定してください。
PlayButtonは自動で設定されるはずですが、されなければ同じくドラッグ&ドロップで設定してください。

c#

1using UnityEngine; 2using UnityEngine.UI; 3using UnityEngine.Video; 4 5[RequireComponent(typeof(Button))] 6public class ChangVButton : MonoBehaviour 7{ 8 [SerializeField] ChangV changV; 9 [SerializeField] Button playButton; 10 [SerializeField] string playTarget = "London"; 11 12 void Start() 13 { 14 playButton.onClick.AddListener(ClickPlayButton); 15 changV.Vp.loopPointReached += OnLoopPointReached; 16 } 17 18 void OnLoopPointReached(VideoPlayer source) 19 { 20 playButton.gameObject.SetActive(true); 21 } 22 23 void ClickPlayButton() 24 { 25 if (!changV.Vp.isPlaying) 26 { 27 changV.ChangeVideo(playTarget); 28 playButton.gameObject.SetActive(false); 29 } 30 } 31 32 void Reset() 33 { 34 playButton = GetComponent<Button>(); 35 } 36}

動画の管理について

今回の質問とは逸れますが、動画量が少ないなら下記のような感じで動画の詳細管理を簡易的に実装しておくのも良いかもしれません。
利点は下記です。

  • 動画のパスを間違って事故ったりしない
  • タイトルなどの情報も管理できる
  • 動画の詳細を実装から分離できる

以上です。よければ参考にしてみてください。

ChangV.csのChangeVideoを書き換える

C#

1public void ChangeVideo (VideoID id) 2{ 3 //既にVideoPlayerに動画が読み込まれている場合 4 if (Vp.clip != null) 5 { 6 Vp.Stop(); 7 //↓その動画をメモリから解放する 8 Resources.UnloadAsset(Vp.clip); 9 } 10 11 var meta = id.GetMeta(); 12 // var title = meta.Title; タイトルを取得できる 13 14 //動画をメモリに読み込む 15 Vp.clip = Resources.Load<VideoClip>(meta.Path); 16 //↓VideoPlayerに再生準備をさせる 17 Vp.Prepare(); 18}

ChangVButton.csのplayTargetを書き換える

c#

1 [SerializeField] string playTarget = "London"; 2 // ↓ 3 [SerializeField] VideoID playTarget;

そうするとボタン側はこんな感じでドロップダウンから選択できるようになり安全です。

イメージ説明

VideoMetaData.csという名前で保存

c#

1using System.Collections.Generic; 2using UnityEngine; 3 4public static class VideoExtensions 5{ 6 static readonly IEnumerable<VideoMeta> Metas = new VideoMeta[] 7 { 8 new VideoMeta 9 { 10 ID = VideoID.London, 11 Title = "ロンドン", 12 Path = "Video/London" 13 }, 14 new VideoMeta 15 { 16 ID = VideoID.Paris, 17 Title = "パリ", 18 Path = "Video/Paris" 19 }, 20 // 他動画の情報をここに追加していく 21 }; 22 23 /// <summary> 24 /// Videoの情報を取得 25 /// </summary> 26 public static VideoMeta GetMeta(this VideoID id) 27 { 28 foreach (var meta in Metas) 29 { 30 if (meta.ID == id) 31 { 32 return meta; 33 } 34 } 35 Debug.LogError($"存在しないVideo {id}"); 36 return default; 37 } 38} 39 40/// <summary> 41/// ビデオのID 42/// ※ 最初に設定する順番変更禁止。増やす場合は後に追加 43/// </summary> 44public enum VideoID 45{ 46 London = 0, 47 Paris 48 // 他動画のIDをここに追加していく 49} 50 51public class VideoMeta 52{ 53 public VideoID ID; 54 public string Title; 55 public string Path; 56 // 入れたい情報を書き足していく 57}

追記

改めて改良した各クラス追記します。
上記の動画の管理に加えてボタンの連携も実装しました。

ボタンの管理

スクリプト名

ChangVButtonController.cs

設置方法
  1. ChangVButtonController.csとういうスクリプトを作成しAssets配下に設置
  2. ボタンの親を作ってそこにアタッチする

イメージ説明

スクリプト

c#

1using UnityEngine; 2using UnityEngine.Assertions; 3using UnityEngine.Video; 4 5/// <summary> 6/// ボタンの管理 7/// すべてのボタンをこのスクリプトがアタッチされた子に配置 8/// </summary> 9public class ChangVButtonController : MonoBehaviour 10{ 11 [SerializeField] ChangV changV; 12 13 /// <summary> 14 /// Videoが再生中か? 15 /// </summary> 16 public bool IsPlaying => changV.Vp.isPlaying; 17 18 ChangVButton[] buttons; 19 20 void Awake() 21 { 22 buttons = GetComponentsInChildren<ChangVButton>(true); 23 Assert.IsTrue(buttons.Length > 0, "ボタンが0です。すべてのボタンをこのスクリプトがアタッチされた子に配置してください。"); 24 } 25 26 void Start() 27 { 28 foreach (var button in buttons) 29 { 30 button.SetController(this); 31 } 32 changV.Vp.loopPointReached += OnLoopPointReached; 33 } 34 35 public void ChangeVideo(VideoID videoID) 36 { 37 Assert.IsTrue(!IsPlaying, "再生中に再生が呼ばれました"); 38 changV.ChangeVideo(videoID); 39 40 foreach (var button in buttons) 41 { 42 button.gameObject.SetActive(false); 43 } 44 } 45 46 void OnLoopPointReached(VideoPlayer source) 47 { 48 foreach (var button in buttons) 49 { 50 button.gameObject.SetActive(true); 51 } 52 } 53 54 void Reset() 55 { 56 changV = FindObjectOfType<ChangV>(); 57 } 58}

動画の再生

スクリプト名

ChangV.cs

設置方法

既に設置済みだと思うので割愛

スクリプト

c#

1using UnityEngine; 2using UnityEngine.Video; 3 4public class ChangV : MonoBehaviour 5{ 6 public VideoPlayer Vp { get; private set; } 7 8 void Start() 9 { 10 Vp = GetComponent<VideoPlayer>(); 11 //↓VideoPlayerの再生準備ができたとき、OnVideoPlayerPreparedが呼ばれる 12 Vp.prepareCompleted += OnVideoPlayerPrepared; 13 } 14 15 void OnVideoPlayerPrepared (VideoPlayer vp) 16 { 17 vp.Play(); 18 } 19 20 public void ChangeVideo (VideoID id) 21 { 22 //既にVideoPlayerに動画が読み込まれている場合 23 if (Vp.clip != null) 24 { 25 Vp.Stop(); 26 //↓その動画をメモリから解放する 27 Resources.UnloadAsset(Vp.clip); 28 } 29 30 var meta = id.GetMeta(); 31 // var title = meta.Title; 32 33 //動画をメモリに読み込む 34 Vp.clip = Resources.Load<VideoClip>(meta.Path); 35 //↓VideoPlayerに再生準備をさせる 36 Vp.Prepare(); 37 } 38}

動画の再生

スクリプト名

ChangVButton.cs

設置方法

既に設置済みだと思うので割愛 ボタンにアタッチする

スクリプト

c#

1 2using UnityEngine; 3using UnityEngine.UI; 4 5[RequireComponent(typeof(Button))] 6public class ChangVButton : MonoBehaviour 7{ 8 [SerializeField] Button playButton; 9 [SerializeField] VideoID playTarget; 10 11 ChangVButtonController controller; 12 13 void Start() 14 { 15 playButton.onClick.AddListener(ClickPlayButton); 16 } 17 18 public void SetController(ChangVButtonController controller) 19 { 20 this.controller = controller; 21 } 22 23 /// <summary> 24 /// プレイボタンのクリック 25 /// </summary> 26 void ClickPlayButton() 27 { 28 if (!controller.IsPlaying) 29 { 30 controller.ChangeVideo(playTarget); 31 } 32 } 33 34 void Reset() 35 { 36 playButton = GetComponent<Button>(); 37 } 38}

動画の管理スクリプト

スクリプト名

VideoMetaData.cs

設置方法

VideoMetaData.csとういうスクリプトを作成しAssets配下に設置

スクリプト

動画の管理で書いたものと同じもので割愛

投稿2022/05/16 05:30

編集2022/05/16 12:19
IShix

総合スコア1724

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

studyUSAAA

2022/05/16 08:11

お忙しい中、こんなにご丁寧に教えていただき誠にありがとうございました。 おかげさまで無事にボタンを押して動画が再生されたらボタンが非表示になりました! また、動画の管理方法まで教えていただきありがとうございます!「こんな便利な方法もあるのかと目から鱗でした!」 その上で追加でお聞きしたいことがございます。図々しく申し訳ございません。 1.ボタンAを押した場合、動画Aが流れてボタンAが消えるのですがボタンBが残り続けてしまいます。こちらを消すにはどうすれば良いでしょうか? 2.教えていただいた通り動画の管理方法を便利にするスクリプトを追加・修正したのですが 以下の画像のようなコンパイラ エラー CS1502(メソッドに渡された引数の型が、そのメソッドのパラメーターの型と一致しない場合に発生)が出てしまったのですがどうすれば良いでしょうか? (動画の管理より前に教えていただいたやり方で動画の再生自体はできるのでこちらは1.より優先度低めで大丈夫です!最悪元々の方法で試してみます!)
studyUSAAA

2022/05/16 08:13

画像を貼れなかったので文面で失礼します エラー名:ChangVButton.cs(27,32): error CS1503: Argument 1: cannot convert from 'string' to 'VideoID' 該当箇所:ChangVButton.csの ClickPlayButton中のchangV.ChangeVideo(playTarget);です! void ClickPlayButton() { if (!changV.Vp.isPlaying) { changV.ChangeVideo(playTarget); playButton.gameObject.SetActive(false); } }
IShix

2022/05/16 12:21

> 1.ボタンAを押した場合、動画Aが流れてボタンAが消えるのですがボタンBが残り続けてしまいます。 コード書いてみたので参考にしてみてください。本文に追記しました。 > 2.教えていただいた通り動画の管理方法を便利にするスクリプトを追加・修正したのですが 以下の画像のようなコンパイラ エラー CS1502 なぜそうなっているのか分からないのでもう少し分かりやすく本文に追記しました。
studyUSAAA

2022/05/16 15:22

見ず知らずの私にこんなに丁寧に何度も教えていただき本当にありがとうございます。 おかげさまで無事にボタンを押したら非表示になり、動画の管理も成功しました! まだまだ勉強不足でしたので、今回教えていただいた関数を調べて勉強していきたいと思います! 本当にお忙しい中助けていただきありがとうございました!
IShix

2022/05/16 17:37

無事動いたようでよかったです。 僕もネットの色々な情報で育ったのでお互い様です。 将来困った人が居たら教えてあげてください。
studyUSAAA

2022/05/17 05:36

本当にありがとうございました! 自分もIShixさんみたいになれるように頑張ります!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問