前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Unity基础(15)-Application与SceneManager类

Unity基础(15)-Application与SceneManager类

作者头像
孙寅
发布2020-06-02 14:49:48
1.3K0
发布2020-06-02 14:49:48
举报
文章被收录于专栏:宜达数字宜达数字

Application类与SceneManager类

  • 在较早Unity版本之前,Application类负责:应用程序运行时数据,获取并加载场景(异步,同步),随着移动端兴起,后期版本中只负责获取跟应用程序运行时数据,而场景相关的被SceneManager替代。这也是与其他移动平台结合的改变。

移动端

静态属性

  • Application静态属性: dataPath属性 : 数据文件路径 public static string dataPath{ get; } Application.dataPath 返回程序的数据文件所在文件夹的路径(只读).返回路径为相对路径,不同游戏平台的数据文件保存路径不同,Editor中就是项目的Assets文件夹的路径,通过这个路径可以访问项目中任何文件夹中的资源,但是在移动端它是完全没用。 Application.persistentDataPath 此属性返回一个持久化数据存储目录的路径,可以在此路径下存储一些持久化的数据文件。这个路径可读、可写,但是只能在程序运行时才能读写操作,不能提前将数据放入这个路径。在IOS上是应用程序的沙盒,可以被iCloud自动备份,可以通过同步推送一类的助手直接取出文件;在Android上的位置是根据Project Setting里设置的Write Access路径,可以设置是程序沙盒还是sdcard,注意:如果在Android设置保存在沙盒中,那么就必须root以后才能用电脑取出文件,因此建议写入sdcard里。一般情况下,建议将获得的文件保存在这个路径下,例如可以从StreamingAsset中读取的二进制文件或者从AssetBundle读取的文件写入PersistentDatapath。 Application.streamingAassetsPath 此属性用于返回流数据的缓存目录,返回路径为相对路径,适合设置一些外部数据文件的路径.在PC/MAC中可实现对文件的“增删改查”等操作,但在移动端是一个只读路径。 Application.temporaryCachePath 此属性返回一个临时数据的缓存目录,跟Application.persistentDataPath类似,但是在IOS上不能被自动备份 以上各路径中的资源加载方式都可以用WWW类加载,但要注意各个平台路径需要加的访问名称,例如Android平台的路径前要加"jar:file://",其他平台使用"file://"。以下是各路径在各平台中的具体位置信息:
  • Android平台
代码语言:javascript
复制
Application.dataPath :  /data/app/xxx.xxx.xxx.apk
Application.streamingAssetsPath :  jar:file:///data/app/xxx.xxx.xxx.apk/!/assets
Application.persistentDataPath :  /data/data/xxx.xxx.xxx/files
Application.temporaryCachePath :  /data/data/xxx.xxx.xxx/cache
  • IOS平台
代码语言:javascript
复制
Application.dataPath :                    Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data
Application.streamingAssetsPath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data/Raw
Application.persistentDataPath :    Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Documents
Application.temporaryCachePath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Library/Caches
  • Windows Web Player
代码语言:javascript
复制
Application.dataPath :  file:///D:/MyGame/WebPlayer (即导包后保存的文件夹,html文件所在文件夹)
Application.streamingAssetsPath : 
Application.persistentDataPath : 
Application.temporaryCachePath : 
代码语言:javascript
复制
#if UNITY_EDITOR
string filepath = Application.dataPath +"/StreamingAssets"+"/version.txt";
#elif UNITY_IPHONE
 string filepath = Application.dataPath +"/Raw"+"/my.xml";
#elif UNITY_ANDROID
 string filepath = "jar:file://" + Application.dataPath + "!/assets/"+"/version.txt";
#endif

StreamingAssets在各个平台上的文本支持读取方式 string path = System.IO.Path.Combine(Application.streamingAssetsPath,"version.txt");

代码语言:javascript
复制
## Editor:
1::System.IO.File.ReadAllText (path);
2:path = "file://"+path;或者 path = "file:/"+path;或者 path = "file:\\"+path或者 path = "file:\\\\"+path;在win7上都可以 在mac上path = "file:/"+path不可以外,别的都可以 
然后WWW www = new WWW (path);

## Android:
1:WWW www = new WWW (path);

##  iphone:
1:System.IO.File.ReadAllText (path);
2:path = "file://"+path;System.IO.File.ReadAllText (path); 

还有一点就是在读取streamingAssets目录下的文本文件时android平台必须要用www来读取哦,因为android平台是被压缩在apk中,
所以不能直接用CSharp去读,ios可以直接用System.IO.File.ReadAllText(filePath)
  • loadedLevel属性 : SceneManager.GetActiveScene().buildIndex返回当前场景的索引值 SceneManager.GetActiveScene().name返回当前场景的名字 SceneManager.sceneCountInBuildSettings游戏中可被加载的场景数量 Application.platform 当前游戏的运行平台,返回值为枚举类型 Application.isPlaying 当前游戏是否正在运行 Application.isEditor 游戏是否处于Unity编辑模式
  • Application类静态方法: 旧方法Application.CaptureScreenshot方法 : 截屏

