unity 加载obj文件的方法(可读取任意地址的文件包括沙盒中之类的)

大家都知道unity支持fbx,obj等等模型,但是动态加载除了resources加载之外还有打包成ab(assetbundle,以下统称ab)包用于加载。

但是可能有些同学会有这样的需求:在加载的时候,拿到了数据,然后转换为obj的格式存储在了一个地方,尤其是移动端,resources等路径都是只读的,所以只能存在sd卡中或者手机内存中,这样我们如何将这个模型加载到手机设备中显现出来就面临着一定的麻烦,所以就有了下面这个以数据转换的方式~~~

加载的过程可能没有ab包或者resources加载等顺畅(目前还没有考虑性能方面,如果有这方面的研究的大家可以一起交流~~~)

也可以初步的解决一些问题,如果大家有什么更好的办法或者方法请联系本人~~~~

下面贴出源码,这里用到的方法是,读取顶点和uv等等数据点,去组合。这个方法不是我写的,我只是对这个方法做了一些改变使之更适合我来使用~~~~~.

有任何问题可以添加 QQ群 207019099

有个方法LoadFile,是用来将读取到的数据分类存储到uv集合和顶点集合等中的。

ReadLine这个 方法是组合后的方法形成mesh网格的重要过程。

然后在主函数里面,是对材质等等的赋值,mesh拿到后,给一个空物体增加meshfilter组件,meshrender组件,material等等,大家可以根据命名看一下,相对简单一些,就不做过多解释了,如果有问题我们大家一块研究。

祝大家都的项目越做越好,技术越来越好~~~

/** 
* 
*----------Dragon be here!----------/ 
*    ┏┓   ┏┓ 
*   ┏┛┻━━━┛┻┓ 
*   ┃       ┃ 
*   ┃   ━   ┃ 
*   ┃ ┳┛ ┗┳ ┃ 
*   ┃       ┃ 
*   ┃   ┻   ┃ 
*   ┃       ┃ 
*   ┗━┓   ┏━┛ 
*     ┃   ┃神兽保佑 
*     ┃   ┃代码无BUG! 
*     ┃   ┗━━━┓ 
*     ┃       ┣┓ 
*     ┃       ┏┛ 
*     ┗┓┓┏━┳┓┏┛ 
*      ┃┫┫ ┃┫┫ 
*      ┗┻┛ ┗┻┛ 
* ━━━━━━神兽出没━━━━━━
*-------------------------------------/
*    by:  GF
* LoadMesh.cs
*-------------------------------------/
*/

using UnityEngine;
using System.Collections;
using System.IO;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine.Networking;
using System;

public class LoadMesh : MonoBehaviour
{
    public GameObject Loadobj;


    private Action<GameObject> creatMeshBack;
    Mesh _myMesh;

    Vector3[] _vertexArray;
    ArrayList _vertexArrayList = new ArrayList();
    Vector3[] _normalArray;
    ArrayList _normalArrayList = new ArrayList();
    Vector2[] _uvArray;
    ArrayList _uvArrayList = new ArrayList();

    int[] _triangleArray;

    ArrayList _facesVertNormUV = new ArrayList();

    private void Start()
    {
        StartCoroutine(SomeFunction(Application.streamingAssetsPath+ "/arrow.obj", 
            Application.streamingAssetsPath + "/arrow.tga",
            _CreatMeshBack));
    }
    /// <summary>
    /// 回掉函数
    /// </summary>
    /// <param name="obj">加载到的obj在场景中显示的物体</param>
    private void _CreatMeshBack(GameObject obj)
    {
        Loadobj = obj;
    }

    internal class PlacesByIndex
    {
        public PlacesByIndex(int index)
        {
            _index = index;
        }
        public int _index;
        public ArrayList _places = new ArrayList();
    }
    void initArrayLists()
    {
        _uvArrayList = new ArrayList();
        _normalArrayList = new ArrayList();
        _vertexArrayList = new ArrayList();
        _facesVertNormUV = new ArrayList();
    }
    /// <summary>
    /// 加载obj
    /// </summary>
    /// <param name="ObjPath">mesh</param>
    /// <param name="_texturepath">texture</param>
    /// <returns></returns>
    public IEnumerator SomeFunction(string ObjPath, string _texturepath, Action<GameObject> act)
    {
        if (File.Exists(ObjPath) && File.Exists(_texturepath))
        {
            creatMeshBack = act;
            GameObject obj_gameobject = new GameObject();
            obj_gameobject.name = "objload";
            initArrayLists();
            if (_myMesh != null)
                _myMesh.Clear();
            _myMesh = new Mesh();
            _myMesh.name = "objload";

            Debug.Log(ObjPath);

            //更具地址加载模型
            UnityWebRequest uwr = UnityWebRequest.Get("file://" + ObjPath);
            yield return uwr.Send();

            if (uwr.isDone && string.IsNullOrEmpty(uwr.error))
            {
                string s = uwr.downloadHandler.text;

                s = s.Replace("  ", " ");
                s = s.Replace("  ", " ");
                LoadFile(s);
            }
            else
            {
                Debug.LogError(uwr.error);
                Debug.LogError(uwr.downloadHandler.text);
            }

            _myMesh.vertices = _vertexArray;
            _myMesh.triangles = _triangleArray;
            if (_uvArrayList.Count > 0)
                _myMesh.uv = _uvArray;
            if (_normalArrayList.Count > 0)
                _myMesh.normals = _normalArray;
            else
                _myMesh.RecalculateNormals();
            _myMesh.RecalculateBounds();
            if ((MeshFilter)obj_gameobject.GetComponent("MeshFilter") == null)
                obj_gameobject.AddComponent<MeshFilter>();
            MeshFilter temp;
            temp = (MeshFilter)obj_gameobject.GetComponent("MeshFilter");
            temp.mesh = _myMesh;

            var material = new Material(Shader.Find("Diffuse"));

            if ((MeshRenderer)obj_gameobject.GetComponent("MeshRenderer") == null)
                obj_gameobject.AddComponent<MeshRenderer>();
            if (_uvArrayList.Count > 0 && _texturepath != "")
            {
                //加载贴图
                UnityWebRequest wwwtx = UnityWebRequest.GetTexture("file://" + _texturepath);
                yield return wwwtx.Send();

                if (wwwtx.isDone && string.IsNullOrEmpty(wwwtx.error))
                {
                    Debug.Log(" @ !the tex has load");
                    material.mainTexture = ((DownloadHandlerTexture)wwwtx.downloadHandler).texture;
                }
                else
                {
                    Debug.LogError(" @ ! load file  texture  +" + _texturepath + " error : " + wwwtx.error);
                }
            }
            MeshRenderer temp2;
            temp2 = (MeshRenderer)obj_gameobject.GetComponent("MeshRenderer");
            if (_uvArrayList.Count > 0 && _texturepath != "")
            {
                temp2.material = material;
            }
            yield return new WaitForFixedUpdate();

            creatMeshBack(obj_gameobject);
        }
        else
        {
            creatMeshBack(null);
        }
    }

