unity中一个完整的视频ui

本文详细描述了如何在Unity中使用组件如RawImage、Slider、Videoplayer等构建一个具有交互性功能的视频播放器,包括滑动条控制播放进度、底部按钮控制快进/快退/暂停,以及音量调整和倍速设置。教程还涉及了鼠标事件处理和UI设计技巧。
摘要由CSDN通过智能技术生成

*重新做了一份,修改了之前的,文末有完整项目

 

右侧目录跳转

场景搭建

一张图简述:c6304117979443e7afe01662a1d55e10.png

play和音量是image,倍速和时间是text,这是最初版的,后续会创建一些子物体

记得给那三个image挂button组件(或者之间创建仨button然后拉成圆形放在左下角)和一个text子物体

 

*如果你做到后面发现ui缩放过小可以调canvas的scale,看不清字可以调canvasscaler,同时我这里的canvas是worldspace的

202d3992add147bb910261ce0313d40e.png

然后创建这仨脚本:

7e67b497ec4b4f1ab78ba6c5d4076529.png分别挂在rawimage,slider和canvas上

 

 

视频

(站里已经有很多人做过了,这里还是写一份吧)

新建一个rendertexture,设置一下宽和高(1920*1080一般)

然后在rawimage上添加一个videoplayer组件

把你的mp4文件拖到videoplayer的vidoeclip

把rendertexture拖到rawimage的texture和videoplayer的targettexture

点一下运行,你的rawimage就应该已经在播放了

 

在rawimage上加audiosource组件,然后把videoplayer的audio output mode改成audio source,再把刚加的组件拖到audio source的位置接口

a690717e402444c48615bfef6e11af42.png

滑动条

(这个站内也有,简单讲讲)

代码:

SliderControl.cs 挂在slider上

using UnityEngine;
using UnityEngine.EventSystems;
public class SliderControl : MonoBehaviour, IDragHandler, IEndDragHandler, IBeginDragHandler
{
    public UImain uimain;
    //是否拖拽进度条(滑动条)
    public bool isDragMove;
    public void OnDrag(PointerEventData eventData)
    {

        isDragMove = true;

    }

    public void OnEndDrag(PointerEventData eventData)
    {
        uimain.MoveSlider();
        isDragMove = false;

    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        isDragMove = true;
    }
}

uimain.cs

//UImain.cs
//start函数中
 videoslider = this.transform.GetChild(0).GetChild(1).GetChild(0).GetComponent<Slider>();//UIBG->Slider


public void MoveSlider()
    {
        videoplayer.time = videoplayer.length * videoslider.value;

    }

在update里加上

    if (!sliderControl.isDragMove)
        {
            videoslider.value = (float)(videoplayer.time / videoplayer.length);
        }

就这些,至于滑动条的效果,贴图什么的就是自己发挥的地方了

我做成了类似b站的效果

07819a2efe20403e906aca7aaae45ed7.png

 

 

底部按钮(快进,暂停,快退)

直接整仨button,这里我偷懒直接用的text没重新画材质,最后效果是这样的

c1fa930e6b8c4b9a9d51b2cde41436f8.png

此外这里需要在rawimage下新建一个image作为tip,然后在tip下新建text

并自行设置样式

4753fb22beaa4383ab84a0da856e1ca3.png

代码

 

 uimain.cs

    public void Backward()
    {
        videoplayer.time -= 5.0;
        videoplayer.transform.GetChild(2).GetChild(0).GetComponent<Text>().text = "快退5秒";
        videoplayer.transform.GetChild(2).gameObject.SetActive(true);
        PlayPPT();
        Invoke("CloseTip", 0.5f);
    }
    public void FastForward()
    {
        videoplayer.time += 5.0;
        videoplayer.transform.GetChild(2).GetChild(0).GetComponent<Text>().text = "快进5秒";
        videoplayer.transform.GetChild(2).gameObject.SetActive(true);
        PlayPPT();
        Invoke("CloseTip", 0.5f);
    }
    public void CloseTip()
    {
        videoplayer.transform.GetChild(2).gameObject.SetActive(false);
    }
    public void PausePPT()
    {

        isPause = true;
        videoplayer.Pause();
        videoplayer.transform.GetChild(0).gameObject.SetActive(true);


    }
    public void PlayPPT()
    {
        isPause = false;
        videoplayer.GetComponent<VideoPlayer>().Play();
        videoplayer.transform.GetChild(0).gameObject.SetActive(false);
    }