目前改为了:ScreenCapture.CaptureScreenshot public static void CaptureScreenshot(string filename); 参数filename 截屏文件名称 superSize放大系数,默认为0,即不放大 public static void CaptureScreenshot(string filename, int superSize); 此方法截取当前游戏画面并保存为PNG格式,文件默认保存在根目录下,若有重名文件则替换.

代码语言:javascript
复制
 public void CameraGame()
 {
         Debug.Log(Application.dataPath);
         string fileName = Application.dataPath +"/Images/" + Time.time+ ".png";
         ScreenCapture.CaptureScreenshot(fileName);
 }
代码语言:javascript
复制
  public void CameraGame()
  {
         Debug.Log(Application.dataPath);
        StartCoroutine(GetScreenCamera());
  }

 IEnumerator GetScreenCamera()
 {
        yield return new WaitForEndOfFrame();
        Texture2D t = new Texture2D(100, 100, TextureFormat.RGB24, false);
        t.ReadPixels(new Rect(0, 0, 100, 100), 0, 0);
        // 保存图片
        t.Apply();
        byte[] imgB = t.EncodeToPNG();
        System.IO.File.WriteAllBytes(Application.dataPath + "/Images/" + Time.time + ".png", imgB);
  }
  • RegisterLogCallback方法 :注册委托 方法1:Application.RegisterLogCallback static function RegisterLogCallback (handler : Application.LogCallback) : void 在一个日志信息上注册一个委托来被调用,这个函数和RegisterLogCallback唯

方法2:Application.RegisterLogCallbackThreaded static function RegisterLogCallbackThreaded (handler : Application.LogCallback) : void 在一个日志信息上注册一个委托来被调用,这个函数和RegisterLogCallback唯一不同的是,这个函数将从不同的线程被调用,注意:你只有你知道你在做什么时才能使用这个函数,否则使用Application.RegisterLogCallback。

两个方法在使用的时候,都需要传递一个委托 public delegate void LogCallback (string condition, string stackTrace, LogType type); 第一个参数为日志描述信息,第二个参数为日志产生的栈数据,第三个参数为日志的类型

代码语言:javascript
复制
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class LogMessage : MonoBehaviour {
    string  message="";
    public Text text;
    void Start () {
        //在一个日志信息上注册一个委托来被调用
        Application.logMessageReceivedThreaded +=MyLogCallback;
    }

    void Update () {
        text.text = message;
    }

    /// <summary>
    /// log callback check
    /// </summary>
    /// <param name="condition">日志描述信息log内容.</param>
    /// <param name="stackTrace">log产生的栈数据追踪</param>
    /// <param name="type">log的类型.</param>
    void  MyLogCallback (string condition, string stackTrace, LogType type){
        switch(type){
        case LogType.Assert:
            message += "      receive an assert log"+",condition="+condition+",stackTrace="+stackTrace;
            break;
        case LogType.Error:
            message += "      receive an Error log"+",condition="+condition+",stackTrace="+stackTrace;
            break;
        case LogType.Exception:
            message += "      receive an Exception log"+",condition="+condition+",stackTrace="+stackTrace;
            break;
        case LogType.Log:
            message += "      receive an Log log"+",condition="+condition+",stackTrace="+stackTrace;
            break;
        case LogType.Warning:
            message += "      receive an Warning log"+",condition="+condition+",stackTrace="+stackTrace;
            break;
        }
    }

    void OnGUI(){
        if(GUI.Button(new Rect(10,20,200,40),"assert")){
            Debug.LogAssertion ("assertion");
        }else if(GUI.Button(new Rect(10,80,200,40),"error")){
            Debug.LogError ("error");
        }else if(GUI.Button(new Rect(10,140,200,40),"exception")){
            Debug.LogException (new System.NullReferenceException());
        }else if(GUI.Button(new Rect(10,200,200,40),"log")){
            Debug.Log ("log");
        }else if(GUI.Button(new Rect(10,260,200,40),"warning")){
            Debug.LogWarning ("waring");
        }
    }
}

Application相关事件函数

OnApplicationPause(bool pause) 如果应用程序暂停,则为True,否则为False OnApplicationFocus(bool focus) 如果应用程序失去焦点 OnApplicationQuit() 程序退出事件

