303 lines
11 KiB
C#
303 lines
11 KiB
C#
using System.Collections.Generic;
|
|
using Gameplay.Common;
|
|
using Gameplay.Performance;
|
|
using Gameplay.Unit;
|
|
|
|
namespace Gameplay.Area
|
|
{
|
|
using Framework;
|
|
using Effect;
|
|
using Level;
|
|
using Skill;
|
|
using UnityEngine;
|
|
|
|
public class SkillAreaSelecter
|
|
{
|
|
|
|
public bool isOnSelecting;
|
|
|
|
public GameUnit unit;
|
|
public SkillHandle skillHandle;
|
|
|
|
private int _areaId;
|
|
private int _lastPlayerCellIndex;
|
|
|
|
private readonly RaycastHit[] _raycastHits;
|
|
|
|
private readonly List<int> _cacheCellIndexList;
|
|
private int _lastCenterCellIndex;
|
|
|
|
private List<int> _totalCellIndexList;
|
|
|
|
private Color _bgAreaColor;
|
|
private readonly Color _selectColor;
|
|
// private Color _selectCenterColorY;
|
|
// private Color _selectCenterColorN;
|
|
|
|
private readonly Color _hintColor;
|
|
private readonly Color _hintColor2;
|
|
private TGS.Territory _cacheTerritory;
|
|
private GameObject _cacheObjBoarder;
|
|
|
|
private bool _isCenterCellValid;
|
|
private AreaChecker _checker;
|
|
|
|
private EffectPlayingData _skillAreaEffect;
|
|
private static readonly int Color1 = Shader.PropertyToID("_Color");
|
|
private static readonly int SecondColor = Shader.PropertyToID("_SecondColor");
|
|
|
|
public SkillAreaSelecter()
|
|
{
|
|
_checker = new AreaChecker();
|
|
_raycastHits = new RaycastHit[10];
|
|
_cacheCellIndexList = new List<int>();
|
|
_totalCellIndexList = new List<int>();
|
|
|
|
_hintColor = ColorUtility.TryParseHtmlString("#C1C336", out Color color) ? color : Color.red;
|
|
_selectColor = ColorUtility.TryParseHtmlString("#FF9600", out Color color1) ? color1 : Color.red;
|
|
_selectColor.a = 0.45f;
|
|
_hintColor2 = ColorUtility.TryParseHtmlString("#c26b36", out Color color2) ? color2 : Color.red;
|
|
_hintColor2.a = 0;
|
|
}
|
|
|
|
public void Init()
|
|
{
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_skillAreaEffect != null)
|
|
{
|
|
_skillAreaEffect.Destroy();
|
|
_skillAreaEffect = null;
|
|
}
|
|
}
|
|
|
|
public void ShowArea(SkillHandle inSkillHandle)
|
|
{
|
|
if (isOnSelecting)
|
|
{
|
|
DebugUtil.LogError("错误的调用: 已经在技能预选中");
|
|
return;
|
|
}
|
|
_isCenterCellValid = false;
|
|
isOnSelecting = true;
|
|
skillHandle = inSkillHandle;
|
|
unit = inSkillHandle.owner;
|
|
_areaId = inSkillHandle.runtimeData.configData.ShowAreaId;
|
|
_lastCenterCellIndex = -1;
|
|
_cacheCellIndexList.Clear();
|
|
|
|
// 初始化checker
|
|
_checker.InitFromCharacterSkill(inSkillHandle);
|
|
|
|
var map = LevelManager.Instance.CurrentLevel.Map;
|
|
var playerCellIndex = unit.transData.cellIndex;
|
|
_lastPlayerCellIndex = playerCellIndex;
|
|
var seletRange = Mathf.CeilToInt(skillHandle.runtimeData.configData.ReleaseArea * skillHandle.owner.fightData.skillReleaseDistanceScale);
|
|
_totalCellIndexList = map.TerrainGridSystem.CellGetNeighboursWithinRange(playerCellIndex, -1, seletRange, canCrossCheckType: TGS.CanCrossCheckType.IgnoreCanCrossCheckOnAllCells);
|
|
_totalCellIndexList.Add(playerCellIndex);
|
|
|
|
_bgAreaColor = new Color(1, 1, 1, 0.5f);
|
|
// _selectCenterColorY = Color.green;
|
|
// _selectCenterColorN = Color.red;
|
|
|
|
map.SetBlocksColor(_totalCellIndexList, true, _bgAreaColor);
|
|
|
|
if (inSkillHandle.runtimeData.configData.ShowEffectId > 0)
|
|
{
|
|
var pos = unit.transData.pos;
|
|
_skillAreaEffect = EffectManager.instance.PlayEffectById(inSkillHandle.runtimeData.configData.ShowEffectId, pos);
|
|
}
|
|
|
|
// 生成技能边框区域
|
|
_cacheTerritory = map.TerrainGridSystem.TerritoryCreate(_totalCellIndexList);
|
|
var obj = map.TerrainGridSystem.ForceDrawTerritoryDrawInteriorBorder(_cacheTerritory, 0, 1, _hintColor, _hintColor2);
|
|
var getMat = obj.transform.GetChild(0).GetComponent<MeshRenderer>().material;
|
|
getMat.SetColor(Color1, _hintColor);
|
|
getMat.SetColor(SecondColor, _hintColor2);
|
|
_cacheObjBoarder = obj;
|
|
}
|
|
|
|
private void _HideAreaBoarderObj()
|
|
{
|
|
var map = LevelManager.Instance.CurrentLevel.Map;
|
|
var territoryIndex = map.TerrainGridSystem.TerritoryGetIndex(_cacheTerritory);
|
|
map.TerrainGridSystem.TerritoryDestroy(territoryIndex);
|
|
_cacheObjBoarder.Destroy();
|
|
}
|
|
|
|
public void EndShow(bool realUse)
|
|
{
|
|
if (!isOnSelecting)
|
|
{
|
|
DebugUtil.LogError("错误的调用: 不在技能预选状态");
|
|
return;
|
|
}
|
|
if (!skillHandle.canRelease)
|
|
{
|
|
DebugUtil.LogError("技能CD没好,强制取消释放");
|
|
realUse = false;
|
|
}
|
|
_HideAreaBoarderObj();
|
|
var map = LevelManager.Instance.CurrentLevel.Map;
|
|
|
|
if (_skillAreaEffect != null)
|
|
{
|
|
_skillAreaEffect.Destroy();
|
|
_skillAreaEffect = null;
|
|
}
|
|
|
|
isOnSelecting = false;
|
|
|
|
map.SetBlocksColor(_cacheCellIndexList, false, _bgAreaColor);
|
|
map.SetBlocksColor(_totalCellIndexList, false, _bgAreaColor);
|
|
|
|
if (realUse)
|
|
{
|
|
if (!_isCenterCellValid)
|
|
{
|
|
UITipsManager.ShowTips("技能释放点不合法");
|
|
EventManager.Instance.Send(EventManager.EventName.UI_SKILL_CANCEL);
|
|
return;
|
|
}
|
|
// 从lastCellIndex进行释放
|
|
var eventData = new EventDataUseSkill()
|
|
{
|
|
sender = unit,
|
|
pointCellIndex = _lastCenterCellIndex,
|
|
};
|
|
EventManager.Instance.Send(EventManager.EventName.UI_USE_SKILL, eventData);
|
|
}
|
|
else
|
|
{
|
|
EventManager.Instance.Send(EventManager.EventName.UI_SKILL_CANCEL);
|
|
}
|
|
}
|
|
|
|
public void LogicUpdate(float dt)
|
|
{
|
|
if (!isOnSelecting)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
var mousePos = Input.mousePosition * PerformanceManager.instance.screenScale;
|
|
// mousePos = Input.mousePosition;
|
|
var camera = Camera.main;
|
|
if (camera == null) return;
|
|
var map = LevelManager.Instance.CurrentLevel.Map;
|
|
|
|
var playerNowCellIndex = unit.transData.cellIndex;
|
|
if (playerNowCellIndex != _lastPlayerCellIndex)
|
|
{
|
|
// Debug.LogError("playerNowCellIndex != _lastCenterCellIndex");
|
|
_lastPlayerCellIndex = playerNowCellIndex;
|
|
|
|
// 清除之前的
|
|
_HideAreaBoarderObj();
|
|
map.SetBlocksColor(_cacheCellIndexList, false, _bgAreaColor);
|
|
map.SetBlocksColor(_totalCellIndexList, false, _bgAreaColor);
|
|
_cacheCellIndexList.Clear();
|
|
|
|
// 更新技能影响区域
|
|
var seletRange = Mathf.CeilToInt(skillHandle.runtimeData.configData.ReleaseArea * skillHandle.owner.fightData.skillReleaseDistanceScale);
|
|
_totalCellIndexList = map.TerrainGridSystem.CellGetNeighboursWithinRange(playerNowCellIndex, -1, seletRange, canCrossCheckType: TGS.CanCrossCheckType.IgnoreCanCrossCheckOnAllCells);
|
|
_totalCellIndexList.Add(playerNowCellIndex);
|
|
_cacheTerritory = map.TerrainGridSystem.TerritoryCreate(_totalCellIndexList);
|
|
var obj = map.TerrainGridSystem.ForceDrawTerritoryDrawInteriorBorder(_cacheTerritory, 0, 1, _hintColor, _hintColor2);
|
|
var getMat = obj.transform.GetChild(0).GetComponent<MeshRenderer>().material;
|
|
getMat.SetColor(Color1, _hintColor);
|
|
getMat.SetColor(SecondColor, _hintColor2);
|
|
_cacheObjBoarder = obj;
|
|
|
|
_lastCenterCellIndex = -1;
|
|
}
|
|
|
|
var ray = camera.ScreenPointToRay(mousePos);
|
|
var layerMask = LayerMask.GetMask("Ground");
|
|
var raycast = Physics.RaycastNonAlloc(ray, _raycastHits, 1000, layerMask);
|
|
if (raycast <= 0) return;
|
|
var firstHit = _raycastHits[0];
|
|
var hitPoint = firstHit.point;
|
|
if (!map.WorldPosition2TGSCellIndex(hitPoint, out var cellIndex)) return;
|
|
var mouseCellIndex = cellIndex;
|
|
var skillConfig = skillHandle.runtimeData.configData;
|
|
if (!_totalCellIndexList.Contains(cellIndex))
|
|
{
|
|
// 计算出最近的点并进行设置
|
|
var minDistance = float.MaxValue;
|
|
var newCellIndex = cellIndex;
|
|
for (var i = 0; i < _totalCellIndexList.Count; ++i)
|
|
{
|
|
var bgIndex = _totalCellIndexList[i];
|
|
var distance = map.TerrainGridSystem.CellGetHexagonDistance(cellIndex, bgIndex);
|
|
if (distance < minDistance)
|
|
{
|
|
minDistance = distance;
|
|
newCellIndex = bgIndex;
|
|
}
|
|
}
|
|
cellIndex = newCellIndex;
|
|
}
|
|
// if (skillConfig.SkillActionId == 2)
|
|
// {
|
|
// // 2号技能不需要中心点
|
|
// cellIndex = unit.transData.cellIndex;
|
|
// }
|
|
|
|
if (cellIndex != _lastCenterCellIndex)
|
|
{
|
|
// Debug.LogError("cellIndex != _lastCenterCellIndex");
|
|
if (_lastCenterCellIndex != -1)
|
|
{
|
|
// 将之前的变回
|
|
for (var i = 0; i < _cacheCellIndexList.Count; ++i)
|
|
{
|
|
var index = _cacheCellIndexList[i];
|
|
var isInBg = _totalCellIndexList.Contains(index);
|
|
map.SetBlockColor(index, isInBg, _bgAreaColor);
|
|
}
|
|
_cacheCellIndexList.Clear();
|
|
}
|
|
|
|
_lastCenterCellIndex = cellIndex;
|
|
|
|
// 更新技能影响区域
|
|
|
|
AreaManager.instance.GetCellIndexs(cellIndex, _areaId, _cacheCellIndexList);
|
|
map.SetBlocksColor(_cacheCellIndexList, true, _selectColor);
|
|
|
|
|
|
// map.SetBlockColor(cellIndex, true, _isCenterCellValid ? _selectCenterColorY : _selectCenterColorN);
|
|
|
|
var centerWorldPos = map.TGSCellIndex2WorldPosition(cellIndex);
|
|
if (_skillAreaEffect != null)
|
|
{
|
|
_skillAreaEffect.transform.position = centerWorldPos;
|
|
}
|
|
}
|
|
|
|
// 中心点单独设置
|
|
_isCenterCellValid = _CheckCenterAvilable(cellIndex);
|
|
|
|
if (_isCenterCellValid && skillConfig.ReleaseArea != 0)
|
|
{
|
|
// 需要处理鼠标是否在技能影响区域内
|
|
var isInArea = _cacheCellIndexList.Contains(mouseCellIndex);
|
|
if (!isInArea)
|
|
{
|
|
_isCenterCellValid = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool _CheckCenterAvilable(int centerCellIndex)
|
|
{
|
|
return _checker.CheckAvailable(centerCellIndex);
|
|
}
|
|
|
|
}
|
|
}
|