using System.Collections; using System.Collections.Generic; using UnityEngine; using KairoEngine.Core; using Sirenix.OdinInspector; namespace KairoEngine.VoxelBuildingSystem { [HideMonoScript] public class BuildingBlueprintController : MonoBehaviour { public VoxelBuildingSystem buildingSystem; public Transform currentBlueprint; [BoxGroup("Materials")] public Material blueprintMain; [BoxGroup("Materials")] public Material blueprintDetail; [BoxGroup("Materials")] public Material invalidMain; [BoxGroup("Materials")] public Material invalidDetail; private void Start() { RefreshVisual(); GenericEvents.StartListening("OnBuildingTemplateChanged", OnBuildingTemplateChanged); } private void OnDisable() { GenericEvents.StopListening("OnBuildingTemplateChanged", OnBuildingTemplateChanged); } private void OnBuildingTemplateChanged() { RefreshVisual(); } private void LateUpdate() { if(currentBlueprint == null) return; var template = buildingSystem.buildingTemplates[buildingSystem.currentBuildingTemplate]; Vector3Int targetPosition = buildingSystem.GetMouseBuildingPosition(); 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(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(); } private void RefreshVisual() { Quaternion currentRotation = currentBlueprint.transform.rotation; Vector3 currentPosition = currentBlueprint.transform.position; if (currentBlueprint != null) { Destroy(currentBlueprint.gameObject); currentBlueprint = null; } BuildingTemplate buildingTemplate = buildingSystem.buildingTemplates[buildingSystem.currentBuildingTemplate]; if (buildingTemplate != null) { Vector3 targetPosition = buildingSystem.GetMouseWorldSnappedPosition(); currentBlueprint = Instantiate(buildingTemplate.visual, currentPosition, currentRotation); currentBlueprint.parent = transform; // currentBlueprint.localPosition = Vector3.zero; // currentBlueprint.localEulerAngles = Vector3.zero; } } private bool canBuild; private Vector3Int lastPosition; private int lastTemplateIndex; private int lastRotationIndex; private void CanBuild() { Vector3Int pos = buildingSystem.GetMouseBuildingPosition(); int templateIndex = buildingSystem.currentBuildingTemplate; int rotationIndex = buildingSystem.currentRotationIndex; if(lastPosition != pos || lastTemplateIndex != templateIndex || lastRotationIndex != rotationIndex) { //Debug.Log("Position changed, updating blueprint materials"); canBuild = buildingSystem.CanPlaceBuilding(pos, templateIndex, rotationIndex); lastPosition = pos; lastTemplateIndex = templateIndex; lastRotationIndex = rotationIndex; ChangeMaterials(); } } private void ChangeMaterials() { MeshRenderer[] renderers = currentBlueprint.GetComponentsInChildren(false); //Debug.Log($"Changing materials in {renderers.Length} renderers"); for (int i = 0; i < renderers.Length; i++) { Material[] materials = renderers[i].materials; //Debug.Log($"Found {renderers[i].materials.Length} materials in render {i}"); for (int a = 0; a < materials.Length; a++) { if(materials[a].name.Contains("Main")) { if(canBuild) materials[a] = blueprintMain; else materials[a] = invalidMain; } else if(materials[a].name.Contains("Detail")) { if(canBuild) materials[a] = blueprintDetail; else materials[a] = invalidDetail; } } renderers[i].materials = materials; } } } }