Load and display obj model on the scene with FastObjImporter

前端 未结 1 1222
旧巷少年郎
旧巷少年郎 2020-12-11 13:33

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

相关标签:
1条回答
  • 2020-12-11 13:51

    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.

    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.

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

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

    Usage:

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

    EDIT:

    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.Create a material and name is "StandardMat".

    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.You can load the material with Resources.Load("StandardMat") as Material.

    In the createMaterial function above,

    Change

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

    to

    Material mat = Resources.Load("StandardMat") as Material;
    
    0 讨论(0)
提交回复
热议问题