大家都知道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 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));
}
///
/// 回掉函数
///
/// 加载到的obj在场景中显示的物体
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();
}
///
/// 加载obj
///
/// mesh
/// texture
///
public IEnumerator SomeFunction(string ObjPath, string _texturepath, Action 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 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();
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);
}
}
}
}