说明

其中backward是快退5s,fastforward是快进5s,

pauseppt是暂停,ispause是个bool,存在是因为我有点一次暂停再点继续的需求

名字都是随便取的毕竟我这里只是练手的项目

这三个函数直接挂在三个button的onclick上,就是最下面那个88e03b82ea5a42d7a17984357002d71d.png

 videoplayer.transform.GetChild(2).GetChild(0).GetComponent<Text>().text = "快进5秒";

这个是一个提示,点快进快退会弹一个小image,然后显示后面的内容

 

 videoplayer.transform.GetChild(0).gameObject.SetActive(true);

这是那个暂停按钮(rawimage下的play),暂停就出现,播放就失活,同时别忘了为它加上button组件,并把playppt赋给它

声音

“音量”这个物体同样是一个空物体,他的范围(unity中按t可以看到)要包括图片和slider

c18bc12edfae4a3382e3894fdb1c483a.png

新建一个image,大小为整个“音量”的大小减去UIBG的部分,命名为sliderbg

然后把slider拖进去

 image和sliderbg最好有交界,避免出现鼠标划过去音量条闪烁的问题

然后自定义你的slider形式即可,注意value为0时handle在下方即可

73176b832ff44410b2d59362d309b046.png

做好就是这个样子

 

然后加组件:

“音量”:60e4eb6b24954195a3903ac8e6914ebc.png

喇叭图标:de24efd85c4b4f008eec942890a53606.png

sliderbg:9c4c39df547841ddad6767e0b6d7079f.png

slider:45576bc0bef04b1084b433301ee885a7.png

记得在canvas中完成拖拽(部分已经在代码中写好了的就不需要了):

acbf61c57d1f4c99a9df6dc24eaec3f9.png物体“音量”和图片“音量”是不一样的需要注意

 

如果你觉得这个喇叭图片有点大可以给他加一个空父物体,然后修改一点代码就好

代码

    public SliderControl sliderControl;
    public GameObject volume;
    public Sprite sound;
    public Sprite Mute;
    bool isVolumeShow = false;
    void Start()
    {
        sliderControl= GameObject.FindObjectOfType<SliderControl>();
        volume = this.transform.GetChild(0).GetChild(1).GetChild(2).gameObject;
    }

    void Update()
    {
         if (!isVolumeShow)
        {
            volume.transform.GetChild(1).gameObject.SetActive(false);
        }
        pptvideo.playbackSpeed = speed;
    }
    public void ChangeVolume()
    {
       // 将视频音量设置为滑动条的值
        videoplayer.GetComponent<AudioSource>().volume = volume.transform.GetChild(1).GetChild(0).GetComponent<Slider>().value;
        volume.transform.GetChild(1).GetChild(1).GetComponent<Text>().text = ((int)(volume.transform.GetChild(1).GetChild(0).GetComponent<Slider>().value * 100)).ToString();
        if (videoplayer.GetComponent<AudioSource>().volume == 0)
        {
            volume.transform.GetChild(0).GetComponent<Image>().sprite = Mute;
        }
        else
        {
            if (volume.transform.GetChild(0).GetComponent<Image>().sprite == Mute)
            {
                volume.transform.GetChild(0).GetComponent<Image>().sprite = sound;
            }
        }
    }
    public void CloseVolume()
    {
        isVolumeShow = false;
    }
    public void ShowVolume()
    {
        isVolumeShow = true;
        volume.transform.GetChild(1).gameObject.SetActive(true);
    }

 

 

倍速

这里是5个倍速(0.5,1,1.25,1.5,2,可以更多,自己加就是了)

6ca5ba87637048eb9ba4e416e80ae15d.png(注意,“倍速”这个物体是个空物体,文字是title显示的)

别忘了五个speed都加上button组件

然后为各个物体添加eventtrigger:

“倍速”:cfa7ed68f81349e091f96ab4d4242a4b.png

title:f739c555768d4fccba6c730450364517.png

