├── .gitignore ├── Images ├── logo.png └── logo.svg ├── README.md └── src ├── Editor └── OpenFile │ └── OFSerializedObjectInspector.js └── Plugins ├── Ionic.Zip.dll ├── JSONObject.dll └── OpenFile ├── OFBundle.js ├── OFBundleManager.js ├── OFDeserializer.js ├── OFHelper.js ├── OFPlanner.js ├── OFPlugin.js ├── OFReader.js ├── OFReflector.js ├── OFSerializedObject.js ├── OFSerializer.js ├── OFWeb.js └── OFWriter.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.swp 3 | Library 4 | Temp 5 | -------------------------------------------------------------------------------- /Images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unity3d-open-tools/openfile/4175f5f489024d7ce6b4e57bb7e5143b78071031/Images/logo.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Notice 2 | This project is unmaintained, but feel free to fork it. 3 | 4 | ![](https://raw.githubusercontent.com/mrzapp/openfile/master/Images/logo.png) 5 | 6 | ### What? 7 | This plugin serializes GameObjects using JSON. It has a range of supported types built in, but more can be added manually. I am developing this in tandem with my Deus Ex-based game project [The Vongott Chronicles](http://jeppezapp.com/games/vongott/) 8 | 9 | ### Why? 10 | It can be used for savegame files, custom level editors, carrying over information between scenes, and it probably has more applications than I can think of. If for any reason you'd want to manage your resources externally, this is your plugin. 11 | 12 | ### Documentation and tutorials 13 | In the [wiki](https://github.com/mrzapp/openfile/wiki) 14 | 15 | ### License 16 | MIT 17 | -------------------------------------------------------------------------------- /src/Editor/OpenFile/OFSerializedObjectInspector.js: -------------------------------------------------------------------------------- 1 | #pragma strict 2 | 3 | @CustomEditor ( OFSerializedObject ) 4 | public class OFSerializedObjectInspector extends Editor { 5 | private var resourceWarning : boolean = false; 6 | 7 | private function SavePrefab ( target : UnityEngine.Object ) { 8 | var selectedGameObject : GameObject; 9 | var selectedPrefabType : PrefabType; 10 | var parentGameObject : GameObject; 11 | var prefabParent : UnityEngine.Object; 12 | 13 | selectedGameObject = Selection.gameObjects[0]; 14 | selectedPrefabType = PrefabUtility.GetPrefabType(selectedGameObject); 15 | parentGameObject = selectedGameObject.transform.root.gameObject; 16 | prefabParent = PrefabUtility.GetPrefabParent(selectedGameObject); 17 | 18 | EditorUtility.SetDirty(target); 19 | 20 | if (selectedPrefabType == PrefabType.PrefabInstance) { 21 | PrefabUtility.ReplacePrefab(parentGameObject, prefabParent, 22 | ReplacePrefabOptions.ConnectToPrefab); 23 | } 24 | } 25 | 26 | override function OnInspectorGUI () { 27 | var obj : OFSerializedObject = target as OFSerializedObject; 28 | var inScene : boolean = obj.gameObject.activeInHierarchy; 29 | 30 | if ( !inScene ) { 31 | GUI.color = new Color ( 1, 1, 1, 0.5 ); 32 | } 33 | 34 | // Instance 35 | EditorGUILayout.LabelField ( "Instance", EditorStyles.boldLabel ); 36 | 37 | EditorGUILayout.BeginHorizontal (); 38 | 39 | EditorGUILayout.TextField ( "ID", obj.id ); 40 | 41 | if ( inScene ) { 42 | GUI.backgroundColor = Color.green; 43 | if ( GUILayout.Button ( "Update", GUILayout.Width ( 60 ) ) ) { 44 | obj.RenewId(); 45 | } 46 | GUI.backgroundColor = Color.white; 47 | } 48 | 49 | EditorGUILayout.EndHorizontal (); 50 | 51 | GUI.color = new Color ( 1, 1, 1, 1 ); 52 | 53 | if ( !inScene ) { 54 | obj.id = ""; 55 | 56 | } else { 57 | GUI.color = new Color ( 1, 1, 1, 0.5 ); 58 | 59 | } 60 | 61 | // Resource 62 | EditorGUILayout.Space (); 63 | EditorGUILayout.LabelField ( "Resource", EditorStyles.boldLabel ); 64 | 65 | EditorGUILayout.BeginHorizontal (); 66 | 67 | EditorGUILayout.TextField ( "Path", obj.prefabPath ); 68 | 69 | if ( !inScene ) { 70 | GUI.backgroundColor = Color.green; 71 | if ( GUILayout.Button ( "Update", GUILayout.Width ( 60 ) ) ) { 72 | var path : String = AssetDatabase.GetAssetPath ( obj.gameObject ); 73 | if ( path.Contains ( "/Resources/" ) ) { 74 | var strings : String [] = path.Split ( [ "/Resources/" ], System.StringSplitOptions.None ); 75 | path = strings [ strings.Length - 1 ]; 76 | path = path.Replace ( ".prefab", "" ); 77 | 78 | obj.prefabPath = path; 79 | 80 | resourceWarning = false; 81 | 82 | } else { 83 | resourceWarning = true; 84 | 85 | } 86 | } 87 | GUI.backgroundColor = Color.white; 88 | } 89 | 90 | EditorGUILayout.EndHorizontal (); 91 | 92 | if ( resourceWarning ) { 93 | obj.prefabPath = ""; 94 | GUI.color = Color.red; 95 | EditorGUILayout.LabelField ( "Object not in /Resources folder!", EditorStyles.boldLabel ); 96 | GUI.color = Color.white; 97 | } 98 | 99 | EditorGUILayout.Space (); 100 | 101 | GUI.color = new Color ( 1, 1, 1, 1 ); 102 | 103 | EditorGUILayout.LabelField ( "Components", EditorStyles.boldLabel ); 104 | var allComponents : Component[] = obj.gameObject.GetComponents.(); 105 | 106 | for ( var i : int = 0; i < allComponents.Length; i++ ) { 107 | if ( !allComponents[i] ) { continue; } 108 | 109 | var name : String = allComponents[i].GetType().ToString(); 110 | name = name.Replace ( "UnityEngine.", "" ); 111 | 112 | if ( allComponents[i].GetType() == OFSerializedObject ) { 113 | continue; 114 | } 115 | 116 | if ( OFSerializer.CanSerialize ( allComponents[i].GetType() ) ) { 117 | var hasField : boolean = obj.HasField ( name ); 118 | 119 | hasField = EditorGUILayout.Toggle ( name, hasField ); 120 | 121 | if ( hasField ) { 122 | obj.SetField ( name, allComponents[i] ); 123 | 124 | } else { 125 | obj.RemoveField ( name ); 126 | 127 | } 128 | 129 | } else { 130 | GUI.color = new Color ( 1, 1, 1, 0.5 ); 131 | EditorGUILayout.LabelField ( name ); 132 | GUI.color = Color.white; 133 | 134 | } 135 | 136 | } 137 | 138 | EditorGUILayout.Space (); 139 | 140 | EditorGUILayout.LabelField ( "File operations", EditorStyles.boldLabel ); 141 | 142 | EditorGUILayout.BeginHorizontal (); 143 | 144 | obj.exportPath = EditorGUILayout.TextField ( obj.exportPath ); 145 | 146 | if ( GUILayout.Button ( "Export" ) ) { 147 | OFWriter.SaveFile ( OFSerializer.Serialize ( obj ), Application.dataPath + "/" + obj.exportPath + "/" + obj.name + ".json" ); 148 | } 149 | 150 | EditorGUILayout.EndHorizontal (); 151 | 152 | if ( GUI.changed ) { 153 | SavePrefab ( target ); 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/Plugins/Ionic.Zip.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unity3d-open-tools/openfile/4175f5f489024d7ce6b4e57bb7e5143b78071031/src/Plugins/Ionic.Zip.dll -------------------------------------------------------------------------------- /src/Plugins/JSONObject.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unity3d-open-tools/openfile/4175f5f489024d7ce6b4e57bb7e5143b78071031/src/Plugins/JSONObject.dll -------------------------------------------------------------------------------- /src/Plugins/OpenFile/OFBundle.js: -------------------------------------------------------------------------------- 1 | #pragma strict 2 | 3 | public class OFBundle { 4 | public class Folder { 5 | public var name : String; 6 | public var path : String; 7 | public var subfolders : Folder [] = new Folder [0]; 8 | public var audioClips : AudioClip [] = new AudioClip [0]; 9 | public var meshes : Mesh [] = new Mesh [0]; 10 | public var textures : Texture2D [] = new Texture2D [0]; 11 | 12 | public function GetFolder ( n : String ) : Folder { 13 | for ( var i : int = 0; i < subfolders.Length; i++ ) { 14 | if ( subfolders[i].name == n ) { 15 | return subfolders[i]; 16 | } 17 | } 18 | 19 | return null; 20 | } 21 | 22 | public function AddMesh ( mesh : Mesh ) { 23 | var tmp : List.< Mesh > = new List.< Mesh > ( meshes ); 24 | 25 | tmp.Add ( mesh ); 26 | 27 | meshes = tmp.ToArray (); 28 | } 29 | 30 | public function AddTexture ( texture : Texture2D ) { 31 | var tmp : List.< Texture2D > = new List.< Texture2D > ( textures ); 32 | 33 | tmp.Add ( texture ); 34 | 35 | textures = tmp.ToArray (); 36 | } 37 | 38 | public function AddAudio ( audio : AudioClip ) { 39 | var tmp : List.< AudioClip > = new List.< AudioClip > ( audioClips ); 40 | 41 | tmp.Add ( audio ); 42 | 43 | audioClips = tmp.ToArray (); 44 | } 45 | } 46 | 47 | public var name : String; 48 | public var root : Folder; 49 | 50 | public function GetParent ( child : Folder ) : Folder { 51 | return GetFolder ( child.path.Replace ( "/" + child.name, "" ) ); 52 | } 53 | 54 | public function GetFolder ( path : String ) : Folder { 55 | var strings : String[] = path.Split ( "/"[0] ); 56 | var currentFolder : Folder = root; 57 | 58 | for ( var dirName : String in strings ) { 59 | var nextFolder : Folder = currentFolder.GetFolder ( dirName ); 60 | 61 | if ( nextFolder ) { 62 | currentFolder = nextFolder; 63 | } 64 | } 65 | 66 | return currentFolder; 67 | } 68 | 69 | public function GetFolders ( path : String ) : Folder [] { 70 | var folder : Folder = GetFolder ( path ); 71 | 72 | if ( folder ) { 73 | return folder.subfolders; 74 | 75 | } else { 76 | return null; 77 | 78 | } 79 | } 80 | 81 | public function GetObject ( path : String, type : System.Type ) : Object { 82 | if ( type == typeof ( Texture2D ) ) { 83 | return GetTexture ( path ); 84 | 85 | } else if ( type == typeof ( AudioClip ) ) { 86 | return GetAudioClip ( path ); 87 | 88 | } else if ( type == typeof ( Mesh ) ) { 89 | return GetMesh ( path ); 90 | 91 | } else { 92 | return null; 93 | 94 | } 95 | } 96 | 97 | public function GetObjects ( path : String, type : System.Type ) : Object [] { 98 | if ( type == typeof ( Texture2D ) ) { 99 | return GetTextures ( path ); 100 | 101 | } else if ( type == typeof ( AudioClip ) ) { 102 | return GetAudioClips ( path ); 103 | 104 | } else if ( type == typeof ( Mesh ) ) { 105 | return GetMeshes ( path ); 106 | 107 | } else { 108 | return null; 109 | 110 | } 111 | } 112 | 113 | public function GetMeshes ( path : String ) : Mesh [] { 114 | var folder : Folder = GetFolder ( path ); 115 | 116 | if ( folder ) { 117 | return folder.meshes; 118 | 119 | } else { 120 | return null; 121 | 122 | } 123 | } 124 | 125 | public function GetMesh ( path : String ) : Mesh { 126 | var folder : Folder = GetFolder ( path ); 127 | var meshName : String = OFBundleManager.GetName ( path ); 128 | 129 | if ( folder ) { 130 | for ( var i : int = 0; i < folder.meshes.Length; i++ ) { 131 | if ( folder.meshes[i].name == meshName ) { 132 | return folder.meshes[i]; 133 | } 134 | } 135 | 136 | return null; 137 | 138 | } else { 139 | return null; 140 | 141 | } 142 | } 143 | 144 | public function GetTextures ( path : String ) : Texture2D [] { 145 | var folder : Folder = GetFolder ( path ); 146 | 147 | if ( folder ) { 148 | return folder.textures; 149 | 150 | } else { 151 | return null; 152 | 153 | } 154 | } 155 | 156 | public function GetTexture ( path : String ) : Texture2D { 157 | var folder : Folder = GetFolder ( path ); 158 | var texName : String = OFBundleManager.GetName ( path ); 159 | 160 | if ( folder ) { 161 | for ( var i : int = 0; i < folder.textures.Length; i++ ) { 162 | if ( folder.textures[i].name == texName ) { 163 | return folder.textures[i]; 164 | } 165 | } 166 | 167 | return null; 168 | 169 | } else { 170 | return null; 171 | 172 | } 173 | } 174 | 175 | public function GetAudioClips ( path : String ) : AudioClip [] { 176 | var folder : Folder = GetFolder ( path ); 177 | 178 | if ( folder ) { 179 | return folder.audioClips; 180 | 181 | } else { 182 | return null; 183 | 184 | } 185 | } 186 | public function GetAudioClip ( path : String ) : AudioClip { 187 | var folder : Folder = GetFolder ( path ); 188 | var audioName : String = OFBundleManager.GetName ( path ); 189 | 190 | if ( folder ) { 191 | for ( var i : int = 0; i < folder.audioClips.Length; i++ ) { 192 | if ( folder.audioClips[i].name == audioName ) { 193 | return folder.audioClips[i]; 194 | } 195 | } 196 | 197 | return null; 198 | 199 | } else { 200 | return null; 201 | 202 | } 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /src/Plugins/OpenFile/OFBundleManager.js: -------------------------------------------------------------------------------- 1 | #pragma strict 2 | 3 | import System.Text; 4 | import System.IO; 5 | import Ionic.Zip; 6 | 7 | public class OFBundleManager extends MonoBehaviour { 8 | public var bundleFolder : String = "Libraries"; 9 | public var bundleExtension : String = "lib"; 10 | public var loadOnAwake : boolean = true; 11 | public var loadedBundles : List.< OFBundle > = new List.< OFBundle > (); 12 | 13 | public static var instance : OFBundleManager; 14 | public static var loading : boolean = false; 15 | 16 | public function Awake () { 17 | if ( instance != this ) { 18 | instance = this; 19 | 20 | if ( loadOnAwake ) { 21 | StartCoroutine ( LoadAllBundles () ); 22 | } 23 | } 24 | } 25 | 26 | public static function GetName ( path : String ) : String { 27 | var strings : String [] = path.Replace ( "\\", "/" ).Split ( "/"[0] ); 28 | 29 | return strings [ strings.length - 1 ]; 30 | } 31 | 32 | private function PopulateFolder ( folder : OFBundle.Folder ) : IEnumerator { 33 | for ( var texPath : String in Directory.GetFiles ( folder.path, "*.png" ) ) { 34 | texPath = texPath.Replace ( "\\", "/" ); 35 | 36 | var www : WWW = new WWW ( "file:///" + texPath ); 37 | yield www; 38 | 39 | var newTex : Texture2D = www.texture; 40 | newTex.name = GetName ( texPath ); 41 | 42 | folder.AddTexture ( newTex ); 43 | } 44 | 45 | for ( var meshPath : String in Directory.GetFiles ( folder.path, "*.obj" ) ) { 46 | meshPath = meshPath.Replace ( "\\", "/" ); 47 | 48 | var newMesh : Mesh = ObjImporter.Importer.ImportFile ( meshPath ); 49 | newMesh.name = GetName ( meshPath ); 50 | 51 | OFHelper.SolveTangents ( newMesh ); 52 | 53 | folder.AddMesh ( newMesh ); 54 | } 55 | 56 | for ( var audioPath : String in Directory.GetFiles ( folder.path, "*.ogg" ) ) { 57 | audioPath = audioPath.Replace ( "\\", "/" ); 58 | 59 | www = new WWW ( "file:///" + audioPath ); 60 | yield www; 61 | 62 | var newAudio : AudioClip = www.audioClip; 63 | newAudio.name = GetName ( audioPath ); 64 | 65 | folder.AddAudio ( newAudio ); 66 | } 67 | 68 | var directories : String [] = Directory.GetDirectories ( folder.path ); 69 | 70 | folder.subfolders = new OFBundle.Folder [ directories.Length ]; 71 | 72 | for ( var i : int = 0; i < directories.Length; i++ ) { 73 | var newFolder : OFBundle.Folder = new OFBundle.Folder (); 74 | newFolder.name = GetName ( directories[i] ); 75 | newFolder.path = folder.path + "/" + newFolder.name; 76 | 77 | PopulateFolder ( newFolder ); 78 | 79 | folder.subfolders[i] = newFolder; 80 | } 81 | } 82 | 83 | public function GetBundle ( name : String ) { 84 | for ( var i : int = 0; i < loadedBundles.Count; i++ ) { 85 | if ( loadedBundles[i].name == name ) { 86 | return loadedBundles[i]; 87 | } 88 | } 89 | 90 | return null; 91 | } 92 | 93 | public function GetBundleStrings () : String [] { 94 | var strings : String[] = new String [ loadedBundles.Count ]; 95 | 96 | for ( var i : int = 0; i < loadedBundles.Count; i++ ) { 97 | strings[i] = loadedBundles[i].name; 98 | } 99 | 100 | return strings; 101 | } 102 | 103 | public function LoadAllBundles () : IEnumerator { 104 | loading = true; 105 | 106 | for ( var dirPath : String in System.IO.Directory.GetDirectories ( Application.dataPath + "/" + bundleFolder ) ) { 107 | yield LoadBundle ( GetName ( dirPath ), false ); 108 | } 109 | 110 | for ( var zipPath : String in System.IO.Directory.GetFiles ( Application.dataPath + "/" + bundleFolder ) ) { 111 | if ( zipPath.Contains ( "." + bundleExtension ) ) { 112 | yield LoadBundle ( GetName ( zipPath ), true ); 113 | } 114 | } 115 | 116 | yield WaitForEndOfFrame (); 117 | 118 | loading = false; 119 | } 120 | 121 | public function LoadBundle ( name : String, compressed : boolean ) : IEnumerator { 122 | var path : String; 123 | 124 | if ( compressed ) { 125 | path = Application.temporaryCachePath + "/OpenFile/Bundles/" + bundleFolder + "/" + name.Split ( "."[0] )[0]; 126 | 127 | var zip : ZipFile = ZipFile.Read ( Application.dataPath + "/" + bundleFolder + "/" + name ); 128 | 129 | name = name.Split ( "."[0] )[0]; 130 | 131 | zip.Dispose (); 132 | 133 | for ( var e : ZipEntry in zip ) { 134 | e.Extract ( path, ExtractExistingFileAction.OverwriteSilently ); 135 | } 136 | 137 | 138 | } else { 139 | path = Application.dataPath + "/" + bundleFolder + "/" + name; 140 | 141 | } 142 | 143 | var newBundle : OFBundle = new OFBundle (); 144 | 145 | newBundle.name = name; 146 | newBundle.root = new OFBundle.Folder (); 147 | newBundle.root.path = path; 148 | 149 | yield PopulateFolder ( newBundle.root ); 150 | 151 | loadedBundles.Add ( newBundle ); 152 | } 153 | 154 | public function UnloadBundle ( name : String ) { 155 | for ( var i : int = loadedBundles.Count - 1; i >= 0; i-- ) { 156 | if ( loadedBundles[i].name == name ) { 157 | loadedBundles.RemoveAt ( i ); 158 | } 159 | } 160 | } 161 | 162 | public function UnloadAll () { 163 | loadedBundles.Clear (); 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/Plugins/OpenFile/OFDeserializer.js: -------------------------------------------------------------------------------- 1 | #pragma strict 2 | 3 | public class OFDeserializer { 4 | public static var planner : OFPlanner; 5 | 6 | private static var plugins : OFPlugin[]; 7 | 8 | public static function GetNumber ( object : JSONObject, fieldName : String ) : float { 9 | if ( object && object.HasField ( fieldName ) ) { 10 | return object.GetField ( fieldName ).n; 11 | 12 | } else { 13 | return 0; 14 | 15 | } 16 | } 17 | 18 | public static function GetString ( object : JSONObject, fieldName : String ) : String { 19 | if ( object && object.HasField ( fieldName ) ) { 20 | return object.GetField ( fieldName ).str; 21 | 22 | } else { 23 | return ""; 24 | 25 | } 26 | } 27 | 28 | public static function GetBool ( object : JSONObject, fieldName : String ) : boolean { 29 | if ( object && object.HasField ( fieldName ) ) { 30 | return object.GetField ( fieldName ).b; 31 | 32 | } else { 33 | return false; 34 | 35 | } 36 | } 37 | 38 | public static function ParseEnum ( e : System.Type, s : String ) : int { 39 | var strings : String[] = System.Enum.GetNames ( e ); 40 | 41 | for ( var i : int = 0; i < strings.Length; i++ ) { 42 | if ( strings[i] == s ) { 43 | return i; 44 | } 45 | } 46 | 47 | return -1; 48 | } 49 | 50 | public static function CheckComponent ( obj : OFSerializedObject, type : System.Type ) : Component { 51 | return CheckComponent ( obj, type, false ); 52 | } 53 | 54 | public static function CheckComponent ( obj : OFSerializedObject, type : System.Type, forceAdd : boolean ) : Component { 55 | var component = obj.gameObject.GetComponent ( type ); 56 | 57 | if ( !component ) { 58 | component = obj.gameObject.AddComponent ( type ); 59 | forceAdd = true; 60 | } 61 | 62 | if ( forceAdd ) { 63 | obj.SetField ( type.ToString().Replace ( "UnityEngine.", "" ), component ); 64 | } 65 | 66 | return component; 67 | } 68 | 69 | public static function CheckComponent ( obj : OFSerializedObject, typeString : String ) : Component { 70 | var component = obj.gameObject.GetComponent ( typeString ); 71 | var forceAdd : boolean = false; 72 | 73 | if ( !component ) { 74 | component = obj.gameObject.AddComponent ( typeString ); 75 | forceAdd = true; 76 | } 77 | 78 | if ( forceAdd ) { 79 | obj.SetField ( typeString.Replace ( "UnityEngine.", "" ), component ); 80 | } 81 | 82 | return component; 83 | } 84 | 85 | public static function DeserializeChildren ( input : JSONObject, parent : Transform ) { 86 | planner = new GameObject ( "OFPlanner" ).AddComponent.< OFPlanner > (); 87 | 88 | for ( var i : int = 0; i < input.list.Count; i++ ) { 89 | var p : JSONObject = input.list[i]; 90 | if ( p.HasField ( "dontInstantiate" ) ) { continue; } 91 | 92 | var k : String = input.keys[i]; 93 | var t : Transform; 94 | var go : GameObject = parent.gameObject.Find ( k ); 95 | 96 | if ( go ) { 97 | t = go.transform; 98 | } 99 | 100 | if ( !t ) { 101 | t = new GameObject ( k ).transform; 102 | t.parent = parent; 103 | t.position = Vector3.zero; 104 | } 105 | 106 | for ( var json : JSONObject in p.list ) { 107 | var so : OFSerializedObject = Deserialize ( json ); 108 | 109 | if ( so ) { 110 | so.transform.parent = t; 111 | planner.AddObject ( so ); 112 | } 113 | } 114 | 115 | } 116 | 117 | planner.ConnectAll (); 118 | } 119 | 120 | // This creates a new GameObject 121 | public static function Deserialize ( input : JSONObject ) : OFSerializedObject { 122 | var so : OFSerializedObject; 123 | 124 | return Deserialize ( input, so ); 125 | } 126 | 127 | // This applies the deserialized values to an existing GameObject 128 | public static function Deserialize ( input : JSONObject, output : OFSerializedObject ) : OFSerializedObject { 129 | if ( !input.HasField ( "name" ) || !input.HasField ( "id" ) ) { return null; } 130 | 131 | if ( !output ) { 132 | if ( input.HasField ( "prefabPath" ) && !String.IsNullOrEmpty ( input.GetField ( "prefabPath" ).str ) ) { 133 | var obj : UnityEngine.Object = Resources.Load ( input.GetField ( "prefabPath" ).str ); 134 | 135 | if ( !obj ) { 136 | Debug.LogError ( "'" + input.GetField ( "prefabPath" ).str + "' doesn't exist!" ); 137 | return null; 138 | } 139 | 140 | var newGO : GameObject = MonoBehaviour.Instantiate ( obj ) as GameObject; 141 | output = newGO.GetComponent.< OFSerializedObject > (); 142 | 143 | } else { 144 | output = new GameObject ().AddComponent.< OFSerializedObject > (); 145 | 146 | } 147 | } 148 | 149 | if ( !plugins ) { 150 | plugins = OFReflector.GetPlugins (); 151 | } 152 | 153 | if ( !String.IsNullOrEmpty ( input.GetField ( "name" ).str ) ) { 154 | output.gameObject.name = input.GetField ( "name" ).str; 155 | } 156 | 157 | if ( String.IsNullOrEmpty ( output.id ) ) { 158 | output.id = input.GetField ( "id" ).str; 159 | } 160 | 161 | var assetLinks : JSONObject = input.GetField ( "assetLinks" ); 162 | 163 | if ( assetLinks != null ) { 164 | for ( var i : int = 0; i < assetLinks.list.Count; i++ ) { 165 | var asFile : boolean = false; 166 | var path : String; 167 | var type : OFAssetLink.Type; 168 | 169 | if ( assetLinks.list[i].HasField ( "filePath" ) ) { 170 | path = assetLinks[i].GetField ( "filePath" ).str; 171 | type = OFAssetLink.Type.File; 172 | 173 | } else if ( assetLinks.list[i].HasField ( "resourcePath" ) ) { 174 | path = assetLinks[i].GetField ( "resourcePath" ).str; 175 | type = OFAssetLink.Type.Resource; 176 | 177 | } else if ( assetLinks.list[i].HasField ( "bundlePath" ) ) { 178 | path = assetLinks[i].GetField ( "bundlePath" ).str; 179 | type = OFAssetLink.Type.Bundle; 180 | 181 | } 182 | 183 | output.SetAssetLink ( assetLinks[i].GetField ( "name" ).str, path, type ); 184 | } 185 | } 186 | 187 | var components : JSONObject = input.GetField ( "components" ); 188 | 189 | for ( i = 0; i < components.list.Count; i++ ) { 190 | var c : Component; 191 | var typeString : String = components.list[i].GetField ( "_TYPE_" ).str; 192 | 193 | // Unity classes 194 | switch ( typeString ) { 195 | case "Light": 196 | Deserialize ( components.list[i], CheckComponent ( output, typeof ( Light ) ) as Light ); 197 | break; 198 | 199 | case "Transform": 200 | Deserialize ( components.list[i], CheckComponent ( output, typeof ( Transform ), true ) as Transform ); 201 | break; 202 | 203 | case "AudioSource": 204 | Deserialize ( components.list[i], CheckComponent ( output, typeof ( AudioSource ) ) as AudioSource ); 205 | break; 206 | 207 | case "MeshFilter": 208 | Deserialize ( components.list[i], CheckComponent ( output, typeof ( MeshFilter ) ) as MeshFilter ); 209 | break; 210 | 211 | case "MeshRenderer": 212 | Deserialize ( components.list[i], CheckComponent ( output, typeof ( MeshRenderer ) ) as MeshRenderer ); 213 | break; 214 | 215 | case "SphereCollider": 216 | Deserialize ( components.list[i], CheckComponent ( output, typeof ( SphereCollider ) ) as SphereCollider ); 217 | break; 218 | 219 | case "BoxCollider": 220 | Deserialize ( components.list[i], CheckComponent ( output, typeof ( BoxCollider ) ) as BoxCollider ); 221 | break; 222 | } 223 | 224 | // Plugins 225 | for ( var p : int = 0; p < plugins.Length; p++ ) { 226 | if ( !String.IsNullOrEmpty ( typeString ) && plugins[p].CheckType ( typeString ) ) { 227 | plugins[p].Deserialize ( components.list[i], CheckComponent ( output, typeString ) ); 228 | } 229 | } 230 | 231 | } 232 | 233 | return output; 234 | } 235 | 236 | 237 | ////////////////// 238 | // Unity classes 239 | ////////////////// 240 | // Light 241 | public static function Deserialize ( input : JSONObject, light : Light ) { 242 | light.type = ParseEnum ( typeof ( LightType ), input.GetField ( "type" ).str ); 243 | light.range = input.GetField ( "range" ).n; 244 | light.color = DeserializeColor ( input.GetField ( "color" ) ); 245 | light.intensity = input.GetField ( "intensity" ).n; 246 | light.shadows = ParseEnum ( typeof ( LightShadows ), input.GetField ( "shadows" ).str ); 247 | } 248 | 249 | // SphereCollider 250 | public static function Deserialize ( input : JSONObject, sphereCollider : SphereCollider ) { 251 | sphereCollider.center = DeserializeVector3 ( input.GetField ( "center" ) ); 252 | sphereCollider.radius = input.GetField ( "radius" ).n; 253 | } 254 | 255 | // BoxCollider 256 | public static function Deserialize ( input : JSONObject, boxCollider : BoxCollider ) { 257 | boxCollider.center = DeserializeVector3 ( input.GetField ( "center" ) ); 258 | boxCollider.size = DeserializeVector3 ( input.GetField ( "size" ) ); 259 | } 260 | 261 | // Transform 262 | public static function Deserialize ( input : JSONObject, transform : Transform ) { 263 | transform.eulerAngles = DeserializeVector3 ( input.GetField ( "eulerAngles" ) ); 264 | transform.position = DeserializeVector3 ( input.GetField ( "position" ) ); 265 | transform.localScale = DeserializeVector3 ( input.GetField ( "localScale" ) ); 266 | } 267 | 268 | // MeshFilter 269 | public static function Deserialize ( input : JSONObject, meshFilter : MeshFilter ) { 270 | var assetLink : OFAssetLink = meshFilter.GetComponent.< OFSerializedObject >().GetAssetLink( "mesh" ); 271 | 272 | if ( assetLink != null ) { 273 | meshFilter.mesh = assetLink.GetMesh (); 274 | } 275 | } 276 | 277 | // MeshRenderer 278 | public static function Deserialize ( input : JSONObject, meshRenderer : MeshRenderer ) { 279 | var materials : List.< JSONObject > = input.GetField ( "materials" ).list; 280 | 281 | for ( var i : int = 0; i < materials.Count; i++ ) { 282 | var assetLinks : OFAssetLink[] = meshRenderer.GetComponent.< OFSerializedObject >().assetLinks; 283 | 284 | var shader : Shader = Shader.Find ( materials[i].GetField ( "shader" ).str ); 285 | meshRenderer.materials[i] = new Material ( shader ); 286 | meshRenderer.materials[i].shader = shader; 287 | meshRenderer.materials[i].name = materials[i].GetField ( "name" ).str; 288 | 289 | for ( var a : int = 0; a < assetLinks.Length; a++ ) { 290 | if ( assetLinks[a] && assetLinks[a].name.Contains ( "materials_" + i ) ) { 291 | var fieldName : String = assetLinks[a].name.Replace ( "materials_" + i, "" ); 292 | meshRenderer.materials[i].SetTexture ( fieldName, assetLinks[a].GetTexture () ); 293 | } 294 | } 295 | } 296 | } 297 | 298 | // AudioSource 299 | public static function Deserialize ( input : JSONObject, audio : AudioSource ) { 300 | var assetLink : OFAssetLink = audio.GetComponent.< OFSerializedObject >().GetAssetLink( "clip" ); 301 | 302 | if ( assetLink != null ) { 303 | audio.clip = assetLink.GetAudioClip (); 304 | } 305 | 306 | audio.dopplerLevel = input.GetField ( "dopplerLevel" ).n; 307 | audio.ignoreListenerPause = input.GetField ( "ignoreListenerPause" ).b; 308 | audio.ignoreListenerVolume = input.GetField ( "ignoreListenerVolume" ).b; 309 | audio.loop = input.GetField ( "loop" ).b; 310 | audio.maxDistance = input.GetField ( "maxDistance" ).n; 311 | audio.minDistance = input.GetField ( "minDistance" ).n; 312 | audio.panLevel = input.GetField ( "panLevel" ).n; 313 | audio.pitch = input.GetField ( "pitch" ).n; 314 | audio.playOnAwake = input.GetField ( "playOnAwake" ).b; 315 | audio.priority = input.GetField ( "priority" ).n; 316 | audio.rolloffMode = Mathf.RoundToInt ( input.GetField ( "rolloffMode" ).n ); 317 | audio.spread = input.GetField ( "spread" ).n; 318 | audio.volume = input.GetField ( "volume" ).n; 319 | 320 | if ( audio.playOnAwake ) { 321 | audio.Play (); 322 | } 323 | } 324 | 325 | 326 | ///////////////// 327 | // Structs 328 | ///////////////// 329 | // Color 330 | public static function DeserializeColor ( input : JSONObject ) : Color { 331 | var output : Color = new Color (); 332 | 333 | output.r = input.GetField ( "r" ).n; 334 | output.g = input.GetField ( "g" ).n; 335 | output.b = input.GetField ( "b" ).n; 336 | output.a = input.GetField ( "a" ).n; 337 | 338 | return output; 339 | } 340 | 341 | // Vector3 342 | public static function DeserializeVector3 ( input : JSONObject ) : Vector3 { 343 | var output : Vector3 = new Vector3(); 344 | 345 | output.x = input.GetField ( "x" ).n; 346 | output.y = input.GetField ( "y" ).n; 347 | output.z = input.GetField ( "z" ).n; 348 | 349 | return output; 350 | } 351 | 352 | // Vector2 353 | public static function DeserializeVector2 ( input : JSONObject ) : Vector2 { 354 | var output : Vector2 = new Vector2(); 355 | 356 | output.x = input.GetField ( "x" ).n; 357 | output.y = input.GetField ( "y" ).n; 358 | 359 | return output; 360 | } 361 | } 362 | -------------------------------------------------------------------------------- /src/Plugins/OpenFile/OFHelper.js: -------------------------------------------------------------------------------- 1 | #pragma strict 2 | 3 | public class OFHelper { 4 | public static function SolveTangents ( theMesh : Mesh ) { 5 | var vertexCount : int = theMesh.vertexCount; 6 | var vertices : Vector3 [] = theMesh.vertices; 7 | var normals : Vector3 [] = theMesh.normals; 8 | var texcoords : Vector2 [] = theMesh.uv; 9 | var triangles : int [] = theMesh.triangles; 10 | var triangleCount : int = triangles.Length / 3; 11 | var tangents : Vector4 [] = new Vector4[vertexCount]; 12 | var tan1 : Vector3 [] = new Vector3[vertexCount]; 13 | var tan2 : Vector3 [] = new Vector3[vertexCount]; 14 | var tri : int = 0; 15 | 16 | for ( var i : int = 0; i < triangleCount; i++ ) { 17 | var i1 : int = triangles[tri]; 18 | var i2 : int = triangles[tri + 1]; 19 | var i3 : int = triangles[tri + 2]; 20 | 21 | var v1 : Vector3 = vertices[i1]; 22 | var v2 : Vector3 = vertices[i2]; 23 | var v3 : Vector3 = vertices[i3]; 24 | 25 | var w1 : Vector2 = texcoords[i1]; 26 | var w2 : Vector2 = texcoords[i2]; 27 | var w3 : Vector2 = texcoords[i3]; 28 | 29 | var x1 : float = v2.x - v1.x; 30 | var x2 : float = v3.x - v1.x; 31 | var y1 : float = v2.y - v1.y; 32 | var y2 : float = v3.y - v1.y; 33 | var z1 : float = v2.z - v1.z; 34 | var z2 : float = v3.z - v1.z; 35 | 36 | var s1 : float = w2.x - w1.x; 37 | var s2 : float = w3.x - w1.x; 38 | var t1 : float = w2.y - w1.y; 39 | var t2 : float = w3.y - w1.y; 40 | 41 | var r : float = 1.0f / (s1 * t2 - s2 * t1); 42 | var sdir : Vector3 = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); 43 | var tdir : Vector3 = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); 44 | 45 | tan1[i1] += sdir; 46 | tan1[i2] += sdir; 47 | tan1[i3] += sdir; 48 | 49 | tan2[i1] += tdir; 50 | tan2[i2] += tdir; 51 | tan2[i3] += tdir; 52 | 53 | tri += 3; 54 | } 55 | 56 | for ( i = 0; i < (vertexCount); i++ ) { 57 | var n : Vector3 = normals[i]; 58 | var t : Vector3 = tan1[i]; 59 | 60 | // Gram-Schmidt orthogonalize 61 | Vector3.OrthoNormalize ( n, t ); 62 | 63 | tangents[i].x = t.x; 64 | tangents[i].y = t.y; 65 | tangents[i].z = t.z; 66 | 67 | // Calculate handedness 68 | tangents[i].w = (Vector3.Dot(Vector3.Cross(n, t), tan2[i]) < 0.0) ? -1.0f : 1.0f; 69 | } 70 | 71 | theMesh.tangents = tangents; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Plugins/OpenFile/OFPlanner.js: -------------------------------------------------------------------------------- 1 | #pragma strict 2 | 3 | public class OFPlanner extends MonoBehaviour { 4 | public class Connection { 5 | public var callback : Action.< OFSerializedObject >; 6 | public var callbackWithIndex : Action.< OFSerializedObject, int >; 7 | public var callbackWithIndices : Action.< OFSerializedObject, int[] >; 8 | public var id : String; 9 | public var index : int = -1; 10 | public var indices : int []; 11 | 12 | function Connection ( callback : Action.< OFSerializedObject >, id : String ) { 13 | this.callback = callback; 14 | this.id = id; 15 | } 16 | 17 | function Connection ( callback : Action.< OFSerializedObject, int >, id : String, index : int ) { 18 | this.callbackWithIndex = callback; 19 | this.id = id; 20 | this.index = index; 21 | } 22 | 23 | function Connection ( callback : Action.< OFSerializedObject, int [] >, id : String, indices : int [] ) { 24 | this.callbackWithIndices = callback; 25 | this.id = id; 26 | this.indices = indices; 27 | } 28 | } 29 | 30 | private var allConnections : List.< Connection > = new List.< Connection > (); 31 | private var spawnedObjects : List.< OFSerializedObject > = new List.< OFSerializedObject > (); 32 | 33 | public function AddObject ( so : OFSerializedObject ) { 34 | spawnedObjects.Add ( so ); 35 | } 36 | 37 | public function DeferConnection ( callback : Action.< OFSerializedObject >, id : String ) { 38 | allConnections.Add ( new Connection ( callback, id ) ); 39 | } 40 | 41 | public function DeferConnection ( callback : Action.< OFSerializedObject, int >, id : String, index : int ) { 42 | allConnections.Add ( new Connection ( callback, id, index ) ); 43 | } 44 | 45 | public function DeferConnection ( callback : Action.< OFSerializedObject, int [] >, id : String, indices : int [] ) { 46 | allConnections.Add ( new Connection ( callback, id, indices ) ); 47 | } 48 | 49 | public function FindObject ( id : String ) : OFSerializedObject { 50 | for ( var so : OFSerializedObject in spawnedObjects ) { 51 | if ( so.id == id ) { 52 | return so; 53 | } 54 | } 55 | 56 | return null; 57 | } 58 | 59 | private function MakeConnections () : IEnumerator { 60 | yield WaitForEndOfFrame (); 61 | 62 | for ( var c : Connection in allConnections ) { 63 | var so : OFSerializedObject = FindObject ( c.id ); 64 | 65 | if ( so ) { 66 | if ( c.callbackWithIndex ) { 67 | c.callbackWithIndex ( so, c.index ); 68 | 69 | } else if ( c.callbackWithIndices ) { 70 | c.callbackWithIndices ( so, c.indices ); 71 | 72 | } else { 73 | c.callback ( so ); 74 | 75 | } 76 | } 77 | } 78 | 79 | yield WaitForEndOfFrame (); 80 | 81 | Destroy ( gameObject ); 82 | } 83 | 84 | public function ConnectAll () { 85 | StartCoroutine ( MakeConnections () ); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Plugins/OpenFile/OFPlugin.js: -------------------------------------------------------------------------------- 1 | #pragma strict 2 | 3 | public class OFPlugin { 4 | public function get types () : System.Type [] { return new System.Type[0]; } 5 | 6 | public function Serialize ( input : Component ) : JSONObject {} 7 | public function Deserialize ( input : JSONObject, output : Component ) {} 8 | 9 | public function CheckType ( type : System.Type ) : boolean { 10 | for ( var i : int = 0; i < types.Length; i++ ) { 11 | if ( type == types[i] ) { 12 | return true; 13 | } 14 | } 15 | 16 | return false; 17 | } 18 | 19 | public function CheckType ( typeString : String ) : boolean { 20 | for ( var i : int = 0; i < types.Length; i++ ) { 21 | if ( typeString == types[i].ToString () ) { 22 | return true; 23 | } 24 | } 25 | 26 | return false; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Plugins/OpenFile/OFReader.js: -------------------------------------------------------------------------------- 1 | #pragma strict 2 | 3 | import System.IO; 4 | 5 | public class OFReader { 6 | public static function LoadFile ( path : String ) : JSONObject { 7 | path = path.Replace ( "\\", "/" ).Replace ( Application.dataPath, "" ); 8 | 9 | #if UNITY_WEBPLAYER && !UNITY_EDITOR 10 | return OFWeb.Get ( path ); 11 | #else 12 | if ( !File.Exists ( Application.dataPath + path ) ) { 13 | Debug.LogError ( "OFReader | No such file '" + Application.dataPath + path + "'" ); 14 | return null; 15 | } 16 | 17 | var sr : StreamReader = new File.OpenText ( Application.dataPath + path ); 18 | var input : String = ""; 19 | var line : String = ""; 20 | 21 | line = sr.ReadLine(); 22 | 23 | while ( line != null ) { 24 | input += line; 25 | line = sr.ReadLine(); 26 | } 27 | 28 | sr.Close(); 29 | 30 | return new JSONObject ( input, -2, false, false ); 31 | #endif 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Plugins/OpenFile/OFReflector.js: -------------------------------------------------------------------------------- 1 | #pragma strict 2 | 3 | import System; 4 | 5 | public class OFReflector { 6 | private static var plugins : OFPlugin []; 7 | 8 | public static function GetPlugin ( type : System.Type ) : OFPlugin { 9 | if ( !plugins ) { 10 | plugins = GetPlugins (); 11 | } 12 | 13 | for ( var i : int = 0; i < plugins.Length; i++ ) { 14 | if ( plugins[i].CheckType ( type ) ) { 15 | return plugins[i]; 16 | } 17 | } 18 | 19 | return null; 20 | } 21 | 22 | public static function GetPlugins () : OFPlugin [] { 23 | if ( !plugins ) { 24 | var types : List.< OFPlugin > = new List.< OFPlugin > (); 25 | 26 | for ( var assembly : System.Reflection.Assembly in AppDomain.CurrentDomain.GetAssemblies () ) { 27 | if ( assembly.FullName.StartsWith ( "Mono.Cecil" ) ) { 28 | continue; 29 | 30 | } else if ( assembly.FullName.StartsWith ( "UnityScript" ) ) { 31 | continue; 32 | 33 | } else if ( assembly.FullName.StartsWith ( "Boo.Lan" ) ) { 34 | continue; 35 | 36 | } else if ( assembly.FullName.StartsWith ( "System" ) ) { 37 | continue; 38 | 39 | } else if ( assembly.FullName.StartsWith ( "I18N" ) ) { 40 | continue; 41 | 42 | } else if ( assembly.FullName.StartsWith ( "UnityEngine" ) ) { 43 | continue; 44 | 45 | } else if ( assembly.FullName.StartsWith ( "UnityEditor" ) ) { 46 | continue; 47 | 48 | } else if ( assembly.FullName.StartsWith ( "mscorlib" ) ) { 49 | continue; 50 | 51 | } 52 | 53 | for ( var type : System.Type in assembly.GetTypes () ) { 54 | if ( !type.IsClass ) { 55 | continue; 56 | 57 | } else if ( type.IsAbstract ) { 58 | continue; 59 | 60 | } else if ( !type.IsSubclassOf ( typeof ( OFPlugin ) ) ) { 61 | continue; 62 | 63 | } 64 | 65 | types.Add ( System.Activator.CreateInstance ( type ) as OFPlugin ); 66 | } 67 | } 68 | 69 | plugins = types.ToArray (); 70 | } 71 | 72 | return plugins; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Plugins/OpenFile/OFSerializedObject.js: -------------------------------------------------------------------------------- 1 | #pragma strict 2 | 3 | public class OFAssetLink { 4 | public enum Type { 5 | Bundle, 6 | File, 7 | Resource, 8 | } 9 | 10 | public var type : Type = Type.Resource; 11 | public var name : String; 12 | public var resourcePath : String; 13 | public var filePath : String; 14 | public var bundlePath : String; 15 | 16 | private var texture : Texture2D; 17 | private var audioClip : AudioClip; 18 | private var mesh : Mesh; 19 | private var material : Material; 20 | private var shader : Shader; 21 | 22 | public function Reset () { 23 | texture = null; 24 | audioClip = null; 25 | resourcePath = ""; 26 | filePath = ""; 27 | bundlePath = ""; 28 | } 29 | 30 | public function GetLinkType () : Type { 31 | if ( !String.IsNullOrEmpty ( filePath ) ) { 32 | type = Type.File; 33 | 34 | } else if ( !String.IsNullOrEmpty ( resourcePath ) ) { 35 | type = Type.Resource; 36 | 37 | } else if ( !String.IsNullOrEmpty ( bundlePath ) ) { 38 | type = Type.Bundle; 39 | 40 | } else { 41 | type = -1; 42 | 43 | } 44 | 45 | return type; 46 | } 47 | 48 | public function GetMesh () : Mesh { 49 | if ( mesh == null && !String.IsNullOrEmpty ( bundlePath ) ) { 50 | var strings : String [] = bundlePath.Split ( ">"[0] ); 51 | var bundle : OFBundle = OFBundleManager.instance.GetBundle ( strings [0] ); 52 | 53 | if ( bundle ) { 54 | mesh = bundle.GetMesh ( strings[1] ); 55 | } 56 | } 57 | 58 | return mesh; 59 | } 60 | 61 | public function GetMesh ( callback : System.Action.< Mesh > ) : IEnumerator { 62 | if ( mesh == null && !String.IsNullOrEmpty ( filePath ) ) { 63 | mesh = ObjImporter.Importer.ImportFile ( filePath ); 64 | 65 | callback ( mesh ); 66 | 67 | } else { 68 | callback ( mesh ); 69 | 70 | } 71 | } 72 | 73 | public function GetAudioClip () : AudioClip { 74 | if ( audioClip == null && !String.IsNullOrEmpty ( resourcePath ) ) { 75 | audioClip = Resources.Load ( resourcePath ) as AudioClip; 76 | 77 | } else if ( audioClip == null && !String.IsNullOrEmpty ( bundlePath ) ) { 78 | var strings : String [] = bundlePath.Split ( ">"[0] ); 79 | var bundle : OFBundle = OFBundleManager.instance.GetBundle ( strings [0] ); 80 | 81 | if ( bundle ) { 82 | audioClip = bundle.GetAudioClip ( strings[1] ); 83 | } 84 | } 85 | 86 | return audioClip; 87 | } 88 | 89 | public function GetAudioClip ( callback : System.Action.< AudioClip > ) : IEnumerator { 90 | if ( audioClip == null && !String.IsNullOrEmpty ( filePath ) ) { 91 | var www : WWW = new WWW ( filePath ); 92 | 93 | yield www; 94 | 95 | audioClip = www.audioClip; 96 | 97 | callback ( audioClip ); 98 | 99 | } else { 100 | callback ( audioClip ); 101 | 102 | } 103 | } 104 | 105 | public function GetTexture () : Texture2D { 106 | if ( texture == null && !String.IsNullOrEmpty ( resourcePath ) ) { 107 | texture = Resources.Load ( resourcePath ) as Texture2D; 108 | 109 | } else if ( texture == null && !String.IsNullOrEmpty ( bundlePath ) ) { 110 | var strings : String [] = bundlePath.Split ( ">"[0] ); 111 | var bundle : OFBundle = OFBundleManager.instance.GetBundle ( strings [0] ); 112 | 113 | if ( bundle ) { 114 | texture = bundle.GetTexture ( strings[1] ); 115 | } 116 | } 117 | 118 | return texture; 119 | } 120 | 121 | public function GetTexture ( callback : System.Action.< Texture2D > ) : IEnumerator { 122 | if ( texture == null && !String.IsNullOrEmpty ( filePath ) ) { 123 | var www : WWW = new WWW ( filePath ); 124 | 125 | yield www; 126 | 127 | texture = www.texture; 128 | 129 | callback ( texture ); 130 | 131 | } else { 132 | callback ( texture ); 133 | 134 | } 135 | } 136 | } 137 | 138 | public class OFField { 139 | public var typeIndex : int; 140 | public var name : String = ""; 141 | public var component : Component; 142 | 143 | private static var plugins : OFPlugin []; 144 | private static var allTypes : System.Type []; 145 | 146 | public function get type () : System.Type { 147 | return GetTypes () [ typeIndex ]; 148 | } 149 | 150 | public static function GetTypeByIndex ( i : int ) : System.Type { 151 | if ( !plugins ) { 152 | plugins = OFReflector.GetPlugins (); 153 | } 154 | 155 | var types : System.Type [] = GetTypes (); 156 | 157 | if ( i >= 0 && i < types.Length ) { 158 | return types [i]; 159 | 160 | } else { 161 | return null; 162 | } 163 | } 164 | 165 | public static function GetTypeByName ( n : String ) : System.Type { 166 | if ( !plugins ) { 167 | plugins = OFReflector.GetPlugins (); 168 | } 169 | 170 | var types : System.Type [] = GetTypes (); 171 | 172 | for ( var i : int = 0; i < types.Length; i++ ) { 173 | if ( types[i].ToString().Replace ( "UnityEngine.", "" ) == n ) { 174 | return types [i]; 175 | } 176 | } 177 | 178 | return null; 179 | } 180 | 181 | public static function GetTypes () : System.Type [] { 182 | if ( !allTypes ) { 183 | if ( !plugins ) { 184 | plugins = OFReflector.GetPlugins (); 185 | } 186 | 187 | var types : List.< System.Type > = new List.< System.Type > (); 188 | 189 | types.Add ( typeof ( AudioSource ) ); 190 | types.Add ( typeof ( Light ) ); 191 | types.Add ( typeof ( MeshFilter ) ); 192 | types.Add ( typeof ( MeshRenderer ) ); 193 | types.Add ( typeof ( SphereCollider ) ); 194 | types.Add ( typeof ( BoxCollider ) ); 195 | types.Add ( typeof ( Transform ) ); 196 | 197 | for ( var i : int = 0; i < plugins.Length; i++ ) { 198 | for ( var t : int = 0; t < plugins[i].types.Length; t++ ) { 199 | types.Add ( plugins[i].types[t] ); 200 | } 201 | } 202 | 203 | allTypes = types.ToArray (); 204 | } 205 | 206 | return allTypes; 207 | } 208 | 209 | public static function GetTypeStrings () : String [] { 210 | var strings : List.< String > = new List.< String > (); 211 | var types : System.Type [] = GetTypes (); 212 | 213 | for ( var i : int = 0; i < types.Length; i++ ) { 214 | strings.Add ( types[i].ToString ().Replace ( "UnityEngine.", "" ) ); 215 | } 216 | 217 | return strings.ToArray (); 218 | } 219 | 220 | public static function GetComponentType ( value : Component ) : int { 221 | if ( !plugins ) { 222 | plugins = OFReflector.GetPlugins (); 223 | } 224 | 225 | var types : System.Type [] = GetTypes (); 226 | 227 | for ( var i : int = 0; i < types.Length; i++ ) { 228 | if ( types[i] == value.GetType() ) { 229 | return i; 230 | } 231 | } 232 | 233 | return -1; 234 | } 235 | 236 | public function Set ( value : Component ) { 237 | typeIndex = GetComponentType ( value ); 238 | component = value; 239 | } 240 | } 241 | 242 | public class OFSerializedObject extends MonoBehaviour { 243 | public var fields : OFField [] = new OFField[0]; 244 | public var assetLinks : OFAssetLink [] = new OFAssetLink[0]; 245 | public var id : String = ""; 246 | public var prefabPath : String = ""; 247 | public var exportPath : String = ""; 248 | 249 | public function RenewId () { 250 | id = System.Guid.NewGuid().ToString(); 251 | } 252 | 253 | public function Start () { 254 | if ( String.IsNullOrEmpty ( id ) ) { 255 | RenewId (); 256 | } 257 | } 258 | 259 | public function ClearAssetLinks () { 260 | assetLinks = new OFAssetLink[0]; 261 | } 262 | 263 | public function AddAssetLink ( name : String, path : String, type : OFAssetLink.Type ) { 264 | var tmp : List.< OFAssetLink > = new List.< OFAssetLink > ( assetLinks ); 265 | 266 | var link : OFAssetLink = new OFAssetLink (); 267 | 268 | link.name = name; 269 | 270 | switch ( type ) { 271 | case OFAssetLink.Type.File: 272 | link.filePath = path; 273 | break; 274 | 275 | case OFAssetLink.Type.Resource: 276 | link.resourcePath = path; 277 | break; 278 | 279 | case OFAssetLink.Type.Bundle: 280 | link.bundlePath = path; 281 | break; 282 | } 283 | 284 | tmp.Add ( link ); 285 | 286 | assetLinks = tmp.ToArray (); 287 | } 288 | 289 | public function GetAssetLink ( name : String ) : OFAssetLink { 290 | for ( var i : int = 0; i < assetLinks.Length; i++ ) { 291 | if ( assetLinks[i].name == name ) { 292 | return assetLinks[i]; 293 | } 294 | } 295 | 296 | return null; 297 | } 298 | 299 | public function RemoveAssetLink ( name : String ) { 300 | var tmp : List.< OFAssetLink > = new List.< OFAssetLink > ( assetLinks ); 301 | 302 | for ( var i : int = tmp.Count - 1; i >= 0; i-- ) { 303 | if ( tmp[i].name == name ) { 304 | tmp.RemoveAt ( i ); 305 | } 306 | } 307 | 308 | assetLinks = tmp.ToArray (); 309 | } 310 | 311 | public function SetAssetLink ( name : String, path : String, type : OFAssetLink.Type ) { 312 | for ( var i : int = 0; i < assetLinks.Length; i++ ) { 313 | if ( assetLinks[i].name == name ) { 314 | assetLinks[i].Reset (); 315 | 316 | switch ( type ) { 317 | case OFAssetLink.Type.File: 318 | assetLinks[i].filePath = path; 319 | break; 320 | 321 | case OFAssetLink.Type.Bundle: 322 | assetLinks[i].bundlePath = path; 323 | break; 324 | 325 | case OFAssetLink.Type.Resource: 326 | assetLinks[i].resourcePath = path; 327 | break; 328 | } 329 | 330 | return; 331 | } 332 | } 333 | 334 | AddAssetLink ( name, path, type ); 335 | } 336 | 337 | public function SetField ( value : Component ) { 338 | SetField ( value.GetType().ToString(), value ); 339 | } 340 | 341 | public function SetField ( name : String, value : Component ) { 342 | var tmpFields : List.< OFField > = new List.< OFField > ( fields ); 343 | var found : boolean = false; 344 | 345 | for ( var i : int = 0; i < tmpFields.Count; i++ ) { 346 | if ( tmpFields[i].name == name ) { 347 | tmpFields[i].Set ( value ); 348 | found = true; 349 | break; 350 | } 351 | } 352 | 353 | if ( !found ) { 354 | var newField : OFField = new OFField (); 355 | newField.name = name; 356 | newField.Set ( value ); 357 | tmpFields.Add ( newField ); 358 | } 359 | 360 | fields = tmpFields.ToArray (); 361 | } 362 | 363 | public function HasFieldType ( type : System.Type ) : boolean { 364 | for ( var i : int = 0; i < fields.Length; i++ ) { 365 | if ( fields[i].type == type ) { 366 | return true; 367 | } 368 | } 369 | 370 | return false; 371 | } 372 | 373 | public function HasField ( name : String ) : boolean { 374 | for ( var i : int = 0; i < fields.Length; i++ ) { 375 | if ( fields[i].name == name ) { 376 | return true; 377 | } 378 | } 379 | 380 | return false; 381 | } 382 | 383 | public function RemoveField ( name : String ) { 384 | var tmpFields : List.< OFField > = new List.< OFField > ( fields ); 385 | 386 | for ( var i : int = 0; i < tmpFields.Count; i++ ) { 387 | if ( tmpFields[i].name == name ) { 388 | tmpFields.RemoveAt ( i ); 389 | break; 390 | } 391 | } 392 | 393 | fields = tmpFields.ToArray (); 394 | } 395 | 396 | public function GetComponentType ( type : System.Type ) : Component { 397 | for ( var i : int = 0; i < fields.Length; i++ ) { 398 | if ( fields[i] && fields[i].component && fields[i].type == type ) { 399 | return fields[i].component; 400 | } 401 | } 402 | 403 | return null; 404 | } 405 | 406 | public static function FindObject ( id : String ) : OFSerializedObject { 407 | var result : OFSerializedObject; 408 | var allObjects : OFSerializedObject[] = GameObject.FindObjectsOfType.(); 409 | 410 | for ( var i : int = 0; i < allObjects.Length; i++ ) { 411 | if ( allObjects[i].id == id ) { 412 | result = allObjects[i]; 413 | break; 414 | } 415 | } 416 | 417 | return result; 418 | } 419 | 420 | public static function GetAllInScene () : OFSerializedObject [] { 421 | return GameObject.FindObjectsOfType.(); 422 | } 423 | } 424 | -------------------------------------------------------------------------------- /src/Plugins/OpenFile/OFSerializer.js: -------------------------------------------------------------------------------- 1 | #pragma strict 2 | 3 | public class OFSerializer extends MonoBehaviour { 4 | private static var plugins : OFPlugin[]; 5 | 6 | public static function GetPlugin ( type : System.Type ) : OFPlugin { 7 | if ( !plugins ) { 8 | plugins = OFReflector.GetPlugins (); 9 | } 10 | 11 | for ( var i : int = 0; i < plugins.Length; i++ ) { 12 | if ( plugins[i].CheckType ( type ) ) { 13 | return plugins[i]; 14 | } 15 | } 16 | 17 | return null; 18 | } 19 | 20 | public static function CanSerialize ( type : System.Type ) : boolean { 21 | return CanSerialize ( type.ToString () ); 22 | } 23 | 24 | public static function CanSerialize ( type : String ) : boolean { 25 | var str : String = type; 26 | str = str.Replace ( "UnityEngine.", "" ); 27 | var strings : String[] = OFField.GetTypeStrings (); 28 | 29 | for ( var i : int = 0; i < strings.Length; i++ ) { 30 | if ( strings[i] == str ) { 31 | return true; 32 | } 33 | } 34 | 35 | return false; 36 | } 37 | 38 | public static function SerializeChildren ( input : Transform ) : JSONObject { 39 | return SerializeChildren ( [ input ] ); 40 | } 41 | 42 | public static function SerializeChildren ( input : Transform[] ) : JSONObject { 43 | var output : JSONObject = new JSONObject ( JSONObject.Type.OBJECT ); 44 | 45 | for ( var i : int = 0; i < input.Length; i++ ) { 46 | var t : JSONObject = new JSONObject ( JSONObject.Type.ARRAY ); 47 | 48 | for ( var o : int = 0; o < input[i].childCount; o++ ) { 49 | var obj : OFSerializedObject = input[i].GetChild ( o ).GetComponent.< OFSerializedObject > (); 50 | 51 | if ( obj ) { 52 | t.Add ( Serialize ( obj ) ); 53 | } 54 | } 55 | 56 | output.AddField ( input[i].gameObject.name, t ); 57 | } 58 | 59 | return output; 60 | } 61 | 62 | public static function Serialize ( input : OFSerializedObject ) : JSONObject { 63 | var output : JSONObject = new JSONObject ( JSONObject.Type.OBJECT ); 64 | var components : JSONObject = new JSONObject ( JSONObject.Type.ARRAY ); 65 | var assetLinks : JSONObject = new JSONObject ( JSONObject.Type.ARRAY ); 66 | 67 | output.AddField ( "name", input.gameObject.name ); 68 | output.AddField ( "id", input.id ); 69 | output.AddField ( "prefabPath", input.prefabPath ); 70 | 71 | for ( var i : int = 0; i < input.fields.Length; i++ ) { 72 | components.Add ( Serialize ( input.fields[i].component ) ); 73 | } 74 | 75 | for ( i = 0; i < input.assetLinks.Length; i++ ) { 76 | var assetLink : JSONObject = new JSONObject ( JSONObject.Type.OBJECT ); 77 | 78 | assetLink.AddField ( "name", input.assetLinks[i].name ); 79 | 80 | if ( !String.IsNullOrEmpty ( input.assetLinks[i].filePath ) ) { 81 | assetLink.AddField ( "filePath", input.assetLinks[i].filePath ); 82 | 83 | } else if ( !String.IsNullOrEmpty ( input.assetLinks[i].resourcePath ) ) { 84 | assetLink.AddField ( "resourcePath", input.assetLinks[i].resourcePath ); 85 | 86 | } else if ( !String.IsNullOrEmpty ( input.assetLinks[i].bundlePath ) ) { 87 | assetLink.AddField ( "bundlePath", input.assetLinks[i].bundlePath ); 88 | 89 | } 90 | 91 | assetLinks.Add ( assetLink ); 92 | } 93 | 94 | output.AddField ( "components", components ); 95 | output.AddField ( "assetLinks", assetLinks ); 96 | 97 | return output; 98 | } 99 | 100 | 101 | ////////////////// 102 | // Classes 103 | ////////////////// 104 | // Component 105 | public static function Serialize ( input : Component ) : JSONObject { 106 | if ( !input ) { return null; } 107 | 108 | if ( !plugins ) { 109 | plugins = OFReflector.GetPlugins (); 110 | } 111 | 112 | var output : JSONObject; 113 | 114 | // Unity classes 115 | if ( input.GetType() == typeof ( Light ) ) { 116 | output = Serialize ( input as Light ); 117 | 118 | } else if ( input.GetType() == typeof ( Transform ) ) { 119 | output = Serialize ( input as Transform ); 120 | 121 | } else if ( input.GetType() == typeof ( AudioSource ) ) { 122 | output = Serialize ( input as AudioSource ); 123 | 124 | } else if ( input.GetType() == typeof ( MeshFilter ) ) { 125 | output = Serialize ( input as MeshFilter ); 126 | 127 | } else if ( input.GetType() == typeof ( MeshRenderer ) ) { 128 | output = Serialize ( input as MeshRenderer ); 129 | 130 | } else if ( input.GetType() == typeof ( SphereCollider ) ) { 131 | output = Serialize ( input as SphereCollider ); 132 | 133 | } else if ( input.GetType() == typeof ( BoxCollider ) ) { 134 | output = Serialize ( input as BoxCollider ); 135 | 136 | // Plugins 137 | } else { 138 | for ( var i : int = 0; i < plugins.Length; i++ ) { 139 | if ( plugins[i].CheckType ( input.GetType() ) ) { 140 | output = plugins[i].Serialize ( input ); 141 | break; 142 | } 143 | } 144 | 145 | } 146 | 147 | if ( output != null ) { 148 | output.AddField ( "_TYPE_", input.GetType().ToString().Replace ( "UnityEngine.", "" ) ); 149 | } 150 | 151 | return output; 152 | } 153 | 154 | // Light 155 | public static function Serialize ( input : Light ) : JSONObject { 156 | if ( !input ) { return null; } 157 | 158 | var output : JSONObject = new JSONObject ( JSONObject.Type.OBJECT ); 159 | 160 | output.AddField ( "type", input.type.ToString () ); 161 | output.AddField ( "range", input.range ); 162 | output.AddField ( "color", Serialize ( input.color ) ); 163 | output.AddField ( "intensity", input.intensity ); 164 | output.AddField ( "shadows", input.shadows.ToString () ); 165 | 166 | return output; 167 | } 168 | 169 | // BoxCollider 170 | public static function Serialize ( input : BoxCollider ) : JSONObject { 171 | if ( !input ) { return null; } 172 | 173 | var output : JSONObject = new JSONObject ( JSONObject.Type.OBJECT ); 174 | 175 | output.AddField ( "center", Serialize ( input.center ) ); 176 | output.AddField ( "size", Serialize ( input.size ) ); 177 | 178 | return output; 179 | } 180 | 181 | // SphereCollider 182 | public static function Serialize ( input : SphereCollider ) : JSONObject { 183 | if ( !input ) { return null; } 184 | 185 | var output : JSONObject = new JSONObject ( JSONObject.Type.OBJECT ); 186 | 187 | output.AddField ( "center", Serialize ( input.center ) ); 188 | output.AddField ( "radius", input.radius ); 189 | 190 | return output; 191 | } 192 | 193 | // MeshFilter 194 | public static function Serialize ( input : MeshFilter ) : JSONObject { 195 | if ( !input ) { return null; } 196 | 197 | var output : JSONObject = new JSONObject ( JSONObject.Type.OBJECT ); 198 | 199 | return output; 200 | } 201 | 202 | // MeshRenderer 203 | public static function Serialize ( input : MeshRenderer ) : JSONObject { 204 | if ( !input ) { return null; } 205 | 206 | var output : JSONObject = new JSONObject ( JSONObject.Type.OBJECT ); 207 | var materials : JSONObject = new JSONObject ( JSONObject.Type.ARRAY ); 208 | 209 | for ( var i : int = 0; i < input.materials.Length; i++ ) { 210 | var material : JSONObject = new JSONObject ( JSONObject.Type.OBJECT ); 211 | 212 | material.AddField ( "name", input.materials[i].name ); 213 | material.AddField ( "shader", input.materials[i].shader.name ); 214 | 215 | materials.Add ( material ); 216 | } 217 | 218 | output.AddField ( "materials", materials ); 219 | 220 | return output; 221 | } 222 | 223 | // AudioSource 224 | public static function Serialize ( input : AudioSource ) : JSONObject { 225 | if ( !input ) { return null; } 226 | 227 | var output : JSONObject = new JSONObject ( JSONObject.Type.OBJECT ); 228 | 229 | output.AddField ( "dopplerLevel", input.dopplerLevel ); 230 | output.AddField ( "ignoreListenerPause", input.ignoreListenerPause ); 231 | output.AddField ( "ignoreListenerVolume", input.ignoreListenerVolume ); 232 | output.AddField ( "loop", input.loop ); 233 | output.AddField ( "maxDistance", input.maxDistance ); 234 | output.AddField ( "minDistance", input.minDistance ); 235 | output.AddField ( "panLevel", input.panLevel ); 236 | output.AddField ( "pitch", input.pitch ); 237 | output.AddField ( "playOnAwake", input.playOnAwake ); 238 | output.AddField ( "priority", input.priority ); 239 | output.AddField ( "rolloffMode", input.rolloffMode ); 240 | output.AddField ( "spread", input.spread ); 241 | output.AddField ( "volume", input.volume ); 242 | 243 | return output; 244 | } 245 | 246 | // Transform 247 | public static function Serialize ( input : Transform ) : JSONObject { 248 | if ( !input ) { return null; } 249 | 250 | var output : JSONObject = new JSONObject ( JSONObject.Type.OBJECT ); 251 | 252 | output.AddField ( "eulerAngles", Serialize ( input.eulerAngles ) ); 253 | output.AddField ( "position", Serialize ( input.position ) ); 254 | output.AddField ( "localScale", Serialize ( input.localScale ) ); 255 | 256 | return output; 257 | } 258 | 259 | 260 | ///////////////// 261 | // Structs 262 | ///////////////// 263 | // Color 264 | public static function Serialize ( input : Color ) : JSONObject { 265 | var output : JSONObject = new JSONObject ( JSONObject.Type.OBJECT ); 266 | 267 | output.AddField ( "r", input.r ); 268 | output.AddField ( "g", input.g ); 269 | output.AddField ( "b", input.b ); 270 | output.AddField ( "a", input.a ); 271 | 272 | return output; 273 | } 274 | 275 | // Vector3 276 | public static function Serialize ( input : Vector3 ) : JSONObject { 277 | var output : JSONObject = new JSONObject ( JSONObject.Type.OBJECT ); 278 | 279 | output.AddField ( "x", input.x ); 280 | output.AddField ( "y", input.y ); 281 | output.AddField ( "z", input.z ); 282 | 283 | return output; 284 | } 285 | 286 | // Vector2 287 | public static function Serialize ( input : Vector2 ) : JSONObject { 288 | var output : JSONObject = new JSONObject ( JSONObject.Type.OBJECT ); 289 | 290 | output.AddField ( "x", input.x ); 291 | output.AddField ( "y", input.y ); 292 | 293 | return output; 294 | } 295 | } 296 | -------------------------------------------------------------------------------- /src/Plugins/OpenFile/OFWeb.js: -------------------------------------------------------------------------------- 1 | #pragma strict 2 | 3 | public class OFWeb { 4 | private static var tempStorage : Dictionary.< String, JSONObject > = new Dictionary.< String, JSONObject > (); 5 | 6 | public static function Set ( path : String, obj : JSONObject ) { 7 | tempStorage[path] = obj; 8 | } 9 | 10 | public static function Get ( path : String ) : JSONObject { 11 | return tempStorage[path]; 12 | } 13 | 14 | public static function Clear () { 15 | tempStorage.Clear (); 16 | } 17 | 18 | public static function IsWebPlayer () : boolean { 19 | return ( Application.platform == RuntimePlatform.OSXWebPlayer || Application.platform == RuntimePlatform.WindowsWebPlayer ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Plugins/OpenFile/OFWriter.js: -------------------------------------------------------------------------------- 1 | #pragma strict 2 | 3 | import System.IO; 4 | 5 | public class OFWriter { 6 | public static function SaveFile ( input : JSONObject, path : String ) { 7 | #if UNITY_WEBPLAYER && !UNITY_EDITOR 8 | OFWeb.Set ( path, input ); 9 | #else 10 | var sw : StreamWriter; 11 | 12 | if ( !File.Exists ( path ) ) { 13 | sw = File.CreateText ( path ); 14 | } else { 15 | sw = new StreamWriter ( path ); 16 | } 17 | 18 | sw.WriteLine ( input ); 19 | sw.Flush(); 20 | sw.Close(); 21 | #endif 22 | } 23 | 24 | public static function SaveScene ( parent : GameObject, path : String ) { 25 | var allObjects : OFSerializedObject[] = parent.GetComponentsInChildren. (); 26 | var output : JSONObject = new JSONObject ( JSONObject.Type.ARRAY ); 27 | 28 | for ( var i : int = 0; i < allObjects.Length; i++ ) { 29 | output.Add ( OFSerializer.Serialize ( allObjects[i] ) ); 30 | } 31 | 32 | SaveFile ( output, path ); 33 | } 34 | } 35 | --------------------------------------------------------------------------------