使用FastObjImporter在场景上加载和显示obj模型 [英] Load and display obj model on the scene with FastObjImporter

查看:179
本文介绍了使用FastObjImporter在场景上加载和显示obj模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的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(标准)。发生这种情况时会出现错误。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