using System.Collections.Generic; using cfg.SkillCfg; using Gameplay.Area; using Gameplay.Character.Skill; using Gameplay.Common; using Gameplay.Effect; using Gameplay.Level; using Gameplay.Pool; using Gameplay.Skill; using Gameplay.Unit; using Gameplay.Vehicle.Impl; using PhxhSDK; using UnityEngine; using Constants = Framework.Constants; namespace Gameplay.Character.Helper { public static class CharacterSkillHelper { /// /// 随机选择指定个数目标 /// 当数量不满足时,返回全部目标 /// /// /// /// private static List _RandomSelectTargets(List allTargets, int count) { if (allTargets.Count <= count) { return allTargets; } var result = PhxhSDK.Utils.GetRandomElementFromList(allTargets, count); return result; } private static List _RandomSelectNoFullHpTargets(List allTargets, int count) { if (allTargets.Count <= count) { return allTargets; } var noFullHpTargets = new List(); var fullHpTargets = new List(); foreach (var target in allTargets) { if (target.aliveData.currentHp < target.aliveData.maxHp) { noFullHpTargets.Add(target); } else { fullHpTargets.Add(target); } } if (noFullHpTargets.Count >= count) { return _RandomSelectTargets(noFullHpTargets, count); } var remainCount = count - noFullHpTargets.Count; if (fullHpTargets.Count >= remainCount) { var remainTargets = _RandomSelectTargets(fullHpTargets, remainCount); noFullHpTargets.AddRange(remainTargets); return noFullHpTargets; } // 理论上不会走到这里 return allTargets; } public static List RandomSelectTargets(List allTargets, int count, ETargetPrefer preferType) { switch (preferType) { case ETargetPrefer.None: return _RandomSelectTargets(allTargets, count); case ETargetPrefer.PreferNoFullHp: return _RandomSelectNoFullHpTargets(allTargets, count); default: DebugUtil.LogError("暂未处理的目标优先类型: {0}", preferType); return new List(); } } public static void PlayEffect(CharacterSkillAction skillAction) { var owner = skillAction.skill.GetOwner(); switch (skillAction.actionData.subId) { case ESkillEffectPosType.SelfLocal: _PlayLocalEffect(skillAction); break; case ESkillEffectPosType.TargetLocal: _PlayTargetEffect(skillAction); break; case ESkillEffectPosType.WeaponFire: _PlayWeaponFireEffect(skillAction); break; case ESkillEffectPosType.WeaponFireFly2Target: { Vector3 startPos = owner.Node.GameObject.transform.position; if (owner is Character c) { var weapon = c.weapon; startPos = weapon.fireTrans.position; } else if (owner is NormalVehicle v) { var weapon = v.battery; startPos = weapon.fireTrans.position; } _PlayStartPosFly2TargetEffect(skillAction, startPos); } break; case ESkillEffectPosType.LeftHand2Target: { Vector3 startPos = owner.Node.GameObject.transform.position; if (owner is Character c) { if (c.leftHandTrans != null) { startPos = c.leftHandTrans.position; } } _PlayStartPosFly2TargetEffect(skillAction, startPos); } break; case ESkillEffectPosType.RightHand2Target: { Vector3 startPos = owner.Node.GameObject.transform.position; if (owner is Character c) { if (c.rightHandTrans != null) { startPos = c.rightHandTrans.position; } } _PlayStartPosFly2TargetEffect(skillAction, startPos); } break; default: DebugUtil.LogError("无效的effectPlayType:{0}", skillAction.actionData.subId); break; } } private static void _PlayLocalEffect(CharacterSkillAction skillAction) { var actionData = skillAction.actionData; var effectId = actionData.id; if (effectId > 0) { var skill = skillAction.skill; var owner = skill.GetOwner(); var trans = owner.Node.GameObject.transform; var effectData = EffectManager.instance.PlayEffectById(effectId, trans.position, trans.rotation, trans); effectData.owner = owner; if (owner.statusData.needSkillPaused) { SkillManager.instance.screenEffect.AttachObj(effectData.rootObj); } } } private static void _PlayWeaponFireEffect(CharacterSkillAction skillAction) { var actionData = skillAction.actionData; var skill = skillAction.skill; var effectId = actionData.id; if (effectId <= 0) return; var owner = skill.GetOwner(); if (owner is Character c) { var trans = owner.Node.GameObject.transform; var weapon = c.weapon; var effectData = EffectManager.instance.PlayEffectById(effectId, weapon.fireTrans.position, trans.rotation, weapon.fireTrans); effectData.owner = owner; if (owner.statusData.needSkillPaused) { SkillManager.instance.screenEffect.AttachObj(effectData.rootObj); } } } private static void _PlayTargetEffect(CharacterSkillAction skillAction) { var actionData = skillAction.actionData; var skill = skillAction.skill; var map = LevelManager.Instance.CurrentLevel.Map; var effectId = actionData.id; if (effectId > 0) { // 获取area的cellIndexs var owner = skill.GetOwner(); var skillHandle = skill.GetSkillHandle(); var releaseCellIndex = owner.controlData.skillCellIndex; var configData = skillHandle.runtimeData.configData; var areaId = configData.InfluenceAreaId; skillAction.preSelectCellIndexs = AreaManager.instance.GetCellIndexs(releaseCellIndex, areaId); for (var i = 0; i < skillAction.preSelectCellIndexs.Count; ++i) { var cellIndex = skillAction.preSelectCellIndexs[i]; var worldPos = map.TGSCellIndex2WorldPosition(cellIndex); var effectData = EffectManager.instance.PlayEffectById(effectId, worldPos, Quaternion.identity); effectData.owner = owner; if (owner.statusData.needSkillPaused) { SkillManager.instance.screenEffect.AttachObj(effectData.rootObj); } } } } private static void _PlayStartPosFly2TargetEffect(CharacterSkillAction skillAction, Vector3 startPos) { var actionData = skillAction.actionData; var skill = skillAction.skill; var effectId = actionData.id; if (effectId <= 0) return; var map = LevelManager.Instance.CurrentLevel.Map; // 获取area的cellIndexs var owner = skill.GetOwner(); var releaseCellIndex = owner.controlData.skillCellIndex; var trans = owner.Node.GameObject.transform; var targetCellIndex = releaseCellIndex; var targetPos = map.TGSCellIndex2WorldPosition(targetCellIndex); var effectData = EffectManager.instance.PlayEffectById(effectId, startPos, trans.rotation); if (DebugUtil.LogEnable) DebugUtil.Log("startPos:{0}, targetPos:{1}, targetIndex:{2}", startPos, targetPos, targetCellIndex); switch (actionData.intParam1) { case 0: // 直线 var flyLogicLine = ObjPoolManager.instance.Get(); flyLogicLine.Ctor(startPos, targetPos, actionData.floatParam1); effectData.AddLogic(flyLogicLine); break; case 1: // 抛物线 var flyLogicBessel = ObjPoolManager.instance.Get(); var midPosFixY = actionData.floatParam2; var midposProgress = actionData.floatParam3; var midPos = Vector3.Lerp(startPos, targetPos, midposProgress); midPos.y += midPosFixY; flyLogicBessel.Ctor(startPos, targetPos, midPos, actionData.floatParam1); effectData.AddLogic(flyLogicBessel); break; } effectData.owner = owner; if (owner.statusData.needSkillPaused) { SkillManager.instance.screenEffect.AttachObj(effectData.rootObj); } } public static void RotateToTargetEnemy(GameUnit owner, GameUnit enemy) { var targetCellIndex = enemy.transData.cellIndex; var map = LevelManager.Instance.CurrentLevel.Map; var targetPos = map.TGSCellIndex2WorldPosition(targetCellIndex); var selfPos = owner.transData.pos; var toTarget = targetPos - selfPos; toTarget.y = 0; var angle = Vector3.SignedAngle(Vector3.forward, toTarget, Vector3.up); owner.transData.yaw = angle; } public static void RotateToTargetCell(GameUnit owner) { var targetCellIndex = owner.controlData.skillCellIndex; if (targetCellIndex == owner.transData.cellIndex) { // 同一个格子,不做处理 return; } var map = LevelManager.Instance.CurrentLevel.Map; var targetPos = map.TGSCellIndex2WorldPosition(targetCellIndex); var selfPos = owner.transData.pos; var toTarget = targetPos - selfPos; toTarget.y = 0; var angle = Vector3.SignedAngle(Vector3.forward, toTarget, Vector3.up); owner.transData.yaw = angle; } public static GameObject CreateSkillGroundHighLight(List cellIndexs) { var fakeObj = new GameObject("SkillGroundHighLight"); for (int i = 0; i < cellIndexs.Count; i++) { var cellIndex = cellIndexs[i]; var worldPos = LevelManager.Instance.CurrentLevel.Map.TGSCellIndex2WorldPosition(cellIndex); var sampleObj = AssetManager.Instance.GetPreLoadResult(PathDefine.SkillArea.SKILL_GORUND_HIGH_LIGHT); var go = Object.Instantiate(sampleObj, worldPos, Quaternion.identity, fakeObj.transform); go.SetLayerEx(LayerDefine.Skill); } return fakeObj; } public static CharacterSkillAction CreateAction(SkillLogicActionData actionData) { CharacterSkillAction action; switch (actionData.actionType) { case ESkillActionType.PLAY_AUDIO: action = new CSA_PlayAudio(); break; case ESkillActionType.EMIT_BULLET: action = new CSA_EmitBullet(); break; case ESkillActionType.EMIT_BULLET_SELECT: action = new CSA_EmitBulletSelect(); break; case ESkillActionType.EMIT_BULLET_TO_SELF: action = new CSA_EmitBulletToSelf(); break; case ESkillActionType.CREATE_SUMMON: action = new CSA_CreateSummon(); break; case ESkillActionType.SKILL_END: action = new CSA_SkillEnd(); break; case ESkillActionType.PAUSE_END: action = new CSA_PauseEnd(); break; case ESkillActionType.HIDE_WEAPON: action = new CSA_HideWeapon(); break; case ESkillActionType.SHOW_WEAPON: action = new CSA_ShowWeapon(); break; case ESkillActionType.PLAY_EFFECT: action = new CSA_PlayEffect(); break; case ESkillActionType.CHANGE_POS: action = new CSA_ChangePos(); break; case ESkillActionType.HIDE_RENDER: action = new CSA_HideRender(); break; case ESkillActionType.SHOW_RENDER: action = new CSA_ShowRender(); break; case ESkillActionType.MARK_UP_VEHICLE: action = new CSA_MarkUpVehicle(); break; default: DebugUtil.LogError("暂未处理的actionType:" + actionData.actionType); return null; } return action; } } }