1. Dashboard
  2. Forum
  3. Filebase
  4. Lexikon
  5. Artikel
  6. Spieletest
  7. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  8. Zur Transport Fever Community
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Artikel
  • Seiten
  • Forum
  • Filebase-Eintrag
  • Lexikon
  • Artikel (Bewertungssystem)
  • Erweiterte Suche
  1. WiSim Welt
  2. Forum
  3. Spiele
  4. Cities in Motion 2
  5. Modding und Erweiterungen für CiM2
  6. Modding-Allgemein

Modifizierbarkeit von CiM2

  • lukiono
  • 3. April 2013 um 15:17
  • eis_os
    Profi
    Beiträge
    1.025
    Filebase Einträge
    2
    • 17. April 2013 um 07:18
    • #61

    Kommt, bin mir nur noch nicht sicher ob in das in C# oder in C schreiben werde,
    erst mal muss man aber die ganzen anderen Sachen verstehen und wie die Abhängigkeiten aufgelöst werden.
    (Verbindung zwischen Textur2D -> Material -> GameObject -> Mesh)

    Außerdem wird es einfacher sein ein fertiges Bundle im UnityEditor zu laden und etwaige Probleme zu sehen als immer CIM2 zu laden ;)

    • Zitieren
  • eis_os
    Profi
    Beiträge
    1.025
    Filebase Einträge
    2
    • 18. April 2013 um 19:06
    • #62

    Irgendwie möchte Unity nicht mehr herausgeben, hier meine letzte Version des Editor Scripts. Vielleicht kann es doch noch jemand brauchen...

    Spoiler anzeigen
    Code
    using UnityEngine;
    using System.Collections;
    using System.Text;
    using System.Collections.Generic;
    
    
    using UnityEditor;
    using UnityEditorInternal;
    using System.IO;
    using System.Reflection;
    
    
    public class eisUncompressBundle : MonoBehaviour
    {
        [MenuItem("Assets/Dump Bundle %u")]
    
        static void Unpack ()
        {
            string file = EditorUtility.OpenFilePanel ("Select bundle file to unpack", "", "bundle");
            if (file.Length == 0)
                return;
    		AssetBundle bundle;
    		var wwwoobj = new WWW ("file:///" + file);
    
    		bundle = wwwoobj.assetBundle;
    		try {
    			ProcessBundle(file, bundle);
    		} catch {
    			bundle.Unload(true);
    			throw;
    		}
    		bundle.Unload(true);
    	}
    	static void ProcessBundle(string file, AssetBundle bundle)
        {
    		string outdir = "Assets/"+Path.GetFileNameWithoutExtension(file)+"_output/";
    		Directory.CreateDirectory(outdir);
    
    		StreamWriter sw = File.AppendText(outdir+Path.GetFileNameWithoutExtension(file)+".txt");
    		sw.AutoFlush = true;
    		sw.WriteLine("===================================================\n");
    
            Object[] objs1 = bundle.LoadAll();
    		foreach (Object obj in objs1) {
    			string filename = obj.name.Replace('/', '_');
    			System.Type type = obj.GetType ();
    			string itemdata = "";
    			PropertyInfo[] properties = type.GetProperties();
    			itemdata = "Name: "+obj.name+"\n";
    			itemdata += "   Instanceid: "+obj.GetInstanceID() +"\n";
    			itemdata += "   HashCode: "+obj.GetHashCode() +"\n"; 
    			itemdata += "   Type: "+type.ToString() +"\n";
    			foreach (System.Reflection.PropertyInfo prop in properties) {
    				try {
    					itemdata += "   Prop: "+prop.Name + "= "+ prop.GetValue(obj,null).ToString() + "\n"; 
    	            } catch {
    					itemdata += "   Prop: "+prop.Name + "= ?can't reflect?" + "\n"; 
    	            }
    
    			}
    
    			sw.WriteLine(itemdata);
    
    			string outdirtype = outdir+type.Name+"/";
    			string f;
    			Object o;
    
    
    			Directory.CreateDirectory(outdirtype);
    			obj.hideFlags = 0;
    			if (type == typeof(GameObject) || (type.IsSubclassOf (typeof(GameObject)))) {
    
    				f = outdirtype + filename + ".prefab";
                    Object prefab = PrefabUtility.CreateEmptyPrefab (f);
                    if (obj == null) {
                        //Debug.LogError ("NullException");
                    } else {
                    	PrefabUtility.ReplacePrefab ((GameObject)(obj), prefab);
    				}
    			} else if (type == typeof(Material) || (type.IsSubclassOf (typeof(Material)))) {
    				f = outdirtype + filename + ".mat";
    				o = Object.Instantiate (obj);
    				AssetDatabase.CreateAsset(o, f);
    			} else if (type == typeof(Texture2D ) || (type.IsSubclassOf (typeof(Texture2D )))) {
    				/*Texture2D tex = (Texture2D)obj;
    				itemdata += "Textureformat: "+(int)tex.format+"\n";
    				var bytes = tex.EncodeToPNG();
    	        	File.WriteAllBytes(outdir+filename+".png", bytes);
    	        	*/
    				f = outdirtype + filename + ".tex";
    				o = Object.Instantiate (obj);
    				AssetDatabase.CreateAsset(o, f);
    			} else if (type == typeof(UnityEngine.Mesh)) {
    				Directory.CreateDirectory(outdir+"objs/");
    				ExportObj( (UnityEngine.Mesh)obj,outdir+"objs/"+filename+".obj");
    				try {
    					o = Object.Instantiate (obj);
    				} catch {
    					o = obj;
    				}
    				f = outdirtype + filename + ".asset";
    				AssetDatabase.CreateAsset(o, f);
    			} else {
    				try {
    					o = Object.Instantiate (obj);
    				} catch {
    					o = obj;
    				}
    				f = outdirtype + filename + ".asset";
    				AssetDatabase.CreateAsset(o, f);
    			}
    			Debug.Log(itemdata);
    			/* Object o;
    			try {
    				o = Object.Instantiate (obj);
    			} catch {
    				o = obj;
    			}
    			o.hideFlags = 0; */
    		}
    		AssetDatabase.Refresh ();
    		sw.Close();
        }
     
    
    
    	static void ExportObj(UnityEngine.Mesh m, string filename) {
    
    
    		System.IO.StreamWriter file = new System.IO.StreamWriter(filename);
    		file.WriteLine("g "+m.name);
    		file.WriteLine("# vertices");
    
    		var ver = m.vertices;
    		for(int i = 0; i < ver.Length; i++) {
    			//file.WriteLine(string.Format("#Index: {0}\n", i));
    			file.WriteLine(string.Format("v {0} {1} {2}\n",ver[i].x.ToString(),ver[i].y.ToString(),ver[i].z.ToString()));
    		}
    
    		file.WriteLine("# normals");
    		var vn = m.normals;
    		for(int i = 0; i < vn.Length; i++) {
    			file.WriteLine(string.Format("vn {0} {1} {2}\n",vn[i].x.ToString(),vn[i].y.ToString(),vn[i].z.ToString()));
    		}
    
    		file.WriteLine("# uv");
    		var uv = m.uv;
    		for(int i = 0; i < uv.Length; i++) {
    			file.WriteLine(string.Format("vt {0} {1}\n",uv[i].x.ToString(),uv[i].y.ToString()));
    		}
    
    		file.WriteLine("# uv1");
    		var uv1 = m.uv1;
    		for(int i = 0; i < uv1.Length; i++) {
    			file.WriteLine(string.Format("vt1 {0} {1}\n",uv1[i].x.ToString(),uv1[i].y.ToString()));
    		}
    
    		file.WriteLine("# uv2");
    		var uv2 = m.uv2;
    		for(int i = 0; i < uv1.Length; i++) {
    			file.WriteLine(string.Format("vt2 {0} {1}\n",uv2[i].x.ToString(),uv2[i].y.ToString()));
    		}
    
    		file.WriteLine("# colors");
    		foreach(Color c in m.colors) {
                file.WriteLine(string.Format("vc {0} {1} {2} {3}\n",c.r,c.g,c.b,c.a));
            }
    
            for (int material=0; material < m.subMeshCount; material ++) {
    		/*	file.WriteLine("#");
                file.WriteLine("usemtl "+mats[material].name);
                file.WriteLine("usemap "+mats[material].name);
     */
                int[] triangles = m.GetTriangles(material);
                for (int i=0;i<triangles.Length;i+=3) {
                    file.WriteLine(string.Format("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\n", 
                        triangles[i]+1, triangles[i+1]+1, triangles[i+2]+1));
                }
            }
    		file.Close();
    	}
    }
    Alles anzeigen

    Einmal editiert, zuletzt von eis_os (18. April 2013 um 19:33)

    • Zitieren
  • eis_os
    Profi
    Beiträge
    1.025
    Filebase Einträge
    2
    • 20. April 2013 um 21:14
    • #63

    Hallo

    Auch wenn ich nicht viel neues Berichten kann, vielleicht interessiert es ja doch jemanden.

    Komplexität eines Gebäudes, ein Reise durch CIM2:

    CIM2 lädt ein Bundle mit verschiedenen Datastores:

    Ein PlaceableDataStore beinhaltet ein Array mit PlaceableInfo (s)
    PlaceableInfo beinhaltet ein Pointer zu einen PlaceableObject

    Ein PlaceableObject hat eine ID, die muss Eindeutig sein, damit CIM2 das Teil in seinen Bundles wiederfindet.
    PlaceableObject hat darüber hinaus:
    Preis
    Wie viel Elektrizität es benötigt.
    Informationen für einen Strassentyp, und die Position.
    Wartungskosten
    Children Array[] PlaceableChild(beinhaltet Position, Rotation, PlaceableObject)
    Varianten Array[] PlaceableVariation(beinhaltet PlaceableObjects)

    Dieses PlaceableObject basiert auf einen MapObject (ein Art Interface Zwischenschicht für virtuelle Mesh Funktionen), dieses beinhaltet ein ObjectData.
    ObjectData beinhaltet einen prefab, ein UnityEngine.GameObject


    Und woher kommt das Mesh? Dafür ist ein BuildingObject zuständig ist, es ist eine Ableitung von PlaceableObject das die Meshfunktionen von MapObject mit "leben" füllt.
    Darin wird eine Instanz des UnityEngine.GameObject erstellt wenn benötigt.


    Und deswegen ist das Bundles Format so verkorkst. ;(

    • Zitieren
  • mediziner
    Administrator
    Reaktionen
    2
    Beiträge
    1.924
    Filebase Einträge
    10
    Einträge
    4
    • 20. April 2013 um 21:37
    • Offizieller Beitrag
    • #64

    Ja, seh schon. Klingt sehr verschachtelt und kompliziert.
    Und ja, freue mich immer, wenn es was neues zu dem Thema hier gibt.

    • Vorheriger offizieller Beitrag
    • Nächster offizieller Beitrag
    • Zitieren
  • Ghorwin
    Anfänger
    Beiträge
    14
    • 21. April 2013 um 08:26
    • #65

    Respekt an jeden, der weiss, wovon er bei sowas spricht :thumbup:
    Ich hab zwar keine Ahnung davon und verstehe wahrscheinlich nur 10% (wenn überhaupt), aber ich finds trotzdem hochinteressant.

    LG
    Ghorwin

    • Zitieren
  • immi
    Gast
    • 21. April 2013 um 11:46
    • #66
    Zitat von eis_os

    Auch wenn ich nicht viel neues Berichten kann, vielleicht interessiert es ja doch jemanden.


    jupp :)
    hab die Woche zwar auch nicht allzu viel bezügl CiM2 getan (außer meine City mit zuviel Buslinien in eine Einfamilienhaussiedlung zu verwandeln :/), aber ein paar Ergänzungen hab ich:

    Jedes Asset, (PlaceableObject, DataStore, Mesh, etc), besitzt eine eindeutige ID.
    Ausnahme davon ist, dass in jedem .bundle sich ein Asset mit der ID 1 befindet, das sozusagen den Einstiegspunkt liefert. Neben ein paar andere Sachen benennt es das mainAsset, was bei CiM2 dann ein Asset vom Type DataStoreBundle ist. Und von da gehts genau mit den Zusammenhängen weiter, die eis_os beschrieben hat. Dem begeisterten Informatikstudent drängt sich anhand der Informationen förmlich das Malen eines UML Diagrames auf :p, ich begnüg mich mal mit einem simplen Textdiagramm

    Spoiler anzeigen
    Code
    Descr:DataStoreBundle:-> Descr:PlaceableDataStore -> Descr:BuildingObject
                                                      -> Descr:BuildingObject
                                                      ...
                          -> Descr:VehicleDataStore   -> Descr:VehicleObject
                          ....
    
    
    
    
    Descr:BuildingObject  # daten wie speed, price, etc
                          -> GameObject -> Transform
                                        -> MeshFilter -> Mesh
                                        -> Renderer -> Material
                                        .... # optional AudioSource, Animation,...
                          -> Descr:GeneratedBuildingInfo
                          -> Mesh # LOD1
                          -> Mesh # LOD2
                          -> Material # LOD1
                          -> Material # LOD2
    
    
    Material: -> Shader
              '_MainTex' -> Texture
              '_ColorMask' -> Texture
              '_SpecularMap" -> Texture
              'InteriorMap' -> Texture
              'CubeMap'  -> Texture
              'NormalMap' -> Texture
    Alles anzeigen


    es gibt da dann noch ein paar andere Assettype wie ParticleSystem, ParticleSystemRenderer, SkinnedMeshRenderer, die auch noch irgendwo da reinsortiert gehören

    Desweitern hab ich festgestellt das CiM2 in der Tat alle .bundle Dateien lädt, auch fremde, solange man sie in einen der 4 Ordner CIM2_Data/Data/Bundle/{Default,Game,Global,Menu} plaziert. Unterordner funktionieren nicht. Ob die Informationen bezüglich der 4 Ordner irgendwo in der .exe fest verdrahtet ist, oder in irgendeiner der anderen Dateien festgehalten ist, ist allerdings unklar.

    und da ich immer das Gefühl habe dass meine Busse die langsamsten Gefährte im Spiel überhaupt sind und ständig von anderen überholt werden, hab ich mal die Fahrzeugdaten zusammengesucht.
    vielleicht interessierts jemanden:

    Spoiler anzeigen
    Code
    - vehicle               speed   acc     dec       turning     nodding maint fuel
    0x9f24d786 sedan-01      6000   750     600        40000       400
    0xa7732855 hatchback-01  5500   700     600        40000       500
    0xe4f79a6e limousine-01  6100   650     500        30000       300
    0x767e1c9  scooter-01    5000   850     500        37000       200
    0x8a3d6b0c sports-car-01 7000  1200     700        50000       250
    0xcf370394 station-wagon-01 5900 600    425        35000       400
    0xb3fdc334 suv-01        5800   700     550        35000       400
    0x2bc2e04f hybrid-01     5200   800     650        39000       450
    0x82ab931  taxi-01       6500   800     650        45000       500
    0xce760449 van-01        5000   450     350        30000       300
    0x6035d72a truck-cab-01  4500   300     250        20000       500
    0x8cedeee  ambulance     7500   800     600        35000       400
    0x97995af4 fire-engine   7000   350     200        20000       400
    0x932d543a police-car-01 8000  1000     600        45000       350
    -- player vehicle
    0xf40db64c bus-01-a      4096   350     256        32768       512  360  75
    0xd7bb2b43 bus-02        4096   350     256        32768       512  420  100
    0x2f4ebb88 bus-03        4096   450     256        32768       512  300  50
    Alles anzeigen


    jemand ne idee was man sich unter 'nodding' vorstellen darf?

    • Zitieren
  • eis_os
    Profi
    Beiträge
    1.025
    Filebase Einträge
    2
    • 21. April 2013 um 12:08
    • #67

    Ein Diagramm von CIM2 wäre zu viel des guten wenn ich es hier Posten würde. C# ist mit den richtigen Tools sehr gesprächig. Leider ist Unity Bundle Laden aber im Native Code.

    nodding, Kippverhalten beim bremsen, beschleunigen würde ich sagen., ist es.

    Ein mainAsset kann der UnityEditor nicht finden, ich bekomme einfach keine GameObjekte importiert an einem Stück, die Verbindungen aller Objekte zerbröckelt immer.
    Der Bundle Lader in Unity scheint sowieso ein Sorgenkind zu sein, da er keine Fehler für den Entwickler ausgibt wenn etwas nicht funktioniert.

    Da CIM2 auch die Animationen adressiert, werden Objekte (Fahrzeuge) ohne die richtigen Animationen nicht funktionieren. Oder es gibt ein Exception im Code.
    Deswegen wäre es mir schon lieb den Unity Free Editor als Basis zum Zusammenbau der Teile zu nutzen. Denn das Teil in ein asset zu Speichern und per externen Tool in ein CIM2 Bundle zu überführen.
    Wobei mein CIM2 schon ein externes Helloworld DLL lädt :D

    • Zitieren
  • immi
    Gast
    • 21. April 2013 um 12:32
    • #68
    Zitat von eis_os

    Ein mainAsset kann der UnityEditor nicht finden,


    Ist vielleicht auch nur für den AssetBundle Loader intern interessant. Da die Assets ansonsten im .bundle nur zusammenhangslos hinterander gereiht sind, gibt es dem Code den direkten Zugriff auf das "Hauptelement" ohne alle Assets durchlaufen zu müssen.

    Code
    >> python asbundle.py Buildings07.bundle -data -id 1
     AssetBundle(8e/8e):0x1
       m_Name:string = ""
       m_PreloadTable:PPtr<Object>[2882]: ... 
       m_Container:map
          Array:pair[174]: ...
       m_MainAsset:AssetInfo
          preloadIndex:int = 0
          preloadSize:int = 329
          asset:PPtr<Object> = MonoBehaviour(DataStoreBundle<GlobalShared>:-4) 'Buildings07' id:0x2d1161a1
       m_ScriptCompatibility:AssetBundleScriptInfo[0]:
       m_ClassCompatibility:pair[0]:
    Alles anzeigen


    Zitat von eis_os

    Da CIM2 auch die Animationen adressiert, werden Objekte (Fahrzeuge) ohne die richtigen Animationen nicht funktionieren. Oder es gibt ein Exception im Code.

    hmm, wir werdens wohl herausfinden ;)

    Zitat von eis_os

    Deswegen wäre es mir schon lieb den Unity Free Editor als Basis zum Zusammenbau der Teile zu nutzen. Denn das Teil in ein asset zu Speichern und per externen Tool in ein CIM2 Bundle zu überführen.

    hat was der Gedanke. Nur müsste man sich dann auch erstmal um die Struktur der .asset Dateien kümmern. Oder ist die irgendwo dokumentiert?
    bin momentan noch etwas unschlüssig wie ich weiter verfahre. erstmal noch weiter mit meinem Python script rumforschen, oder schon mal anfangen nen "richtiges" Tool in C oder so zu bauen. Ein Pythonscript wird als Moddingtool in der Windowswelt wohl nicht die große Akzeptanz finden :p

    //edit:

    Zitat

    nodding, Kippverhalten beim bremsen, beschleunigen würde ich sagen., ist es.

    jo, macht sinn

    • Zitieren
  • eis_os
    Profi
    Beiträge
    1.025
    Filebase Einträge
    2
    • 21. April 2013 um 18:03
    • #69

    So, ich hab versucht den Loader aus CIM2 nach zubauen, aber obwohl er sagt das X01 im Bundle vorhanden ist, laden per Bundle.Load funktioniert nicht, und es kommt immer eine Null Reference Exception, ?(

    Ich hab mein Unity Free Projekt eingestellt das es Yaml Dateien erstellt (Asset Serialization auf Text Only, per Hex Editor) und Versions Control auf Meta Dateien.
    Die Yaml Dateien beinhalten keine Typen und sehen dann etwa so aus:

    Spoiler anzeigen
    Code
    %YAML 1.1
    %TAG !u! tag:unity3d.com,2011:
    --- !u!43 &4300000
    Mesh:
      m_ObjectHideFlags: 0
      m_PrefabParentObject: {fileID: 0}
      m_PrefabInternal: {fileID: 0}
      m_Name: tram0410692
      serializedVersion: 6
      m_SubMeshes:
      - firstByte: 0
        indexCount: 1391
        isTriStrip: 2
        triangleCount: 655
        firstVertex: 0
        vertexCount: 814
        localAABB:
          m_Center: {x: 0, y: 1.62499988, z: -.0499436855}
          m_Extent: {x: 1.31434143, y: 1.52499998, z: 6.57105541}
      m_MeshCompression: 0
      m_IndexBuffer: 9d0094009e00930092009200b002b002af02cb009....
    Alles anzeigen


    ....

    Spoiler anzeigen
    Code
    m_VertexData:
        m_CurrentChannels: 43
        m_VertexCount: 814
        m_Streams[0]:
          channelMask: 43
          offset: 0
          stride: 48
          align: 16
        m_Streams[1]:
          channelMask: 0
          offset: 0
          stride: 0
          align: 16
        m_Streams[2]:
          channelMask: 0
          offset: 0
          stride: 0
          align: 16
        m_Streams[3]:
          channelMask: 0
          offset: 0
          stride: 0
          align: 16
        m_DataSize: 39072
        _typelessdata: 8f69943fcccccc3ddeddb640ea67513f......
    Alles anzeigen


    Da ich ja aber schon mal ein Mesh exportiert habe, ist diese _typelessdata Gemüse auch nicht hilfreicher.

    Ein MonoBehaviour hat zwar eine Bytes Eigenschaft im Editor, die ist aber immer Leer.

    Und hier mal eine Animation:

    Spoiler anzeigen
    Code
    %YAML 1.1
    %TAG !u! tag:unity3d.com,2011:
    --- !u!74 &7400000
    AnimationClip:
      m_ObjectHideFlags: 0
      m_PrefabParentObject: {fileID: 0}
      m_PrefabInternal: {fileID: 0}
      m_Name: close10414
      serializedVersion: 3
      m_Compressed: 0
      m_RotationCurves:
      - curve:
          serializedVersion: 2
          m_Curve:
          - time: 1.1920929e-07
            value: {x: -.707106829, y: 0, z: -0, w: .707106829}
            inSlope: {x: 0, y: 0, z: 0, w: 0}
            outSlope: {x: 0, y: 0, z: 0, w: 0}
            tangentMode: 0
          - time: 1.00000012
            value: {x: -.707106829, y: 0, z: -0, w: .707106829}
            inSlope: {x: 0, y: 0, z: 0, w: 0}
            outSlope: {x: 0, y: 0, z: 0, w: 0}
            tangentMode: 0
          m_PreInfinity: 2
          m_PostInfinity: 2
        path: root-bone
      - curve:
          serializedVersion: 2
          m_Curve:
          - time: 1.1920929e-07
            value: {x: -.707106829, y: 0, z: -0, w: .707106829}
            inSlope: {x: 0, y: 0, z: 0, w: 0}
            outSlope: {x: 0, y: 0, z: 0, w: 0}
            tangentMode: 0
          - time: 1.00000012
            value: {x: -.707106829, y: 0, z: -0, w: .707106829}
            inSlope: {x: 0, y: 0, z: 0, w: 0}
            outSlope: {x: 0, y: 0, z: 0, w: 0}
            tangentMode: 0
          m_PreInfinity: 2
          m_PostInfinity: 2
        path: door-bone01
      - curve:
          serializedVersion: 2
          m_Curve:
          - time: 1.1920929e-07
            value: {x: -.707106829, y: 0, z: -0, w: .707106829}
            inSlope: {x: 0, y: 0, z: 0, w: 0}
            outSlope: {x: 0, y: 0, z: 0, w: 0}
            tangentMode: 0
          - time: 1.00000012
            value: {x: -.707106829, y: 0, z: -0, w: .707106829}
            inSlope: {x: 0, y: 0, z: 0, w: 0}
            outSlope: {x: 0, y: 0, z: 0, w: 0}
            tangentMode: 0
          m_PreInfinity: 2
          m_PostInfinity: 2
        path: door-bone02
      m_CompressedRotationCurves: []
      m_PositionCurves:
      - curve:
          serializedVersion: 2
          m_Curve:
          - time: 1.1920929e-07
            value: {x: -0, y: 0, z: 0}
            inSlope: {x: 0, y: 0, z: 0}
            outSlope: {x: 0, y: 0, z: 0}
            tangentMode: 0
          - time: 1.00000012
            value: {x: -0, y: 0, z: 0}
            inSlope: {x: 0, y: 0, z: 0}
            outSlope: {x: 0, y: 0, z: 0}
            tangentMode: 0
          m_PreInfinity: 2
          m_PostInfinity: 2
        path: root-bone
      - curve:
          serializedVersion: 2
          m_Curve:
          - time: 0
            value: {x: 1.29860914, y: 1.2480402, z: 2.58589315}
            inSlope: {x: 3.80649618e-15, y: -0, z: -.408983558}
            outSlope: {x: -1.52754751e-06, y: -0, z: -1.96058936e-05}
            tangentMode: 0
          - time: .833333373
            value: {x: 1.29860914, y: 1.2480402, z: 1.92815149}
            inSlope: {x: -.361668885, y: -0, z: .303576052}
            outSlope: {x: -.361633599, y: -0, z: 1.77634583e-14}
            tangentMode: 0
          - time: 1.00000012
            value: {x: 1.17805696, y: 1.2480402, z: 1.92815149}
            inSlope: {x: -.723310292, y: -0, z: 7.61296526e-15}
            outSlope: {x: -.723310292, y: -0, z: 7.61296526e-15}
            tangentMode: 0
          m_PreInfinity: 2
          m_PostInfinity: 2
        path: door-bone01
      - curve:
          serializedVersion: 2
          m_Curve:
          - time: 0
            value: {x: 1.29860914, y: 1.2480402, z: .595137775}
            inSlope: {x: 3.80649618e-15, y: -0, z: .355650544}
            outSlope: {x: -1.52754751e-06, y: -0, z: 6.14527698e-06}
            tangentMode: 0
          - time: .833333373
            value: {x: 1.29860914, y: 1.2480402, z: 1.24821436}
            inSlope: {x: -.361668885, y: -0, z: -.378641993}
            outSlope: {x: -.361633599, y: -0, z: 8.88172914e-15}
            tangentMode: 0
          - time: 1.00000012
            value: {x: 1.17805696, y: 1.2480402, z: 1.24821436}
            inSlope: {x: -.723310292, y: -0, z: 3.80648263e-15}
            outSlope: {x: -.723310292, y: -0, z: 3.80648263e-15}
            tangentMode: 0
          m_PreInfinity: 2
          m_PostInfinity: 2
        path: door-bone02
      m_ScaleCurves:
      - curve:
          serializedVersion: 2
          m_Curve:
          - time: 1.1920929e-07
            value: {x: 1, y: 1, z: 1}
            inSlope: {x: 0, y: 0, z: 0}
            outSlope: {x: 0, y: 0, z: 0}
            tangentMode: 0
          - time: 1.00000012
            value: {x: 1, y: 1, z: 1}
            inSlope: {x: 0, y: 0, z: 0}
            outSlope: {x: 0, y: 0, z: 0}
            tangentMode: 0
          m_PreInfinity: 2
          m_PostInfinity: 2
        path: root-bone
      - curve:
          serializedVersion: 2
          m_Curve:
          - time: 1.1920929e-07
            value: {x: 1, y: 1, z: 1}
            inSlope: {x: 0, y: 0, z: 0}
            outSlope: {x: 0, y: 0, z: 0}
            tangentMode: 0
          - time: 1.00000012
            value: {x: 1, y: 1, z: 1}
            inSlope: {x: 0, y: 0, z: 0}
            outSlope: {x: 0, y: 0, z: 0}
            tangentMode: 0
          m_PreInfinity: 2
          m_PostInfinity: 2
        path: door-bone01
      - curve:
          serializedVersion: 2
          m_Curve:
          - time: 1.1920929e-07
            value: {x: 1, y: 1, z: 1}
            inSlope: {x: 0, y: 0, z: 0}
            outSlope: {x: 0, y: 0, z: 0}
            tangentMode: 0
          - time: 1.00000012
            value: {x: 1, y: 1, z: 1}
            inSlope: {x: 0, y: 0, z: 0}
            outSlope: {x: 0, y: 0, z: 0}
            tangentMode: 0
          m_PreInfinity: 2
          m_PostInfinity: 2
        path: door-bone02
      m_FloatCurves: []
      m_SampleRate: 30
      m_WrapMode: 8
      m_Bounds:
        m_Center: {x: .0817383528, y: 2.74223709, z: 0}
        m_Extent: {x: 1.32373595, y: 2.74776363, z: 4.85393906}
      m_EditorCurves: []
      m_EulerEditorCurves: []
      m_Events: []
    Alles anzeigen

    Immer bedenken, die Ausgabe ist mit Vorsicht zu genießen, da die Objekte geklont werden um Sie in eine externe Datei schreiben zu können.

    Also viel versucht heute, aber immer noch kein gescheites Ergebnis, warum der Lader in Unity nicht an das DataStore kommt ist auch sehr komisch.
    PS: Wenn man die Dateien in ein Package packt, konvertiert Unity die Daten wieder in das Binary Format. Na toll!

    • Zitieren
  • ArkenbergeJoe
    Gast
    • 21. April 2013 um 20:48
    • #70

    Programmierung ist für mich auch etwas zu groß, aber die Sache mit den Instancen-IDs erinnert mich sehr an SimCity4. Hier scheint nur alles einzeln zu sein, damit werden aus wenigen kleinen Grundstückchen, so wie bei LEGO, viele komplexe Sachen zusammengerechnet, zumindest denke ich es so, wenn ich es richtig interpretiert habe. Aber ähnliche Strukturen gibts bei SC4 auch, nur sind die Quellobjekte wesentlich größer, dort funktioniert die Verbindung von Teilstücken nur über Nummern. (Dabei nochmal Hut ab vor dem SC-NAM-Team)

    Zitat

    Da CIM2 auch die Animationen adressiert, werden Objekte (Fahrzeuge) ohne
    die richtigen Animationen nicht funktionieren. Oder es gibt ein
    Exception im Code.

    Eigentlich sollten aber eigene animierte Objekte, wenn man noch keine funktionfähige Animation hinbekommt, die Animationanweisung mit einer "0" enden lassen, dann bekäme man sowas rein, wenns überhaupt so funktioniert.

    EDIT: Was mir noch so durch den Kopf ging
    Verkehrswege sollten ja auch nicht mehr als vorgefertigte Modelle/Objekte vorhanden sein. Sondern ich nehme mal an, dass es pro Verkehrsweg nur einen Punkt gibt, welcher mit den nur nötigen Grafiken und Informationen versehen ist. Alles andere wird wie z.B. bei Blender erst als Spline erstellt. Käme man da hinein, könnte man mit einem kleinen gelben Klecks jede Menge Sandwege bauen.

    2 Mal editiert, zuletzt von ArkenbergeJoe (22. April 2013 um 19:10)

    • Zitieren
  • eis_os
    Profi
    Beiträge
    1.025
    Filebase Einträge
    2
    • 22. April 2013 um 19:43
    • #71

    Ich mag alles, also mal "-all" einfügen, Vorsicht, Datei wird sehr groß!
    Patch für asbundle.py -all:

    Spoiler anzeigen
    Diff
    --- asbundle.py.org	Mon Apr 22 19:29:10 2013
    +++ asbundle.py	Mon Apr 22 19:24:49 2013
    @@ -97,6 +97,7 @@
     FilterType = {}
     Files = []
     Verbose = False
    +AllData = False
     
     #Data
     AssetIndexEntry = namedtuple('AssetIndexEntry', ['id', 'ofs', 'len', 'type1', 'type2'])
    @@ -142,7 +143,7 @@
     		self.size = size
     	def pr(self, indent):
     		print_i(indent, "%s:%s[size:%i]"%(self.type_info.name, self.type_info.typ,self.size.value)	)
    -		if len(self.value) > 43:
    +		if not AllData and (len(self.value) > 43):
     			print_i(indent+3, "[...]")
     		else:
     			for mem in self.value:
    @@ -152,7 +153,7 @@
     def read_array(File, ty):
     	size = read_typ(File, ty.member[0])
     	var = VarArray(ty, size)
    -	if size.value > 0xffff:
    +	if not AllData and size.value > 0xffff:
     		print("oops")
     	else:
     		for i in range(size.value):
    @@ -356,6 +357,7 @@
     	print("     -type <type>    filter by asset type (<type> in hex)")
     	print("     -id <id>        filter by asset id (<id> in hex)")
     	print("     -v               more verbose output")
    +	print("     -all            show all data, don't truncate")
     	sys.exit()
     
     it = iter(sys.argv[1:])
    @@ -368,6 +370,8 @@
     		ShowAssetData = True
     	elif x == '-v':
     		Verbose = True
    +	elif x == '-all':
    +		AllData = True
     	elif x == '-id':
     		try:
     			FilterIDs[ int(it.next(), 16) ] = True
    Alles anzeigen

    Als erste Applikation würde ich Vorschlagen das eine Bundle in verschiedene Dateien zu splitten und zu mergen.
    Format, vielleicht YAML, JSON und nach jedem Namen den Typen mit angeben damit man theoretisch jedes Objekt beschreiben kann. Für die Mesh könnte man dann einen YAML<->OBJ konverter bauen, bzw. YAML<->Textur. Vorteil man kann auch per einfachen Texteditor in den Daten herumbasteln ;)

    Was hättet Ihr denn gerne?

    • Zitieren
  • rovapasi
    Gast
    • 22. April 2013 um 19:54
    • #72

    Mit einem Texteditor an den Dateien rumbasteln - hört sich super an. Das Erinnert an die Script Dateien aus CIM1.

    • Zitieren
  • GT670DN
    Gast
    • 22. April 2013 um 20:03
    • #73

    Tut mir leid, aber für welche asbundle.py?

    • Zitieren
  • immi
    Gast
    • 22. April 2013 um 20:53
    • #74
    Zitat von eis_os

    Ich mag alles, also mal "-all" einfügen, Vorsicht, Datei wird sehr groß!


    ich kommentier den Part einfach immer nur aus, wenn ich mehr Output haben will :), das is das Schöne an scriptdateien, Änderungen sind fix gemacht

    Zitat von eis_os

    Als erste Applikation würde ich Vorschlagen das eine Bundle in verschiedene Dateien zu splitten und zu mergen.


    *zustimm*, sowas wie Yaml würde schon ganz gut passen.
    Weiß nicht, ob sich für Meshes/Texturen der Zwischenschritt über eine Textdatei lohnt. Die Daten wird eh keiner im Texteditor bearbeiten können.
    Bei den Texture könnte man gleich eine DDS Datei draus basteln und bei den Meshes einfach nur den Datenblob wie er ist exportieren. Und dann im zweiten Schritt einen Blender Exporter/Importer oder OBJ Konverter dafür basteln.

    @GT670DN
    blätter mal nen paar Beiträge zurück. Irgendwo hatte ich die hier angehängt

    • Zitieren
  • ArkenbergeJoe
    Gast
    • 24. April 2013 um 21:42
    • #75

    Mal nebenbei, wird auf anderen Seiten auch über Modifizierbarkeit diskutiert? Oder was auf die Beine gestellt? :r2d2:

    • Zitieren
  • eis_os
    Profi
    Beiträge
    1.025
    Filebase Einträge
    2
    • 1. Mai 2013 um 19:55
    • #76

    BundleCodec

    Wie gesagt, hab ich angefangen eine C Version eines Tools erstellt, der die Dateien liest, splittet und irgendwann in der Zukunft auch wieder zusammen bauen kann. (Nein das geht nicht und das Format ist nicht entgültig)
    Alles sehr Work in Progress und eigentlich nur mit der X01.bundle Datei getestet.

    Aber da auch die FileOffsets jeder einzelnen Variable ausgegeben werden kann, ist das Tool in seiner jetzigen Form vielleicht für jemanden interessant.
    Es im Allgemeinen einfacher mit kleineren Dateien zu arbeiten als mit einem riesigen Dump.

    bundlecodec.exe -x -o X01.bundle erstellt ein X01 Verzeichnis mit den Daten

    Die eigentlichen Daten werden zurzeit mit einer Menge C Preprozessor Makro Magic eingelesen, (wer mag kann es mit -vv starten) und dann mit einer Tonne printf wieder in ein Dateiformat gegossen.

    Eigentlich möchte ich die "Schablonen" in zukünftigen Versionen in separate Dateien auslagern inklusive aller Flags.
    Also die Typen bekommen eigene Dateien die jeweils von den anderen Dateien referenziert werden.

    Was mir an den Python Dumps aufgefallen ist, es scheint das die Dicts die Daten anders sortieren als mein C Parser.

    Wie es weiter geht, noch keine Ahnung. Vielleicht erst mal nach C++ oder GoLang konvertieren, für das Einlesen der Textdaten wären native Hashlisten, Maps und co doch eine schöne Sache.

    Download Link:
    http://cim.bytetransfer.de/cim2/bundlecodec/

    2 Mal editiert, zuletzt von eis_os (2. Mai 2013 um 06:59)

    • Zitieren
  • ArkenbergeJoe
    Gast
    • 1. Mai 2013 um 21:59
    • #77

    Was dein BundleCodec da an Daten rausschmeisst, erinnert mich tatsächlich an die Zeiten, wo ich mit den IliveReader für SC4 gearbeitet habe. Dort standen die Adressen statt Dateinamen. Somit konnten dort auch keine reinen Windowsdateien gelesen werden. Wahrscheinlich wird es auch hier sowas wie eine zentrale Controllerdatei geben, wenn jeder Modder diese einzeln ändert, werden jeweils andere Modds nicht angezeigt. Aber bei Programmierung kann ich nur mutmaßen, sollte tatsächlich mal ein Bearbeitungstool auf Hex-ID-Basis rauskommen, wird mir die Arbeit damit nicht fremd sein.

    • Zitieren
  • eis_os
    Profi
    Beiträge
    1.025
    Filebase Einträge
    2
    • 2. Mai 2013 um 07:21
    • #78

    Nein, es sind die serialisierten Objektdaten einer UnityEngine bzw. der C# Scripts die CO in Unity geschrieben hat.

    Es gibt da ein paar Fallstricke:
    a) Jede Unity Engine Revision hat ein leicht anderes Format.
    b) Es explizit so ausgelegt schnell zu laden mit wenig Daten.
    c) Es soll nicht wieder in der Unity Engine geladen werden können.
    d) Es beinhaltet keine/kaum Spiellogik, also nicht denken man kann so etwas wie in CIM1 machen.
    e) Jedes Spiel hat seine eigene Objekte, so das man Bundles nicht austauschen kann,
    f) Bundle Erstellung ist ein Unity Pro Feature. Somit kann man nicht mal eben ein Bundle erszellen und es so modifizieren das es in CIM2 läuft.

    Der Workflow in Unity ist in etwa so:
    Habe eine Szene, habe 3D Daten, Texturen usw. in ein Verzeichnis, erstelle im Editor ein Gameobjekt, sage dem Editor welche Daten und Scripte das Gameobjekt braucht.
    Unity baut dann beim Kompilieren / Anzeigen die internen C# Objekte zusammen. Die können dann in der Pro Version in ein Bundle gespeichert werden.

    Wir müssen jetzt den anderen Weg gehen, aus den C# Objekten wieder sinnvolle Daten herauslesen, diese wieder in eine Textur, Mesh, Animation verwandeln. Das man die Meshs wiederbekommen kann hab ich ja sogar in Unity geschafft. Die Texturen sollten auch nicht das Problem sein. Problematisch wird es ein sinnvolles Bundle zu erstellen mit nur den wichtigsten Daten. Dann kann man die Datei einfach CIM2 unterjubeln und es wird die Daten laden.


    Es wird auch dringend Abgeraten die Unity Engine Version zu wechseln, da dieses scheinbar erhebliche Probleme verursacht, d.h. das was wir da gerade auseinander nehmen war nie als editierbares oder allgemeines Format ausgelegt. -edit- Auch CO kennt dieses Format nicht oder hat die viel viel teurere Source Code Version von Unity gekauft, ist eher unwahrscheinlich-/edit-


    PS: Du sollst nicht an den Daten herum basteln, Du kannst die Bundles sowieso nicht verteilen, außerdem sind diese viel zu groß. Für Stats soll es ja einen Aufsatz von CO geben. Mir geht es primär darum neue Objekte zu erstellen.

    4 Mal editiert, zuletzt von eis_os (2. Mai 2013 um 07:29)

    • Zitieren
  • immi
    Gast
    • 3. Mai 2013 um 13:14
    • #79
    Zitat von eis_os

    Alles sehr Work in Progress und eigentlich nur mit der X01.bundle Datei getestet.


    Scheint auch bei den anderen zu funktionieren.
    wenn du so schön an dem Tool bastelts, werd ich mal schauen ob ich den Mesh Blob und Blender nicht irgendwie verkuppeln kann.
    Und wenn du irgendne Möglichkeit siehst die Programmierarbeiten sinnvoll zu splitten, sag Bescheid. Ich mach gerne mit :)

    Zitat von eis_os


    Eigentlich möchte ich die "Schablonen" in zukünftigen Versionen in separate Dateien auslagern inklusive aller Flags.
    Also die Typen bekommen eigene Dateien die jeweils von den anderen Dateien referenziert werden.


    meine Gedanken gingen eher dahin, das ganze Typenbeschreibungsgedöngs gar nicht auszugeben, sondern intern im Programm nur fest zu verdrahten mit den einzelnen Objekten. Letztlich kann der Modder an der Strukturbeschreibung eh nichts ändern, insofern wären Schablonendateien fürs editieren eh tabu.
    Dann lieber intern die Strukturinformationen dafür nutzen, dass man nicht alle Typen generisch nach Schablonen ausgibt, sondern die Daten "anwenderfreundlicher" formatiert.

    also so

    Spoiler anzeigen
    Code
    AssetType = "GameObject"
    ID = 0x52f7adec
    m_children = [  ref("Transform",0xb940013a)
                    ref("MeshFilter",0x732a362a)
                    ref("Renderer",0xe9624b5d)
                    ref("MonoBehaviour",0x665b1f3)
                  ]
    m_Layer = 10
    m_Name = "Pavillion"
    m_Tag = 0
    m_IsActive = 0
    Alles anzeigen

    oder so

    Spoiler anzeigen
    Code
    AssetType = "Texture2D"
    ID = 0x2846b40d
    m_Name = "fountain-lod1"
    m_FilterMode = 2
    m_Aniso = 4
    m_MipBias = 0.0
    m_WrapMode = 0
    m_LightmapFormat = 0
    m_ColorSpace = 1
    ImageFile = "fountain-lod1.dds"


    anstatt so:

    Spoiler anzeigen
    Code
    GameObject(1/1):0x52f7adec
       m_Component:vector
          Array:Array
             data:pair
                first:SInt32 = 4
                second:PPtr<Component>
                   m_FileID:SInt32 = 0
                   m_PathID:SInt32 = 3107979578
             data:pair
                first:SInt32 = 33
                second:PPtr<Component>
                   m_FileID:SInt32 = 0
                   m_PathID:SInt32 = 1932146218
             data:pair
                first:SInt32 = 23
                second:PPtr<Component>
                   m_FileID:SInt32 = 0
                   m_PathID:SInt32 = 3915533149
             data:pair
                first:SInt32 = 114
                second:PPtr<Component>
                   m_FileID:SInt32 = 0
                  m_PathID:SInt32 = 107327987
       m_Layer:UInt32 = 10
     ....
    Alles anzeigen

    Das sollte dem Programm dann beim Einlesen immer noch ausreichen, um die Strukturen wieder herzurichten, aber wiegesagt, alles nur lose Gedankengänge ...

    ich hatte mein python script überigens noch dahingehend erweitert die Texturen gleich als DDS Dateien auszugeben. Werd das script hier demnächst nochma anhängen, habs nur derzeit irgendwie kaputtgewurschtelt.muss das erstma entwirren :/

    Zitat von eis_os

    Was mir an den Python Dumps aufgefallen ist, es scheint das die Dicts die Daten anders sortieren als mein C Parser.

    jo liegt aber an python. richtet sich vmtl danach wie die hash tabelle intern gespeichert ist

    Da grade die Hex-IDs erwähnt wurden, das ist auch noch ne Untersuchung wert: Müssen die programmweit eindeutig sein? oder (hoffentlich) nur innerhalb des Bundle? Da in den Assetverweise immer extra angezeigt wird wenn es sich um externe Verweise handelt, hoff ich mal auf letzteres.

    • Zitieren
  • eis_os
    Profi
    Beiträge
    1.025
    Filebase Einträge
    2
    • 3. Mai 2013 um 17:49
    • #80

    Ein Problem liegt in den Flags, wir wissen nicht was man als Flags wirklich nutzen muss, CO bestimmt auch nicht und die Unity Entwickler werden es uns bestimmt nicht sagen.

    Wer weiß, vielleicht möchte ja CO noch die Daten ändern oder eine neue Version herausbringen.
    Außerdem kann man mit den Programm eigentlich alle Unity 3.x Spiele modifizieren wenn man es nicht zu sehr auf CIM eicht. Unity kennt aber noch ne Menge andere Daten.
    Ich hab schon Code der die AssetInfo Zeugs in invalides JSON, weil HEX Werte genutzt werden schreibt. Flags als Integer ist doof!

    Die Referenzen in meinen Unity Free Projekt sind immer eindeutig (sind aber keine IDs), wenn man neue Objekte erstellen möchte sollte man wohl neue Hex ID Werte nutzen.

    Auf meiner ToDo Liste ist erst mal den Code aufräumen, einen Parser zu bauen der halbwegs eine Art JSON versteht und der die Strukturen lesen kann.
    Außerdem möchte ich die Asset Daten auch splitten können, bin der Meinung das ein Bundle intern eine Art Abwandlung einer Asset Datei ist und man den Code mit nutzen kann.

    Ich bin daran interessiert einen Roundtrip zu schaffen, d.h. ein extrahiertes Bundle sollte Binär identisch werden wenn man es wieder packt.

    Ja, für die Texturen wollte ich eigentlich einen Konverter bauen, da aber das wieder mehr Strukturen als mir gerade lieb sind bedeutet hab ich erst mal aufgeben, den Code debuggt und eine funktionierende exe Datei hochgeladen.
    Ich wundere mich sowieso das NetBeans mit den ganzen Makro kram überhaupt noch eine Art Intellisense schafft.
    Ich mag die Unix Philosophie, jedes Programm braucht nur eine Teilmenge zu erstellen.

    -edit-
    Die Schablonen müssen ja nicht geändert werden, sie dienen nur dem BundleCodec ein valides CIM2 Objekt zu kreieren. Trenne reine Daten und Struktur ...

    2 Mal editiert, zuletzt von eis_os (3. Mai 2013 um 17:53)

    • Zitieren

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

Benutzerkonto erstellen Anmelden

Twitch

  1. Datenschutzerklärung
  2. Impressum
Community-Software: WoltLab Suite™