在我的Unity项目中,我希望在运行时导入.obj模型时有一个开始加载的进度条 .

我想要它的工作原理是当我按下“空格键”时,ObjImporter将开始导入/绘制指定的模型,并且在绘制时的那段时间内,会有一个进度条显示导入/绘制的完成进度,因此用户可以看到完成所需的估计时间并且不会感到不耐烦 .

我正在使用来自unity wiki的稍微修改过的ObjImporter.cs:

/* This version of ObjImporter first reads through the entire file, getting a count of how large
 * the final arrays will be, and then uses standard arrays for everything (as opposed to ArrayLists
 * or any other fancy things). 
 */

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;

public class ObjImporter : MonoBehaviour {

    public GameObject spawnPoint;
    public GameObject emptyPrefabWithMeshRenderer;
    public string meshPath;
    public GameObject spawnedPrefab;
    public float progressPercentage;

    int noOfLines;

    void Start ()
    {
        progressPercentage = 0;
    }

    void Update ()
    {
        if(Input.GetKeyDown("space")){
            Mesh importedMesh = GetComponent<ObjImporter>().ImportFile(meshPath);
            noOfLines = TotalLines(meshPath);
            spawnedPrefab=Instantiate(emptyPrefabWithMeshRenderer,spawnPoint.transform.position,spawnPoint.transform.rotation) as GameObject;
            spawnedPrefab.GetComponent<MeshFilter>().mesh=importedMesh;
            spawnedPrefab.GetComponent<Renderer>().material.color = new Color(Random.value, Random.value, Random.value, 1.0f);
        }
    }

    private struct meshStruct
    {
        public Vector3[] vertices;
        public Vector3[] normals;
        public Vector2[] uv;
        public Vector2[] uv1;
        public Vector2[] uv2;
        public int[] triangles;
        public int[] faceVerts;
        public int[] faceUVs;
        public Vector3[] faceData;
        public string name;
        public string fileName;
    }

    // Use this for initialization
    public Mesh ImportFile (string filePath){
        meshStruct newMesh = createMeshStruct(filePath);
        populateMeshStruct(ref newMesh);

        Vector3[] newVerts = new Vector3[newMesh.faceData.Length];
        Vector2[] newUVs = new Vector2[newMesh.faceData.Length];
        Vector3[] newNormals = new Vector3[newMesh.faceData.Length];
        int i = 0;
        /* The following foreach loops through the facedata and assigns the appropriate vertex, uv, or normal
         * for the appropriate Unity mesh array.
         */
        foreach (Vector3 v in newMesh.faceData)
        {
            newVerts[i] = newMesh.vertices[(int)v.x - 1];
            if (v.y >= 1)
                newUVs[i] = newMesh.uv[(int)v.y - 1];

            if (v.z >= 1)
                newNormals[i] = newMesh.normals[(int)v.z - 1];
            i++;
        }

        Mesh mesh = new Mesh();

        mesh.vertices = newVerts;
        mesh.uv = newUVs;
        mesh.normals = newNormals;
        mesh.triangles = newMesh.triangles;

        mesh.RecalculateBounds();
        mesh.Optimize ();

        return mesh;
    }

    private int TotalLines(string filePath)
    {
        using (StreamReader r = new StreamReader(filePath))
        {
            int i = 0;
            while (r.ReadLine() != null)
            {
                i++;
            }
            return i;
        }
    }

    private static meshStruct createMeshStruct(string filename)
    {
        int triangles = 0;
        int vertices = 0;
        int vt = 0;
        int vn = 0;
        int face = 0;
        meshStruct mesh = new meshStruct();
        mesh.fileName = filename;

        // Read and retrieve all the text in the file.
        StreamReader stream = File.OpenText(filename);
        string entireText = stream.ReadToEnd();
        stream.Close(); // End of stream.

        // Going through the retrieved text.
        using (StringReader reader = new StringReader(entireText))
        {
            string currentText = reader.ReadLine();
            char[] splitIdentifier = { ' ' };
            string[] brokenString;
            while (currentText != null)
            {
                if (!currentText.StartsWith("f ") && !currentText.StartsWith("v ") && !currentText.StartsWith("vt ")
                    && !currentText.StartsWith("vn "))
                {
                    currentText = reader.ReadLine();
                    if (currentText != null)
                    {
                        currentText = currentText.Replace("  ", " ");
                    }
                }
                else
                {
                    currentText = currentText.Trim();                           // Trim the current line
                    brokenString = currentText.Split(splitIdentifier, 50);      // Split the line into an array, separating the original line by blank spaces
                    switch (brokenString[0])
                    {
                    case "v":
                        vertices++;
                        break;
                    case "vt":
                        vt++;
                        break;
                    case "vn":
                        vn++;
                        break;
                    case "f":
                        face = face + brokenString.Length - 1;
                        triangles = triangles + 3 * (brokenString.Length - 2); /*brokenString.Length is 3 or greater since a face must have at least
                                                                                     3 vertices.  For each additional vertice, there is an additional
                                                                                     triangle in the mesh (hence this formula).*/
                        break;
                    }
                    currentText = reader.ReadLine();
                    if (currentText != null)
                    {
                        currentText = currentText.Replace("  ", " ");
                    }
                }
            }
        }
        mesh.triangles = new int[triangles];
        mesh.vertices = new Vector3[vertices];
        mesh.uv = new Vector2[vt];
        mesh.normals = new Vector3[vn];
        mesh.faceData = new Vector3[face];
        return mesh;
    }

