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); } } }
public LayerInfoOnEditor(LayerInfo layerInfo, Vector2 collisionBaseSize) { this.layerInfo = layerInfo; this.collisionBaseSize = collisionBaseSize; }