/// <summary> /// <b>호출</b> : ElementPresenter.MakeWall()<br></br> /// <b>참조</b> : CalcPadding(),FindRotateAngle(), MakeMesh.MakeWalls(), Outliner.FindAllOutline()<br></br> /// 문/창문 위치 반영한 벽 생성 함수. /// Outliner로 방의 외곽선 점을 얻은 다음, /// 그 점들을 따라 quad로 기준이 될 벽을 생성하고, /// MakeMesh.MakeWalls()으로 기준 벽에 문/창문 오브젝트의 정보를 반영하여 새로운 벽 오브젝트를 생성한 뒤, /// 생성된 오브젝트와 그 벽의 면적을 딕셔너리로 묶어서 저장하여 반환한다. /// </summary> /// <param name="rooms">모든 방 리스트</param> /// <param name="elements">모든 문/창문 오브젝트 리스트</param> /// <param name="height">벽 높이</param> /// <param name="material">생성된 벽에 적용할 기본 재질</param> /// <param name="wallParent">생성된 벽 오브젝트를 담을 부모 오브젝트</param> /// <param name="isDebug">디버그 옵션</param> /// <returns>생성된 벽 오브젝트와 벽의 면적을 담은 딕셔너리</returns> public static Dictionary <Transform, float> MakeWalls(List <Transform> rooms, List <Transform> elements, float height, Material material, out Transform wallParent, bool isDebug = false) { Dictionary <Transform, float> generatedWallList = new Dictionary <Transform, float>(); wallParent = new GameObject().transform; wallParent.transform.parent = rooms[0].parent; wallParent.name = "Walls"; foreach (var room in rooms) { // 방 외곽선을 이루는 점 수집 List <Transform> subFloors = new List <Transform>(); for (int i = 0; i < room.childCount; i++) { subFloors.Add(room.GetChild(i)); } Outliner outliner = new Outliner(); List <List <Dot> > allDots = outliner.FindAllOutline(subFloors); // 외곽선을 따라 벽 오브젝트 생성 foreach (var dots in allDots) { for (int i = 0; i < dots.Count; i++) { Vector3 dot1 = dots[i].position; Vector3 dot2 = dots[(i + 1) % dots.Count].position; // quad로 기준 벽을 생성 Transform wall = GameObject.CreatePrimitive(PrimitiveType.Quad).transform; float angle = FindRotateAngle(dot1, dot2); Vector3 padding = CalcPadding(angle); wall.position = (dot1 + dot2) * 0.5f + Vector3.up * height * 0.5f; wall.GetComponent <Renderer>().material.color = Color.black; wall.localScale = new Vector3(Mathf.Max(Mathf.Abs(dot1.x - dot2.x), Mathf.Abs(dot1.z - dot2.z)), height, 1); wall.Rotate(Vector3.up * angle); // 기준 벽과 문/창문 오브젝트 정보를 이용하여 새로운 벽 오브젝트 생성 Transform madeWall = MakeMesh.MakeWalls(wall, elements, material, out float area, isDebug).transform; generatedWallList.Add(madeWall, area); madeWall.parent = wallParent; GameObject.Destroy(wall.gameObject); } } } return(generatedWallList); }
/// <summary> /// <b>호출</b> : ElementPresenter.MakeWall()<br></br> /// <b>참조</b> : FindRotateAngle(), MakeMesh.MakeWalls(), Outliner.FindAllOutline()<br></br> /// 외곽벽을 생성하는 함수. /// Outliner를 이용하여 전체 방의 외곽 점을 수집한 뒤, 점사이 공간에 quad로 임시 벽을 생성한다. /// 임시벽의 위치, 크기, 회전을 참조해서 문/창문 오브젝트를 고려한 벽을 MakeMesh 클래스를 이용하여 생성한다. /// </summary> /// <param name="allFloors">전체 바닥 정보</param> /// <param name="elements">문/창문 리스트</param> /// <param name="border">벽 두께</param> /// <param name="height">벽 높이</param> /// <param name="material">외곽벽 생성시 적용할 기본 오브젝트</param> /// <returns>생성된 외곽벽 오브젝트를 담은 부모 오브젝트</returns> public static GameObject MakeOutlineWalls(List <Transform> allFloors, List <Transform> elements, float border, float height, Material material) { // 위치,크기,회전 참조를 위해 quad로 임시 생성한 벽 오브젝트를 담을 부모 오브젝트 Transform wallParent = new GameObject().transform; wallParent.name = "OutlineWalls"; // 문/창문 오브젝트를 고려하여 다시 생성한 벽 오브젝트를 담을 부모 오브젝트 Transform outlinewallParent = new GameObject().transform; outlinewallParent.name = "OutlineWalls"; // 전체 방 외곽 점 수집 Outliner outliner = new Outliner(); List <List <Dot> > allDots = outliner.FindAllOutline(allFloors); foreach (var dots in allDots) { for (int i = 0; i < dots.Count; i++) { Vector3 dot1 = dots[i].position; Vector3 dot2 = dots[(i + 1) % dots.Count].position; float angle = FindRotateAngle(dot1, dot2); // 임시 벽 생성 Transform wall = GameObject.CreatePrimitive(PrimitiveType.Quad).transform; wall.position = (dot1 + dot2) * 0.5f + Vector3.up * height * 0.5f; wall.localScale = new Vector3(Mathf.Max(Mathf.Abs(dot1.x - dot2.x), Mathf.Abs(dot1.z - dot2.z)), height, 1); wall.Rotate(Vector3.up * ((angle + 180) % 360)); wall.parent = wallParent; // 문/창문 고려한 벽 생성 Transform madeWall = MakeMesh.MakeWalls(wall, elements, material, out float area).transform; madeWall.parent = outlinewallParent; madeWall.GetComponent <Renderer>().receiveShadows = false; } } GameObject.Destroy(wallParent.gameObject); return(outlinewallParent.gameObject); }