Jump to content
Unity Insider Forum

Unity ObjImporter, wie?


Tiles

Recommended Posts

Ich wage mich grade auf Neuland. Ich will ein Obj File importieren, und es später auch wieder exportieren.

 

Und da gibt es ja praktischerweise diese zwei schnuckeligen Obj Im- und Exporterscripts im Unity Wiki. Geschrieben in C#

 

http://wiki.unity3d....tle=ObjImporter

http://wiki.unity3d....php/ObjExporter

 

Leider gibts keine Beschreibung dazu wie es funktioniert, wie man damit arbeitet. Und beim Importer beiss ich mir grade die Zähne aus.

 

Den Exporter habe ich inzwischen zum Laufen gebracht. Man muss das Script in einen Ordner namens \Assets\Standard Assets\ packen. Wenn mir da vielleicht jemand erklären könnte wieso das unbedingt dieser Ordner sein muss, jedenfalls nur mit diesem Pfad funktioniert es.

 

Und dann habe ich auf mein Gameobjekt ein zweites Script gepackt das die entsprechende Funktion im Exporter aufruft. Das hier macht den Export gleich am Start. Achtung, JS.

 

#pragma strict

var mesh1 : MeshFilter;

function Start ()
{
mesh1= GetComponent(typeof(MeshFilter)) as MeshFilter;
ObjExporter.MeshToFile(mesh1,"C:/Users/x/Documents/temp/testobj.obj"); //C# function in objexporter
}

 

Zurück zu unserem Importer. Den habe ich gleich neben dem Exportscript geparkt. Also auch unter \Assets\Standard Assets\. Der Importer hat auch eine Funktion mit der man wohl das Ganze startet.

 

// Use this for initialization

