zoukankan      html  css  js  c++  java
  • U3D 协程和www

    1、一个应用程序一般对应一个进程,一个进程一般有一个主线程,还有若干个辅助线程,线程之间是平行运行的,在线程里面可以开启协程,让程序在特定的时间内运行。
    2协程和线程的区别是:协程避免了无意义的调度,由此可以提高性能,但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力。
    什么是协程
    答:协程是一段在主线程中执行的代码逻辑(代码块)协程不是多线程,本质依然是从上到下依次执行。
    Unity协程的执行原理(执行过程)是什么?(15分,每条5分)
    答:(1)unity中协程执行过程中,通过yield return XXX,将程序挂起,去执行接下来的内容。
    (2)注意协程不是线程,在为遇到yield return XXX语句之前,协程的方法和一般的方法是相同的,也就是程序在执行到yield return XXX语句之后,接着才会执行的是 StartCoroutine()方法之后的程序。
    (3)协程走的还是单线程模式,仅仅是将yield return XXX语句之后的内容暂时挂起,等到特定的时间才执行。
    unity中协程执行过程中,通过yield return XXX,将程序挂起,去执行接下来的内容,注意协程不是线程,在为遇到yield return XXX语句之前,协程的方法和一般的方法是相同的,也就是程序在执行到yield return XXX语句之后,接着才会执行的是 StartCoroutine()方法之后的程序,走的还是单线程模式,仅仅是将yield return XXX语句之后的内容暂时挂起,等到特定的时间才执行。

    //协程的返回值
    /*
    * 1.协程和普通方法一样,可以被多次调用
    * 2.协程一旦被开启后,总是试图将方法内所有的代码执行完毕,之后停止
    * 3.在协程内如果遇到yield return null,0,1,2... 表示将之后的代码放到"下一帧"继续执行
    * 4.在协程内,遇到yield return new WaitForSeconds (n) 表示将剩余代码放到n秒后执行
    * 5.在协程内,遇到yield return StartCoroutine(),表示剩余代将在子协程执行完毕后执行
    * 6.在协程内,遇到yield return WaitForEndOfFrame(),表示剩余代码将在OnGUI()执行完成后继续执行
    * 7.在协程内,遇到yield return WaitForEndOfUpdate(),表示剩余代码将在FixedUpdate执行后继续执行
    * 8.在协程内,遇到yield return www,表示剩余代码将在www下载文件结束后继续执行
    * 9.在协程内,遇到yield return obj,表示剩余代码将在obj不为空时,继续执行(一般用于创建一个比较大的预设体时使用)
    * 10.想方法可以当做普通方法在两个脚本之间自由调用
    * 11.生命周期的回调方法,也可以改成协程方法(将void改为IEnumerator)
    */

    协程使用时的注意事项:
    在使用协程的时候,一个协程内必须要有返回值
    在开启协程的时候使用StartCoroutine()方法开启,里面开启的协程,可以洗洗车方法,也可以写与协程名字相同的字符串.
    如果要使用StopCoroutine(),停止协程,则该协程的开启和停止都要使用字符串

    使用www类下载图片,并赋值给RawImage
    IEnumerator LoadImg()
    {
    创建www对象 传入图片链接
    WWW www = new WWW ("图片链接");
    判断是否下载图片完成
    yield return www;
    将下载的图片的Texture赋值给RawImg的Texture
    RawImg.texture=www.texture;
    }

    使用www类下载视频,并播放视频(在此过程中,显现出加载进度条)
    创建www对象,传入视频链接
    WWW www = new WWW ("视频链接");
    在加载过程中,将加载的进度赋值给UI控件Scrollbar的size或者slider的Value
    while (www.isDone == false) {
    //将进度条设置为一直显示在所有的UI控件的最前面
    m_loadLine.transform.SetAsLastSibling ();
    m_loadLine.size = www.progress;
    yield return null;
    }
    将下载下来的视频材质赋值给创建的MovieTexture对象
    movieTexture = www.GetMovieTexture ();
    将创建的MovieTexture对象赋值给RawImg的Texture
    m_rawImg.texture = movieTexture;
    设置视频的循环播放
    movieTexture.loop = true;
    得到视频的声音
    m_aud.clip = movieTexture.audioClip;
    设置声音循环
    m_aud.loop = true;
    播放视频,音频
    movieTexture.Play ();
    m_aud.Play ();
    在视频下载完成后,movieTexture的duration属性可以得到视频的总时长,可用于制作播放进度条.//判断是否开始播放,在视频开始播放时赋值为true
    bool isPlay = false;
    //计时器
    float timer = 0;
    void Update ()
    {
    if (isPlay) {
    timer += Time.deltaTime;
    m_loadLine.size = timer / movieTexture.duration;
    if (timer >= movieTexture.duration) {
    timer = 0;
    }
    }
    }

    下载视频到存储到本地,下一次播放时,可以不用下载
    IEnumerator DownloadVideo ()
            {
            WWW downloadwww = new WWW (m_url);
            while (downloadwww.isDone == false) {
                //进度条展示
                m_downloadProgress.size = downloadwww.progress;
                //禁用掉播放按钮
                m_playBtn.interactable = false;
                yield return null;
            }
            //已经下载完成
            m_downloadProgress.size = 1.0f;
            try {
                //将内存中下载的视频资源写在文件中,存在本地
                File.WriteAllBytes (m_filePath, downloadwww.bytes);
            } catch (System.Exception ex) {
                Debug.Log (ex.Message);
            }
            //如果文件存在
            while (!IsExitsFilePath (m_filePath)) {
                yield return null;
            }
            m_playBtn.interactable = true;
            //调用播放视频的协程方法
            StartCoroutine ("PlayingMovie");
        }
    
    //播放本地视频
        IEnumerator PlayingMovie ()
        {
            //从本地路径中加载视频文件
            WWW www = new WWW ("file:///" + m_filePath);
            yield return www; 
            m_movieTexture = www.GetMovieTexture ();
            m_rawImg.texture = m_movieTexture;
            m_aud.clip = m_movieTexture.audioClip;
            m_movieTexture.loop = true;
            m_aud.loop = true;
            m_movieTexture.Play ();
            m_aud.Play ();
            isPlay = true;
        }
    判断本地是否存有相对应的视频文件
    //给按钮添加事件,播放或下载的事件
            m_playBtn.onClick.RemoveAllListeners ();
            m_playBtn.onClick.AddListener (OnPlayOrDownloadAction);ss
    可添加到按钮点击响应事件上
    void OnPlayOrDownloadAction ()
            {
            //判断本地是否有要播放的路径
            if (IsExitsFilePath (m_filePath)) {
                StartCoroutine (PlayingMovie ());
            } else {
                //通过协程下载
                StartCoroutine (DownloadVideo ());
            }
            }
    
    可更改UI控件的宽和高
    rectTransform.sizeDelta = new Vector2( yourWidth, yourHeight);
    在一个圆形范围内随机生成一个Vector2类型的点
    Vector2 Pos = Random.insideUnitCircle * radius;
    radius为生成随机点的圆形范围的半径
  • 相关阅读:
    iOS推送证书从申请到使用
    leetcode
    C++測量一段代码的执行时时间
    UIView的几个枚举定义
    在CDialog::OnInitDialog设置DEFAULT-BUTTON的注意事项
    转:VS中的路径宏 vc++中OutDir、ProjectDir、SolutionDir各种路径
    COM学习笔记
    关于StdAfx.h和StdAfx.cpp
    解决:CWnd::SetWindowText报Assertion failure
    四种DLL:NON-MFC DLL, Regular DLL Statically/Dynamically Linked to MFC, MFC Extension DLL
  • 原文地址:https://www.cnblogs.com/zpy1993-09/p/11895485.html
Copyright © 2011-2022 走看看