Browse Source

Added Y rotation to buildings

James Peret 2 years ago
parent
commit
44c5a44643
3 changed files with 100 additions and 25 deletions
  1. 13 7
      Runtime/BuildingBlueprintController.cs
  2. 3 1
      Runtime/VoxelBuildData.cs
  3. 84 17
      Runtime/VoxelBuildingSystem.cs

+ 13 - 7
Runtime/BuildingBlueprintController.cs

@@ -32,10 +32,14 @@ namespace KairoEngine.VoxelBuildingSystem
 
         private void LateUpdate() {
             if(currentBlueprint == null) return;
-            Vector3 targetPosition = buildingSystem.GetMouseWorldSnappedPosition();
-            //targetPosition.y = 1f;
+            var template = buildingSystem.buildingTemplates[buildingSystem.currentBuildingTemplate];
+            Vector3Int targetPosition = buildingSystem.GetMouseVoxelPosition();
+            Vector3Int dir = buildingSystem.rotationList[buildingSystem.currentRotationIndex];
+            Quaternion rotation = Quaternion.Euler(dir.x, dir.y, dir.z);
             currentBlueprint.transform.position = Vector3.Lerp(currentBlueprint.transform.position, targetPosition, Time.deltaTime * 15f);
-            currentBlueprint.transform.rotation = Quaternion.Lerp(transform.rotation, buildingSystem.transform.rotation, Time.deltaTime * 15f);
+            currentBlueprint.transform.rotation = Quaternion.Lerp(currentBlueprint.transform.rotation, rotation, Time.deltaTime * 15f);
+            //currentBlueprint.transform.localEulerAngles = Vector3.Lerp(transform.localEulerAngles, dir, Time.deltaTime * 15f);
+            //currentBlueprint.transform.localEulerAngles = dir;
             if(buildingSystem.tool == VoxelBuildingTool.Build) currentBlueprint.gameObject.SetActive(true);
             else currentBlueprint.gameObject.SetActive(false);
             CanBuild();
@@ -48,10 +52,11 @@ namespace KairoEngine.VoxelBuildingSystem
             }
             BuildingTemplate buildingTemplate = buildingSystem.buildingTemplates[buildingSystem.currentBuildingTemplate];
             if (buildingTemplate != null) {
-                currentBlueprint = Instantiate(buildingTemplate.visual, Vector3.zero, Quaternion.identity);
+                Vector3 targetPosition = buildingSystem.GetMouseWorldSnappedPosition();
+                currentBlueprint = Instantiate(buildingTemplate.visual, targetPosition, Quaternion.identity);
                 currentBlueprint.parent = transform;
-                currentBlueprint.localPosition = Vector3.zero;
-                currentBlueprint.localEulerAngles = Vector3.zero;
+                // currentBlueprint.localPosition = Vector3.zero;
+                // currentBlueprint.localEulerAngles = Vector3.zero;
             }
         }
 
@@ -62,10 +67,11 @@ namespace KairoEngine.VoxelBuildingSystem
         {
             Vector3Int pos = buildingSystem.GetMouseVoxelPosition();
             int templateIndex = buildingSystem.currentBuildingTemplate;
+            int rotationIndex = buildingSystem.currentRotationIndex;
             if(lastPosition != pos || lastTemplateIndex != templateIndex)
             {
                 //Debug.Log("Position changed, updating blueprint materials");
-                canBuild = buildingSystem.CanPlaceBuilding(pos, templateIndex);
+                canBuild = buildingSystem.CanPlaceBuilding(pos, templateIndex, rotationIndex);
                 lastPosition = pos;
                 lastTemplateIndex = templateIndex;
                 ChangeMaterials();

+ 3 - 1
Runtime/VoxelBuildData.cs

@@ -9,12 +9,14 @@ namespace KairoEngine.VoxelBuildingSystem
         public Vector3Int pos;
         public int buildingIndex;
         public int buildingTemplateIndex;
+        public int rotationIndex;
 
-        public VoxelBuildData(Vector3Int pos, int buildingIndex = -1, int buildingTemplateIndex = -1)
+        public VoxelBuildData(Vector3Int pos, int buildingIndex = -1, int buildingTemplateIndex = -1, int rotationIndex = 0)
         {
             this.pos = pos;
             this.buildingIndex = buildingIndex;
             this.buildingTemplateIndex = buildingTemplateIndex;
+            this.rotationIndex = rotationIndex;
         }
     }
 }

