NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Gameplay/Area/SkillAreaSelecter.cs

371 lines
14 KiB
C#
Raw Normal View History

2023-08-22 19:08:45 +08:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
2023-10-31 13:05:30 +08:00
using cfg.SkillCfg;
2023-10-19 15:00:19 +08:00
using Gameplay.Common;
2023-08-22 19:08:45 +08:00
namespace Gameplay.Area
{
using Framework;
2023-10-19 15:00:19 +08:00
using Character;
using Effect;
using Level;
using Skill;
2023-08-22 19:08:45 +08:00
using TMPro;
using UnityEngine;
public class SkillAreaSelecter
{
public bool isOnSelecting;
2023-10-19 15:00:19 +08:00
public GameUnit unit;
2023-08-22 19:08:45 +08:00
public SkillHandle skillHandle;
private int _areaId;
2023-10-31 14:16:34 +08:00
private int _lastPlayerCellIndex;
2023-08-22 19:08:45 +08:00
2023-10-19 15:00:19 +08:00
private readonly RaycastHit[] _raycastHits;
2023-08-22 19:08:45 +08:00
2023-10-19 15:00:19 +08:00
private readonly List<int> _cacheCellIndexList;
2023-08-22 19:08:45 +08:00
private int _lastCenterCellIndex;
private List<int> _totalCellIndexList;
private Color _bgAreaColor;
2023-10-19 15:00:19 +08:00
private readonly Color _selectColor;
// private Color _selectCenterColorY;
// private Color _selectCenterColorN;
2023-08-22 19:08:45 +08:00
2023-10-19 15:00:19 +08:00
private readonly Color _hintColor;
private readonly Color _hintColor2;
2023-08-22 19:08:45 +08:00
private TGS.Territory _cacheTerritory;
2023-10-19 15:00:19 +08:00
private GameObject _cacheObjBoarder;
2023-08-22 19:08:45 +08:00
private bool _isCenterCellValid;
private EffectPlayingData _skillAreaEffect;
2023-10-19 15:00:19 +08:00
private static readonly int Color1 = Shader.PropertyToID("_Color");
private static readonly int SecondColor = Shader.PropertyToID("_SecondColor");
2023-08-22 19:08:45 +08:00
public SkillAreaSelecter()
{
_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;
}
}
2023-10-19 15:00:19 +08:00
public void ShowArea(SkillHandle inSkillHandle)
2023-08-22 19:08:45 +08:00
{
if (isOnSelecting)
{
DebugUtil.LogError("错误的调用: 已经在技能预选中");
return;
}
_isCenterCellValid = false;
isOnSelecting = true;
2023-10-19 15:00:19 +08:00
skillHandle = inSkillHandle;
unit = inSkillHandle.owner;
_areaId = inSkillHandle.runtimeData.configData.ShowAreaId;
2023-08-22 19:08:45 +08:00
_lastCenterCellIndex = -1;
_cacheCellIndexList.Clear();
var map = LevelManager.Instance.CurrentLevel.Map;
2023-10-19 15:00:19 +08:00
var playerCellIndex = unit.transData.cellIndex;
2023-10-31 14:16:34 +08:00
_lastPlayerCellIndex = playerCellIndex;
2023-11-06 16:50:41 +08:00
var seletRange = Mathf.CeilToInt(skillHandle.runtimeData.configData.ReleaseArea * skillHandle.owner.fightData.skillReleaseDistanceScale);
2023-08-22 19:08:45 +08:00
_totalCellIndexList = map.TerrainGridSystem.CellGetNeighboursWithinRange(playerCellIndex, -1, seletRange, canCrossCheckType: TGS.CanCrossCheckType.IgnoreCanCrossCheckOnAllCells);
_totalCellIndexList.Add(playerCellIndex);
_bgAreaColor = new Color(1, 1, 1, 0.5f);
2023-10-19 15:00:19 +08:00
// _selectCenterColorY = Color.green;
// _selectCenterColorN = Color.red;
2023-08-22 19:08:45 +08:00
map.SetBlocksColor(_totalCellIndexList, true, _bgAreaColor);
2023-10-19 15:00:19 +08:00
if (inSkillHandle.runtimeData.configData.ShowEffectId > 0)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
var pos = unit.transData.pos;
_skillAreaEffect = EffectManager.instance.PlayEffectById(inSkillHandle.runtimeData.configData.ShowEffectId, pos);
2023-08-22 19:08:45 +08:00
}
// 生成技能边框区域
_cacheTerritory = map.TerrainGridSystem.TerritoryCreate(_totalCellIndexList);
var obj = map.TerrainGridSystem.ForceDrawTerritoryDrawInteriorBorder(_cacheTerritory, 0, 1, _hintColor, _hintColor2);
var getMat = obj.transform.GetChild(0).GetComponent<MeshRenderer>().material;
2023-10-19 15:00:19 +08:00
getMat.SetColor(Color1, _hintColor);
getMat.SetColor(SecondColor, _hintColor2);
_cacheObjBoarder = obj;
2023-08-22 19:08:45 +08:00
}
2023-10-31 14:16:34 +08:00
private void _HideAreaBoarderObj()
2023-08-22 19:08:45 +08:00
{
var map = LevelManager.Instance.CurrentLevel.Map;
var territoryIndex = map.TerrainGridSystem.TerritoryGetIndex(_cacheTerritory);
map.TerrainGridSystem.TerritoryDestroy(territoryIndex);
2023-10-19 15:00:19 +08:00
_cacheObjBoarder.Destroy();
2023-08-22 19:08:45 +08:00
}
public void EndShow(bool realUse)
{
if (!isOnSelecting)
{
DebugUtil.LogError("错误的调用: 不在技能预选状态");
return;
}
if (!skillHandle.canRelease)
{
DebugUtil.LogError("技能CD没好,强制取消释放");
realUse = false;
}
2023-10-31 14:16:34 +08:00
_HideAreaBoarderObj();
2023-08-22 19:08:45 +08:00
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 && _isCenterCellValid)
{
// 从lastCellIndex进行释放
var eventData = new EventDataUseSkill()
{
2023-10-19 15:00:19 +08:00
sender = unit,
2023-08-22 19:08:45 +08:00
pointCellIndex = _lastCenterCellIndex,
};
EventManager.Instance.Send(EventManager.EventName.UI_USE_SKILL, eventData);
}
}
public void LogicUpdate(float dt)
{
if (!isOnSelecting)
{
return;
}
2023-10-31 14:16:34 +08:00
2023-08-22 19:08:45 +08:00
var mousePos = InputManager.Instance.GetTouchPosition();
var camera = Camera.main;
2023-10-19 15:00:19 +08:00
if (camera == null) return;
2023-10-31 14:16:34 +08:00
var map = LevelManager.Instance.CurrentLevel.Map;
var playerNowCellIndex = unit.transData.cellIndex;
if (playerNowCellIndex != _lastCenterCellIndex)
{
_lastPlayerCellIndex = playerNowCellIndex;
// 清除之前的
_HideAreaBoarderObj();
map.SetBlocksColor(_cacheCellIndexList, false, _bgAreaColor);
map.SetBlocksColor(_totalCellIndexList, false, _bgAreaColor);
_cacheCellIndexList.Clear();
// 更新技能影响区域
2023-11-06 16:50:41 +08:00
var seletRange = Mathf.CeilToInt(skillHandle.runtimeData.configData.ReleaseArea * skillHandle.owner.fightData.skillReleaseDistanceScale);
2023-10-31 14:16:34 +08:00
_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;
}
2023-08-22 19:08:45 +08:00
var ray = camera.ScreenPointToRay(mousePos);
var layerMask = LayerMask.GetMask("Ground");
var raycast = Physics.RaycastNonAlloc(ray, _raycastHits, 1000, layerMask);
2023-10-19 15:00:19 +08:00
if (raycast <= 0) return;
var firstHit = _raycastHits[0];
var hitPoint = firstHit.point;
if (!map.WorldPosition2TGSCellIndex(hitPoint, out var cellIndex)) return;
var skillConfig = skillHandle.runtimeData.configData;
if (!_totalCellIndexList.Contains(cellIndex))
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
// 计算出最近的点并进行设置
var minDistance = float.MaxValue;
var newCellIndex = cellIndex;
for (var i = 0; i < _totalCellIndexList.Count; ++i)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
var bgIndex = _totalCellIndexList[i];
var distance = map.TerrainGridSystem.CellGetHexagonDistance(cellIndex, bgIndex);
if (distance < minDistance)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
minDistance = distance;
newCellIndex = bgIndex;
2023-08-22 19:08:45 +08:00
}
2023-10-19 15:00:19 +08:00
}
cellIndex = newCellIndex;
}
2023-10-31 13:05:30 +08:00
// if (skillConfig.SkillActionId == 2)
// {
// // 2号技能不需要中心点
// cellIndex = unit.transData.cellIndex;
// }
2023-08-22 19:08:45 +08:00
2023-10-19 15:00:19 +08:00
if (cellIndex != _lastCenterCellIndex)
{
if (_lastCenterCellIndex != -1)
{
// 将之前的变回
for (var i = 0; i < _cacheCellIndexList.Count; ++i)
2023-08-22 19:08:45 +08:00
{
2023-10-19 15:00:19 +08:00
var index = _cacheCellIndexList[i];
var isInBg = _totalCellIndexList.Contains(index);
map.SetBlockColor(index, isInBg, _bgAreaColor);
}
_cacheCellIndexList.Clear();
}
2023-08-22 19:08:45 +08:00
2023-10-19 15:00:19 +08:00
_lastCenterCellIndex = cellIndex;
2023-08-22 19:08:45 +08:00
2023-10-19 15:00:19 +08:00
// 更新技能影响区域
2023-08-22 19:08:45 +08:00
2023-10-19 15:00:19 +08:00
AreaManager.instance.GetCellIndexs(cellIndex, _areaId, _cacheCellIndexList);
map.SetBlocksColor(_cacheCellIndexList, true, _selectColor);
2023-08-22 19:08:45 +08:00
2023-10-19 15:00:19 +08:00
// map.SetBlockColor(cellIndex, true, _isCenterCellValid ? _selectCenterColorY : _selectCenterColorN);
var centerWorldPos = map.TGSCellIndex2WorldPosition(cellIndex);
if (_skillAreaEffect != null)
{
_skillAreaEffect.transform.position = centerWorldPos;
2023-08-22 19:08:45 +08:00
}
}
2023-10-19 15:00:19 +08:00
// 中心点单独设置
_isCenterCellValid = _CheckCenterAvilable(cellIndex);
2023-08-22 19:08:45 +08:00
}
private bool _CheckCenterAvilable(int centerCellIndex)
2023-10-19 15:00:19 +08:00
{
var skillConfig = skillHandle.runtimeData.configData;
2023-10-31 13:05:30 +08:00
switch (skillConfig.ReleaseCheckType)
2023-10-19 15:00:19 +08:00
{
// 常规
2023-10-31 13:05:30 +08:00
case EReleaseCheckType.None:
return true;
case EReleaseCheckType.CenterIsEnemy:
return _CheckCenterIsEnemy(centerCellIndex);
case EReleaseCheckType.CenterIsSelfSide:
return _CheckCenterIsSelfSide(centerCellIndex);
case EReleaseCheckType.CenterIsEmpty:
return _CheckCenterIsEmpty(centerCellIndex);
case EReleaseCheckType.AreaContainsEnemy:
return _CheckAreaContainsEnemy(centerCellIndex);
2023-10-31 13:50:11 +08:00
case EReleaseCheckType.AreaContainsSelfSide:
return _CheckAreaContainsSelfSide(centerCellIndex);
2023-10-19 15:00:19 +08:00
default:
2023-10-31 13:05:30 +08:00
DebugUtil.LogError("暂未处理的检查类型:{0}", skillConfig.ReleaseCheckType);
2023-10-19 15:00:19 +08:00
return false;
}
}
2023-10-31 13:50:11 +08:00
private bool _CheckAreaContainsSelfSide(int centerCellIndex)
{
var influenceAreaId = skillHandle.runtimeData.configData.InfluenceAreaId;
var areaIndexs = AreaManager.instance.GetCellIndexs(centerCellIndex, influenceAreaId);
// 查找所有友军
for (var i = 0; i < areaIndexs.Count; ++i)
{
var searchCellIndex = areaIndexs[i];
var isSelf = _CheckCenterIsSelfSide(searchCellIndex);
if (isSelf) return true;
}
return false;
}
2023-10-31 13:05:30 +08:00
private bool _CheckAreaContainsEnemy(int centerCellIndex)
{
2023-10-31 13:28:54 +08:00
var influenceAreaId = skillHandle.runtimeData.configData.InfluenceAreaId;
var areaIndexs = AreaManager.instance.GetCellIndexs(centerCellIndex, influenceAreaId);
2023-10-31 13:05:30 +08:00
// 查找所有敌人
for (var i = 0; i < areaIndexs.Count; ++i)
{
var searchCellIndex = areaIndexs[i];
2023-10-31 13:28:54 +08:00
var isEnemy = _CheckCenterIsEnemy(searchCellIndex);
2023-10-31 13:05:30 +08:00
if (isEnemy) return true;
}
return false;
}
private bool _CheckCenterIsEmpty(int centerCellIndex)
{
var units = AreaManager.instance.GetUnitsByCellIndex(centerCellIndex);
var isEmpty = units.Count == 0;
return isEmpty;
}
private bool _CheckCenterIsSelfSide(int centerCellIndex)
{
var units = AreaManager.instance.GetUnitsByCellIndex(centerCellIndex);
var senderTroopId = unit.commonData.troopId;
var isSelf = false;
for (var i = 0; i < units.Count; ++i)
{
var u = units[i];
if (u.gameunitType != EGameUnitType.Character) continue;
if (u.commonData.troopId == senderTroopId)
{
isSelf = true;
break;
}
}
return isSelf;
}
private bool _CheckCenterIsEnemy(int centerCellIndex)
{
var units = AreaManager.instance.GetUnitsByCellIndex(centerCellIndex);
var senderTroopId = unit.commonData.troopId;
var isEnemy = false;
for (var i = 0; i < units.Count; ++i)
{
var u = units[i];
if (u.gameunitType != EGameUnitType.Character) continue;
if (u.commonData.troopId != senderTroopId)
{
isEnemy = true;
break;
}
}
return isEnemy;
}
2023-08-22 19:08:45 +08:00
}
}