游戏蛮牛学习群(纯技术交流,不闲聊):959392658
新宝娱乐城博彩打不开 手机端
开发者专栏

关注:2372

当前位置:新宝娱乐城博彩打不开 技术专区 开发者专栏

__________________________________________________________________________________
开发者干货区版块规则:

  1、文章必须是图文形式。(至少2幅图)
      2、文章字数必须保持在1500字节以上。(编辑器右下角有字数检查)
      3、本版块只支持在游戏蛮牛原创首发,不支持转载。
      4、本版块回复不得无意义,如:顶、呵呵、不错......【真的会扣分的哦】
      5、......
__________________________________________________________________________________
查看: 2531|回复: 81
发新帖

新宝娱乐城赌球打不开: [志远] 大话链式编程之Video改造术(三)

[复制链接]  [移动端链接]
排名
9518
昨日变化
5

新宝娱乐城博彩打不开 www.sl6cl.com.cn 4

主题

160

帖子

747

积分

Rank: 9Rank: 9Rank: 9

UID
21402
好友
4
蛮牛币
160
威望
0
注册时间
2014-4-14
在线时间
339 小时
最后登录
2018-12-13

认证开发者

跳转到指定楼层
楼主
发表于 2018-7-16 16:57:09 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本帖最后由 zhiyuan 于 2018-7-16 16:59 编辑

0x00  前言
首先回答一下上篇文章中大家的问题点: 一. 性能消耗问题:
     1).这么多静态方法会不会很占用内存?  表示不会很占用内存,我们只是用来扩展类方法而已,主要逻辑代码不在扩展方法中直接写=-=。
     2).频繁调用Update会不会很消耗资源?  我们是采用委托事件的方式进行调用不会很消耗的,且我们没有频繁调用 - -
二. 复杂度问题:
     1).这样书写代码会不会增加代码的复杂度?  表示对新手来说会的,但是万事无规则不成方圆,我觉得要进度,首先要先多看,多学,然后开始创造自己的规则!对老手来说这点复杂度往往可以解决很多问题!也节省很多麻烦
     2).新手该如何学会这种风格,需要哪些前置的条件?   首先数据结构要玩好,其次OO概念要清晰(面向对象),设计模式要清楚,最好去看一下两本书 大话设计模式大话数据结构,设计模式很重要!
0x01 本篇目标
对unity中VideoPlayer组件进行简单的改造,对VideoPlayer中存在的bug进行规避性的修复,实现基于VideoPlayer的透明视频播放。
已知VideoPlayer中的bug没有详细测试?。?! 1.frameReady 事件没有正确的执行 也就是说我们要在某帧执行事件是没法直接实现的
我们要制作的函数列表
1.GetEventDriver
2.SetStyle
3.OnPrepareCompleted
4.OnLoopPointReached
5.OnUpdate
当然还有很多可以改造 这里只是举一个例子
先看一下成品演示


