using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class MapBuildPlacer : MonoBehaviour { [HideInInspector] public HomeMapSO SO_HomeMap; // 地图SO数据 [HideInInspector] public GameObject startPositionObject; // 坐标起始点 [HideInInspector] public int cellSize = 2; // 单元格大小 [HideInInspector] public Camera mainCamera; [Tooltip("可建造格子的图层")] public LayerMask buildableCellLayer; private Color spriteRenderColor; private SpriteRenderer spriteRenderChildren; private MapBuildableCell adsorb_component; private bool is_trigger_with_has_build = false; private SpriteRenderer stopUI_sprite_render; private bool isSnaping = false; private void Start() { spriteRenderChildren = transform.GetChild(0).GetComponent(); spriteRenderColor = spriteRenderChildren.color; stopUI_sprite_render = spriteRenderChildren.transform.Find("StopUI").GetComponent(); } private void Update() { // m_move_with_mouse_with_overlay(); m_move_with_mouse_with_ray(); } // 跟随鼠标移动使用射线检测 private void m_move_with_mouse_with_ray() { // 获取鼠标的世界坐标 Vector3 mouse_world_position = mainCamera.ScreenToWorldPoint(Input.mousePosition); mouse_world_position.z = 0; // 射线检测 RaycastHit2D hit = Physics2D.Raycast( origin: mouse_world_position, direction: Vector2.zero, distance: 0.1f, layerMask: buildableCellLayer); // 命中格子 if (hit.collider) { // 吸附到格子坐标 adsorb_component = hit.collider.GetComponent(); Vector3 adsorb_position = startPositionObject.transform.position + adsorb_component.get_grid_position_with_vector3() * cellSize; transform.position = adsorb_position; isSnaping = true; // 判断是否与以建造的建筑物触发器接触 if (is_trigger_with_has_build == false) { // 更改颜色并取消激活边框 spriteRenderChildren.color = spriteRenderColor; stopUI_sprite_render.enabled = false; } } else { // 鼠标不在格子上时触发, 还原默认状态 if (adsorb_component) { stopUI_sprite_render.enabled = true; adsorb_component = null; } isSnaping = false; // 没有命中格子, 自由移动 transform.position = mouse_world_position; // 更改颜色并激活边框 spriteRenderChildren.color = new Color32(166, 73, 73, 215); } } public bool get_placer_is_snap() => isSnaping; // trigger private void m_on_trigger_event(Collider2D other, bool status) { // 检测是否与某个图层的碰撞器相交 if (other.gameObject.layer == LayerMask.NameToLayer("AlreadyBuild")) { is_trigger_with_has_build = status; } } private void OnTriggerStay2D(Collider2D other) { m_on_trigger_event(other, true); } private void OnTriggerEnter2D(Collider2D other) { m_on_trigger_event(other, true); } private void OnTriggerExit2D(Collider2D other) { m_on_trigger_event(other, false); } // 跟随鼠标移动使用overlay方法 private void m_move_with_mouse_with_overlay() { // 跟随鼠标移动 Vector3 mouse_world_position = mainCamera.ScreenToWorldPoint(Input.mousePosition); mouse_world_position.z = 0; // 碰撞器射线检测 Collider2D hit = Physics2D.OverlapPoint(mouse_world_position, LayerMask.GetMask("BuildableCell")); if (hit) { MapBuildableCell adsorb_component = hit.GetComponent(); if (adsorb_component) { // 鼠标在格子上时触发, 吸附到格子的坐标上 transform.position = startPositionObject.transform.position + adsorb_component.get_grid_position_with_vector3() * cellSize; } } else { // 没有检测到格子, 自由移动 transform.position = mouse_world_position; } } }