Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

ObjReader - load .obj files at runtime

Discussion in 'Assets and Asset Store' started by Eric5h5, May 7, 2013.

  1. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You have to destroy the game objects in the array, not the array itself.

    --Eric
     
  2. imagoculturae

    imagoculturae

    Joined:
    Apr 8, 2014
    Posts:
    81
    Below there is what was in the original load function I have only copied/pasted the code for an extra array of object coming from another file.
    So you are suggesting to use
    Destroy (objData);
    and
    Destroy (objData2);

    instead of
    Destroy (objData.gameObjects);
    and
    Destroy (objData2.gameObjects);

    By the way now it works with Destroy (objData2.gameObjects); I think it was some kind of bug in Unity I have restarted and it worked! o_O

    IEnumerator Load () {
    loading = true;
    if (objData != null && objData.gameObjects != null) {
    for (var i = 0; i < objData.gameObjects.Length; i++) {
    Destroy (objData.gameObjects);
    }
    }
    objData = ObjReader.use.ConvertFileAsync (objFileName, true, standardMaterial);


    if (objData2 != null && objData2.gameObjects != null) {
    for (var b = 0; b < objData2.gameObjects.Length; b++) {
    Destroy (objData2.gameObjects);
    }
    }
    objData2 = ObjReader.use.ConvertFileAsync (objFileName2, true, standardMaterial);


    while (!objData.isDone) {
    loadingText = "Loading... " + (objData.progress*100).ToString("f0") + "%";
    yield return null;
    }
    loading = false;
    if (objData == null || objData.gameObjects == null) {
    loadingText = "Error loading file";
    return false;
    }

    loadingText = "Import completed";
    yield return new WaitForSeconds(3);
    loadingText = "";
    FocusOnObjects();
    }
     
  3. slimshader

    slimshader

    Joined:
    Jun 11, 2013
    Posts:
    187
    Hey,

    I just bought your package and since I was also considering same-priced competition I tried it with this test file: http://orbcreation.com/SimpleObj/Ayumi.obj with WWW test scene from your packages and it seems it loads materials incorrectly. I only looked at hair mesh material but instead of transparent/diffuse it was loaded as diffuse making eyes of the model hidden.
     
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The MTL file says "d 1.000000" for the hair, which means non-transparent, so ObjReader uses a non-transparent material.

    --Eric
     
  5. slimshader

    slimshader

    Joined:
    Jun 11, 2013
    Posts:
    187
    So how come it looks fine in this demo?
    http://orbcreation.com/SimpleObj/Demo.html
     
  6. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I'm not really sure offhand; hard-coded maybe?

    --Eric
     
  7. slimshader

    slimshader

    Joined:
    Jun 11, 2013
    Posts:
    187
    Kindof suspected that. Thanks! Will make sure materials in my objs are correct.
     
  8. CarpetHead

    CarpetHead

    Joined:
    Nov 22, 2013
    Posts:
    20
    Hey, I don't want to be rude or bug you about this, but my employer is asking if you have any idea when this feature might be implemented? Just so I know if I need to come up with a workaround for the mean time.

    Thanks!
     
  9. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I would guess 2-3 weeks based on other stuff on the to-do list.

    --Eric
     
  10. imagoculturae

    imagoculturae

    Joined:
    Apr 8, 2014
    Posts:
    81
    Hi Eric
    I was wandering if there is a way to write to a text file the names of all the imported objects after
    objData = ObjReader.use.ConvertFileAsync (objFileName, true, standardMaterial);

    I am trying to create a list of objects that I will include into the web page of the webplayer so that I can click and focus on each object.
     
  11. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    objData.gameObjects contains an array of all the GameObjects, so you can use their names.

    --Eric
     
  12. imagoculturae

    imagoculturae

    Joined:
    Apr 8, 2014
    Posts:
    81
    Hi there!
    I was trying to modify the focusOnObjects function so that the camera is closer to the focused object.
    I have only put var radius = maxSize.magnitude / 4.0f; instead of /2, then I have used a variable in order to choose which object of the array I am focusing on:
    var bounds = new Bounds(objData.gameObjects[focusobject].transform.position, Vector3.zero);
    however the focus goes always on the center of the whole array.o_O
    Could you help me on this?
    Many thanks
    Nic
     
  13. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I actually adapted that function from some code that somebody posted here on the forums, so I'm not really sure how the math works I'm afraid. But if you're just using the bounds from one object, and not looping through the array, then it should only be using those particular bounds.

    --Eric
     
  14. imagoculturae

    imagoculturae

    Joined:
    Apr 8, 2014
    Posts:
    81
    OK, I now have this:


    Code (CSharp):
    1. public int FocusOnObjects (int focusobject) {
    2.         var cam = Camera.main;
    3.         var bounds = new Bounds(objData.gameObjects[focusobject].transform.position, Vector3.zero);
    4.         //for (var i = 0; i < objData.gameObjects.Length; i++) {
    5.         bounds.Encapsulate (objData.gameObjects[focusobject].GetComponent<Renderer>().bounds);
    6.         //}
    7.      
    8.         var maxSize = bounds.size;
    9.         var radius = maxSize.magnitude / 4.0f;
    10.         var horizontalFOV = 2.0f * Mathf.Atan (Mathf.Tan (cam.fieldOfView * Mathf.Deg2Rad / 2.0f) * cam.aspect) * Mathf.Rad2Deg;
    11.         var fov = Mathf.Min (cam.fieldOfView, horizontalFOV);
    12.         var distance = radius / Mathf.Sin (fov * Mathf.Deg2Rad / 2.0f);
    13.      
    14.         cam.transform.position = bounds.center;
    15.         cam.transform.Translate (-Vector3.forward * distance);
    16.         cam.transform.LookAt (bounds.center);
    17.         return focusobject;
    18.     }
    Where focusobject is a variable that I pass in order to choose the object I want from the array.
    However is still not focusing on the chosen object, if someone can help will really appraciate.
    Many thanks
    p.s. if I can get the original post of where this come from maybe I can continue the conversation there
     
    Last edited: Mar 2, 2015
  15. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You don't seem to have any bounds, since you're just setting it to Vector3.zero. By the way, please use code tags when posting code.

    --Eric
     
  16. imagoculturae

    imagoculturae

    Joined:
    Apr 8, 2014
    Posts:
    81
    Don't know how to use bounds I just tought to remove the for loop in order to apply what is there to a single object in the array.
    Sorry for the tag I just saw the option now, is a bit hidden.
     
  17. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
  18. raj231

    raj231

    Joined:
    Nov 18, 2014
    Posts:
    46
    I've searched in the forum but i don't answer for camera freezing when model load once reach 100%. Please anyone help me on this....Have you tried to load the model in the cameraview than the sceneview?
     
    Last edited: Mar 3, 2015
  19. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I think you're confused about how Unity works. There is no "camera freezing" per se, and you can't load models in the "camera view" (I guess you mean game view?) as opposed to the scene view. You can only load models in the level; the scene view is basically just another camera. If you're talking about the fact that it takes a moment to process the model when you import it, yes, that's inevitable. When you import models into Unity the normal way, you can clearly see that it also takes a little while to process. So when you import models at runtime, you can expect that it will need a little time to do that. Since this is expected, it's not a problem, and it's not something that can be "fixed", unless someone finds a way to make CPUs infinitely fast.

    --Eric
     
  20. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    ObjReader 2.4 is out! Will be submitted to the asset store next.

    Additions:
    • The ObjData variable returned by ConvertFileAsync has a Cancel function now, so downloads can be cancelled at any time.
    • Bumpmap textures are loaded, if they're specified by "map_bump" or "bump" in the MTL file.
    • UseFileNameAsObjectName variable, which if checked will use the actual name of the file as the name of the generated GameObject(s), rather than any group names specified in the OBJ file.

    --Eric
     
  21. Eric-Pratt

    Eric-Pratt

    Joined:
    Apr 28, 2014
    Posts:
    30
    I'm trying to assign a texture to a material name in a loaded object, can anyone point me in the right direction?
     
  22. Eric-Pratt

    Eric-Pratt

    Joined:
    Apr 28, 2014
    Posts:
    30
    I sorted it out:
    void OpenFileM (string[] pathsToFiles) {
    //load models, assign to game object (game object is singular for now), find b sources and change their shader
    for (var i = 0; i < pathsToFiles.Length; i++) {
    var fileIndex = pathsToFiles.LastIndexOf (pathChar);
    message += pathsToFiles.Substring (fileIndex+1, pathsToFiles.Length-fileIndex-1) ;
    ObjReader.use.ConvertFile (pathsToFiles, true, standardMaterial, transparentMaterial);

    LoadedSceneGO=GameObject.Find(message);
    }
    foreach(Material matt in LoadedSceneGO.renderer.materials)
    {
    Debug.Log (matt.name);
    if(matt.name == "VideoBSource (Instance)") {
    //matt.mainTexture = videoBSource;
    VideoBSourceMat[materialcounter] = matt;
    matt.shader = shaderB;
    materialcounter++;
    //matt.mainTexture = Resources.Load("Comp0000");
    }
    }
     
  23. SuHwanK

    SuHwanK

    Joined:
    Dec 30, 2014
    Posts:
    43
    Hi Eric.
    I need your help.
    Warnning_01.png
    Here is my Obj model.
    and i'd imported unity by ObjReader.
    Then, this pic.
    Warnning_02.png
    Export my Obj model -> obj File at running time unity.
    open in 3D max
    Warnning_03.png
    and deconstruct mesh.
    Warnning_04.png

    how can i do?
    please help.
    thank you :)
     
  24. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Hi, I don't really understand what you're asking.

    --Eric
     
  25. SuHwanK

    SuHwanK

    Joined:
    Dec 30, 2014
    Posts:
    43
    Sorry my bad english.
    so, first pic is my example model(in 3DMAX).
    and second, imported my example model in unity by OBJReader.(in Unity)
    It's look like diffrent mesh.(like blacken).
    thank you. :)
     
  26. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Make sure hard edges are split in Max.

    --Eric
     
  27. MyGenericUsername

    MyGenericUsername

    Joined:
    Sep 6, 2014
    Posts:
    95
    What about an FBX reader? Could that be accomplished using the same techniques?
     
  28. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Yes, but the FBX format is proprietary and comes in binary formats as well as text, so it's not something I'm interested in.

    --Eric
     
  29. MyGenericUsername

    MyGenericUsername

    Joined:
    Sep 6, 2014
    Posts:
    95
    Okay, Thanks. just wondering.
     
  30. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    As I recall, there's an FBX importer on the asset store, so apparently someone else was more interested in it than I am. ;)

    --Eric
     
  31. SuHwanK

    SuHwanK

    Joined:
    Dec 30, 2014
    Posts:
    43
    Warnning_05_unity.png
    It's Original Object. not runtime import by just unity3D.
    hard edges are not split.
    Warnning_02.png
    This Image is Imported by OBJ Reader.
    how can i fix my problem?
    thank you.
     
  32. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    As I mentioned, you'll need to split the hard edges. Unity has an option to split edges based on angle, which ObjReader doesn't have.

    --Eric
     
  33. SuHwanK

    SuHwanK

    Joined:
    Dec 30, 2014
    Posts:
    43
    I think i was wrong.
    Max and Maya's Obj exporter is little different.
    So, I cunfused. The Problem is solved.
    Thank you for your help.
    have a nice day eric!
    :)
     
  34. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Glad to hear you got it worked out. :)

    --Eric
     
  35. hkha

    hkha

    Joined:
    Jul 21, 2012
    Posts:
    6
    Hi Eric, I'm trying to open Obj files .. I can open some of the files, but the ones i'm interested in give me a
    "Unknown char: n" error .. any ideas whats causing this ?

    Thanks.
     
  36. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Maybe the text format is wrong.

    --Eric
     
  37. hkha

    hkha

    Joined:
    Jul 21, 2012
    Posts:
    6
    Ok did some digging .. it turns out that the Obj files that I have contain a few "nan" values .. and that trips the parser
    I know the Obj shouldn't have bad entries, and i'm looking into fixing the issue when I'm saving the Obj files in objective C. but for a quick fix I just added "if (line.Length < 3 || line.IndexOf("nan") != -1) continue;" within the try while loop.

    It seems to be working, not sure if i need to add this exception anywhere else within the ObjReader class tho.
    Any thoughts ?

    Thanks,
    Howie.
     
  38. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Sounds about right...I would assume that if it was needed elsewhere then it wouldn't be working. ;)

    --Eric
     
  39. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,350
    hi,

    Does this automatically split large meshes into smaller ones?
    65k vertex limit seems to break other model importers (tested few),
    i'm looking into reading quite highpoly objects (made from cad models).

    (sorry didnt read every page, if its already mentioned)
     
  40. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It depends...if the model has groups where each group is <65K vertices, then it will work if you use the option for separate objects per group. But if any group is >65K vertices, then it won't work.

    --Eric
     
  41. raj231

    raj231

    Joined:
    Nov 18, 2014
    Posts:
    46
    When i was downloading the loading text showing 60% and if i've button to cancel the download. How can i cancel or stop the download when press the button.
     
  42. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Use the Cancel function in the ObjData class.

    --Eric
     
  43. Eric-Pratt

    Eric-Pratt

    Joined:
    Apr 28, 2014
    Posts:
    30
    Okay, so I've had ObjReader working for quite some time in Unity loading very complex texture baked models. For some reason though now that I'm testing out the compiled version of the project when I load the obj files the loaded model is pink.
    Dev Console gives me this:
    > UnitEngine.Debug.LogError(Object)
    ObjReader:parseMTL(String[], Material, Material, String, Dictionary`2)
    ObjReader:Convert(String&, Material, Material, String, Boolean)
    ObjReader:ConvertFile(String, Boolean, Material, Material)
    controls:OpenFileM(String[]) (at E:/Clientwork/VS/Unity/IK LiveV0.91/Assets/Sources/controls.cs 1848)
    $:MoveNext() (at E/ClientWork/VS/Unity/IK
    LiveV0.91/Assets/Plugins/UniFileBrowser/UniFileBrowser.js:1345)
    UnityEngine.MonoBehaviour:StartCoroutine_Auto(IEnumerator)
    UniFileBrowser:DrawFileWindow() (at E:/ClientWork/VS/Unity/IK LiveV0.91/Assets/Plugins/UniFileBrowser/UniFileBrowser.js:670)
    CompilterGenerated.$adaptor$__UniFileBrowser_closeWindowFunction$callable2$120_35__$WindowFunction$0:Invoke(Int32)
    UnityEngine.GUI:CallWindowDelegate(WindowFunction, Int32, GUISkin, Int32, Single, Single, GUIStyle)

    I didn't find this terribly enlightening (even while retyping it). Any thoughts? Seems like the .mtl file isn't getting read, but it gets read just fine when running it in Unity.
    Thanks,
    Eric
     
  44. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I haven't seen any issues with builds here, but pink models means a missing material. I would assume that your project is set up in a way that the required materials aren't referenced. Putting stuff in Resources is typically a good way to fix that, since everything in Resources is always included in a build whether it's referenced or not.

    --Eric
     
  45. Eric-Pratt

    Eric-Pratt

    Joined:
    Apr 28, 2014
    Posts:
    30
    They are objects external to resources. Any reason why the materials would import in testing and not in production?
     
  46. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Materials are always present in the editor, but when you make a build, unreferenced assets aren't included (aside from stuff in Resources, as mentioned).

    --Eric
     
  47. Eric-Pratt

    Eric-Pratt

    Joined:
    Apr 28, 2014
    Posts:
    30
    But the materials are being imported at runtime, they aren't present in the editor until they are loaded. You can use ObjReader to load an obj over the internet (in my case they are just on a different drive), is there no way to load materials at runtime from outside the resources folder?
     
  48. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    The materials aren't being imported at runtime. Materials only exist in Unity. Importing a texture is a different matter, and uses existing materials. If the material isn't present then the texture won't show up either.

    --Eric
     
  49. Eric-Pratt

    Eric-Pratt

    Joined:
    Apr 28, 2014
    Posts:
    30
    Is there a code example of loading an external .obj into a preexisting material array with textures?
     
  50. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    No, that's not something that's possible. Textures come from external sources as specified in the .mtl file. Again, materials and textures are entirely separate things. A material is basically a container for things like the shader and so on. With ObjReader, you specify the standard material and transparent material, where the standard material is used for non-transparent objects and the transparent material is used for transparent objects. If the materials are missing you get pink.

    --Eric