【战斗】修改block规则为动态

main
刘涛 2024-09-09 19:22:22 +08:00
parent 861105f9c5
commit a3812ca5f1
29 changed files with 392 additions and 41 deletions

View File

@ -570,6 +570,19 @@ MonoBehaviour:
FilterRuleName: CollectAll
AssetTags:
UserData:
- GroupName: Build
GroupDesc: "\u6218\u6597\u7528\u5EFA\u7B51"
AssetTags:
ActiveRuleName: EnableGroup
Collectors:
- CollectPath: Assets/Art/Character/Prefabs/Build
CollectorGUID: a853d9c29fa592f468f2f735492c5a5b
CollectorType: 0
AddressRuleName: AddressByFileName
PackRuleName: PackDirectory
FilterRuleName: CollectPrefab
AssetTags:
UserData:
- PackageName: RawPackage
PackageDesc:
EnableAddressable: 0

View File

@ -317,6 +317,7 @@ namespace Gameplay.Area
{
return result;
}
DebugUtil.LogError("无法获取到CellIndex:" + pos);
return -1;
}
@ -444,6 +445,7 @@ namespace Gameplay.Area
}
_attackArea.LogicUpdate(dt);
readyAreaManager.LogicUpdate(dt);
attackAreaManager.LogicUpdate(dt);
}
public List<GameUnit> GetUnitsByCellIndex(int cellIndex)

View File

@ -36,10 +36,27 @@ namespace Gameplay.Area.AttackArea
}
else
{
var isBlocked = _CheckIsBlocked(cellIndex, checkCellIndex);
if (isBlocked)
var hitCellIndex = _CheckIsBlocked(cellIndex, checkCellIndex);
if (hitCellIndex > -1)
{
blockedCells.Add(checkCellIndex);
if (hitCellIndex == checkCellIndex
&& AreaManager.instance.attackAreaManager.tempBlockAttackCellMap.TryGetValue(hitCellIndex, out var tempBlockData))
{
// 有临时阻挡
if (tempBlockData.canBeAttack)
{
canAttackCells.Add(checkCellIndex);
}
else
{
blockedCells.Add(checkCellIndex);
}
}
else
{
blockedCells.Add(checkCellIndex);
}
}
else
{
@ -52,7 +69,7 @@ namespace Gameplay.Area.AttackArea
}
}
private static bool _CheckIsBlocked(int startCellIndex,
private static int _CheckIsBlocked(int startCellIndex,
int endCellIndex)
{
var startPos = AreaManager.instance.GetCellPosByIndex(startCellIndex);
@ -65,9 +82,13 @@ namespace Gameplay.Area.AttackArea
distance, layerMask);
if (hitCount > 0)
{
return true;
var hit = AreaManager.instance.attackAreaManager.raycastHits[0];
var hitObj = hit.collider.gameObject;
var pos = hitObj.transform.position;
var hitCellIndex = AreaManager.instance.GetCellIndexByPos(pos);
return hitCellIndex;
}
return false;
return -1;
}
}

View File

