【游戏技术群】959392658  【游戏出海群】12067810
新宝娱乐城博彩打不开 手机端
开发者专栏

关注:2422

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

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

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

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

[复制链接]  [移动端链接]
排名
9493
昨日变化
4

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

主题

174

帖子

810

积分

Rank: 9Rank: 9Rank: 9

UID
21402
好友
4
蛮牛币
58
威望
0
注册时间
2014-4-14
在线时间
381 小时
最后登录
2019-2-22

认证开发者

跳转到指定楼层
楼主
发表于 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





评分

参与人数 2蛮牛币 +10 鲜花 +2 收起 理由
13810570019 + 2 很给力!
ubbs + 10 神马都是浮云

查看全部评分


5熟悉之中
636/1000
排名
3940
昨日变化
12

3

主题

68

帖子

636

积分

Rank: 5Rank: 5

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

2初来乍到
105/150
排名
15176
昨日变化
3

0

主题

15

帖子

105

积分

Rank: 2Rank: 2

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

6蛮牛粉丝
1036/1500
排名
2071
昨日变化
8

0

主题

57

帖子

1036

积分

Rank: 6Rank: 6Rank: 6

UID
263664
好友
0
蛮牛币
9848
威望
0
注册时间
2018-1-9
在线时间
319 小时
最后登录
2019-2-22

迈向小康

地板
发表于 2018-7-16 17:46:56 | 只看该作者

7日久生情
3555/5000
排名
1563
昨日变化
5

0

主题

2131

帖子

3555

积分

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

UID
219676
好友
1
蛮牛币
2826
威望
0
注册时间
2017-7-12
在线时间
604 小时
最后登录
2019-2-22

活力之星

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

6蛮牛粉丝
1084/1500
排名
3009
昨日变化
2

1

主题

168

帖子

1084

积分

Rank: 6Rank: 6Rank: 6

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

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

0

主题

1333

帖子

1917

积分

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

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

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

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熟悉之中
686/1000
排名
3078
昨日变化
18

0

主题

40

帖子

686

积分

Rank: 5Rank: 5

UID
282063
好友
0
蛮牛币
3138
威望
0
注册时间
2018-5-21
在线时间
170 小时
最后登录
2019-2-22
9#
发表于 2018-7-16 21:04:04 | 只看该作者
学习了,谢谢
5熟悉之中
973/1000
排名
2542
昨日变化
1

2

主题

76

帖子

973

积分

Rank: 5Rank: 5

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

6蛮牛粉丝
1012/1500
排名
1768
昨日变化
6

0

主题

46

帖子

1012

积分

Rank: 6Rank: 6Rank: 6

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

5熟悉之中
861/1000
排名
2523
昨日变化
6

0

主题

50

帖子

861

积分

Rank: 5Rank: 5

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

7日久生情
2444/5000
排名
806
昨日变化
1

0

主题

251

帖子

2444

积分

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

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

真的棒棒 支持

5熟悉之中
725/1000
排名
4444
昨日变化
2

2

主题

121

帖子

725

积分

Rank: 5Rank: 5

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

6蛮牛粉丝
1452/1500
排名
1476
昨日变化
1

0

主题

93

帖子

1452

积分

Rank: 6Rank: 6Rank: 6

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

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

本版积分规则

快速回复 新宝娱乐城博彩打不开 返回列表
  • “人民体育 健康中国”赛事日历 2019-02-22
  • 孕期压力大影响胎儿大脑发育 2019-02-22
  • 特朗普和金正恩先后抵达嘉佩乐酒店 会晤即将开始 2019-02-21
  • 林彬杨实地督导九江高铁新区规划建设工作 2019-02-21
  • 春节我在岗:爸妈,儿子在军营给您们拜年了 2019-02-20
  • 搂住所言延退对于企业和零活就业者或专家型科技工作者而言很恰当,可是对于公务员这一群体来说延退可能导致利益固化行政僵化,这是普罗大众不能够容忍的。 2019-02-19
  • 与名画撞脸,在博物馆发现自己“前世”是怎样的体验 2019-02-18
  • 十万海棠闹新春 重庆“棠城”邀你来赏花 2019-02-18
  • 三晋史话“胡服骑射”的赵武灵王为何被饿死? 2019-02-17
  • 地采暖新品类 洛基木业“石墨烯发热地板”探索产业化新方向 2019-02-17
  • CAMEL骆驼品牌简介文章中国国家地理网 2019-02-16
  • 7600元一支抗癌药缺货因价廉? 2019-02-16
  • 【新媒体矩阵】河北头条 2019-02-15
  • 卖假证当黄牛 日韩3男子倒卖AKB48演唱会门票被捕 2019-02-14
  • 2020年产销整车60万辆以上 汽车之都或成杭州新称号 2019-02-13
  • 697| 203| 681| 347| 668| 466| 919| 1| 145| 51|