    private static void populateMeshStruct(ref meshStruct mesh)
    {
        StreamReader stream = File.OpenText(mesh.fileName);
        string entireText = stream.ReadToEnd();
        stream.Close();
        using (StringReader reader = new StringReader(entireText))
        {
            string currentText = reader.ReadLine();

            char[] splitIdentifier = { ' ' };
            char[] splitIdentifier2 = { '/' };
            string[] brokenString;
            string[] brokenBrokenString;
            int f = 0;
            int f2 = 0;
            int v = 0;
            int vn = 0;
            int vt = 0;
            int vt1 = 0;
            int vt2 = 0;
            while (currentText != null)
            {
                if (!currentText.StartsWith("f ") && !currentText.StartsWith("v ") && !currentText.StartsWith("vt ") &&
                    !currentText.StartsWith("vn ") && !currentText.StartsWith("g ") && !currentText.StartsWith("usemtl ") &&
                    !currentText.StartsWith("mtllib ") && !currentText.StartsWith("vt1 ") && !currentText.StartsWith("vt2 ") &&
                    !currentText.StartsWith("vc ") && !currentText.StartsWith("usemap "))
                {
                    currentText = reader.ReadLine();
                    if (currentText != null)
                    {
                        currentText = currentText.Replace("  ", " ");
                    }
                }
                else
                {
                    currentText = currentText.Trim();
                    brokenString = currentText.Split(splitIdentifier, 50);
                    switch (brokenString[0])
                    {
                    case "g":
                        break;
                    case "usemtl":
                        break;
                    case "usemap":
                        break;
                    case "mtllib":
                        break;
                    case "v":
                        mesh.vertices[v] = new Vector3(System.Convert.ToSingle(brokenString[1]), System.Convert.ToSingle(brokenString[2]),
                                                       System.Convert.ToSingle(brokenString[3]));
                        v++;
                        break;
                    case "vt":
                        mesh.uv[vt] = new Vector2(System.Convert.ToSingle(brokenString[1]), System.Convert.ToSingle(brokenString[2]));
                        vt++;
                        break;
                    case "vt1":
                        mesh.uv[vt1] = new Vector2(System.Convert.ToSingle(brokenString[1]), System.Convert.ToSingle(brokenString[2]));
                        vt1++;
                        break;
                    case "vt2":
                        mesh.uv[vt2] = new Vector2(System.Convert.ToSingle(brokenString[1]), System.Convert.ToSingle(brokenString[2]));
                        vt2++;
                        break;
                    case "vn":
                        mesh.normals[vn] = new Vector3(System.Convert.ToSingle(brokenString[1]), System.Convert.ToSingle(brokenString[2]),
                                                       System.Convert.ToSingle(brokenString[3]));
                        vn++;
                        break;
                    case "vc":
                        break;
                    case "f":

                        int j = 1;
                        List<int> intArray = new List<int>();
                        while (j < brokenString.Length && ("" + brokenString[j]).Length > 0)
                        {
                            Vector3 temp = new Vector3();
                            brokenBrokenString = brokenString[j].Split(splitIdentifier2, 3);    //Separate the face into individual components (vert, uv, normal)
                            temp.x = System.Convert.ToInt32(brokenBrokenString[0]);
                            if (brokenBrokenString.Length > 1)                                  //Some .obj files skip UV and normal
                            {
                                if (brokenBrokenString[1] != "")                                    //Some .obj files skip the uv and not the normal
                                {
                                    temp.y = System.Convert.ToInt32(brokenBrokenString[1]);
                                }
                                temp.z = System.Convert.ToInt32(brokenBrokenString[2]);
                            }
                            j++;

                            mesh.faceData[f2] = temp;
                            intArray.Add(f2);
                            f2++;
                        }
                        j = 1;
                        while (j + 2 < brokenString.Length)     //Create triangles out of the face data.  There will generally be more than 1 triangle per face.
                        {
                            mesh.triangles[f] = intArray[0];
                            f++;
                            mesh.triangles[f] = intArray[j];
                            f++;
                            mesh.triangles[f] = intArray[j+1];
                            f++;

                            j++;
                        }
                        break;
                    }
                    currentText = reader.ReadLine();
                    if (currentText != null)
                    {
                        currentText = currentText.Replace("  ", " ");       //Some .obj files insert double spaces, this removes them.
                    }
                }
            }
        }
    }

    void OnGUI()
    {
        GUI.Label (new Rect (20, 20, 100, 100), noOfLines.ToString());
    }
}

这是一个简单的ProgressBar.cs我写道:

using UnityEngine;
using System.Collections;

public class ProgressBar : MonoBehaviour {

    float progress;
    Vector2 pos;
    Vector2 size;
    public Texture2D barBG;
    public Texture2D barLoad;

    // Use this for initialization
    void Start () {
        progress = 0;
        pos = new Vector2 (20, 40);
        size = new Vector2 (100, 10);
    }

    // Update is called once per frame
    void Update () {
        progress = Time.time * 0.05f; // Place holder.
    }

    void OnGUI ()
    {
        GUI.DrawTexture(new Rect(pos.x, pos.y, size.x, size.y), barBG); 
        GUI.DrawTexture(new Rect(pos.x, pos.y, size.x * Mathf.Clamp01(progress), size.y), barLoad);
    }
}

我找到了找到网格文件读取图纸的进度完成的方法,无法找到一个 .

我已经尝试将progressBar加载到.obj文件中的行数,但由于读取速度比网格的实际绘制速度快,所以效果不好 .

我没有想法,任何人都知道吗?提前致谢!