using System; using System.Collections; using System.Collections.Generic; using sc.modeling.splines.runtime; using UnityEngine; using UnityEngine.Splines; namespace Gameplay.LegionBattle.View { public class FightLineControl : MonoBehaviour { public GameObject m_groundView; public GameObject m_unitView; public GameObject m_areaParent; public GameObject m_unitsParent; public GameObject m_linesParentt; public GameObject m_boardQuadLeft; public GameObject m_boardQuadRight; public Camera m_mainCamera; private FightLineMap _baseMap; private List _team1StandUnits; private List _team2StandUnits; public const int MAP_X_COUNT = 40; public const int MAP_Y_COUNT = 40; private void Awake() { _baseMap = new FightLineMap(MAP_X_COUNT, MAP_Y_COUNT); _baseMap.FillStartWeights(); _baseMap.CreateViewMap(m_groundView, m_areaParent.transform); _baseMap.UpdateColors(); _team1StandUnits = new List(); for (int i = 0; i < 20; i++) { var unit = new FightLineStandUnit(); unit.side = -1; unit.standPos = new Vector2Int(0, 10 + i); unit.CreateView(m_unitView, m_unitsParent.transform); _team1StandUnits.Add(unit); } _team1StandUnits[0].isMainUnit = true; _team2StandUnits = new List(); for (int i = 0; i < 20; i++) { var unit = new FightLineStandUnit(); unit.side = 1; unit.standPos = new Vector2Int(39, 10 + i); unit.CreateView(m_unitView, m_unitsParent.transform); _team2StandUnits.Add(unit); } _team2StandUnits[0].isMainUnit = true; } private Vector3 _GetClickWorldPoint(Vector2 mousePos) { var ray = m_mainCamera.ScreenPointToRay(mousePos); Physics.Raycast(ray, out RaycastHit hit); var worldPos = hit.point; return worldPos; } public static Vector2Int GetGridPosFromWorld(Vector3 worldPos) { worldPos.x += 0.5f; worldPos.y += 0.5f; // 获取点击的格子 var x = Mathf.FloorToInt(worldPos.x); var y = Mathf.FloorToInt(worldPos.y); return new Vector2Int(x, y); } public static Vector3 GetWorldPosFromGrid(Vector2Int gridPos) { var worldPos = new Vector3(gridPos.x, gridPos.y, 0); return worldPos; } private FightLineStandUnit _selectUnit; private void _HandleInput() { if (Input.GetMouseButtonDown(0)) { var hitWorldPos = _GetClickWorldPoint(Input.mousePosition); var hitGridPos = GetGridPosFromWorld(hitWorldPos); if (_selectUnit == null) { _selectUnit = _SelectUnit(hitGridPos); if (_selectUnit != null) { Debug.Log("选中单位"); } else { Debug.Log("未选中单位 at " + hitGridPos); } return; } if (_selectUnit != null) { // 移动 var newWorldPos = GetWorldPosFromGrid(hitGridPos); _selectUnit.MoveTo(newWorldPos); _selectUnit = null; Debug.Log("移动单位"); } } } private void OnEnable() { _baseMap.UpdateLineBoard(); } private void Update() { _HandleInput(); var isStandChanged = false; for (int i = 0; i < _team1StandUnits.Count; i++) { var unit = _team1StandUnits[i]; unit.LogicUpdate(Time.deltaTime); isStandChanged = isStandChanged || unit.isStandChanged; unit.isStandChanged = false; } for (int i = 0; i < _team2StandUnits.Count; i++) { var unit = _team2StandUnits[i]; unit.LogicUpdate(Time.deltaTime); isStandChanged = isStandChanged || unit.isStandChanged; unit.isStandChanged = false; } if (isStandChanged) { _UpdateStandMap(); // _baseMap.ReverseTuDian(); _baseMap.UpdateAreas(); _baseMap.ReverseAloneArea(); _baseMap.UpdateColors(); _baseMap.leftArea.CalcBoarder(); _baseMap.leftArea.CreateBoardView(m_boardQuadLeft, m_linesParentt.transform); _baseMap.rightArea.CalcBoarder(); _baseMap.rightArea.CreateBoardView(m_boardQuadRight, m_linesParentt.transform); } } private List _leftCellList = new List(); private List _leftCellList2 = new List(); private List _rightCellList = new List(); private List _rightCellList2 = new List(); private void _UpdateStandMap() { _baseMap.ForEachCell(cell => { cell.iteration = 0; cell.isVisited = false; }); _leftCellList.Clear(); _leftCellList2.Clear(); _rightCellList.Clear(); _rightCellList2.Clear(); for (int i = 0; i < _team1StandUnits.Count; i++) { var unit = _team1StandUnits[i]; var cell = _baseMap.GetCellByGridPos(unit.standPos); if (cell == null) continue; if (cell.standValue != unit.side) { continue; } cell.iteration = unit.maxDistance; _leftCellList.Add(cell); cell.isVisited = true; if (unit.isMainUnit) { cell.isMainCell = true; } } for (int i = 0; i < _team2StandUnits.Count; i++) { var unit = _team2StandUnits[i]; var cell = _baseMap.GetCellByGridPos(unit.standPos); if (cell == null) continue; if (cell.standValue != unit.side) { continue; } cell.iteration = unit.maxDistance; _rightCellList.Add(cell); cell.isVisited = true; if (unit.isMainUnit) { cell.isMainCell = true; } } // 向外扩张 while (_leftCellList.Count > 0 || _rightCellList.Count > 0) { for (int i = 0; i < _leftCellList.Count; i++) { var cell = _leftCellList[i]; cell.standValue = -1; if (cell.iteration > 0) { var aroundCellList = cell.neighbors; for (int j = 0; j < aroundCellList.Count; j++) { var aroundCell = aroundCellList[j]; if (aroundCell.isVisited) continue; aroundCell.iteration = Mathf.Max(cell.iteration - 1, aroundCell.iteration); aroundCell.isVisited = true; _leftCellList2.Add(aroundCell); } } } _leftCellList.Clear(); _leftCellList.AddRange(_leftCellList2); _leftCellList2.Clear(); for (int i = 0; i < _rightCellList.Count; i++) { var cell = _rightCellList[i]; cell.standValue = 1; if (cell.iteration > 0) { var aroundCellList = cell.neighbors; for (int j = 0; j < aroundCellList.Count; j++) { var aroundCell = aroundCellList[j]; if (aroundCell.isVisited) continue; aroundCell.isVisited = true; aroundCell.iteration = Mathf.Max(cell.iteration - 1, aroundCell.iteration); _rightCellList2.Add(aroundCell); } } } _rightCellList.Clear(); _rightCellList.AddRange(_rightCellList2); _rightCellList2.Clear(); } } private FightLineStandUnit _SelectUnit(Vector2Int gridPos) { for (int i = 0; i < _team1StandUnits.Count; i++) { var unit = _team1StandUnits[i]; if (unit.standPos == gridPos) { return unit; } } for (int i = 0; i < _team2StandUnits.Count; i++) { var unit = _team2StandUnits[i]; if (unit.standPos == gridPos) { return unit; } } return null; } } }