public Mesh ImportFile (string filePath) {

 

 

Also flux ein ähnliches Script gezimmert wie für den Export. Und versucht die Funktion aufzurufen:

 

#pragma strict

var mesh1 : MeshFilter;

function Start ()
{
mesh1= GetComponent(typeof(MeshFilter)) as MeshFilter;
  ObjImporter.ImportFile(mesh1,"C:/Users/x/Documents/temp/testobj.obj");
}

 

Und diesmal bekomme ich Mecker.

 

Assets/importit.js(10,16): BCE0020: An instance of type 'ObjImporter' is required to access non static member 'ImportFile'.

 

Mit der ich einfach nichts anfangen kann. Denn das Script existiert ja im \Assets\Standard Assets\ Ordner. Und anhängen lässt sich das ObjImport Script nirgends. The script needs to derive from Monobehaviour ...

 

Weiss jemand was ich anstellen muss um das Script zum Laufen zu bekommen? Wie ist das denn überhaupt gedacht dass das funktioniert? Mit Kommentaren war der Programmierer echt geizig :/

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mit Hilfe von Marrrk habe ich das Importdilemma wohl gefixt bekommen. Danke noch mal für die Hilfe.

 

var mesh1 : MeshFilter;

function Start ()
{
mesh1= GetComponent(typeof(MeshFilter)) as MeshFilter;
  var objImporter = ObjImporter(); var mesh = objImporter.ImportFile("C:/Users/x/Documents/mesh_spinningtop/spinningtop.obj");
}

 

Nun meckert mir allerdings der Importer.

 

IndexOutOfRangeException: Array index is out of range.
ObjImporter.populateMeshStruct (.meshStruct& mesh) (at F:/aaa - in development/importexportobj/Assets/Standard Assets/ObjImporter.cs:217)
ObjImporter.ImportFile (System.String filePath) (at F:/aaa - in development/importexportobj/Assets/Standard Assets/ObjImporter.cs:32)
importit.Start () (at Assets/importit.js:8)

 

Mich deucht so komme ich nicht weiter :(

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich kann dir nur empfehlen dir erstmal die grundsachen anzuschauen um zu verstehen was passiert. Wen du dies verstanden hast kannst du ganz einfach diesem Importer und Exporter selbst schreiben ohne große Probleme zu haben.(was auch schlecht dokumentiere Scripts angeht).

 

Als erste musst du dich mit der Materie ".obj" auseinandere setzten. Wie ist ein ".obj" aufgebaut. Im grunde ist es recht einfach aufgebaut und du kannst die jeweils die einzelne Sachen super "rauslesen" lassen. Hier hab ich mal den Aufbau eines einfachen Cubes:

 

//Info über das Object(eher unterintressant für den Import)
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 23.07.2014 21:37:46

//material Libary(kommt ganz drauf an ob du die drin haben willst)
mtllib object.mtl

//Objecte bzw. benennung
#
# object Box001
#

//Die guten Alten veritces positionen
v  -25.0000 0.0000 25.0000
v  -25.0000 0.0000 -25.0000
v  25.0000 0.0000 -25.0000
v  25.0000 0.0000 25.0000
v  -25.0000 50.0000 25.0000
v  25.0000 50.0000 25.0000
v  25.0000 50.0000 -25.0000
v  -25.0000 50.0000 -25.0000
# 8 vertices
//ende der Vertices Position

// Die Vertex normals position
vn 0.0000 -1.0000 -0.0000
vn 0.0000 1.0000 -0.0000
vn 0.0000 0.0000 1.0000
vn 1.0000 0.0000 -0.0000
vn 0.0000 0.0000 -1.0000
vn -1.0000 0.0000 -0.0000
# 6 vertex normals
//ende der normal positionen

//UV coords
vt 1.0000 0.0000 0.0000
vt 1.0000 1.0000 0.0000
vt 0.0000 1.0000 0.0000
vt 0.0000 0.0000 0.0000
# 4 texture coords
//ende der uv coords

//Groupname
g Box001

//material informationen
usemtl wire_057008136

//Smooth Groups
s 2
//die Faces/Triangle
f 1/1/1 2/2/1 3/3/1
f 3/3/1 4/4/1 1/1/1
// Bis hier hin hat er jetzt eine seite gezeichnet
s 4
f 5/4/2 6/1/2 7/2/2
f 7/2/2 8/3/2 5/4/2
s 8
f 1/4/3 4/1/3 6/2/3
f 6/2/3 5/3/3 1/4/3
s 16
f 4/4/4 3/1/4 7/2/4
f 7/2/4 6/3/4 4/4/4
s 32
f 3/4/5 2/1/5 8/2/5
f 8/2/5 7/3/5 3/4/5
s 64
f 2/4/6 1/1/6 5/2/6
f 5/2/6 8/3/6 2/4/6
# 12 faces
// 6 seiten hat ein cube dazu kommt das jeweils eine seite 2 triangle hat also im Schlussstrich hat es 12 faces also 12 Flächen.

 

 

So ist ein aufbau eines Cubes ungefähr:

 

http://blogs.msdn.co...00_0B213CAD.png

 

Du siehst alle Komponenten. Das hier

f 1/1/1 2/2/1 3/3/1

f 3/3/1 4/4/1 1/1/1

sind die anordnung der ersten 2 Triangles

 

Das ist die Positionsangegabe für ein "eck-Punkt" eines Cubes. Davon gibt es ja 8 Stück.

v -25.0000 0.0000 25.0000

 

Okay so ist der grobe aufbau eine ".Obj-Datei" jetzt musst du nur noch her gehen und das alles richtig auslesen/bzw. später richtig abspeichern. Du kannst hier am besten mit einem Streamreader und einem Streamwriter arbeiten.

 

Wen du jeweils die Datei einliest musst du nur die eingelesenen Daten den richtigen Arrays zuweisen. Anschließend ist es ganz einfach unity zu sagen das er das ganze rendern soll mit folgenden Befehlen:

 

//Dies ist dein Mesh hier stehen alle daten drinen die dein Object betrifft.

Mesh

//

mesh.vertices

//

mesh.uv

//

mesh.triangles

//

mesh.normals

 

Hier findest du die wichtigen Befehle nochmal:

 

http://docs.unity3d....rence/Mesh.html

 

Hier noch ein link zum Streamwriter:

 

http://msdn.microsoft.com/de-de/library/system.io.streamwriter%28v=vs.110%29.aspx

 

sowie Reader:

 

http://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CCAQFjAA&url=http%3A%2F%2Fmsdn.microsoft.com%2Fde-de%2Flibrary%2Fsystem.io.streamreader%28v%3Dvs.110%29.aspx&ei=BxnQU9_FJOSB4gSm-YDgCA&usg=AFQjCNGlQRAsRSGbGESp9npep04dbQm6qA&sig2=RrmsftK-f6GyYLDufRbx-Q&bvm=bv.71667212,d.bGE

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi Johnnydiango,

 

Wie Obj grob aufgebaut ist weiss ich, danke. Mir gings aber eigentlich darum mir das ganze Neugeschreibe zu ersparen. Denn es kostet einfach Zeit und Nerven das selber zu zimmern. Und mit Arrays und Text auslesen habe ich bisher in Unity noch nicht gearbeitet.

 

Der Obj Importer hier existiert halt schon. Man muss ja nicht immer das Rad neu erfinden wenn schon eins da steht. Der deutlich kleinere Aufwand wäre gewesen einfach die entsprechende Funktion aufzurufen, wenn es denn funktioniert. Und das hat ja beim Exporter auch funktioniert. Halbe Stunde und es lief. Was da allerdings fehlt ist das mtl File. Aber das kriege ich dem Exporter sicher noch beigebogen.

 

Nun muss ich mich erst mal einarbeiten und mir selber was basteln. Was mich eben viel Zeit kostet. Zeit die ich viel lieber ins Tool gesteckt hätte. Bin grade am Überlegen mir die Extension zu kaufen. Kost ja glaub nur 15 Euro oder so.

 

Danke jedenfalls für deine Links :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das schau ich mir auf jeden Fall noch an, das brauch ich dann für das was ich eigentlich tun will. Danke :)

 

Mit Marrrks Hilfe habe ich übrigens den Importer doch zum Laufen bekommen. Seine Adleraugen haben es gleich gesehen. Das Problem sass in den Indexwerten. Der Importer erwartete entweder eine Zahl oder drei Zahlen. Wenn da zwei Zahlen kommen weil das obj keine Normals hat kommt er ins straucheln. Sowas hier zum Beispiel f 5/1 6/2 2/3 1/4

 

Zu ersetzen ist das hier:

 

if (brokenBrokenString.Length > 1) //Some .obj files skip UV and normal
{
if (brokenBrokenString[1] != "") //Some .obj files skip the uv and not the normal
{
	temp.y = System.Convert.ToInt32(brokenBrokenString[1]);
}
temp.z = System.Convert.ToInt32(brokenBrokenString[2]);
}

 

mit dem hier:

 

if (brokenBrokenString.Length == 2) //Some .obj files skip UV and normal
{
   temp.y = System.Convert.ToInt32(brokenBrokenString[1]);
}

if (brokenBrokenString.Length == 3) //Some .obj files skip UV and normal
{
   if (brokenBrokenString[1] != "") //Some .obj files skip the uv and not the normal
   {
       temp.y = System.Convert.ToInt32(brokenBrokenString[1]);
   }
   temp.z = System.Convert.ToInt32(brokenBrokenString[2]);
}

 

Und dann habe ich mir noch zwei Stunden die Zähne dran ausgebissen wie ich denn nu die Sache in den Meshfilter bekomme.

 

Des Rätsels Lösung war ein Empty mit einem Meshfilter und einem Meshrenderer (den hatte ich vergessen, klar dass ich dann nichts sehe).

 

Und wenn man dann diesen Code dranhängt, dann wird beim Start das im Pfad eingetragene Mesh geladen.

#pragma strict

function Start () {

   var mymeshfilter= GetComponent(typeof(MeshFilter)) as MeshFilter;

   var objImporter = ObjImporter();
   mymeshfilter.mesh = objImporter.ImportFile("C:/meinpfad/meinmesh.obj");

}

 

Danke für die Hilfe Marrrk :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...