    public void LoadFile(string s)
    {
        string[] lines = s.Split("\n"[0]);

        foreach (string item in lines)
        {
            ReadLine(item);
        }
        ArrayList tempArrayList = new ArrayList();
        for (int i = 0; i < _facesVertNormUV.Count; ++i)
        {
            if (_facesVertNormUV[i] != null)
            {
                PlacesByIndex indextemp = new PlacesByIndex(i);
                indextemp._places.Add(i);
                for (int j = 0; j < _facesVertNormUV.Count; ++j)
                {
                    if (_facesVertNormUV[j] != null)
                    {
                        if (i != j)
                        {
                            Vector3 iTemp = (Vector3)_facesVertNormUV[i];
                            Vector3 jTemp = (Vector3)_facesVertNormUV[j];
                            if (iTemp.x == jTemp.x && iTemp.y == jTemp.y)
                            {
                                indextemp._places.Add(j);
                                _facesVertNormUV[j] = null;
                            }
                        }
                    }
                }
                tempArrayList.Add(indextemp);
            }
        }
        _vertexArray = new Vector3[tempArrayList.Count];
        _uvArray = new Vector2[tempArrayList.Count];
        _normalArray = new Vector3[tempArrayList.Count];
        _triangleArray = new int[_facesVertNormUV.Count];
        int teller = 0;
        foreach (PlacesByIndex item in tempArrayList)
        {
            foreach (int item2 in item._places)
            {
                _triangleArray[item2] = teller;
            }
            Vector3 vTemp = (Vector3)_facesVertNormUV[item._index];
            _vertexArray[teller] = (Vector3)_vertexArrayList[(int)vTemp.x - 1];
            if (_uvArrayList.Count > 0)
            {
                Vector3 tVec = (Vector3)_uvArrayList[(int)vTemp.y - 1];
                _uvArray[teller] = new Vector2(tVec.x, tVec.y);
            }
            if (_normalArrayList.Count > 0)
            {
                _normalArray[teller] = (Vector3)_normalArrayList[(int)vTemp.z - 1];
            }
            teller++;
        }
    }

    public void ReadLine(string s)
    {
        char[] charsToTrim = { ' ', '\n', '\t', '\r' };
        s = s.TrimEnd(charsToTrim);
        string[] words = s.Split(" "[0]);
        foreach (string item in words)
            item.Trim();
        if (words[0] == "v")
            _vertexArrayList.Add(new Vector3(System.Convert.ToSingle(words[1], CultureInfo.InvariantCulture), System.Convert.ToSingle(words[2], CultureInfo.InvariantCulture), System.Convert.ToSingle(words[3], CultureInfo.InvariantCulture)));

        if (words[0] == "vn")
            _normalArrayList.Add(new Vector3(System.Convert.ToSingle(words[1], CultureInfo.InvariantCulture), System.Convert.ToSingle(words[2], CultureInfo.InvariantCulture), System.Convert.ToSingle(words[3], CultureInfo.InvariantCulture)));
        if (words[0] == "vt")
            _uvArrayList.Add(new Vector3(System.Convert.ToSingle(words[1], CultureInfo.InvariantCulture), System.Convert.ToSingle(words[2], CultureInfo.InvariantCulture)));
        if (words[0] == "f")
        {
            ArrayList temp = new ArrayList();
            ArrayList triangleList = new ArrayList();
            for (int j = 1; j < words.Length; ++j)
            {
                Vector3 indexVector = new Vector3(0, 0);
                string[] indices = words[j].Split("/"[0]);
                indexVector.x = System.Convert.ToInt32(indices[0], CultureInfo.InvariantCulture);
                if (indices.Length > 1)
                {
                    if (indices[1] != "")
                        indexVector.y = System.Convert.ToInt32(indices[1], CultureInfo.InvariantCulture);
                }
                if (indices.Length > 2)
                {
                    if (indices[2] != "")
                        indexVector.z = System.Convert.ToInt32(indices[2], CultureInfo.InvariantCulture);
                }
                temp.Add(indexVector);
            }
            for (int i = 1; i < temp.Count - 1; ++i)
            {
                triangleList.Add(temp[0]);
                triangleList.Add(temp[i]);
                triangleList.Add(temp[i + 1]);
            }

            foreach (Vector3 item in triangleList)
            {
                _facesVertNormUV.Add(item);
            }
        }
    }
}


  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值