+ 84 - 17
Runtime/VoxelBuildingSystem.cs

@@ -18,7 +18,13 @@ namespace KairoEngine.VoxelBuildingSystem
         public Vector3 voxelSize = new Vector3(1f, 1f, 1f);
         public LayerMask layerMask;
         public List<BuildingTemplate> buildingTemplates = new List<BuildingTemplate>();
+
+        public bool debugBlocks = false;
+        public GameObject blockVisualPrefab;
+        public Transform blockContainer;
+
         [ReadOnly] public int currentBuildingTemplate;
+        [ReadOnly] public int currentRotationIndex;
 
         [ReadOnly] public VoxelBuildingTool tool = VoxelBuildingTool.Build;
         public ChunkSystem<VoxelBuildData> chunkSystem;
@@ -30,6 +36,7 @@ namespace KairoEngine.VoxelBuildingSystem
 
         public void CreateVoxelSystem()
         {
+            SetupRotationList();
             chunkSystem = new ChunkSystem<VoxelBuildData>(chunkSize, false);
             for (int x = 0; x < chunkCount.x; x++) {
                 for (int z = 0; z < chunkCount.z; z++) {
@@ -64,14 +71,20 @@ namespace KairoEngine.VoxelBuildingSystem
             if(Input.GetKeyDown(KeyCode.Alpha1)) CycleBuildingTemplate();
         }
 
-        public void RotateBuilding() {}
+        public void RotateBuilding() 
+        {
+            if(currentRotationIndex < rotationList.Count - 1) currentRotationIndex += 1;
+            else currentRotationIndex = 0;
+        }
         
         public void PlaceBuilding(Vector3 pos) 
         {
-            Vector3 worldPos = GetMouseWorldSnappedPosition();
-            Vector3Int voxelPos = FindVoxelPosition(pointerPosition);
-            if(!CanPlaceBuilding(voxelPos, currentBuildingTemplate, true)) return;
-            Transform newBuilding = Instantiate(buildingTemplates[currentBuildingTemplate].prefab, worldPos, this.transform.rotation, this.transform);
+            Vector3Int buildingPos = GetMouseBuildingPosition();
+            Vector3Int voxelPos = GetMouseVoxelPosition();
+            Vector3Int buildingRotation = rotationList[currentRotationIndex];
+            if(!CanPlaceBuilding(voxelPos, currentBuildingTemplate, currentRotationIndex, true)) return;
+            Quaternion rotation = Quaternion.Euler(buildingRotation.x, buildingRotation.y, buildingRotation.z);
+            Transform newBuilding = Instantiate(buildingTemplates[currentBuildingTemplate].prefab, voxelPos, rotation, this.transform);
             BuildingBehaviour buildingBehaviour = newBuilding.GetComponent<BuildingBehaviour>();
             if(buildingBehaviour == null)
             {
@@ -82,19 +95,20 @@ namespace KairoEngine.VoxelBuildingSystem
             buildingBehaviour.origin = voxelPos;
             buildings.Add(voxelPos, buildingBehaviour);
             buildingList.Add(buildingBehaviour);
-            List<Vector3Int> voxelPositions = GetBuildingVoxelList(voxelPos, currentBuildingTemplate);
+            List<Vector3Int> voxelPositions = GetBuildingVoxelList(voxelPos, currentBuildingTemplate, currentRotationIndex);
             for (int i = 0; i < voxelPositions.Count; i++)
             {
                 VoxelBuildData block = chunkSystem.GetBlock(voxelPositions[i]);
                 block.buildingIndex = buildingList.Count - 1;
                 block.buildingTemplateIndex = currentBuildingTemplate;
                 chunkSystem.SetBlock(voxelPositions[i], block);
+                if(debugBlocks) Instantiate(blockVisualPrefab, voxelPositions[i], new Quaternion(), blockContainer);
             }
         } 
 
-        public bool CanPlaceBuilding(Vector3Int voxelPos, int buildingTemplateIndex, bool debug = false)
+        public bool CanPlaceBuilding(Vector3Int voxelPos, int buildingTemplateIndex, int buildingRotationIndex = 0, bool debug = false)
         {
-            List<Vector3Int> voxelPositions = GetBuildingVoxelList(voxelPos, buildingTemplateIndex);
+            List<Vector3Int> voxelPositions = GetBuildingVoxelList(voxelPos, buildingTemplateIndex, buildingRotationIndex);
             for (int i = 0; i < voxelPositions.Count; i++)
             {
                 VoxelBuildData block = chunkSystem.GetBlock(voxelPositions[i]);
@@ -117,6 +131,13 @@ namespace KairoEngine.VoxelBuildingSystem
         public Vector3 GetMouseWorldSnappedPosition() => (Vector3)FindVoxelPosition(pointerPosition);
         public Vector3Int GetMouseVoxelPosition() => FindVoxelPosition(pointerPosition);
 
+        public Vector3Int GetMouseBuildingPosition()
+        {
+            Vector3Int voxelPos = FindVoxelPosition(pointerPosition);
+            Vector3Int rotationOffset = GetRotationOffset(currentRotationIndex, buildingTemplates[currentBuildingTemplate].size);
+            return voxelPos + rotationOffset;
+        }
+
         public void CycleBuildingTemplate()
         {
             if(currentBuildingTemplate < buildingTemplates.Count - 1) currentBuildingTemplate += 1;
@@ -125,25 +146,71 @@ namespace KairoEngine.VoxelBuildingSystem
             //Debug.Log($"Changing current building template to {currentBuildingTemplate}");
         }
 
-        public List<Vector3Int> GetBuildingVoxelList(Vector3Int offset, int buildingTemplateId) 
+        public List<Vector3Int> GetBuildingVoxelList(Vector3Int offset, int buildingTemplateId, int buildingRotationIndex = 0) 
         { 
             BuildingTemplate template = buildingTemplates[buildingTemplateId];
             List<Vector3Int> positionList = new List<Vector3Int>();
-            for(int x = 0; x < template.size.x; x++)
+            Vector3Int rotationOffset = GetRotationOffset(buildingRotationIndex, template.size);
+            switch (buildingRotationIndex)
             {
-                for (int y = 0; y < template.size.y; y++)
-                {
-                    for (int z = 0; z < template.size.z; z++)
+                default:
+                case 0:
+                case 2:
+                    for(int x = 0; x < template.size.x; x++)
                     {
-                        Vector3Int pos = new Vector3Int(offset.x + x, offset.y + y, offset.z + z);
-                        positionList.Add(pos);
-                        //Debug.Log(pos);
+                        for (int y = 0; y < template.size.y; y++)
+                        {
+                            for (int z = 0; z < template.size.z; z++)
+                            {
+                                Vector3Int pos = new Vector3Int(offset.x + rotationOffset.x + x, offset.y + rotationOffset.y + y, offset.z + rotationOffset.z + z);
+                                positionList.Add(pos);
+                            }
+                        }
                     }
-                }
+                    break;
+                case 1:
+                case 3:
+                    for(int x = 0; x < template.size.z; x++)
+                    {
+                        for (int y = 0; y < template.size.y; y++)
+                        {
+                            for (int z = 0; z < template.size.x; z++)
+                            {
+                                Vector3Int pos = new Vector3Int(offset.x + rotationOffset.x + x, offset.y + rotationOffset.y + y, offset.z + rotationOffset.z + z);
+                                positionList.Add(pos);
+                            }
+                        }
+                    }
+                    break;
             }
+            
             //Debug.Log($"{positionList.Count} voxel positions found for building \"{buildingTemplates[buildingTemplateId].title}\"");
             return positionList;
         }
+
+        public List<Vector3Int> rotationList = new List<Vector3Int>();
+        private void SetupRotationList()
+        {
+            rotationList = new List<Vector3Int>
+            {
+                new Vector3Int(0, 0, 0),
+                new Vector3Int(0, 90, 0),
+                new Vector3Int(0, 180, 0),
+                new Vector3Int(0, 270, 0)
+            };
+        }
+
+        public Vector3Int GetRotationOffset(int rotationIndex, Vector3Int size) 
+        { 
+            switch (rotationIndex)
+            {
+                default:
+                case 0:  return new Vector3Int(0, 0, 0);
+                case 1:  return new Vector3Int(0, 0, -size.x);
+                case 2:  return new Vector3Int(-size.x, 0, -size.z);
+                case 3:  return new Vector3Int(-size.z, 0, 0);
+            }
+        }
         
     }