@ -15,7 +15,17 @@ namespace Gameplay.Area.AttackArea
public int hitMask;
public GameObject rootObj;
private Dictionary<int, TempBlockData> _tempBlockAttackCellMap = new Dictionary<int, TempBlockData>();
public Dictionary<int, TempBlockData> tempBlockAttackCellMap
{
get
{
return _tempBlockAttackCellMap;
}
}
private bool _isMapChanged;
public AttackAreaManager()
{
@ -37,7 +47,53 @@ namespace Gameplay.Area.AttackArea
instanceObj.transform.position = worldPos;
}
}
Physics.Simulate(0.16f);
_isMapChanged = true;
}
public void LogicUpdate(float dt)
{
if (_isMapChanged)
{
_isMapChanged = false;
Physics.Simulate(dt);
// 清空攻击区域
foreach (var attackAreaPoint in _attackAreaPointMap.Values)
{
attackAreaPoint.attackAreaMap.Clear();
}
}
}
public TempBlockData CreateBlockAttackCell(int cellIndex)
{
if (_tempBlockAttackCellMap.ContainsKey(cellIndex))
{
DebugUtil.LogError("已经存在的阻挡攻击的格子:{0}", cellIndex);
return null;
}
var worldPos = AreaManager.instance.GetCellPosByIndex(cellIndex);
var sampleObj = AssetManager.Instance.GetPreLoadResult<GameObject>(Constants.FIGHT_CELL_COLLIDER_PATH);
var instanceObj = Object.Instantiate(sampleObj, rootObj.transform);
instanceObj.transform.position = worldPos;
var tempData = new TempBlockData(cellIndex, instanceObj);
_tempBlockAttackCellMap.Add(cellIndex, tempData);
_isMapChanged = true;
return tempData;
}
public void RemoveBlockAttackCell(int cellIndex)
{
if (_tempBlockAttackCellMap.TryGetValue(cellIndex, out var searchObj))
{
Object.Destroy(searchObj.blockObj);
_tempBlockAttackCellMap.Remove(cellIndex);
_isMapChanged = true;
}
else
{
DebugUtil.LogError("不存在的阻挡攻击的格子:{0}", cellIndex);
}
}
public AttackAreaData GetAttackArea(int centerCellIndex,

View File

@ -0,0 +1,17 @@
using UnityEngine;
namespace Gameplay.Area.AttackArea
{
public class TempBlockData
{
public int blockCellIndex;
public GameObject blockObj;
public bool canBeAttack;
public TempBlockData(int blockCellIndex, GameObject blockObj)
{
this.blockCellIndex = blockCellIndex;
this.blockObj = blockObj;
canBeAttack = false;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3e8df1446b4249e58f27e1b9db7c5f49
timeCreated: 1725880193

View File

@ -166,7 +166,7 @@ namespace Gameplay.Buff
EventManager.Instance.Send(EventManager.EventName.INFIGHT_BUFF_ADDICON, this);
}
if (owner.debugShowInfo.cacheConfigId != 0 && configData.BuffEffectType == EBuffEffectType.PositiveBuff)
if (owner.debugShowInfo != null && owner.debugShowInfo.cacheConfigId != 0 && configData.BuffEffectType == EBuffEffectType.PositiveBuff)
{
EventManager.Instance.Send(EventManager.EventName.INFIGHT_AUDIO_GET_P_BUFF, owner.debugShowInfo.cacheConfigId);
}

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using Gameplay.Building;
using Gameplay.Fight.Protect;
using Gameplay.Pool;
using Gameplay.Summon;
@ -141,6 +142,7 @@ namespace Gameplay.Buff
case EGameUnitType.Vehicle:
case EGameUnitType.Summon:
case EGameUnitType.BeProtect:
case EGameUnitType.Building:
if (_unitDict.TryGetValue(unit, out var unitManager))
{
unitManager.AddBuff(buff);
@ -156,6 +158,21 @@ namespace Gameplay.Buff
}
}
public void InitBuild(UnitBuild build)
{
if (_unitDict.ContainsKey(build))
{
DebugUtil.LogError("FATA ERROR: 不应该出现两个相同的build");
return;
}
var unitManager = new UnitBuffManager(build);
_unitDict.Add(build, unitManager);
_unitList.Add(unitManager);
// 双向绑定
build.buffManager = unitManager;
}
public void InitVehicle(NormalVehicle vehicle)
{
if (_unitDict.ContainsKey(vehicle))

View File

@ -0,0 +1,24 @@
using cfg.FightCfg;
using Framework;
namespace Gameplay.Building.Data
{
public class BuildConfigData
{
public DataBuild rawConfig;
public EFightBuildType buildType;
public BuildConfigData(int buildId)
{
rawConfig = TableManager.Instance.Tables.BuildConfig.GetOrDefault(buildId);
if (rawConfig == null)
{
DebugUtil.LogError("BuildConfigData: rawConfig is null, buildId: " + buildId);
return;
}
buildType = (EFightBuildType)rawConfig.BuildType;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 68dd4e1380df417d9d428448dd7560f2
timeCreated: 1725875709

View File

@ -0,0 +1,13 @@
namespace Gameplay.Building.Data
{
public static class BuildDataHelper
{
public static BuildConfigData CombineConfigData(int buildId)
{
var buildConfig = new BuildConfigData(buildId);
return buildConfig;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b610f1e07a7e4224bb2abfcc7ba92ce4
timeCreated: 1725875685

View File

@ -0,0 +1,11 @@
namespace Gameplay.Building.Impl
{
public class BuildMine : UnitBuild
{
public BuildMine(uint id,
int troopId) : base(id, troopId)
{
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b8a77609318e4dadafef63e6df699acf
timeCreated: 1725876500

View File

@ -0,0 +1,11 @@
namespace Gameplay.Building.Impl
{
public class BuildPillBox : UnitBuild
{
public BuildPillBox(uint id,
int troopId) : base(id, troopId)
{
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 22d2afcd30184fd2ad497890a6c1c8fe
timeCreated: 1725876432

View File

@ -0,0 +1,11 @@
namespace Gameplay.Building.Impl
{
public class BuildTrap : UnitBuild
{
public BuildTrap(uint id,
int troopId) : base(id, troopId)
{
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8e93034a0705478ba9015f6d0a928b4a
timeCreated: 1725876482

View File

@ -0,0 +1,11 @@
namespace Gameplay.Building.Impl
{
public class BuildWall : UnitBuild
{
public BuildWall(uint id,
int troopId) : base(id, troopId)
{
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0bb2ee4909f5434dbffbc039f0e53efb
timeCreated: 1725876464

View File

@ -1,12 +1,10 @@
using Gameplay.Building.Data;
namespace Gameplay.Building.Impl
namespace Gameplay.Building.Impl
{
public class BuildWatchTower : UnitBuild
{
public BuildWatchTower(uint id, int troopId) : base(id, troopId)
{
buildType = EFightBuildType.WatchTower;
}
}

View File

@ -1,17 +1,94 @@
using Gameplay.Building.Data;
using Cysharp.Threading.Tasks;
using Gameplay.Area;
using Gameplay.Buff;
using Gameplay.Building.Data;
using Gameplay.Character;
using Gameplay.Performance;
using Gameplay.Unit;
using Gameplay.Unit.Data;
using PhxhSDK;
using UnityEngine;
namespace Gameplay.Building
{
public abstract class UnitBuild : GameUnit
{
public EFightBuildType buildType { get; protected set; } = EFightBuildType.None;
public EFightBuildType buildType { get; private set; } = EFightBuildType.None;
public BuildConfigData configData { get; private set; }
public UnitBuild(uint id,
int troopId) : base(id, troopId, EGameUnitType.Building)
{
}
public void InitConfig(BuildConfigData setConfig)
{
configData = setConfig;
buildType = configData.buildType;
statusData.canBeAttack = configData.rawConfig.Hp > 0;
if (statusData.canBeAttack)
{
aliveData.maxHp = configData.rawConfig.Hp;
aliveData.currentHp = aliveData.maxHp;
}
commonData.standLevel = configData.rawConfig.StandCrossLevel;
}
public async UniTask CreateAsync()
{
var modelPath = configData.rawConfig.ModelPath;
GameUnitManager.instance.RecordLoadPath(modelPath);
var sampleObj = await AssetManager.Instance.LoadAssetAsync<GameObject>(modelPath);
if (sampleObj == null)
{
DebugUtil.LogError("加载建筑失败: {0}", modelPath);
return;
}
// 父节点已销毁
if (Node == null) return;
// 创建对象
var parent = Node.GameObject.transform;
var go = Object.Instantiate(sampleObj, parent, true);
go.transform.ResetLocals();
Node.GameObject.SetLayerEx(Node.GameObject.layer);
// 设置后处理
var obj = Node.GameObject;
var isEnemy = commonData.troopId != ETroopsId.Self;
OutlineManager.instance.AutoAddFromObj(obj, isEnemy);
PerformanceManager.instance.HandleCreateUnit(obj);
}
protected override void _OnEnterBattle()
{
base._OnEnterBattle();
isReady = true;
BuffManager.instance.InitBuild(this);
buffManager.TriggerEnterBattle();
if (configData.rawConfig.BlockAttack)
{
var blockData = AreaManager.instance.attackAreaManager.CreateBlockAttackCell(transData.cellIndex);
blockData.canBeAttack = statusData.canBeAttack;
}
}
protected override void _OnExitBattle()
{
base._OnExitBattle();
isReady = false;
buffManager?.TriggerExitBattle();
if (configData.rawConfig.BlockAttack)
{
AreaManager.instance.attackAreaManager.RemoveBlockAttackCell(transData.cellIndex);
}
}
}
}

View File

@ -5,11 +5,27 @@ namespace Gameplay.Building
public static class UnitBuildFactory
{
public static UnitBuild CreateBuild(EFightBuildType buildType, uint uId, int troopId)
public static UnitBuild CreateBuild(BuildConfigData configData, uint uId, int troopId)
{
UnitBuild unitBuild = null;
switch (buildType)
switch (configData.buildType)
{
case EFightBuildType.Wall:
var wall = new BuildWall(uId, troopId);
unitBuild = wall;
break;
case EFightBuildType.Trap:
var trap = new BuildTrap(uId, troopId);
unitBuild = trap;
break;
case EFightBuildType.Pillbox:
var pillBox = new BuildPillBox(uId, troopId);
unitBuild = pillBox;
break;
case EFightBuildType.Mine:
var mine = new BuildMine(uId, troopId);
unitBuild = mine;
break;
case EFightBuildType.WatchTower:
var watchTower = new BuildWatchTower(uId, troopId);
unitBuild = watchTower;
@ -17,10 +33,11 @@ namespace Gameplay.Building
}
if (unitBuild != null)
{
unitBuild.InitConfig(configData);
}
else
{
DebugUtil.LogError("暂未实现的建筑类型:" + buildType);
DebugUtil.LogError("暂未实现的建筑类型:" + configData.buildType);
}
return unitBuild;
}

View File

@ -112,9 +112,25 @@ namespace Gameplay.Level
else
{
await _LoadNPCFromPVPData();
await _TempCreateBuild();
}
}
private async UniTask _TempCreateBuild()
{
DebugUtil.LogError("临时创建建筑");
var tempCellIndex = 37;
var tempBuildId = 1001;
var teamId = ETroopsId.Enemy1;
var createUnit = await GameUnitManager.instance.PrepareBuild(tempBuildId, teamId);
if (createUnit == null)
{
DebugUtil.LogError("创建建筑失败");
return;
}
GameUnitManager.instance.MoveUnitToFight(createUnit.GetID(), tempCellIndex, 0);
}
private async UniTask _LoadBeProtectFromLevelData()
{
if (_levelData == null) return;

View File

@ -151,23 +151,6 @@ namespace Gameplay.Level
if (ValueValidator.IsIdValid(teamSelectID))
{
var unit = GameUnitManager.instance.totalUnits.Search(teamSelectID);
// if (TeamManager.Instance.IsInLevel(teamSelectID))
// {
// if (unit.gameunitType == EGameUnitType.Character)
// {
// if (unit.statusData.isOnVehicle)
// {
// //下车
// _GetOutVehicle(teamSelectID, cellIndex);
// return;
// }
// }
// }
// else
// {
// _FightInBattle(map, cellIndex, worldPosition);
// return;
// }
if (GameUnitManager.instance.prepareUnits.Contains(teamSelectID))
{
//在车上不算在准备席只是UI在备战席

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Gameplay.Building;
using Gameplay.Common;
using Gameplay.Fight.Protect;
using Gameplay.Summon;
@ -114,11 +115,33 @@ namespace Gameplay.Pause
var beProtectUnit = unit as BeProtectUnit;
_AddBeProtect(beProtectUnit);
break;
case EGameUnitType.Building:
var building = unit as UnitBuild;
_AddBuilding(building);
break;
default:
DebugUtil.LogError("暂未处理的类型:{0}", unit.gameunitType);
break;
}
}
private void _AddBuilding(UnitBuild building)
{
// 建筑有一个动画
var anims = building.Node.GameObject.GetComponentsInChildren<Animator>();
for (var i = 0; i < anims.Length; ++i)
{
var anim = anims[i];
_AddAnim(anim, building);
}
// 建筑也可能有特效
var particals = building.Node.GameObject.GetComponentsInChildren<ParticleSystem>();
for (var i = 0; i < particals.Length; ++i)
{
var partical = particals[i];
_AddPartical(partical, building);
}
}
private void _AddBeProtect(BeProtectUnit beProtectUnit)
{

View File

@ -49,25 +49,21 @@ namespace Gameplay.Unit
/// <summary>
/// 公用数据,或者其他一些不知道放哪的数据
/// </summary>
[FightDebug]
public UnitCommonData commonData;
/// <summary>
/// logic移动相关数据,view层主要与此进行同步
/// </summary>
[FightDebug]
public UnitTransData transData;
/// <summary>
/// 生存相关数据,控制角色的死亡,复活等
/// </summary>
[FightDebug]
public UnitAliveData aliveData;
/// <summary>
/// 战斗相关数据,主要用于公式计算相关
/// </summary>
[FightDebug]
public UnitFightData fightData
{
get;
@ -77,13 +73,11 @@ namespace Gameplay.Unit
/// <summary>
/// 战斗内的控制数据,主要用于战斗内的逻辑控制
/// </summary>
[FightDebug]
public UnitControlData controlData;
/// <summary>
/// 状态数据,主要用于标识判定
/// </summary>
[FightDebug]
public UnitStatusData statusData
{
get;

View File

@ -2,6 +2,8 @@
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using Framework;
using Gameplay.Building;
using Gameplay.Building.Data;
using Gameplay.Character;
using Gameplay.Character.Utils;
using Gameplay.Fight.Protect;
@ -259,6 +261,18 @@ namespace Gameplay.Unit
return createUnit;
}
public async UniTask<UnitBuild> PrepareBuild(int buildId, int troopId)
{
var nGuid = GUIDManager.GenGuid();
var dataConfig = BuildDataHelper.CombineConfigData(buildId);
var createUnit = UnitBuildFactory.CreateBuild(dataConfig, nGuid, troopId);
await createUnit.CreateAsync();
await createUnit.Prepare();
_PrepareUnit(createUnit);
return createUnit;
}
public async UniTask<NormalVehicle> PrepareVehicle(VehicleCultivateData vInfo, int troopId)
{
var nGuid = GUIDManager.GenGuid();

View File

@ -216,6 +216,7 @@ namespace Gameplay.Weapon
case EGameUnitType.Vehicle:
case EGameUnitType.Summon:
case EGameUnitType.BeProtect:
case EGameUnitType.Building:
{
var getCmp = enemy.Node.GameObject.GetComponent<CmpCharacterEffectPoints>();
if (getCmp != null)