2017-12-18 389 views
0

在我的Unity項目中,我想使用互聯網上的FastObjImporter類將obj放到場景中。我是否必須創建一個空的GameObject並將處理的obj分配給它?使用FastObjImporter在場景中加載和顯示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; 

有人能解釋我做錯了嗎?

CODE:

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; 
     } 
} 

問候

+0

我在開始 –

+0

objPath = Application.persistentDataPath + 「/testObj.obj」 初始化objPath; –

+0

這是Android手機應用程序 –

回答

1

沒有必要實例化網格。它是一個組件,我不確定你是否可以實例化它。只需將其分配給材料。

你的代碼中的主要問題是你沒有創建材質和着色器。您需要創建一個材質,然後創建一個「標準」着色器並將該着色器分配給該材質。

我注意到FastObjImporter腳本是舊的,並決定嘗試它來確保它正常運行。我遇到了一個索引異常錯誤,然後修復它。您可以獲取固定版本here的副本。請參閱行#57爲我所做的實際修復。

函數來創建MeshFilder,材質和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 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)); 
} 

編輯:

在某些罕見的情況下,團結找不到Android上的着色器在使用Shader.Find("Standard")。發生這種情況時會出現錯誤。

解決此問題的方法是在編輯器中創建一個材質併爲其分配「標準」着色器。它應該默認使用「標準」着色器。

。創建一個材料和名稱是「StandardMat」。

。將該材質放在名爲「Resources」的文件夾中。如果它不存在,就創建它。你必須正確拼寫。同樣,該文件夾必須命名爲「資源」並放置在「資產」文件夾內。

。您可以使用Resources.Load("StandardMat") as Material加載材料。

在上述createMaterial功能,

變化

Material mat = new Material(Shader.Find("Standard")); 

Material mat = Resources.Load("StandardMat") as Material; 
+0

我必須添加MeshFilter和MeshRenderer以在場景上清空GameObject「Loaded Mesh」? –

+0

我根據說明做了所有事情,但不起作用。調試器中沒有錯誤。最初,這個錯誤是由於我的錯,因爲我沒有添加材料到遊戲對象。 –

+0

發現問題。原來,進口商並沒有製造前牆(我輸入了立方體),其餘的牆壁都很薄,以至於在現場看不到。 –