如果觉得手调倍速内容的位置比较麻烦可以在content(image,颜色为黑色有一定透明)上加一个vertical layout group,然后把六个勾都勾上

代码

uimain.cs(脚本挂在canvas上)

    bool isHover = false;
    void Update()
    {
        if (!isHover)
        {
            GameObject.Find("倍速").transform.GetChild(1).gameObject.SetActive(false);
            isHover = true;
        }
         videoplayer.playbackSpeed = speed;
    }
    /// <summary>
    /// 修改倍速
    /// </summary>
    /// <param name="speed">修改后的值,由编辑器界面写死</param>
    public void ChangeSpeed(float speed)
    {
        this.speed = speed;
        GameObject.Find("倍速").transform.GetChild(1).gameObject.SetActive(false);//更换倍速之后关掉这个部分
        PlayPPT();//暂停部分的bug 的补丁
    }
    //修改状态
    public void ChangeClose()
    {
        isHover = false;
    }
    public void ShowXSpeedUI()
    {
        GameObject.Find("倍速").transform.GetChild(1).gameObject.SetActive(true);
        isHover = true;
        //高亮当前倍速
        foreach (Transform item in GameObject.Find("倍速").transform.GetChild(1))
        {
            if (item.gameObject.GetComponent<Text>().text == "x" + speed)
            {
                item.gameObject.GetComponent<Text>().color = Color.blue;
            }
            else
            {
                item.gameObject.GetComponent<Text>().color = Color.white;

            }
        }
    }

 

说明

 

 

 

效果:

当鼠标进入title的范围中时触发ShowXSpeedUI,将content激活

此时当鼠标在“倍速”的范围中时content不会失活,还可以点击倍速进行切换,当前倍速为蓝色,点击之后content失活

 

时间

新建一个text即可

代码

public void MatchTime()
    {
        int curm = (int)pptvideo.time / 60;
        int curs = (int)pptvideo.time % 60;
        timeText.text = $"{curm:D2}:{curs:D2}/{(int)pptvideo.length / 60:D2}:{(int)pptvideo.length % 60:D2}";
    }

timetext就是新建的那个text,拿到其中的text组件,然后在update里一直调用就好了

 

暂停

这个暂停值得我单开一小节

我想实现的效果类似常规播放器(或者说b站那种效果)

鼠标出现在屏幕中时下方ui出现,点击上方无ui空白区域暂停视频,点击有ui的区域无效

这个东西还挺不好弄的,直接用pointerclick会按任何鼠标键都生效,也不会区分有无ui

所以我最后想到的办法是——用ray

ray是不能识别到ui元素的,所以需要在ui和ground之间加一层实体,我是把ground复制了一份(称为clickposition)然后将scale的z调成0,再把meshrender删掉,这样它就没有厚度也没有材质,但确实能被ray检测到

建议先调好位置再删meshrender,不然不好操作

 

代码

 ClickToPauseTheScreen.cs

进阶效果的,可以不要,会有一些bug,没找到解决办法就只能打补丁了,挂在rawimage上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class ClickToPauseTheScreen : EventTrigger
{
    private UImain uimain;
    public GameObject clickposition;

    void Start()
    {
        uimain = GameObject.FindObjectOfType<UImain>();
        clickposition = GameObject.Find("clickposition");
    }


    public override void OnPointerEnter(PointerEventData eventData)
    {
        uimain.ShowPPTUI();
        base.OnPointerEnter(eventData);
    }
    public override void OnPointerExit(PointerEventData eventData)
    {
        uimain.ClosePPTUI();
        base.OnPointerExit(eventData);
    }
}

另一部分写在关于人物控制的地方,我这里省事就直接控制的摄像机

写一个脚本挂在摄像机上,在update函数里这样写

 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit))
        {
            if (Input.GetMouseButtonDown(0))
            {
                if (hit.collider.name == "clicktopause")
                {
                    uimain.PausePPT();
                }
                
            }
        }

 

代价是任何范围内的点击操作都会暂停,但是没关系加一个playppt就好了

 

完整文件

 

有一些写的过程中没删掉的冗余代码,但是

嗯……能看懂就行

https://pan.baidu.com/s/1oyAQyJvRpYmo0L8QFT86xA?pwd=jv9u 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值