unity avpro实现互动影游关键问题

发布于:2025-08-02 ⋅ 阅读:(13) ⋅ 点赞:(0)

创建视频播放器

  • 在Hierarchy面板中右键创建:Video > AVPro Video - MediaPlayer
  • 创建后会生成一个MediaPlayer对象,用于控制视频播放

添加视频资源

  • 将视频文件放入项目的StreamingAssets文件夹下
  • 在MediaPlayer组件的设置中选择要播放的视频文件

在UI上显示视频

  • 创建Canvas对象
  • 在Canvas下添加DisplayUGUI组件用于将视频渲染到UI
  • 将MediaPlayer拖拽到DisplayUGUI组件中

unity avpro切换视频播放

核心思路,需要切换视频时。将当前视频A截一帧图片pic显示。播放器加载第二个视频,等第二个视频B事件MediaPlayerEvent.EventType.FirstFrameReady,延迟一帧将图片pic隐藏即可。

实现简单影游根据选项跳转不同视频播放

主要代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using RenderHeads.Media.AVProVideo;
using TMPro;
using System;


public class Level : MonoBehaviour
{
    public MediaPlayer mediaPlayer;
    public string levelID; // 关卡唯一标识
    public Button op_btn1; // 操作按钮1
    public Button op_btn2;

    public TextMeshProUGUI op_btn1_text;
    public TextMeshProUGUI op_btn2_text;

    public LevelNode levelNode;

    public float targetTime = 0.0f;

    public bool hasTriggered = false;

    public UnityEngine.UI.RawImage displayImage;

    // Start is called before the first frame update
    void Start()
    {
        mediaPlayer.AutoStart = false;
        mediaPlayer.Events.AddListener(OnVideoEvent);
        op_btn1.onClick.AddListener(OnButtonClick_op1);
        op_btn2.onClick.AddListener(OnButtonClick_op2);
        HideOptionsUI();

        Invoke("test", 1.0f); // 延迟1秒显示操作按钮
        displayImage.gameObject.SetActive(false);
    }

    // Update is called once per frame
    void Update()
    {
       
    }

    void FixedUpdate()
    {
        CheckCurrentTime();
    }

    void OnButtonClick_op1()
    {
        Debug.Log("Button 1 clicked in level: " + levelID);
        mediaPlayer.Pause();
        // 在这里添加按钮1的操作逻辑
        FinishLevel(levelNode.op1_level);
    }

    void OnButtonClick_op2()
    {
        Debug.Log("Button 2 clicked in level: " + levelID);
        // 在这里添加按钮2的操作逻辑
        FinishLevel(levelNode.op2_level);
    }

    void ShowOptionsUI()
    {

        op_btn1_text.text = levelNode.op1;
        op_btn2_text.text = levelNode.op2;
        op_btn1.GetComponent<RectTransform>().localPosition = new Vector3(levelNode.op1_x, levelNode.op1_y, 0);
        op_btn2.GetComponent<RectTransform>().localPosition = new Vector3(levelNode.op2_x, levelNode.op2_y, 0);
        op_btn1.gameObject.SetActive(true);
        op_btn2.gameObject.SetActive(true);
    }

    void HideOptionsUI()
    {
        op_btn1.gameObject.SetActive(false);
        op_btn2.gameObject.SetActive(false);
    }

    void OnVideoEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
    {
        switch (et)
        {
            case MediaPlayerEvent.EventType.ReadyToPlay:
                Debug.Log("视频加载完成,准备播放");
                break;
            case MediaPlayerEvent.EventType.Started:
                Debug.Log($"当前时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}视频播放开始");
                break;
            case MediaPlayerEvent.EventType.FirstFrameReady:
                Debug.Log($"当前时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}第一帧渲染完成");
                StartCoroutine(DelayFunction());
                break;
            case MediaPlayerEvent.EventType.FinishedPlaying:
                Debug.Log("视频播放完毕");
                break;
            case MediaPlayerEvent.EventType.FinishedSeeking:
                Debug.Log("跳转到指定时间完成");
                break;
            default:
                //Debug.Log("未知视频事件",et);
                break;
        }
    }

    void CheckCurrentTime()
    {
        float currentTime = (float)mediaPlayer.Control.GetCurrentTime();
        if (targetTime != 0 && currentTime >= targetTime && !hasTriggered)
        {
            hasTriggered = true;
            Debug.Log($"视频已播放到目标时间: {targetTime}秒");
            // 在这里执行你的回调逻辑
            ShowOptionsUI();
        }
    }

    void test()
    {
        StartLevel("1");
    }

    void StartLevel(string levelid)
    {
        LevelNode n = NodeCfg.Instance.GetNode(levelid);
        levelNode = n;
        Debug.Log($"当前时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}加载视频开始");
        string fullpath = System.IO.Path.Combine(Application.streamingAssetsPath, "videos", levelNode.mp4);
        if (!mediaPlayer.OpenMedia(MediaPathType.RelativeToStreamingAssetsFolder, fullpath, false))
        {
            Debug.LogError("Video not found!");
            return;
        }

        if (n.op_time > 0)
        {
            targetTime = n.op_time;
        }
        mediaPlayer.Play();
        Debug.Log($"当前时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}加载视频结束");
    }

    void FinishLevel(string nextlevelid)
    {
        HideOptionsUI();
        hasTriggered = false; // 重置触发状态
        targetTime = 0;
        CaptureAndDisplayLastFrame();
        StartLevel(nextlevelid);
    }

    private void CaptureAndDisplayLastFrame()
    {
        Debug.Log($"当前时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}截图");

        // 创建Texture2D来保存截图
        Texture2D texture = new Texture2D(mediaPlayer.Info.GetVideoWidth(), mediaPlayer.Info.GetVideoHeight(), TextureFormat.ARGB32, false);

        // 截取当前帧(最后一帧)
        mediaPlayer.ExtractFrame(texture);
        
        // 显示截图
        if (displayImage != null)
        {
            displayImage.texture = texture;
        }
        displayImage.gameObject.SetActive(true);

    }

    IEnumerator DelayFunction()
    {
        yield return null; // 暂停一帧
        Debug.Log($"当前时间: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}下一帧执行");
        displayImage.gameObject.SetActive(false);
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到