使用FastObjImporter在场景上加载和显示obj模型 [英] Load and display obj model on the scene with FastObjImporter
问题描述
在我的Unity项目中,我想使用互联网上的FastObjImporter类将obj放在场景中。我是否必须创建一个空GameObject并将已处理的obj分配给它?
In my Unity project I would like to use the FastObjImporter class found on the internet to put obj on the scene. Do I have to create an empty GameObject and assign processed obj to it?
尝试使用空游戏对象:
GameObject go = new GameObject("obj");
myMesh = FastObjImporter.Instance.ImportFile(objPath);
Instantiate(myMesh, Vector3.zero, Quaternion.identity);
go.AddComponent<MeshRenderer>();
go.GetComponent<MeshFilter>().mesh = myMesh;
早些时候我试过这种方式,但它也没有用:
Earlier I tried this way but it also did not work:
GameObject go;
myMesh = FastObjImporter.Instance.ImportFile(objPath);
Instantiate(myMesh, Vector3.zero, Quaternion.identity);
go.GetComponent<MeshFilter>().mesh = myMesh;
有人可以解释我做错了吗?
Could someone explain what I'm doing wrong?
代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using System.IO;
/// <summary>
/// Sample
/// </summary>
public class DriveTest : MonoBehaviour
{
//public static readonly string REQUIRED_MIME = "image/jpeg";
//public string filePath;
public string objPath;
bool initInProgress = false;
GoogleDrive drive;
public string url;
List<GoogleDrive.File> remoteObjFiles;
public Mesh myMesh;
public GameObject go;
/* ---------------------------------------------------------------------------------------------------------------------------------- */
void Start()
{
objPath = Application.persistentDataPath + "/testObj.obj";
StartCoroutine(ImportObj());
go = new GameObject("obj");
}
/* ---------------------------------------------------------------------------------------------------------------------------------- */
void Update()
{
if (Input.GetKey(KeyCode.Escape))
Application.Quit();
}
/* ---------------------------------------------------------------------------------------------------------------------------------- */
IEnumerator ImportObj()
{
initInProgress = true;
drive = new GoogleDrive();
var driveInit = drive.Initialize();
while (driveInit.MoveNext())
yield return null;
initInProgress = false;
for (;;)
{
( SEARCHING AND SETTING DOWNLOAD FOLDER IN GDRIVE )
var download = drive.DownloadFile(remoteObjFiles[0]);
yield return StartCoroutine(download);
var data = GoogleDrive.GetResult<byte[]>(download);
if (File.Exists(objPath))
{
File.Delete(objPath);
File.WriteAllBytes(objPath, data);
}
else
File.WriteAllBytes(objPath, data);
Debug.Log("Obj: " + remoteObjFiles[0].ToString());
if (File.Exists(objPath))
{
Debug.Log("Loading OBJ from the device");
myMesh = FastObjImporter.Instance.ImportFile(objPath);
Debug.Log("Obj imported...");
Instantiate(myMesh, Vector3.zero, Quaternion.identity);
go.AddComponent<MeshRenderer>();
go.GetComponent<MeshFilter>().mesh = myMesh;
}
break;
}
}
问候
推荐答案
无需实例化Mesh。它是一个组件,我不确定你是否可以实例化它。只需将其分配给材料即可。
There is no need to instantiate the Mesh. It is a component and I am not sure if you can even instantiate it. Just assign it to the material.
代码中的主要问题是您没有创建材质和着色器。您需要创建一个材质,然后创建一个标准着色器并将该着色器指定给该材质。
The main problem in your code is that you are not creating a material and a shader. You need to create a material, then create a "Standard" shader and assign that shader to the that material.
我注意到 FastObjImporter
脚本是旧的,并决定尝试它以确保它正常运行。我遇到了一个索引异常错误然后修复它。您可以获取此处的固定版本的副本。请参阅第#57 行以了解我所做的实际修正。
I noticed that the FastObjImporter
script is old and decided to try it to make sure it is functioning properly. I ran into an index exception bug in it then fixed it. You can grab the copy of the fixed version here. See line #57 for the actual fix I made.
创建函数 MeshFilder
,Material和 MeshRenderer
:
Functions to create MeshFilder
, Material and MeshRenderer
:
void attachMeshFilter(GameObject target, Mesh mesh)
{
MeshFilter mF = target.AddComponent<MeshFilter>();
mF.mesh = mesh;
}
Material createMaterial()
{
Material mat = new Material(Shader.Find("Standard"));
return mat;
}
void attachMeshRenderer(GameObject target, Material mat)
{
MeshRenderer mR = target.AddComponent<MeshRenderer>();
mR.material = mat;
}
创建新GameObject,加载模型并将所有必要组件附加到其上的功能为了显示它:
Function to create new GameObject, load the model and attach every necessary components to it in order to display it:
GameObject loadAndDisplayMesh(string path)
{
//Create new GameObject to hold it
GameObject meshHolder = new GameObject("Loaded Mesh");
//Load Mesh
Mesh mesh = FastObjImporter.Instance.ImportFile(path);
//return null;
//Attach Mesh Filter
attachMeshFilter(meshHolder, mesh);
//Create Material
Material mat = createMaterial();
//Attach Mesh Renderer
attachMeshRenderer(meshHolder, mat);
return meshHolder;
}
用法:
void Start()
{
string objPath = Application.persistentDataPath + "/testObj.obj";
GameObject obj = loadAndDisplayMesh(objPath);
//Position it in front od=f the camera. Your ZOffset may be different
Camera cam = Camera.main;
float zOffset = 40f;
obj.transform.position = cam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, cam.nearClipPlane + zOffset));
}
编辑:
在极少数情况下,当 Shader.Find(标准)$ c时,Unity无法在Android上找到着色器使用$ c>。发生这种情况时会出现错误。
In some rare cases, Unity cannot find the shader on Android when Shader.Find("Standard")
is used. You get the error when that happens.
解决此问题的方法是在编辑器中创建一个材质并为其指定标准着色器。它应该默认使用标准着色器。
A work around for this would be to create a Material in the Editor and assign the "Standard" shader to it. It should use "Standard" shader by default.
1 。创建一个材料,名称为StandardMat。
1.Create a material and name is "StandardMat".
2 。在名为资源的文件夹中输入该材料。如果它不存在则创建它。你必须正确拼写。同样,该文件夹必须命名为Resources并放在Asset文件夹中。
2.Put that material inside a folder called "Resources". Create it if it doesn't exist. You must spell this correctly. Again, the folder must be named "Resources" and placed inside the "Asset" folder.
3 。您可以使用<加载材料 Resources.Load(StandardMat)as Material
。
在 createMaterial
上面的功能,
更改
Material mat = new Material(Shader.Find("Standard"));
到
Material mat = Resources.Load("StandardMat") as Material;
这篇关于使用FastObjImporter在场景上加载和显示obj模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!