Load and display obj model on the scene with FastObjImporter
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?
Try with an empty game object:
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?
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;
Regards
c# object unity3d import
|
show 1 more comment
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?
Try with an empty game object:
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?
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;
Regards
c# object unity3d import
I initialized objPath in start
– Robert Piotrowski
Dec 18 '17 at 9:08
objPath = Application.persistentDataPath + "/testObj.obj";
– Robert Piotrowski
Dec 18 '17 at 9:08
This is android mobile app
– Robert Piotrowski
Dec 18 '17 at 9:09
Ok, sorry. In my app I download obj file from google drive and save it in this location. All works, when I download jpg and use as maintexture in cube, but I don't know how to put obj on scene.
– Robert Piotrowski
Dec 18 '17 at 9:16
Yes, I want show loaded model on the screen.
– Robert Piotrowski
Dec 18 '17 at 9:26
|
show 1 more comment
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?
Try with an empty game object:
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?
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;
Regards
c# object unity3d import
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?
Try with an empty game object:
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?
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;
Regards
c# object unity3d import
c# object unity3d import
edited Dec 18 '17 at 10:58
Programmer
76.2k1086151
76.2k1086151
asked Dec 18 '17 at 9:02
Robert PiotrowskiRobert Piotrowski
209
209
I initialized objPath in start
– Robert Piotrowski
Dec 18 '17 at 9:08
objPath = Application.persistentDataPath + "/testObj.obj";
– Robert Piotrowski
Dec 18 '17 at 9:08
This is android mobile app
– Robert Piotrowski
Dec 18 '17 at 9:09
Ok, sorry. In my app I download obj file from google drive and save it in this location. All works, when I download jpg and use as maintexture in cube, but I don't know how to put obj on scene.
– Robert Piotrowski
Dec 18 '17 at 9:16
Yes, I want show loaded model on the screen.
– Robert Piotrowski
Dec 18 '17 at 9:26
|
show 1 more comment
I initialized objPath in start
– Robert Piotrowski
Dec 18 '17 at 9:08
objPath = Application.persistentDataPath + "/testObj.obj";
– Robert Piotrowski
Dec 18 '17 at 9:08
This is android mobile app
– Robert Piotrowski
Dec 18 '17 at 9:09
Ok, sorry. In my app I download obj file from google drive and save it in this location. All works, when I download jpg and use as maintexture in cube, but I don't know how to put obj on scene.
– Robert Piotrowski
Dec 18 '17 at 9:16
Yes, I want show loaded model on the screen.
– Robert Piotrowski
Dec 18 '17 at 9:26
I initialized objPath in start
– Robert Piotrowski
Dec 18 '17 at 9:08
I initialized objPath in start
– Robert Piotrowski
Dec 18 '17 at 9:08
objPath = Application.persistentDataPath + "/testObj.obj";
– Robert Piotrowski
Dec 18 '17 at 9:08
objPath = Application.persistentDataPath + "/testObj.obj";
– Robert Piotrowski
Dec 18 '17 at 9:08
This is android mobile app
– Robert Piotrowski
Dec 18 '17 at 9:09
This is android mobile app
– Robert Piotrowski
Dec 18 '17 at 9:09
Ok, sorry. In my app I download obj file from google drive and save it in this location. All works, when I download jpg and use as maintexture in cube, but I don't know how to put obj on scene.
– Robert Piotrowski
Dec 18 '17 at 9:16
Ok, sorry. In my app I download obj file from google drive and save it in this location. All works, when I download jpg and use as maintexture in cube, but I don't know how to put obj on scene.
– Robert Piotrowski
Dec 18 '17 at 9:16
Yes, I want show loaded model on the screen.
– Robert Piotrowski
Dec 18 '17 at 9:26
Yes, I want show loaded model on the screen.
– Robert Piotrowski
Dec 18 '17 at 9:26
|
show 1 more comment
1 Answer
1
active
oldest
votes
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;
I must add MeshFilter and MeshRenderer to empty GameObject "Loaded Mesh" on the scene?
– Robert Piotrowski
Dec 18 '17 at 12:11
I did everything according to the instructions and it does not work. There are no errors in the debugger. Initially, the mistake was due to my fault, because I did not add material to the game object.
– Robert Piotrowski
Dec 18 '17 at 12:32
Problem found. It turned out that the importer does not create the front wall (I imported the cube) and the remaining walls are thin enough that it was not visible on the scene.
– Robert Piotrowski
Dec 18 '17 at 13:50
@RobertPiotrowski How did you fix it? I'm using the fixed code but Unity simply doesn't display the object, no matter what shader I use (I'm testing on PC, not Android).
– Neph
May 24 '18 at 11:49
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f47865014%2fload-and-display-obj-model-on-the-scene-with-fastobjimporter%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
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;
I must add MeshFilter and MeshRenderer to empty GameObject "Loaded Mesh" on the scene?
– Robert Piotrowski
Dec 18 '17 at 12:11
I did everything according to the instructions and it does not work. There are no errors in the debugger. Initially, the mistake was due to my fault, because I did not add material to the game object.
– Robert Piotrowski
Dec 18 '17 at 12:32
Problem found. It turned out that the importer does not create the front wall (I imported the cube) and the remaining walls are thin enough that it was not visible on the scene.
– Robert Piotrowski
Dec 18 '17 at 13:50
@RobertPiotrowski How did you fix it? I'm using the fixed code but Unity simply doesn't display the object, no matter what shader I use (I'm testing on PC, not Android).
– Neph
May 24 '18 at 11:49
add a comment |
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;
I must add MeshFilter and MeshRenderer to empty GameObject "Loaded Mesh" on the scene?
– Robert Piotrowski
Dec 18 '17 at 12:11
I did everything according to the instructions and it does not work. There are no errors in the debugger. Initially, the mistake was due to my fault, because I did not add material to the game object.
– Robert Piotrowski
Dec 18 '17 at 12:32
Problem found. It turned out that the importer does not create the front wall (I imported the cube) and the remaining walls are thin enough that it was not visible on the scene.
– Robert Piotrowski
Dec 18 '17 at 13:50
@RobertPiotrowski How did you fix it? I'm using the fixed code but Unity simply doesn't display the object, no matter what shader I use (I'm testing on PC, not Android).
– Neph
May 24 '18 at 11:49
add a comment |
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;
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;
edited Dec 18 '17 at 11:56
answered Dec 18 '17 at 10:54
ProgrammerProgrammer
76.2k1086151
76.2k1086151
I must add MeshFilter and MeshRenderer to empty GameObject "Loaded Mesh" on the scene?
– Robert Piotrowski
Dec 18 '17 at 12:11
I did everything according to the instructions and it does not work. There are no errors in the debugger. Initially, the mistake was due to my fault, because I did not add material to the game object.
– Robert Piotrowski
Dec 18 '17 at 12:32
Problem found. It turned out that the importer does not create the front wall (I imported the cube) and the remaining walls are thin enough that it was not visible on the scene.
– Robert Piotrowski
Dec 18 '17 at 13:50
@RobertPiotrowski How did you fix it? I'm using the fixed code but Unity simply doesn't display the object, no matter what shader I use (I'm testing on PC, not Android).
– Neph
May 24 '18 at 11:49
add a comment |
I must add MeshFilter and MeshRenderer to empty GameObject "Loaded Mesh" on the scene?
– Robert Piotrowski
Dec 18 '17 at 12:11
I did everything according to the instructions and it does not work. There are no errors in the debugger. Initially, the mistake was due to my fault, because I did not add material to the game object.
– Robert Piotrowski
Dec 18 '17 at 12:32
Problem found. It turned out that the importer does not create the front wall (I imported the cube) and the remaining walls are thin enough that it was not visible on the scene.
– Robert Piotrowski
Dec 18 '17 at 13:50
@RobertPiotrowski How did you fix it? I'm using the fixed code but Unity simply doesn't display the object, no matter what shader I use (I'm testing on PC, not Android).
– Neph
May 24 '18 at 11:49
I must add MeshFilter and MeshRenderer to empty GameObject "Loaded Mesh" on the scene?
– Robert Piotrowski
Dec 18 '17 at 12:11
I must add MeshFilter and MeshRenderer to empty GameObject "Loaded Mesh" on the scene?
– Robert Piotrowski
Dec 18 '17 at 12:11
I did everything according to the instructions and it does not work. There are no errors in the debugger. Initially, the mistake was due to my fault, because I did not add material to the game object.
– Robert Piotrowski
Dec 18 '17 at 12:32
I did everything according to the instructions and it does not work. There are no errors in the debugger. Initially, the mistake was due to my fault, because I did not add material to the game object.
– Robert Piotrowski
Dec 18 '17 at 12:32
Problem found. It turned out that the importer does not create the front wall (I imported the cube) and the remaining walls are thin enough that it was not visible on the scene.
– Robert Piotrowski
Dec 18 '17 at 13:50
Problem found. It turned out that the importer does not create the front wall (I imported the cube) and the remaining walls are thin enough that it was not visible on the scene.
– Robert Piotrowski
Dec 18 '17 at 13:50
@RobertPiotrowski How did you fix it? I'm using the fixed code but Unity simply doesn't display the object, no matter what shader I use (I'm testing on PC, not Android).
– Neph
May 24 '18 at 11:49
@RobertPiotrowski How did you fix it? I'm using the fixed code but Unity simply doesn't display the object, no matter what shader I use (I'm testing on PC, not Android).
– Neph
May 24 '18 at 11:49
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f47865014%2fload-and-display-obj-model-on-the-scene-with-fastobjimporter%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I initialized objPath in start
– Robert Piotrowski
Dec 18 '17 at 9:08
objPath = Application.persistentDataPath + "/testObj.obj";
– Robert Piotrowski
Dec 18 '17 at 9:08
This is android mobile app
– Robert Piotrowski
Dec 18 '17 at 9:09
Ok, sorry. In my app I download obj file from google drive and save it in this location. All works, when I download jpg and use as maintexture in cube, but I don't know how to put obj on scene.
– Robert Piotrowski
Dec 18 '17 at 9:16
Yes, I want show loaded model on the screen.
– Robert Piotrowski
Dec 18 '17 at 9:26