protected ModifyArea(ModifyArea copyThis) : this() { assetPath = copyThis.assetPath; isSphere = copyThis.isSphere; pos = (float[])copyThis.pos.Clone(); rot = (float[])copyThis.rot.Clone(); scale = (float[])copyThis.scale.Clone(); }
/** * @brief Block 정보를 변경한다. * 1. CustomObject와 청크 충돌 검사 * 2. 충돌된 청크를 대상으로 Modify 정보 구성 함수 호출 * 3. 구성된 정보를 바탕으로 Block 정보를 변경할 함수 호출 ** CustomObject는 Layer가 CustomBlock인 오브젝트로 Prefab/CustomArea 내에 위치해야 한다. */ void ModifyChunk(Transform tf, ModifyArea areaInfo) { if (tf == null) { return; } VoxelPlanet planet = tf.GetComponent <VoxelPlanet>(); int layerMask = (1 << LayerMask.NameToLayer("CustomBlock")); for (int i = 0; i < tf.childCount; i++) { //Custom Area에 포함된 청크 체크를 위해 청크 범위 정보를 구성 Chunk chunk = tf.GetChild(i).GetComponent <Chunk>(); //int chunkSize = chunk.chunkSize; float radius = chunk.chunkSize * 0.5f; Vector3 halfExtent = new Vector3(radius, radius, radius); //(tf.position+ chunk.pos) : world 좌표 //world좌표 + halfExtent : chunk의 pos 정보는 -x,-y,-z 위치이기 때문에 center로 맞춰준다. Vector3 center = tf.position + chunk.pos + halfExtent; Quaternion checkQuat = Quaternion.identity; //Sphere화 된 경우 if (chunk.isSphere) { var prevCenter = center; //center 정보를 Sphere 좌표로 변환 float len = Mathf.Max(Mathf.Abs(center.x), Mathf.Abs(center.y), Mathf.Abs(center.z)); center = center.normalized * len; //chunk의 회전 정보 checkQuat = Quaternion.FromToRotation(prevCenter, center); } //Area에 포함된 Chunk 검사 var colList = Physics.OverlapBox(center, halfExtent, checkQuat, layerMask); if (colList.Length == 0) { continue; } // area 정보 구성 string objPath = AssetDatabase.GetAssetPath(PrefabUtility.GetCorrespondingObjectFromSource(colList[0])); planet.SetModifyArea(chunk.pos, areaInfo, colList[0], objPath); //Block 정보 수정 planet.UpdateModifyBlockArea(chunk, false); } SaveCurrentPlanetInfo(tf.parent.gameObject); Debug.Log("Finish Modify"); }
/** * @function ModifyArea(변경 정보) * @brief 지정된 영역의 블럭 정보를 변경한다. */ public void ModifyArea(ModifyArea areaInfo) { var voxelPlanet = VoxelPlanetInfo.GetVoxelPlanet(); if (voxelPlanet == null) { return; } ModifyChunk(voxelPlanet.transform.Find("Terrain"), areaInfo); ModifyChunk(voxelPlanet.transform.Find("Clouds"), areaInfo); }
/** * @brief CustomArea 정보 구성 */ private void ModifyAreaPropertie() { //Modify Area GUILayout.Label("[Modify Area Properties]", EditorStyles.boldLabel); fillmode = (ModifyFillMode)EditorGUILayout.EnumPopup("Modify Mode:", fillmode); ModifyArea area = null; //채우기 모드일 경우 if (fillmode == ModifyFillMode.FILL) { fillArea.blockType = (FillArea.BlockType)EditorGUILayout.EnumPopup("BlockType:", fillArea.blockType); area = fillArea; } //Noise 모드 일 경우 else { GUILayout.Space(2); GUILayout.Label("[Area Block Rate]", EditorStyles.miniBoldLabel); noiseArea.blockRate = EditorGUILayout.Slider("BlockRate", noiseArea.blockRate, 0.1f, 1f); noiseArea.desertRate = EditorGUILayout.Slider("DesertRate", noiseArea.desertRate, 0.0f, 1f); noiseArea.grassRate = EditorGUILayout.Slider("GrassRate", noiseArea.grassRate, 0.0f, 1f); noiseArea.cloudRate = EditorGUILayout.Slider("Cloud", noiseArea.cloudRate, 0.0f, 1f); GUILayout.Space(2); GUILayout.Label("[Area Noise Paramiter]", EditorStyles.miniBoldLabel); noiseArea.octave = EditorGUILayout.IntSlider("Octave", noiseArea.octave, 1, 7); noiseArea.frequency = EditorGUILayout.Slider("Frequency", noiseArea.frequency, 0.005f, 0.1f); noiseArea.persistence = EditorGUILayout.Slider("Persistence", noiseArea.persistence, 0.05f, 0.3f); area = noiseArea; } //Modify 함수 호출 if (GUILayout.Button("Modity Block Area")) { genPlanet.ModifyArea(area); } DrawUILine(Color.gray); }
/** * @brief 변경될 청크와 변경 정보 및 CustomObject 정보를 구성 * @param pos : 변경될 ChunkPos, area : AreaInfo, collidder : AreaCollider, path : prefab path */ public void SetModifyArea(Vector3Int pos, ModifyArea area, Collider collider, string path) { //충돌 에리어 정보구성 area.assetPath = "Prefabs/CustomArea/" + Path.GetFileNameWithoutExtension(path); area.isSphere = planetInfo.isSphere; area.SetTransformInfo(collider.transform); planetInfo.modifyAreaObject[area.assetPath] = collider.gameObject; if (planetInfo.modifyList == null) { planetInfo.modifyList = new Dictionary <WorldPos, List <ModifyArea> >(); } //Modify 정보 추가 WorldPos position = (WorldPos)pos; if (!planetInfo.modifyList.ContainsKey(position)) { planetInfo.modifyList[position] = new List <ModifyArea>(); } planetInfo.modifyList[position].Add(area.DeepCopy()); }
public void ModifyArea() { int count = uow.ModifyAreas.GetAll().AsQueryable<ModifyArea>().Count<ModifyArea>(); #region Add ModifyArea newEntity = new ModifyArea() { EastDimensionsNew = "EastDimensionsNew", EastDimensionsOld = "EastDimensionsOld", NewFMolArea = 1, NewGMolArea = 1, NewQArea = 1, NorthDimensionsNew = "NorthDimensionsNew", NorthDimensionsOld = "NorthDimensionsOld", OldFMolArea = 1, OldGMolArea = 1, OldQArea = 1, RequestID = (long)LookUps.LookUpsValues["RequestID"], SouthDimensionsNew = "SouthDimensionsNew", SouthDimensionsOld = "SouthDimensionsOld", WestDimensionsNew = "WestDimensionsNew", WestDimensionsOld = "WestDimensionsOld" }; uow.ModifyAreas.Add<ModifyArea, long>(newEntity); uow.ModifyAreas.Commit(); var result = uow.ModifyAreas.GetAll().AsQueryable<ModifyArea>(); Assert.AreEqual(count + 1, result.Count<ModifyArea>(), "Adding Error"); #endregion #region Update ModifyArea entity = uow.ModifyAreas.GetById(newEntity.ID); entity.EastDimensionsNew = "EastDimensionsNew2"; entity.EastDimensionsOld = "EastDimensionsOld2"; entity.NewFMolArea = 2; entity.NewGMolArea = 2; entity.NewQArea = 2; entity.NorthDimensionsNew = "NorthDimensionsNew2"; entity.NorthDimensionsOld = "NorthDimensionsOld2"; entity.OldFMolArea = 2; entity.OldGMolArea = 2; entity.OldQArea = 2; entity.SouthDimensionsNew = "SouthDimensionsNew2"; entity.SouthDimensionsOld = "SouthDimensionsOld2"; entity.WestDimensionsNew = "WestDimensionsNew2"; entity.WestDimensionsOld = "WestDimensionsOld2"; uow.ModifyAreas.Update(entity); uow.ModifyAreas.Commit(); ModifyArea entity2 = uow.ModifyAreas.GetById(newEntity.ID); Assert.AreEqual("EastDimensionsNew2", entity2.EastDimensionsNew, "Updating Error"); Assert.AreEqual("EastDimensionsOld2", entity2.EastDimensionsOld, "Updating Error"); Assert.AreEqual(2, entity2.NewFMolArea, "Updating Error"); Assert.AreEqual(2, entity2.NewGMolArea, "Updating Error"); Assert.AreEqual(2, entity2.NewQArea, "Updating Error"); Assert.AreEqual("NorthDimensionsNew2", entity2.NorthDimensionsNew, "Updating Error"); Assert.AreEqual("NorthDimensionsOld2", entity2.NorthDimensionsOld, "Updating Error"); Assert.AreEqual(2, entity2.OldFMolArea, "Updating Error"); Assert.AreEqual(2, entity2.OldGMolArea, "Updating Error"); Assert.AreEqual(2, entity2.OldQArea, "Updating Error"); Assert.AreEqual("SouthDimensionsNew2", entity2.SouthDimensionsNew, "Updating Error"); Assert.AreEqual("SouthDimensionsOld2", entity2.SouthDimensionsOld, "Updating Error"); Assert.AreEqual("WestDimensionsNew2", entity2.WestDimensionsNew, "Updating Error"); Assert.AreEqual("WestDimensionsOld2", entity2.WestDimensionsOld, "Updating Error"); #endregion #region Delete ModifyArea entityDeleted = uow.ModifyAreas.GetById(newEntity.ID); uow.ModifyAreas.Delete(entity2); uow.ModifyAreas.Commit(); Assert.AreEqual(count, uow.ModifyAreas.GetAll().AsQueryable<ModifyArea>().Count<ModifyArea>(), "Deleting Error"); #endregion }
/** * @brief 변경정보를 참조해 해당 chunk의 block 정보를 변경 * @param chunk : 변경될 Chunk, areaList : 변경 정보, isBuildPlanet : Planet 생성 중인가? */ private void ModifyBlock(Chunk chunk, List <ModifyArea> areaList, bool isBuildPlanet) { if (areaList == null) { return; } ModifyArea area = null; for (int i = 0; i < areaList.Count; i++) { area = areaList[i]; if (!area.isUpdate && !isBuildPlanet) { continue; } area.isUpdate = false; //변경 영역 구성 오브젝트 후 활성화 GameObject areaObj = planetInfo.modifyAreaObject[area.assetPath]; if (areaObj == null) { areaObj = Instantiate(Resources.Load(area.assetPath), Vector3.zero, Quaternion.Euler(Vector3.zero)) as GameObject; } areaObj.transform.position = area.GetPosition(); areaObj.transform.localScale = area.GetScale(); areaObj.transform.rotation = area.GetRotation(); areaObj.SetActive(true); var chunkSize = chunk.chunkSize; Vector3 blockHalfExtent = Vector3.one * 0.5f; int layerMask = (1 << LayerMask.NameToLayer("CustomBlock")); for (int x = 0; x < chunkSize; x++) { for (int y = 0; y < chunkSize; y++) { for (int z = 0; z < chunkSize; z++) { //변경 가능한 블럭인지 체크 var block = chunk.GetBlock(x, y, z); if (block.isLock) { continue; } //블럭의 위치 정보구성(worldPos + block의 center) Vector3 blockCenter = transform.position + chunk.pos + new Vector3(x, y, z) + blockHalfExtent; //구형에서 수정된 정보면 구형 좌표에 맞춰 center 좌표 변경 if (area.isSphere) { float len = Mathf.Max(Mathf.Abs(blockCenter.x), Mathf.Abs(blockCenter.y), Mathf.Abs(blockCenter.z)); blockCenter = blockCenter.normalized * len; } //변환 영역에 포함된 블럭인지 체크 if (!Physics.CheckBox(blockCenter, blockHalfExtent, Quaternion.identity, layerMask)) { continue; } //block정보 재구성 Block newBlock = area.BuildBlock(new Vector3Int(chunk.pos.x + x, chunk.pos.y + y, chunk.pos.z + z)); //재구성 block이 waterBlock인 경우 공기 블럭인 경우만 변경 가능 if (newBlock.GetType() == typeof(BlockWater) && block.IsSolid() != -1) { continue; } chunk.SetBlock(x, y, z, newBlock); } } } //행성 생성중이면 area obj 제거 if (isBuildPlanet) { DestroyImmediate(areaObj); } } }