0x02  首先老规矩 先实现驱动器类  下面为驱动器类代码
[C#] 纯文本查看 复制代码
    /// <summary>
    /// 视频事件驱动器
    /// </summary>
    public class VideoEventDriver : MonoBehaviour
    {
        /// <summary>
        /// 委托定义
        /// </summary>
        /// <param name="source">播放器</param>
        /// <param name="frameIdx">当前帧</param>
        /// <param name="time">当前时间</param>
        public delegate void FrameReadyEventHandler(VideoPlayer source, float frameIdx,float time);
        /// <summary>
        /// 委托实例
        /// </summary>
        public VideoEventDriver.FrameReadyEventHandler onUpdate = null;
        private VideoPlayer videoPlayer = null;
        /// <summary>
        /// 驱动方法
        /// </summary>
        /// <param name="videoPlayer_"></param>
        /// <param name="onUpdate_"></param>
        public void OnUpdate(VideoPlayer videoPlayer_, VideoEventDriver.FrameReadyEventHandler onUpdate_)
        {
            onUpdate = onUpdate_;
            videoPlayer = videoPlayer_;
        }
        /// <summary>
        /// MonoBehaviour Update 更新驱动函数
        /// </summary>
        private void Update()
        {
            if (onUpdate != null && videoPlayer!=null)
            {
                if (videoPlayer.isPlaying)
                {
                    onUpdate(videoPlayer, (float)videoPlayer.frame, (float)videoPlayer.time);
                }
            }
        }
    }


上面代码 我们实现了一个FrameReadyEventHandler的事件 并且 定义了onUpdate委托 ,利用unity的Update生命周期去驱动onUpdate委托的执行。
下面我们实现一下
GetEventDriver、OnLoopPointReached、OnPrepareCompleted、OnUpdate
注意这里我们是扩展方法实现 所以先定义一个静态的类 名为 VideoExtend
1).GetEventDriver
[C#] 纯文本查看 复制代码
        /// <summary>
        /// 获得视频事件驱动
        /// </summary>
        /// <param name="videoPlayer"></param>
        /// <returns></returns>
        private static VideoEventDriver GetEventDriver(VideoPlayer videoPlayer)
        {
            VideoEventDriver videoEventDriver = videoPlayer.gameObject.GetComponent<VideoEventDriver>();
            if (videoEventDriver == null)
            {
                videoEventDriver = videoPlayer.gameObject.AddComponent<VideoEventDriver>();
            }
            return videoEventDriver;
        }

这个不需要解释吧!

2).OnLoopPointReached  OnPrepareCompleted
[C#] 纯文本查看 复制代码
 /// <summary>
        ///  播放结束或播放到循环的点时回调
        /// </summary>
        /// <param name="videoPlayer"></param>
        /// <param name="onLoopPointReached"></param>
        /// <returns></returns>
        public static VideoPlayer OnLoopPointReached(this VideoPlayer videoPlayer, VideoPlayer.EventHandler onLoopPointReached)
        {
            videoPlayer.loopPointReached += onLoopPointReached;
            return videoPlayer;
        }
        /// <summary>
        /// 视频准备完成时回调
        /// </summary>
        /// <param name="videoPlayer"></param>
        /// <param name="onPrepareCompleted"></param>
        /// <returns></returns>
        public static VideoPlayer OnPrepareCompleted(this VideoPlayer videoPlayer, VideoPlayer.EventHandler onPrepareCompleted)
        {
            videoPlayer.prepareCompleted += onPrepareCompleted;
            return videoPlayer;
        }

利用原组件已有的事件,对其进行改造为链式!


3).OnUpdate
[C#] 纯文本查看 复制代码
        /// <summary>
        /// 视频播放中回调
        /// </summary>
        /// <param name="videoPlayer"></param>
        /// <param name="onUpdate"></param>
        /// <returns></returns>
        public static VideoPlayer OnUpdate(this VideoPlayer videoPlayer, VideoEventDriver.FrameReadyEventHandler onUpdate)
        {
            GetEventDriver(videoPlayer).OnUpdate(videoPlayer, onUpdate);
            return videoPlayer;
        }


到此我们的基础功能就ok了
我们可以这样用



0x03  继续改进
上面基本实现了功能,但是没有对功能进行大幅度的扩展,下面我们就扩展点东西,比如:对透明视频的支持=-=
要支持透明视频大家都在用的方法就是对视频限制要求并且编写对应的shader
因为这里不是专门讲解shader代码的,所以我只说一下原理部分然后放上我写的shader


如上图就是一个视频的一帧,我们可以把这个图片从中间一分为二
图1       图2
我这里截的不准 凑活着看吧
然后用图2的像素颜色 作为 图1 的像素透明度,也就是用图2的取抠图1。
shader如下
[C#] 纯文本查看 复制代码
Shader "zFrame/Video/Transparent" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
                _TransVal("Transparency Value", Range(0,10)) = 1.0
                _Color("_Color",Color) = (1,1,1,1)
                _Emission("_Emission",float) = 1
        }
                SubShader{
                        Tags { "RenderType"="Opaque" "Queue"="Transparent"} 
                        LOD 200
                        cull front
                        CGPROGRAM
                #pragma surface surf Lambert  alpha 
                sampler2D _MainTex;
                float4  _Color;
                float _TransVal;
                float _Emission;
                struct Input {
                        float2 uv_MainTex;
                };
                void surf(Input IN, inout SurfaceOutput o) {
                        half4 h = half4(0, 0, 0, 1);
                        if (IN.uv_MainTex.x >= 0.5)
                        {
                                h.a = 0;
                        }
                        else
                        {
                                half4 he = tex2D(_MainTex, half2(IN.uv_MainTex.x + 0.5, IN.uv_MainTex.y));
                                h.a = (he.r + he.g + he.b)*_TransVal;
                                if(h.a>1)
                                {
                                        h.a =1;        
                                }
                                half4 c = tex2D(_MainTex, IN.uv_MainTex);
                                //o.Albedo = c.rgb;
                                o.Emission = c*_Emission*_Color;
                        }
                        o.Alpha = h.a;
                }
                ENDCG
                cull back
                CGPROGRAM
                #pragma surface surf Lambert alpha 
                sampler2D _MainTex;
                float4  _Color;
                float _TransVal;
                float _Emission;
                struct Input {
                        float2 uv_MainTex;
                };
                void surf(Input IN, inout SurfaceOutput o) {
                        half4 h = half4(0, 0, 0, 1);
                        if (IN.uv_MainTex.x >= 0.5)
                        {
                                h.a = 0;
                        }
                        else
                        {
                                half4 he = tex2D(_MainTex, half2(IN.uv_MainTex.x + 0.5, IN.uv_MainTex.y));
                                h.a = (he.r + he.g + he.b)*_TransVal;
                                if(h.a>1)
                                {
                                        h.a =1;        
                                }
                                half4 c = tex2D(_MainTex, IN.uv_MainTex);
                                o.Emission = c*_Color*_Emission;
                        }
                        o.Alpha = h.a;
                }
                ENDCG
        }
}


