unity3d异步加载场景

 



unity3dloading界面异步加载进度条

根据宣雨松前辈的教程来做的,因为我用到的场景不是在游戏里的那种(本人做增强现实的,完全把unity拿来做应用了==),所以这里的方法不是很全面,原文戳这里:点击打开链接

 

异步加载流程:

 

    lovdlevel                  异步读取
A---------------> B ------------------------>C
                                 
播放加载动画

 

示例背景介绍:A场景是一个菜单,鼠标选中其中一项,则跳转到相应场景(C场景),B场景为加载动画播放场景

A场景:摄像机添加menu.cs
B
场景:绑定loading.cs,把loading图片附到loading.cs

menu.cs

[csharp] view plaincopy在CODE上查看代码片 派生到我的代码片

1.  using UnityEngine;  

2.  using System.Collections;  

3.    

4.  public class Globe{  

5.           //在这里记录当前切换场景的名称  

6.       public static string loadName;  

7.   

8.  public class menu MonoBehaviour  

9.    

10.    // Use this for initialization  

11.    void Start ()   

12.     

13.          

14.     

15.      

16.    // Update is called once per frame  

17.    void Update ()   

18.     

19.        if (Input.GetKey(KeyCode.Escape))  

20.            Application.Quit();  

21.        Camera cam Camera.mainCamera;  

22.        if (Input.GetMouseButtonDown(0))  

23.          

24.            Ray ray cam.ScreenPointToRay(Input.mousePosition);  

25.            RaycastHit hit;  

26.            if (Physics.Raycast(ray, out hit)  

27.             

28.                switch (hit.collider.name)  

29.                 

30.                      

31.                    case "***" 

32.                        Globe.loadName "C" 

33.            Application.LoadLevel ("B");      

34.                        break 

35.                    case "***" 

36.            Globe.loadName "CCC" 

37.            Application.LoadLevel ("B");  

38.            break   

39.                  

40.                                 

41.             

42.                

43.     

44. 


loading.cs

[csharp] view plaincopy在CODE上查看代码片 派生到我的代码片

1.  using UnityEngine;  

2.  using System.Collections;  

3.    

4.  public class loading MonoBehaviour  

5.    

6.      private float fps 1000.0f;  

7.      private float time;  

8.      //一组动画的贴图,在编辑器中赋值。  

9.      public Texture2D[] animations;  

10.    private int nowFram;  

11.    //异步对象  

12.    AsyncOperation async;  

13.  

14.    //读取场景的进度,它的取值范围在之间。  

15.    int progress 1;  

16.  

17.    void Start()  

18.     

19.        //在这里开启一个异步任务,  

20.        //进入loadScene方法。  

21.        StartCoroutine(loadScene());  

22.     

23.  

24.    //注意这里返回值一定是 IEnumerator  

25.    IEnumerator loadScene()  

26.     

27.        //异步读取场景。  

28.        //Globe.loadName 就是A场景中需要读取的C场景名称。  

29.        async Application.LoadLevelAsync(Globe.loadName);  

30.  

31.        //读取完毕后返回, 系统会自动进入C场景  

32.        yield return async;  

33.  

34.     

35.  

36.    void OnGUI()  

37.     

38.        //因为在异步读取场景,  

39.        //所以这里我们可以刷新UI  

40.        DrawAnimation(animations);  

41.  

42.     

43.  

44.    void Update()  

45.     

46.  

47.        //在这里计算读取的进度,  

48.        //progress 的取值范围在0.1 1之间, 但是它不会等于1  

49.        //也就是说progress可能是0.9的时候就直接进入新场景了  

50.        //所以在写进度条的时候需要注意一下。  

51.        //为了计算百分比 所以直接乘以100即可  

52.        progress  (int)(async.progress *100);  

53.  

54.        //有了读取进度的数值,大家可以自行制作进度条啦。  

55.        Debug.Log(progress);  

56.  

57.     

58.    //简单绘制2D动画  

59.    void  DrawAnimation(Texture2D[] tex)  

60.     

61.  

62.        time += Time.deltaTime;  

63.  

64.         if(time >= 1.0 fps){  

65.  

66.             nowFram++;  

67.  

68.             time 0;  

69.  

70.             if(nowFram >= tex.Length)  

71.              

72.                nowFram 0;  

73.              

74.         

75.          

76.        GUI.DrawTexture(new Rect( (Screen.width-60)*0.5f,(Screen.height-60)*0.5f,60,60) ,tex[nowFram] );  

77.                //在这里显示读取的进度。  

78.        GUI.Label(new Rect( (Screen.width-100)*0.5f,(Screen.height-60)*0.5f+100,100,60), "LOADING..." progress+"%");  

79.  

80.     

 

 

 

 

IEnumerator 接口

语法


C#

C++

VB


IEnumerator 是所有非泛型枚举数的基接口。

有关此接口的泛形版本,请参见 IEnumerator

C# 语言的 foreach 语句(在 Visual Basic 中为 for each)隐藏了枚举数的复杂性。因此,建议使用 foreach,而不直接操作枚举数。

枚举数可用于读取集合中的数据,但不能用于修改基础集合。

最初,枚举数定位在集合中第一个元素前。Reset 方法还会将枚举数返回到此位置。在此位置,调用 Current 属性会引发异常。因此,在读取 Current 的值之前,必须调用 MoveNext 方法将枚举数提前到集合的第一个元素。

在调用 MoveNextReset 之前,Current 返回同一对象。MoveNextCurrent 设置为下一个元素。

如果 MoveNext 越过集合的末尾,则枚举数将被放置在此集合中最后一个元素的后面,而且 MoveNext 返回 false。当枚举数位于此位置时,对 MoveNext 的后续调用也返回 false。如果最后一次调用 MoveNext 返回 false,则调用 Current 会引发异常。若要再次将 Current 设置为集合的第一个元素,可以调用 Reset,然后再调用 MoveNext

只要集合保持不变,枚举数就保持有效。如果对集合进行了更改(如添加、修改或删除元素),则枚举数将失效且不可恢复,并且下一次对 MoveNextReset 的调用将引发 InvalidOperationException。如果在 MoveNextCurrent 之间修改集合,那么即使枚举数已经无效,Current 也将返回它所设置成的元素。

枚举数没有对集合的独占访问权;因此,枚举通过集合在本质上不是一个线程安全的过程。即使一个集合已进行同步,其他线程仍可以修改该集合,这将导致枚举数引发异常。若要在枚举过程中保证线程安全,可以在整个枚举过程中锁定集合,或者捕捉由于其他线程进行的更改而引发的异常。

示例


下面的代码示例演示如何实现自定义集合的 IEnumerableIEnumerator 接口。在此示例中,没有显式调用这些接口的成员,但实现了它们,以便支持使用 foreach(在 Visual Basic 中为 for each)循环访问该集合。

C#

VB

复制

using System;
using System.Collections;
 
public class Person
{
    public Person(string fName, string lName)
    {
        this.firstName = fName;
        this.lastName = lName;
    }
 
    public string firstName;
    public string lastName;
}
 
public class People : IEnumerable
{
    private Person[] _people;
    public People(Person[] pArray)
    {
        _people = new Person[pArray.Length];
 
        for (int i = 0; i < pArray.Length; i++)
        {
            _people[i] = pArray[i];
        }
    }
 
    public IEnumerator GetEnumerator()
    {
        return new PeopleEnum(_people);
    }
}
 
public class PeopleEnum : IEnumerator
{
    public Person[] _people;
 
    // Enumerators are positioned before the first element
    // until the first MoveNext() call.
    int position = -1;
 
    public PeopleEnum(Person[] list)
    {
        _people = list;
    }
 
    public bool MoveNext()
    {
        position++;
        return (position < _people.Length);
    }
 
    public void Reset()
    {
        position = -1;
    }
 
    public object Current
    {
        get
        {
            try
            {
                return _people[position];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
}
 
class App
{
    static void Main()
    {
        Person[] peopleArray = new Person[3]
        {
            new Person("John", "Smith"),
            new Person("Jim", "Johnson"),
            new Person("Sue", "Rabon"),
        };
 
        People peopleList = new People(peopleArray);
        foreach (Person p in peopleList)
            Console.WriteLine(p.firstName + " " + p.lastName);
 
    }
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值