private static void Antimaterialize(GameObject target) { var viewName = target.name; var exportBasePath = ConstSettings.FULLPATH_INFORMATION_RESOURCE + viewName; Debug.Log("start antimaterialize:" + viewName + ". view name is:" + target + " export file path:" + exportBasePath); // remove all files in exportBasePath. FileController.RemakeDirectory(exportBasePath); // childrenがいろいろなタグの根本にあたる。 var layersInEditor = new List <LayerInfoOnEditor>(); var contents = new List <ContentInfo>(); var rectTrans = target.GetComponent <RectTransform>(); if ( rectTrans.anchorMin.x == 0 && rectTrans.anchorMin.y == 1 && rectTrans.anchorMax.x == 0 && rectTrans.anchorMax.y == 1 && rectTrans.pivot.x == 0 && rectTrans.pivot.y == 1 ) { // pass. } else { throw new Exception("root gameObject should have rectTrans.anchorMin:(0,1) ectTrans.anchorMax:(0,1) rectTrans.pivot:(0,1) anchor. please set it."); } var rootHeight = rectTrans.sizeDelta.y; // recursiveに、コンテンツを分解していく。 for (var i = 0; i < target.transform.childCount; i++) { var child = target.transform.GetChild(i); CollectConstraintsAndContents(viewName, child.gameObject, layersInEditor, contents, rootHeight); } var UUebTags = new UUebTags(viewName, contents.ToArray(), layersInEditor.Select(l => l.layerInfo).ToArray()); var jsonStr = JsonUtility.ToJson(UUebTags); using (var sw = new StreamWriter(Path.Combine(exportBasePath, ConstSettings.listFileName))) { sw.WriteLine(jsonStr); } AssetDatabase.Refresh(); Debug.Log("finished antimaterialize:" + viewName + ". view name is:" + target + " export file path:" + exportBasePath); }
// private static string[] defaultTagStrs; private static string[] CollectDefaultTag() { var htmlTags = new List <string>(); var defaultAssetPaths = ConstSettings.FULLPATH_DEFAULT_TAGS; var filePaths = FileController.FilePathsInFolder(defaultAssetPaths); foreach (var filePath in filePaths) { // Debug.LogError("filePath:" + filePath + " filenameWithoutExtension:" + Path.GetFileNameWithoutExtension(filePath)); var tagStr = Path.GetFileNameWithoutExtension(filePath); htmlTags.Add(tagStr); } return(htmlTags.ToArray()); }
private static void ModifyLayerInstance(string viewName, GameObject currentLayerInstance, List <LayerInfoOnEditor> currentLayers, float parentWidth, float parentHeight) { // このインスタンスのポジションを0,0 leftTopAnchor、左上pivotにする。 // レイヤーのインスタンスは、インスタンス化時に必ず親のサイズにフィットするように変形される。 // ただし、親がboxではないlayerの場合、パーツ作成時の高さが使用される。 // アンカーは成立するため、相対的な配置をしつつ、レイアウトを綺麗に行うことができる。 var rectTrans = currentLayerInstance.GetComponent <RectTransform>(); var anchorWidth = (parentWidth * rectTrans.anchorMin.x) + (parentWidth * (1 - rectTrans.anchorMax.x)); var anchorHeight = (parentHeight * rectTrans.anchorMin.y) + (parentHeight * (1 - rectTrans.anchorMax.y)); var calculatedWidth = parentWidth - anchorWidth - rectTrans.offsetMin.x + rectTrans.offsetMax.x; var calculatedHeight = parentHeight - anchorHeight - rectTrans.offsetMin.y + rectTrans.offsetMax.y; var unboxedLayerSize = new BoxPos(rectTrans, calculatedHeight); rectTrans.anchoredPosition = new Vector2(0, 0); rectTrans.anchorMin = new Vector2(0, 1); rectTrans.anchorMax = new Vector2(0, 1); rectTrans.pivot = new Vector2(0, 1); var size = new Vector2(calculatedWidth, calculatedHeight); if (size.x <= 0 || size.y <= 0) { throw new Exception("layer size is negative. size:" + size); } var layerName = currentLayerInstance.name.ToLower(); var childrenConstraintDict = new Dictionary <string, BoxPos>(); var copiedChildList = new List <GameObject>(); /* * 元々のchildrenを別GameObjectとして分離 */ { foreach (Transform component in currentLayerInstance.transform) { var childGameObject = component.gameObject; // enableでなければスキップ if (!childGameObject.activeSelf) { continue; } var newChildGameObject = GameObject.Instantiate(childGameObject); newChildGameObject.name = childGameObject.name; copiedChildList.Add(newChildGameObject); } } using (new GameObjectDeleteUsing(copiedChildList.ToArray())) { /* * box情報を生成 */ { foreach (var boxObject in copiedChildList) { var boxRectTrans = boxObject.GetComponent <RectTransform>(); var boxName = layerName + "_" + boxObject.name; if (childrenConstraintDict.ContainsKey(boxName)) { throw new Exception("another box:" + boxName + " is already exist in layer:" + layerName + ". please set other name for each customTag on this layer."); } childrenConstraintDict[boxName] = new BoxPos(boxRectTrans, 0); } } /* * layer内のboxの削除(レイアウトの動的な伸張、変更を実行時に動的に行ないたいため、jsonにして吐き出す。実態がないほうがいい) */ { var list = new List <GameObject>(); for (var i = 0; i < currentLayerInstance.transform.childCount; i++) { list.Add(currentLayerInstance.transform.GetChild(i).gameObject); } // 取り出してから消す foreach (var childObj in list) { GameObject.DestroyImmediate(childObj); } } /* * このレイヤーのunboxed時のサイズと、内包しているboxの情報を追加 */ { var newChildConstraint = childrenConstraintDict .Select(kv => new BoxConstraint(kv.Key, kv.Value)) .ToArray(); var newLayer = new LayerInfo( layerName, unboxedLayerSize, newChildConstraint, "resources://" + ConstSettings.PREFIX_PATH_INFORMATION_RESOURCE + viewName + "/" + layerName.ToUpper() ); currentLayers.Add(new LayerInfoOnEditor(newLayer, size)); } /* * このprefabはlayer = レイアウトを行う前提の箱として使われる。 * レイヤー内には、box = 特定の名前の要素(prefabになる前の子供ゲームオブジェクト名のタグ要素)のみをレイアウトする。 * そのboxタグの中身にはなんでも入れることができる。 * * prefab名は大文字 になる。 */ { var prefabPath = "Assets/InformationResources/Resources/Views/" + viewName + "/" + layerName.ToUpper() + ".prefab"; var dirPath = Path.GetDirectoryName(prefabPath); FileController.CreateDirectoryRecursively(dirPath); PrefabUtility.CreatePrefab(prefabPath, currentLayerInstance); // layer自体の削除 GameObject.DestroyImmediate(currentLayerInstance); } /* * 取り出しておいたchildに対して再帰 */ foreach (var disposableChild in copiedChildList) { ModifyLayerInstance(viewName, disposableChild, currentLayers, calculatedWidth, calculatedHeight); } } }
private static void ModifyContentInstance(string viewName, GameObject currentContentInstance, List <ContentInfo> currentContents) { var contentName = currentContentInstance.name.ToLower(); // set default rect. var rectTrans = currentContentInstance.GetComponent <RectTransform>(); rectTrans.anchoredPosition = new Vector2(0, 0); rectTrans.anchorMin = new Vector2(0, 1); rectTrans.anchorMax = new Vector2(0, 1); // 画像か文字を含んでいるコンテンツで、コードも可。でもボタンの実行に関しては画像に対してボタンが勝手にセットされる。ボタンをつけたらエラー。 // 文字のリンク化も勝手に行われる。というかあれもボタンだっけ。 // ボタンコンポーネントが付いていたら外す。 if (currentContentInstance.GetComponent <Button>() != null) { throw new Exception("do not attach Button component directory. Button component will be attached automatically."); } var components = currentContentInstance.GetComponents <Component>(); var type = TreeType.Content_Img; if (components.Length < 3) { type = TreeType.Content_Img; } else { // foreach (var s in components) { // Debug.LogError("s:" + s.GetType().Name); // } // rectTrans, canvasRenderer 以外を採用する。 var currentFirstComponent = components[2]; switch (currentFirstComponent.GetType().Name) { case "Image": { type = TreeType.Content_Img; break; } case "Text": { type = TreeType.Container; // not Content_Text. break; } default: { throw new Exception("unsupported second component on content. found component type:" + currentFirstComponent); } } } // 名前を登録する currentContents.Add(new ContentInfo(contentName, type, "resources://" + ConstSettings.PREFIX_PATH_INFORMATION_RESOURCE + viewName + "/" + contentName.ToUpper())); // このコンポーネントをprefab化する { var prefabPath = "Assets/InformationResources/Resources/Views/" + viewName + "/" + contentName.ToUpper() + ".prefab"; var dirPath = Path.GetDirectoryName(prefabPath); FileController.CreateDirectoryRecursively(dirPath); PrefabUtility.CreatePrefab(prefabPath, currentContentInstance); // 自体の削除 GameObject.DestroyImmediate(currentContentInstance); } }
private static void Antimaterialize(GameObject target) { Debug.Log("start tag-generation check."); var childNames = GetChildNames(target); // 名前の重複チェック var overlappedNameList = childNames.GroupBy(n => n).Where(c => 1 < c.Count()).ToList(); if (0 < overlappedNameList.Count) { Debug.LogError("two or multiple gameobject has same name. please set unique name for converting gameobject to HTML tag."); foreach (var name in overlappedNameList) { Debug.LogError("gameobject name:" + name + " is defined multiple times. please change for each object name to unique."); } return; } var viewName = target.name; var exportBasePath = ConstSettings.FULLPATH_INFORMATION_RESOURCE + viewName; Debug.Log("start antimaterialize:" + viewName + ". view name is:" + target + " export file path:" + exportBasePath); // remove all files in exportBasePath. FileController.RemakeDirectory(exportBasePath); // childrenがいろいろなタグの根本にあたる。 var layersInEditor = new List <LayerInfoOnEditor>(); var contents = new List <ContentInfo>(); var rectTrans = target.GetComponent <RectTransform>(); if ( rectTrans.anchorMin.x == 0 && rectTrans.anchorMin.y == 1 && rectTrans.anchorMax.x == 0 && rectTrans.anchorMax.y == 1 && rectTrans.pivot.x == 0 && rectTrans.pivot.y == 1 ) { // pass. } else { throw new Exception("root gameObject should have rectTrans.anchorMin:(0,1) ectTrans.anchorMax:(0,1) rectTrans.pivot:(0,1) anchor. please set it."); } var rootWidth = rectTrans.sizeDelta.x; var rootHeight = rectTrans.sizeDelta.y; // recursiveに、コンテンツを分解していく。 for (var i = 0; i < target.transform.childCount; i++) { var child = target.transform.GetChild(i); CollectLayerConstraintsAndContents(viewName, child.gameObject, layersInEditor, contents, rootWidth, rootHeight); } // 存在するlayer内の要素に対して、重なっているもの、縦に干渉しないものをグループとして扱う。 foreach (var currentLayer in layersInEditor) { if (currentLayer.layerInfo.boxes.Any()) { CollectCollisionInLayer(currentLayer); } } var UUebTags = new UUebTags(viewName, contents.ToArray(), layersInEditor.Select(l => l.layerInfo).ToArray()); var jsonStr = JsonUtility.ToJson(UUebTags); using (var sw = new StreamWriter(Path.Combine(exportBasePath, ConstSettings.listFileName))) { sw.WriteLine(jsonStr); } // オリジナルのオブジェクト自体をprefabとして別途保存する。 if (!Directory.Exists(exportBasePath + "/Editor/")) { Directory.CreateDirectory(exportBasePath + "/Editor/"); } PrefabUtility.CreatePrefab(exportBasePath + "/Editor/" + viewName + ".prefab", target); AssetDatabase.Refresh(); Debug.Log("finished antimaterialize:" + viewName + ". view name is:" + target + " export file path:" + exportBasePath); }