这是一个双面的surf透明shader 如果只需要一面 删掉cull back以下代码
下面我们来继续实现代码功能
1.SetMeshRenderer       应对MeshRenderer渲染的对象(3D对象)私有的
2.SetRawImage 应对RawImage渲染的对象(UI部分)私有的
3.SetMaterial    渲染顺序的封装 私有的
4.SetStyle   用户可调用的扩展方法
这里直接贴代码了
[C#] 纯文本查看 复制代码
        /// <summary>
        /// MeshRenderer 渲染
        /// <summary>
        private static bool SetMeshRenderer(VideoPlayer videoPlayer, VideoStyle videoStyle, bool Add = false)
        {
            MeshRenderer meshRenderer = videoPlayer.gameObject.GetComponent<MeshRenderer>();

            if (meshRenderer == null && !Add)
            {
                return false;
            }
            else if (meshRenderer == null)
            {
                meshRenderer = videoPlayer.gameObject.AddComponent<MeshRenderer>();
            }
            switch (videoStyle)
            {
                case VideoStyle.Default:
                    meshRenderer.materials = new Material[] { new Material(Shader.Find("zFrame/Video/Default")) };
                    break;
                case VideoStyle.Transparent:
                    meshRenderer.materials = new Material[] { new Material(Shader.Find("zFrame/Video/Transparent")) };
                    break;
                default:
                    meshRenderer.materials = new Material[] { new Material(Shader.Find("zFrame/Video/Default")) };
                    break;
            }

            RenderTexture renderTexture = new RenderTexture((int)videoPlayer.clip.width, (int)videoPlayer.clip.height, 24);
            videoPlayer.renderMode = VideoRenderMode.RenderTexture;
            videoPlayer.targetTexture = renderTexture;
            meshRenderer.material.SetTexture("_MainTex", renderTexture);
            meshRenderer.material.SetTextureScale("_MainTex", new Vector2(0.5f, 1f));
            return true;
        }
        /// <summary>
        /// RawImage 渲染
        /// <summary>
        private static bool SetRawImage(VideoPlayer videoPlayer, VideoStyle videoStyle, bool Add = false)
        {
            RawImage rawImage = videoPlayer.gameObject.GetComponent<RawImage>();

            if (rawImage == null && !Add)
            {
                return false;
            }
            else if (rawImage == null)
            {
                rawImage = videoPlayer.gameObject.AddComponent<RawImage>();
            }
            switch (videoStyle)
            {
                case VideoStyle.Default:
                    rawImage.material = new Material(Shader.Find("zFrame/Video/Default"));
                    break;
                case VideoStyle.Transparent:
                    rawImage.material = new Material(Shader.Find("zFrame/Video/Transparent"));
                    break;
                default:
                    rawImage.material = new Material(Shader.Find("zFrame/Video/Default"));
                    break;
            }


            RenderTexture renderTexture = new RenderTexture((int)videoPlayer.clip.width, (int)videoPlayer.clip.height, 24);
            videoPlayer.renderMode = VideoRenderMode.RenderTexture;
            videoPlayer.targetTexture = renderTexture;
            rawImage.material.SetTexture("_MainTex", renderTexture);
            rawImage.material.SetTextureScale("_MainTex", new Vector2(0.5f, 1f));
            return true;
        }
        /// <summary>
        /// 渲染顺序封装
        /// </summary>
        private static void SetMaterial(VideoPlayer videoPlayer, VideoStyle videoStyle)
        {
            if (SetRawImage(videoPlayer, videoStyle))
            {
                return;
            }
            else if (SetMeshRenderer(videoPlayer, videoStyle))
            {
                return;
            }
            SetMeshRenderer(videoPlayer, videoStyle, true);
        }
        /// <summary>
        /// 设置视频样式 
        /// </summary>
        /// <param name="videoPlayer">视频组件</param>
        /// <param name="videoStyle">样式枚举</param>
        /// <returns></returns>
        public static VideoPlayer SetStyle(this VideoPlayer videoPlayer, VideoStyle videoStyle = VideoStyle.Default)
        {
            SetMaterial(videoPlayer, videoStyle);

            return videoPlayer;
        }
//别忘了我们的枚举

public enum VideoStyle{
 /// <summary>
/// 默认样式
/// </summary>
Default,
/// <summary>
/// 透明样式
/// </summary>
Transparent
}



到此我们的视频改造差不多要完工了。但是我们发现几个可以改进的地方
1.我们发现我们用的话,要先拿到VideoPlayer。能不能有一个方法扩展自GameObject然后直接获取VideoPlayer,没有则创建。
2.我们还没有实现VideoPlayer的大部分功能的改造。
以上问题欢迎大家自己试着写写。

下面完整代码回复拿走
游客,如果您要查看本帖隐藏内容请回复
其他章节
//www.sl6cl.com.cn/forum-47-497-1.html





评分

参与人数 1蛮牛币 +10 收起 理由
ubbs + 10 神马都是浮云

查看全部评分


5熟悉之中
609/1000
排名
4025
昨日变化
2

3

主题

66

帖子

609

积分

Rank: 5Rank: 5

UID
259967
好友
1
蛮牛币
378
威望
0
注册时间
2017-12-16
在线时间
176 小时
最后登录
2018-12-11
沙发
发表于 2018-7-16 17:02:42 | 只看该作者
大佬,我来给你助阵了

2初来乍到
105/150
排名
14910
昨日变化
6

0

主题

15

帖子

105

积分

Rank: 2Rank: 2

UID
267376
好友
0
蛮牛币
17
威望
0
注册时间
2018-2-1
在线时间
40 小时
最后登录
2018-10-30
板凳
发表于 2018-7-16 17:29:32 | 只看该作者
真的棒棒 支持

5熟悉之中
891/1000
排名
2455
昨日变化
9

0

主题

56

帖子

891

积分

Rank: 5Rank: 5

UID
263664
好友
0
蛮牛币
3030
威望
0
注册时间
2018-1-9
在线时间
271 小时
最后登录
2018-12-13
地板
发表于 2018-7-16 17:46:56 | 只看该作者

7日久生情
3433/5000
排名
1711
昨日变化
3

0

主题

2127

帖子

3433

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
219676
好友
1
蛮牛币
2625
威望
0
注册时间
2017-7-12
在线时间
558 小时
最后登录
2018-12-13

活力之星

5#
发表于 2018-7-16 17:53:26 | 只看该作者
谢谢分享

6蛮牛粉丝
1033/1500
排名
3093
昨日变化
1

1

主题

166

帖子

1033

积分

Rank: 6Rank: 6Rank: 6

UID
139214
好友
0
蛮牛币
1554
威望
0
注册时间
2016-3-12
在线时间
408 小时
最后登录
2018-11-22
6#
发表于 2018-7-16 17:58:54 | 只看该作者
6666666666666666

7日久生情
1917/5000
排名
4344
昨日变化

0

主题

1335

帖子

1917

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
267381
好友
6
蛮牛币
3212
威望
0
注册时间
2018-2-1
在线时间
258 小时
最后登录
2018-11-6
7#
发表于 2018-7-16 18:21:40 | 只看该作者
炒鸡棒,谢谢分享。
[发帖际遇]: 墨染青天 乐于助人,奖励 3 蛮牛币. 幸运榜 / 衰神榜

4四处流浪
439/500
排名
8015
昨日变化
1

0

主题

226

帖子

439

积分

Rank: 4

UID
281167
好友
1
蛮牛币
884
威望
0
注册时间
2018-5-14
在线时间
65 小时
最后登录
2018-12-10
8#
发表于 2018-7-16 19:24:39 | 只看该作者
厉害了,感谢分享

5熟悉之中
510/1000
排名
4004
昨日变化
19

0

主题

29

帖子

510

积分

Rank: 5Rank: 5

UID
282063
好友
0
蛮牛币
2270
威望
0
注册时间
2018-5-21
在线时间
125 小时
最后登录
2018-12-13
9#
发表于 2018-7-16 21:04:04 | 只看该作者
学习了,谢谢

5熟悉之中
887/1000
排名
2866
昨日变化
5

2

主题

76

帖子

887

积分

Rank: 5Rank: 5

UID
9302
好友
1
蛮牛币
1800
威望
0
注册时间
2013-12-1
在线时间
313 小时
最后登录
2018-12-13
10#
发表于 2018-7-17 08:18:06 | 只看该作者
支持大佬!

5熟悉之中
935/1000
排名
1905
昨日变化
5

0

主题

45

帖子

935

积分

Rank: 5Rank: 5

UID
165111
好友
0
蛮牛币
1961
威望
0
注册时间
2016-8-31
在线时间
208 小时
最后登录
2018-12-13
11#
发表于 2018-7-17 08:57:30 | 只看该作者
666666666666

5熟悉之中
761/1000
排名
2903
昨日变化
10

0

主题

47

帖子

761

积分

Rank: 5Rank: 5

UID
233767
好友
0
蛮牛币
841
威望
0
注册时间
2017-7-23
在线时间
224 小时
最后登录
2018-12-13
12#
发表于 2018-7-17 09:01:48 | 只看该作者
saaaaaaaaaaaaaaaaaaaaa

7日久生情
2273/5000
排名
901
昨日变化

0

主题

232

帖子

2273

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
147766
好友
0
蛮牛币
608
威望
0
注册时间
2016-5-6
在线时间
938 小时
最后登录
2018-12-13
QQ
13#
发表于 2018-7-17 09:08:02 | 只看该作者

真的棒棒 支持

5熟悉之中
712/1000
排名
4411
昨日变化
1

2

主题

118

帖子

712

积分

Rank: 5Rank: 5

UID
252095
好友
1
蛮牛币
590
威望
0
注册时间
2017-11-2
在线时间
270 小时
最后登录
2018-12-13
14#
发表于 2018-7-17 09:45:11 | 只看该作者
跪拜大神
[发帖际遇]: 一个袋子砸在了 一切为了孩子 头上,一切为了孩子 赚了 1 蛮牛币. 幸运榜 / 衰神榜

6蛮牛粉丝
1425/1500
排名
1470
昨日变化

0

主题

93

帖子

1425

积分

Rank: 6Rank: 6Rank: 6

UID
49519
好友
1
蛮牛币
3182
威望
0
注册时间
2014-10-17
在线时间
502 小时
最后登录
2018-12-6
15#
发表于 2018-7-17 09:51:24 | 只看该作者
看看源码怎么样

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

快速回复 新宝娱乐城博彩打不开 返回列表
  • 险!年近八旬老人就医晕倒 赞!医生不顾腰伤抱起抢救(图) 2018-12-13
  • 政府牵头凯迪集团债委会 违约处理牵融资市场神经 2018-12-13
  • 香港田径锦标赛飞人夺冠 2018-12-12
  • 李思思元元月亮姐姐 盘点央视主持人与子女温馨合影 2018-12-11
  • “忻州工匠”“忻州技能标兵”评选活动启动 2018-12-11
  • 包住内力,在不断变化中寻找契机,可出击可借力亦可卸力。 2018-12-10
  • 广州中考首用计算机辅助命题 满满的广州元素 2018-12-09
  • 植树、采茶、挖野菜…… 这才是春天正确的打开方式 2018-12-08
  • 【纯黑】《生化危机7》克里斯DLC不是英雄 2018-12-08
  • 150块地铁灯牌高调“炫父” 温暖南京城 2018-12-07
  • 【光明网专论】鞠立新:习近平新时代中国特色社会主义经济思想的内涵、逻辑和特质 2018-12-06
  • 江西“放管服”改革再出实招 2018-12-05
  • 首列商用磁浮2.0版列车下线 适用中心城市到卫星城间交通--旅游频道 2018-12-05
  • 空警-500改进型新照曝光,监控效率成倍提升 2018-12-04
  • 对美敲诈老手不能软越软越诈你要打就来 2018-12-04
  • 213| 460| 914| 61| 168| 304| 645| 975| 786| 582|