代码语言:javascript
复制
`强制暂停时`,先 `OnApplicationPause`,后 `OnApplicationFocus`;
`重新“启动”手机时`,先`OnApplicationFocus`,后 `OnApplicationPause`;
`启用键盘按Home`不会调用OnApplicationFocus,而是调用OnApplicationPause;
`安卓上启用手机键盘`,会调用OnApplicationFocus](false)事件。
  private void OnApplicationPause(bool pause)
    {
        Debug.Log("停止程序" + pause);
    }
    private void OnApplicationFocus(bool focus)
    {
        Debug.Log("程序失去焦点" + focus);
    }


  // 当前应用双击Home,然后Kill(IOS 有回调,android 没回调)
  private void OnApplicationQuit()
    {
        QuitGame();
    }
    public void QuitGame()
    {
        Debug.Log("Quit");
        // 在编辑器或者web播放器中退出被忽略
        // Application.Quit();
#if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
#elif UNITY_IPHONE
        Application.Quit();
#elif UNITY_ANDROID
       Application.Quit();
#else
        Application.Quit();
#endif
    }

SceneManager

通常游戏的主场景包含的资源较多,这会导致加载场景的时间较长。 为了避免这个问题,可以首先加载Loading场景,然后再通过Loading场景来加载主场景。 因为Loading场景包含的资源较少,所以加载速度快。 在加载主场景的时候一般会在Loading界面中显示一个进度条来告知玩家当前加载的进度。 在Unity中可以通过调用SceneManager.LoadSceneAsync(旧版本:Application.LoadLevelAsync)函数来异步加载游戏场景, 通过查询AsyncOperation.progress的值来得到场景加载的进度。 通过Unity提供的Coroutine机制,我们可以方便的在每一帧结束后调用SetLoadingPercentage函数来更新界面中显示的进度条的数值。 SceneManager.LoadSceneAsync() 此方法用于按照关卡名字在后台异步加载关卡到当前场景中,此方法只是将新关卡加载到当前场景,当前场景的原有内容不会被销毁. AsynvOperation colve = public static AsynvOperation LoadLevelAdditiveAsync(int index); colve.isDone 是否加载完成 colve.progress 加载进度

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System;

public class Loading : MonoBehaviour {

    public Slider loadingSlider;
    public Text loadingText;
    public AsyncOperation op;
    public float targetValue;

    void Start () {
        loadingSlider.value = 0.0f;
        // 判断当前场景的名字是Loading
        if (SceneManager.GetActiveScene().name == "Loading")
        {
            // 加载下一个场景
            StartCoroutine(AsyncLoading());
        }
    }

    private IEnumerator AsyncLoading()
    {
        op =  SceneManager.LoadSceneAsync(3);
        // 阻止当加载完成自动切换
        op.allowSceneActivation = false;
        // 
        yield return op;
    }

    void Update () {
        Debug.Log(op.progress);
        targetValue = op.progress;
        if (op.progress >= 0.9f)
        {
                //operation.progress的值最大为0.9
                targetValue = 1.0f;
        }
        if (targetValue != loadingSlider.value)
        {
            //插值运算
            loadingSlider.value = Mathf.Lerp(loadingSlider.value, targetValue, Time.deltaTime * 1);
            if (Mathf.Abs(loadingSlider.value - targetValue) < 0.01f)
            {
                loadingSlider.value = targetValue;
            }
        }
        loadingText.text = ((int)(loadingSlider.value * 100)).ToString() + "%";
        if ((int)(loadingSlider.value * 100) == 100)
        {
            //允许异步加载完毕后自动切换场景
            op.allowSceneActivation = true;
        }
    }
}

第二种方式:进度条加载

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class LoadScene : MonoBehaviour {
    public Slider sl;
    public Text t;
    void Start () {
        sl.value = 0;
        StartCoroutine(LoadingScene());
    }

    private IEnumerator LoadingScene(int scene)
    {
        AsyncOperation op = SceneManager.LoadSceneAsync(3);
        while (!op.isDone)
        {
            t.text = op.progress * 100 + "%";
           sl.value = op.progress * 100 ;
            yield return new WaitForEndOfFrame();        
        }
    }

    private IEnumerator LoadingScene()
    {
        int displayProgress = 0;
        int toProgress = 0;
        AsyncOperation op = SceneManager.LoadSceneAsync(3);
        op.allowSceneActivation = false;
        while (op.progress < 0.9f)
        {
            toProgress = (int)op.progress * 100;
            while (displayProgress < toProgress)
            {
                ++displayProgress;
                t.text = displayProgress + "%";
                sl.value = displayProgress * 0.01f;
                yield return new WaitForEndOfFrame();
            }
        }
        toProgress = 100;
        while (displayProgress < toProgress)
        {
           ++displayProgress;
           t.text = displayProgress  + "%";
           sl.value = displayProgress * 0.01f;
           yield return new WaitForEndOfFrame();
        }
       op.allowSceneActivation = true;
    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Application类与SceneManager类
  • Application相关事件函数
  • SceneManager
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档