private string convertScene() { string ret_str = ""; bool isThereCamera = false; bool isThereLight = false; //sky if (enable_sky) { string add_str = "<a-sky "; Camera mainCamera = Camera.main; if (sky_color_from_MainCamera_Background && mainCamera) { add_str += "color=\"#" + ColorToHex(mainCamera.backgroundColor) + "\" "; } else { add_str += "color=\"#" + ColorToHex(sky_color) + "\" "; } if (sky_texture) { string texture_path = AssetDatabase.GetAssetPath(sky_texture); string new_path = export_path + "/images/" + Path.GetFileName(texture_path); //テクスチャ無ければコピー if (AssetDatabase.AssetPathToGUID(new_path) == "") { AssetDatabase.CopyAsset(texture_path, new_path); } add_str += "src=\"images/" + Path.ChangeExtension(Path.GetFileName(texture_path), ".png") + "\" "; } add_str += "></a-sky>\n"; ret_str += add_str; } GameObject[] allObjects = Resources.FindObjectsOfTypeAll <GameObject>(); int objects_num = allObjects.Length; int process_num = 0; int meshIndex = 0; //オブジェクト全検索 foreach (GameObject obj in allObjects) { process_num++; //プログレスバー表示 EditorUtility.DisplayProgressBar("Progress", "Now Processing... " + process_num + "/" + objects_num, (float)process_num / (float)objects_num); // ProjectにあるものならAsset Path, SceneにあるオブジェクトはそのシーンのPathが返ってくる string path = AssetDatabase.GetAssetOrScenePath(obj); // シーンのPathは拡張子が .unity string sceneExtension = ".unity"; // Path.GetExtension(path) で pathの拡張子を取得 // Equals(sceneExtension)で sceneExtensionと比較 bool isExistInScene = Path.GetExtension(path).Equals(sceneExtension); // シーン内のオブジェクトかどうか判定 if (isExistInScene) { //非表示オブジェクトならスキップ if (!obj.activeInHierarchy) { continue; } MeshFilter meshFilter = obj.GetComponent <MeshFilter>(); Light light = obj.GetComponent <Light>(); SpriteRenderer spriteRenderer = obj.GetComponent <SpriteRenderer>(); SkinnedMeshRenderer skinnedMeshRenderer = obj.GetComponent <SkinnedMeshRenderer>(); //メッシュフィルターコンポーネントを持ってるなら if (meshFilter && meshFilter.sharedMesh) { // Get the image src url string to reference in the HTML tag. Material mat = obj.GetComponent <Renderer>().sharedMaterial; string imageSrcUrl = ""; if (mat) { imageSrcUrl = "src=\"" + outputTexture(mat, meshIndex).Replace("src: ", "") + "\" "; } //Cubeの場合 if (meshFilter.sharedMesh.name == "Cube") { Vector3 scale = obj.transform.lossyScale; //string append_str = indent + "<a-entity geometry=\"primitive: box; width: " + scale.x + "; height: " + scale.y + "; depth: " + scale.z + "\" " + outputRotation(obj) + outputPosition(obj) + outputMaterial(obj) + "></a-entity>\n"; string append_str = indent + "<a-box " + (enable_physics ? "static-body " : " ") + imageSrcUrl + "geometry=\"primitive: box; width: " + scale.x + "; height: " + scale.y + "; depth: " + scale.z + "\" " + outputRotation(obj) + outputPosition(obj) + outputMaterial(obj, meshIndex) + "></a-box>\n"; ret_str += append_str; } //Sphereの場合 else if (meshFilter.sharedMesh.name == "Sphere") { //各軸scaleが使えないので各スケールの平均値をradiusとする Vector3 scale = obj.transform.lossyScale; float radius = 0.5f; if (scale != Vector3.one) { radius = (scale.x + scale.y + scale.z) * 0.333333333f * 0.5f; } //string append_str = indent + "<a-entity geometry=\"primitive: sphere; radius: " + radius + "\" " + outputRotation(obj) + outputPosition(obj) + outputMaterial(obj) + "></a-entity>\n"; string append_str = indent + "<a-sphere " + (enable_physics ? "static-body " : " ") + imageSrcUrl + "geometry=\"primitive: sphere; radius: " + radius + "\" " + outputRotation(obj) + outputPosition(obj) + outputMaterial(obj, meshIndex) + "></a-sphere>\n"; ret_str += append_str; } //Cylinderの場合(Unityのスケール1,1,1のシリンダーは半径0.5で高さ2) TODO:パックマンみたいに欠けたシリンダー対応 独自コンポーネントくっつけて対応予定 else if (meshFilter.sharedMesh.name == "Cylinder") { //例によってスケールのxとzの平均を半径、yを高さとする Vector3 scale = obj.transform.lossyScale; float radius = 0.5f; radius = (scale.x + scale.z) * 0.5f * 0.5f; float height = scale.y * 2f; //string append_str = indent + "<a-entity geometry=\"primitive: cylinder; radius: " + radius + "\" height:" + height + "; " + outputRotation(obj) + outputPosition(obj) + outputMaterial(obj) + "></a-entity>\n"; string append_str = indent + "<a-cylinder " + (enable_physics ? "static-body " : " ") + imageSrcUrl + "geometry=\"primitive: cylinder; radius: " + radius + "\" height:" + height + "; " + outputRotation(obj) + outputPosition(obj) + outputMaterial(obj, meshIndex) + "></a-cylinder>\n"; ret_str += append_str; } //Planeの場合(Unityのスケール1,1,1のプレーンは幅10高さ10)x90回転でa-frameと揃う else if (meshFilter.sharedMesh.name == "Plane") { Vector3 eulerAngles = obj.transform.eulerAngles; eulerAngles.x -= 90f; float width = obj.transform.lossyScale.x * 10f; float height = obj.transform.lossyScale.z * 10f; //string append_str = indent + "<a-entity geometry=\"primitive: plane; width:" + width + "; height:" + height + "\" " + outputRotation(eulerAngles) + outputPosition(obj) + outputMaterial(obj) + "></a-entity>\n"; string append_str = indent + "<a-plane " + (enable_physics ? "static-body " : " ") + imageSrcUrl + "geometry=\"primitive: plane; width:" + width + "; height:" + height + "\" " + outputRotation(eulerAngles) + outputPosition(obj) + outputMaterial(obj, meshIndex, false) + "></a-plane>\n"; ret_str += append_str; } //TODO:videoの場合 //TODO:curvedimageの場合 //TODO:videosphereの場合 //TODO:Coneの場合 //TODO:Ringの場合 //TODO:Torusの場合 //TODO:Torus Knotの場合 //Modelの場合 else { string objFileName = meshFilter.sharedMesh.name.Replace(":", "_") + (unique_assets ? meshIndex.ToString() : ""); string new_path = export_path + "/models/" + objFileName + ".obj"; //obj無ければ作成 if (!File.Exists(Application.dataPath + "/AFrameExporter/export/models/" + objFileName + ".obj")) { ObjExporter.MeshToFile(meshFilter, new_path, true); AssetDatabase.ImportAsset(new_path); var importer = (ModelImporter)ModelImporter.GetAtPath(new_path); importer.animationType = ModelImporterAnimationType.None; AssetDatabase.Refresh(); } //マテリアルからテクスチャを取り出す //string append_str = indent + "<a-entity loader=\"src: url(models/" + objFileName + ".obj); format: obj\" " + outputScale(obj) + outputRotation(obj) + outputPosition(obj) + outputMaterial(obj) + "></a-entity>\n"; string append_str = indent + "<a-obj-model " + (enable_physics ? "static-body" : "") + " src=\"url(models/" + objFileName + ".obj)\" loader=\"src: url(models/" + objFileName + ".obj); format: obj\" " + outputScale(obj) + outputRotation(obj) + outputPosition(obj) + outputMaterial(obj, meshIndex) + "></a-obj-model>\n"; ret_str += append_str; } } //skinnedMeshModelの場合 else if (skinnedMeshRenderer && skinnedMeshRenderer.sharedMesh) { string objFileName = skinnedMeshRenderer.sharedMesh.name.Replace(":", "_") + (unique_assets ? meshIndex.ToString() : ""); string new_path = export_path + "/models/" + objFileName + ".obj"; //obj無ければ作成 if (!File.Exists(Application.dataPath + "/AFrameExporter/export/models/" + objFileName + ".obj")) { ObjExporter.SkinnedMeshToFile(skinnedMeshRenderer, new_path, true); AssetDatabase.ImportAsset(new_path); var importer = (ModelImporter)ModelImporter.GetAtPath(new_path); importer.animationType = ModelImporterAnimationType.None; AssetDatabase.Refresh(); } //マテリアルからテクスチャを取り出す //string append_str = indent + "<a-entity loader=\"src: url(models/" + objFileName + ".obj); format: obj\" " + outputScale(obj) + outputRotation(obj) + outputPosition(obj) + outputMaterial(obj) + "></a-entity>\n"; string append_str = indent + "<a-obj-model " + (enable_physics ? "static-body" : "") + " src=\"url(models/" + objFileName + ".obj)\" loader=\"src: url(models/" + objFileName + ".obj); format: obj\" " + outputScale(obj) + outputRotation(obj) + outputPosition(obj) + outputMaterial(obj, meshIndex) + "></a-obj-model>\n"; ret_str += append_str; } //imageの場合 UnityはQuad シングルスプライトのみ対応 else if (spriteRenderer && spriteRenderer.sprite && spriteRenderer.sprite.pixelsPerUnit != 0) { Sprite sprite = spriteRenderer.sprite; float width = sprite.rect.width / sprite.pixelsPerUnit * obj.transform.lossyScale.x; float height = sprite.rect.height / sprite.pixelsPerUnit * obj.transform.lossyScale.y; //テクスチャ Texture tex = sprite.texture; string tex_str = ""; if (tex) { string texture_path = AssetDatabase.GetAssetPath(tex); string new_path = export_path + "/images/" + Path.GetFileName(texture_path); //テクスチャ無ければコピー if (!File.Exists(Application.dataPath + "/AFrameExporter/export/images/" + Path.GetFileName(texture_path))) { AssetDatabase.CopyAsset(texture_path, new_path); AssetDatabase.Refresh(); } tex_str = "src=\"images/" + Path.GetFileName(texture_path) + "\" "; } string append_str = indent + "<a-image " + tex_str + "width=\"" + -width + "\" height=\"" + height + "\" " + outputRotation(obj) + outputPosition(obj) + "></a-image>\n"; ret_str += append_str; } //MainCameraの場合 else if (!isThereCamera && obj.tag == "MainCamera") { string append_str = ""; Camera camera = obj.GetComponent <Camera>(); if (camera && !enable_web) { append_str = indent + "<a-entity id=\"rig\" " + outputPosition(obj) + " " + outputRotation(obj, false) + ">\n"; append_str += indent + indent + "<a-camera cursor-color=#" + ColorToHex(cursor_color) + " wasd-controls-enabled=" + wasd_controls_enabled.ToString().ToLower() + /*" fov=" + camera.fieldOfView + " near=" + camera.nearClipPlane + " far=" + camera.farClipPlane +*/ " cursor-maxdistance=" + cursor_maxdistance + " cursor-offset=" + cursor_offset + " cursor-opacity=" + cursor_opacity + " cursor-scale=" + cursor_scale + " look-controls-enabled=" + look_controls_enabled.ToString().ToLower() + "></a-camera>\n"; append_str += indent + "</a-entity>\n"; } else { append_str = indent + "<a-entity id=\"rig\" position=\"8.88 3.26 -16.53\" rotation=\"0 98.6636581420898 0\" movement-controls kinematic-body>\n"; append_str += indent + indent + "<a-entity camera look-controls tilt-controls></a-entity>\n"; append_str += indent + "</a-entity>\n"; } ret_str += append_str; isThereCamera = true; } //Lightの場合 else if (light) { //Vector3 forward = -obj.transform.forward; //Vector3 rotation = obj.transform.eulerAngles; //rotation.x -= 90f; SerializedObject serializedObject = new UnityEditor.SerializedObject(obj.transform); SerializedProperty serializedEulerHint = serializedObject.FindProperty("m_LocalEulerAnglesHint"); Vector3 rotation = serializedEulerHint.vector3Value; //string lightPosition_str = "position=\"" + -forward.x + " " + forward.y + " " + forward.z + "\" "; string lightRotation_str = "rotation=\"" + -rotation.x + " " + rotation.y + " " + rotation.z + "\" "; //DirectionalLightの場合 if (light.type == LightType.Directional) { //string append_str = indent + "<a-light type=directional; intensity=" + light.intensity + " color=#" + ColorToHex(light.color) + " " + lightPosition_str + "></a-light>\n"; string append_str = indent + "<a-light type=directional intensity=" + light.intensity + " color=#" + ColorToHex(light.color) + " " + outputPosition(obj) + " " + lightRotation_str + "></a-light>\n"; ret_str += append_str; isThereLight = true; } else if (light.type == LightType.Point) { //string append_str = indent + "<a-light type=directional; intensity=" + light.intensity + " color=#" + ColorToHex(light.color) + " " + lightPosition_str + "></a-light>\n"; string append_str = indent + "<a-light type=point distance=" + light.range + " intensity=" + light.intensity + " color=#" + ColorToHex(light.color) + " " + outputPosition(obj) + " " + lightRotation_str + "></a-light>\n"; ret_str += append_str; isThereLight = true; } else if (light.type == LightType.Spot) { //string append_str = indent + "<a-light type=directional; intensity=" + light.intensity + " color=#" + ColorToHex(light.color) + " " + lightPosition_str + "></a-light>\n"; string append_str = indent + "<a-light type=spot distance=" + light.range + " angle=" + light.spotAngle + " intensity=" + light.intensity + " color=#" + ColorToHex(light.color) + " " + outputPosition(obj) + " " + lightRotation_str + "></a-light>\n"; ret_str += append_str; isThereLight = true; } //TODO:PointLightの場合 //TODO:SpotLightの場合 //TODO:AmbientLightの場合 //TODO:Hemisphereの場合 } } meshIndex++; } //Cameraが無い場合はデフォルト設定 if (!isThereCamera) { string append_str = ""; if (!enable_web) { append_str = indent + "<a-camera cursor-color=#" + ColorToHex(cursor_color) + " wasd-controls-enabled=" + wasd_controls_enabled.ToString().ToLower() + "></a-camera>\n"; } else { append_str = indent + "<a-entity id=\"rig\" position=\"8.88 3.26 -16.53\" rotation=\"0 98.6636581420898 0\" movement-controls kinematic-body>\n"; append_str += indent + indent + "<a-entity camera look-controls tilt-controls></a-entity>\n"; append_str += indent + "</a-entity>\n"; } ret_str += append_str; isThereCamera = true; } //Lightが無い場合はデフォルトライト if (!isThereLight) { } EditorUtility.ClearProgressBar(); return(ret_str); }