在我的Unity项目中,我想使用互联网上的FastObjImporter类将obj放在场景中。我是否必须创建一个空GameObject并将已处理的obj分配给它?
尝试使用空游戏对象:
GameObject go = new GameObject("obj");
myMesh = FastObjImporter.Instance.ImportFile(objPath);
Instantiate(myMesh, Vector3.zero, Quaternion.identity);
go.AddComponent<MeshRenderer>();
go.GetComponent<MeshFilter>().mesh = myMesh;
早些时候我尝试过这种方式,但它也没有用:
GameObject go;
myMesh = FastObjImporter.Instance.ImportFile(objPath);
Instantiate(myMesh, Vector3.zero, Quaternion.identity);
go.GetComponent<MeshFilter>().mesh = myMesh;
有人可以解释我做错了吗?
码:
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。它是一个组件,我不确定你是否可以实例化它。只需将其分配给材料即可。
代码中的主要问题是您没有创建材质和着色器。您需要创建一个材质,然后创建一个“标准”着色器并将该着色器指定给该材质。
我注意到FastObjImporter
脚本是旧的,并决定尝试它以确保它正常运行。我遇到了一个索引异常错误,然后修复它。您可以获取固定版本here的副本。有关我所做的实际修复,请参阅第57行。
创建MeshFilder
,Material和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的功能,加载模型并将所有必要的组件附加到它上面以显示它:
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("Standard")
时,Unity无法在Android上找到着色器。发生这种情况时会出现错误。
解决此问题的方法是在编辑器中创建材质并为其指定“标准”着色器。它应该默认使用“标准”着色器。
1.创建一个材料,名称为“StandardMat”。
2.将该材料放在名为“Resources”的文件夹中。如果它不存在则创建它。你必须正确拼写。同样,该文件夹必须命名为“Resources”并放在“Asset”文件夹中。
你可以用Resources.Load("StandardMat") as Material
加载材料。
在上面的createMaterial
函数中,
更改
Material mat = new Material(Shader.Find("Standard"));
至
Material mat = Resources.Load("StandardMat") as Material;