/// <summary> /// 光束引导技能是一种特化的引导技能, 只释放一次技能实体, 而不是每次间隔都释放, 引导间隔只是服务器用了计算伤害 /// </summary> /// <param name="skillID"></param> /// <returns></returns> public bool IsChannellingBeamSkill(int skillID) { SkillSystemGrow grow = GetSkillGrow(skillID); SkillSystemPath path = GetSkillPath(grow.PathID); return(SkillNeedChannelling(skillID) && path.PathType == (int)SkillPathType.LightBeam_DestroyByEvent); }
private bool CanCreateSkill(int skillID) { SkillBase.SLog("CanCreateSkill"); SkillSystemGrow skillGrow = m_CfgSkillProxy.GetSkillGrow(skillID); if (skillGrow.ByteBuffer == null) { SkillBase.SLog("没有这个技能"); Debug.LogError("没有这个技能: " + skillID); return(false); } if (m_Property.IsMain() && m_Property.GetCurrentState().GetMainState() == EnumMainState.Cruise) { SkillBase.SLog("巡航模式不能放技能"); Debug.Log("巡航模式不能放技能"); return(false); } if (m_SkillProxy.IsOnCD(skillID) || m_SkillProxy.IsOnTriggerCD(skillID)) { SkillBase.SLog("IsOnCD"); return(false); } return(true); }
/// <summary> /// 技能是不是立即释放的 /// </summary> public bool SkillReleaseImmediatly(int skillID) { SkillSystemGrow grow = GetSkillGrow(skillID); return(grow.CastWay == (int)SkillCategory.Immediate || grow.CastWay == (int)SkillCategory.Immediate_MultiShot || grow.CastWay == (int)SkillCategory.Immediate_Trigger); }
/// <summary> /// 技能释放间隔, 单位: 毫秒 /// </summary> /// <param name="skillID"></param> /// <returns></returns> public float GetSkillReleaseInterval(int skillID) { SkillSystemGrow grow = GetSkillGrow(skillID); SkillCategory category = (SkillCategory)grow.CastWay; switch (category) { case SkillCategory.Immediate: case SkillCategory.Immediate_MultiShot: case SkillCategory.Chanting: case SkillCategory.Charge: case SkillCategory.Charge_MultiShot: return(grow.Cooldown); case SkillCategory.Chanting_Trigger: return(grow.CastWayArgs(1)); case SkillCategory.Immediate_Trigger: return(grow.CastWayArgs(0)); case SkillCategory.ManualChannel: case SkillCategory.AutoChannel: case SkillCategory.RapidFire: case SkillCategory.MiningBeam: return(grow.CastWayArgs(0)); default: return(1000f); } }
/// <summary> /// 技能是不是需要一个目标才能释放 /// </summary> public bool SkillNeedTarget(int skillID) { SkillSystemGrow grow = GetSkillGrow(skillID); return(grow.CastWay == (int)SkillCategory.ManualChannel || grow.CastWay == (int)SkillCategory.AutoChannel || grow.CastWay == (int)SkillCategory.MiningBeam); }
private bool GetAllEntitySelectedByVirtualCamera(ref List <SpacecraftEntity> targetList) { MainCameraComponent mainCam = CameraManager.GetInstance().GetMainCamereComponent(); SkillSystemGrow skillGrow = m_PlayerSkillProxy.GetCurrentWeaponSkill().GetSkillGrow(); float range = skillGrow.Range * SceneController.SPACE_ACCURACY_TO_CLIENT; // 粗略的拾取. // 拾取锥体视为一个相机, 把技能射程视为远裁剪面. 根据FOV取远裁剪面的大小, 投射这个大小的Box, 获取所有拾取到的Entity { // 所有粗略裁剪的物体 = Physics.BoxCastAll(投射开始点, 盒子边长, 相机方向, SkillLayer) float halfBoxVerticalSideLength = range * Mathf.Tan(m_ReticleHorizontalFOVParam / m_ReticleAspect * 0.5f * Mathf.Deg2Rad); float halfBoxHorizontalSideLength = halfBoxVerticalSideLength * m_ReticleAspect; // 投射开始的点 = 相机近裁剪面的中心点 + 相机方向 * 盒子边长的一半 Vector3 startPoint = mainCam.transform.position + (mainCam.GetCamera().nearClipPlane + halfBoxVerticalSideLength) * mainCam.GetForward(); RaycastHit[] hitInfos = Physics.BoxCastAll(startPoint, new Vector3(halfBoxHorizontalSideLength, halfBoxVerticalSideLength, halfBoxVerticalSideLength), mainCam.GetForward(), Quaternion.identity, range, LayerUtil.GetLayersIntersectWithSkillProjectile(true)); for (int iHit = 0; iHit < hitInfos.Length; iHit++) { Rigidbody rigidBody = hitInfos[iHit].rigidbody; if (rigidBody == null) { continue; } SpacecraftEntity entity = rigidBody.GetComponent <SpacecraftEntity>(); if (entity != null) { targetList.Add(entity); } } } if (m_VirtualCameraForReticleSelection != null) { // 更新虚拟相机的方向和位置 m_VirtualCameraForReticleSelection.transform.position = mainCam.transform.position; m_VirtualCameraForReticleSelection.transform.rotation = mainCam.transform.rotation; // 更精细的判断. 当前版本仅计算目标中心点是不是在 虚拟相机 里面 for (int iTarget = 0; iTarget < targetList.Count; iTarget++) { Vector3 viewportPos = m_VirtualCameraForReticleSelection.WorldToViewportPoint(targetList[iTarget].transform.position); if (viewportPos.x < 0 || viewportPos.y < 0 || viewportPos.x > 1 || viewportPos.y > 1) { targetList.RemoveAt(iTarget); iTarget--; } } } return(targetList.Count > 0); }
/// <summary> /// 中心点射线选中的目标 /// </summary> /// <returns></returns> private SpacecraftEntity GetTargetSelectedByCenterRay() { PlayerSkillVO skillVO = m_PlayerSkillProxy.GetCurrentWeaponSkill(); SkillSystemGrow skillGrow = skillVO.GetSkillGrow(); float maxDistance = skillGrow.Range * SceneController.SPACE_ACCURACY_TO_CLIENT; MainCameraComponent mainCam = CameraManager.GetInstance().GetMainCamereComponent(); Ray ray = new Ray(mainCam.GetPosition(), mainCam.GetForward()); RaycastHit hitInfo = new RaycastHit(); if (Physics.Raycast(ray, out hitInfo, maxDistance, LayerUtil.GetLayersIntersectWithSkillProjectile(true))) { return(hitInfo.collider.attachedRigidbody?.GetComponent <SpacecraftEntity>()); } else { return(null); } }
// FIXME 技能. 预计SkillVO这里做一个池子. 消除GC //static PlayerSkillVO s_SkillVOTemplate; static public PlayerSkillVO CreateSkillVO(int skillID) { CfgSkillSystemProxy cfgSkillProxy = GameFacade.Instance.RetrieveProxy(ProxyName.CfgSkillSystemProxy) as CfgSkillSystemProxy; SkillSystemGrow skillGrow = cfgSkillProxy.GetSkillGrow(skillID); if (skillGrow.ByteBuffer == null) { Debug.LogErrorFormat("找不到SkillGrow. SkillID: {0}", skillID); return(null); } SkillSystemPath skillPath = cfgSkillProxy.GetSkillPath(skillGrow.PathID); if (skillPath.ByteBuffer == null) { Debug.LogErrorFormat("找不到SkillPath. PathID: {0}", skillGrow.PathID); return(null); } List <SkillSystemFx> skillFxList = cfgSkillProxy.GetSkillFxList(skillGrow.PathID); for (int iEffect = 0; iEffect < skillFxList.Count; iEffect++) { if (skillFxList[iEffect].ByteBuffer == null) { Debug.LogErrorFormat("找不到skillFxList. PathID: {0}", skillGrow.PathID); return(null); } } List <SkillSystemEffect> skillEffectList = cfgSkillProxy.GetSkillEffectList(skillID); for (int iEffect = 0; iEffect < skillFxList.Count; iEffect++) { if (skillEffectList[iEffect].ByteBuffer == null) { Debug.LogErrorFormat("找不到skillEffectList. skillID: {0}", skillID); return(null); } } return(new PlayerSkillVO(skillID)); }
/// <summary> /// 根据这次射击的弹道方向, 计算命中的目标Entity和目标点 /// </summary> /// <param name="camDirAffectedByRecoil"></param> /// <returns></returns> protected SkillTarget CalulateTargetDataByShootingDirection(Vector3 camDirAffectedByRecoil) { // 计算射线碰到的目标点, 并重新计算从Launcher到目标点的方向 PlayerSkillVO skillVO = m_PlayerSkillProxy.GetCurrentWeaponSkill(); SkillSystemGrow skillGrow = skillVO.GetSkillGrow(); float maxDistance = skillGrow.Range * SceneController.SPACE_ACCURACY_TO_CLIENT; Ray ray = new Ray(CameraManager.GetInstance().GetMainCamereComponent().GetPosition(), camDirAffectedByRecoil); RaycastHit hitInfo = new RaycastHit(); if (Physics.Raycast(ray, out hitInfo, maxDistance, LayerUtil.GetLayersIntersectWithSkillProjectile(true))) { return(new SkillTarget(hitInfo.collider.attachedRigidbody?.GetComponent <SpacecraftEntity>(), hitInfo.point)); } else { Vector3 skillReleasingDir = (ray.GetPoint(maxDistance) - m_MainPlayer.GetRootTransform().position).normalized; return(new SkillTarget(null, m_MainPlayer.GetRootTransform().position + skillReleasingDir * maxDistance)); } }
/// <summary> /// 技能释放完成后开始CD /// </summary> /// <param name="skillID"></param> public void StartCD(int skillID) { Debug.Assert(m_SkillIDToSkill.ContainsKey(skillID)); if (!m_SkillIDToSkill.ContainsKey(skillID)) { return; } // 开始公共CD SkillSystemGrow skillGrowVO = m_CfgSkillProxy.GetSkillGrow(skillID); if (m_SkillTypeToGlobalCDEndTime[GetSkillType(skillID)] < Time.time + skillGrowVO.GlobalCd / 1000.0f) { m_SkillTypeToGlobalCDEndTime[GetSkillType(skillID)] = Time.time + skillGrowVO.GlobalCd / 1000.0f; } // 开始技能本身的CD m_SkillIDToSkill[skillID].StartCD(); }
private PlayerSkillVO(int id) { m_CfgSkillProxy = GameFacade.Instance.RetrieveProxy(ProxyName.CfgSkillSystemProxy) as CfgSkillSystemProxy; m_TemplateID = id; skillGrow = m_CfgSkillProxy.GetSkillGrow(m_TemplateID); if (skillGrow.ByteBuffer != null) { m_SkillPath = m_CfgSkillProxy.GetSkillPath(skillGrow.PathID); m_SkillFxList = m_CfgSkillProxy.GetSkillFxList(skillGrow.PathID); m_SkillEffectList = m_CfgSkillProxy.GetSkillEffectList(m_TemplateID); m_CDEndTime = Time.time; m_TriggerCDEndTime = Time.time; m_IsValid = true; } else { m_IsValid = false; Debug.LogErrorFormat("技能不存在, 请查Skill_system_grow表. ID: {0}", id); } }
public List <SkillSystemEffect> GetSkillEffectList(int skillID) { List <SkillSystemEffect> skillEffectList = new List <SkillSystemEffect>(); SkillSystemGrow skillGrow = GetSkillGrow(skillID); if (skillGrow.ByteBuffer == null) { return(null); } for (int iEffect = 0; iEffect < skillGrow.GetEffectIdArray().Length; iEffect++) { SkillSystemEffect skillEffect = m_CfgEternityProxy.GetSkillEffect(skillGrow.GetEffectIdArray()[iEffect]); if (skillEffect.ByteBuffer == null) { continue; } skillEffectList.Add(skillEffect); } return(skillEffectList); }
/// <summary> /// 选中一个新的目标 /// 1. 与上一帧选中的目标不同 /// 2. 上一帧选中的目标已经锁定完成, 进行下一轮锁定 /// </summary> /// <returns>是否有新的目标</returns> private bool PickNewTarget(out SpacecraftEntity newTarget) { PlayerSkillVO skillVO = m_PlayerSkillProxy.GetCurrentWeaponSkill(); SkillSystemGrow skillGrow = skillVO.GetSkillGrow(); float maxDistance = skillGrow.Range * SceneController.SPACE_ACCURACY_TO_CLIENT; MainCameraComponent mainCam = CameraManager.GetInstance().GetMainCamereComponent(); Ray ray = new Ray(mainCam.GetPosition(), mainCam.GetForward()); RaycastHit hitInfo = new RaycastHit(); // UNDONE // 第一版: 使用屏幕中心射线作为目标选取射线. NOW // 第二版: 使用 Physics.BoxCast if (Physics.Raycast(ray, out hitInfo, maxDistance, LayerUtil.GetLayersIntersectWithSkillProjectile(true))) { SpacecraftEntity pickedTarget = hitInfo.collider.attachedRigidbody?.GetComponent <SpacecraftEntity>(); newTarget = pickedTarget; return(true); } else { newTarget = null; return(false); } }
/// <summary> /// 技能支持锁定多个目标 /// </summary> /// <param name="skillID"></param> /// <returns></returns> public bool SkillSupportMultiTargets(int skillID) { SkillSystemGrow grow = GetSkillGrow(skillID); return(grow.CastWay == (int)SkillCategory.Immediate_MultiTarget); }
/// <summary> /// 技能是不是需要吟唱的 /// </summary> public bool SkillNeedChanting(int skillID) { SkillSystemGrow grow = GetSkillGrow(skillID); return(grow.CastWay == (int)SkillCategory.Chanting || grow.CastWay == (int)SkillCategory.Chanting_Trigger); }
/// <summary> /// 技能是不是需要蓄力的 /// </summary> public bool SkillNeedCharging(int skillID) { SkillSystemGrow grow = GetSkillGrow(skillID); return(grow.CastWay == (int)SkillCategory.Charge || grow.CastWay == (int)SkillCategory.Charge_MultiShot); }
/// <summary> /// 预加载玩家飞船的所有技能的资源 /// </summary> private void PreloadSkill() { // 读取当前Entity的飞船的所有技能 List <int> shipSkillIDList = new List <int>(); // TODO 技能. 现在技能使用物品的方式存储. 自己的技能由服务器通知. 服务器不会告知其他玩家的技能 if (m_Property.IsMain()) { PlayerSkillVO[] skills = m_SkillProxy.GetSkills(); for (int iSkill = 0; iSkill < skills.Length; iSkill++) { shipSkillIDList.Add(skills[iSkill].GetID()); } } else if (m_Property.GetNPCTemplateVO().ByteBuffer != null) { } // 预加载技能所需资源 for (int iSkill = 0; iSkill < shipSkillIDList.Count; ++iSkill) { SkillSystemGrow skillGrow = m_CfgSkillProxy.GetSkillGrow(shipSkillIDList[iSkill]); if (skillGrow.ByteBuffer == null) { continue; } SkillSystemPath skillPath = m_CfgSkillProxy.GetSkillPath(skillGrow.PathID); if (skillPath.ByteBuffer == null) { continue; } for (int iFx = 0; iFx < skillPath.FxIdLength; iFx++) { SkillSystemFx skillFx = m_CfgSkillProxy.GetSkillFx(skillPath.GetFxIdArray()[iFx]); // 加载技能特效资源 if (!string.IsNullOrEmpty(skillFx.CastFxBegin) && !"None".Equals(skillFx.CastFxBegin)) { LoadAssetAsync(skillFx.CastFxBegin); } if (!string.IsNullOrEmpty(skillFx.CastFxLoop) && !"None".Equals(skillFx.CastFxLoop)) { LoadAssetAsync(skillFx.CastFxLoop); } if (!string.IsNullOrEmpty(skillFx.CastFxEnd) && !"None".Equals(skillFx.CastFxEnd)) { LoadAssetAsync(skillFx.CastFxEnd); } if (!string.IsNullOrEmpty(skillFx.LauncherFx) && !"None".Equals(skillFx.LauncherFx)) { LoadAssetAsync(skillFx.LauncherFx); } if (!string.IsNullOrEmpty(skillFx.AssetName) && !"None".Equals(skillFx.AssetName)) { LoadAssetAsync(skillFx.AssetName); } if (!string.IsNullOrEmpty(skillFx.HitFx) && !"None".Equals(skillFx.HitFx)) { LoadAssetAsync(skillFx.HitFx); } // UNDONE 技能, 音效 // 加载音频资源 //AudioProxy audioProxy = DataManager.GetProxy<AudioProxy>(); //if (skillFx.BeforeAudio > 0) //{ // AudioVO audioVO = audioProxy.GetAudioByKey(skillFx.BeforeAudio); // if (audioVO.ByteBuffer != null && !"None".Equals(audioVO.AssetBundle) && !"None".Equals(audioVO.AssetName)) // AssetManager.LoadAsset<GameObject>(audioVO.AssetName, PreloadCallback); //} //if (skillFx.LauncherAudio > 0) //{ // AudioVO audioVO = audioProxy.GetAudioByKey(skillFx.LauncherAudio); // if (audioVO.ByteBuffer != null && !"None".Equals(audioVO.AssetBundle) && !"None".Equals(audioVO.AssetName)) // AssetManager.LoadAsset<GameObject>(audioVO.AssetName, PreloadCallback); //} //if (skillFx.HitAudio > 0) //{ // AudioVO audioVO = audioProxy.GetAudioByKey(skillFx.HitAudio); // if (audioVO.ByteBuffer != null && !"None".Equals(audioVO.AssetBundle) && !"None".Equals(audioVO.AssetName)) // AssetManager.LoadAsset<GameObject>(audioVO.AssetName, PreloadCallback); //} //if (skillFx.SkillAudio > 0) //{ // AudioVO audioVO = audioProxy.GetAudioByKey(skillFx.SkillAudio); // if (audioVO.ByteBuffer != null && !"None".Equals(audioVO.AssetBundle) && !"None".Equals(audioVO.AssetName)) // AssetManager.LoadAsset<GameObject>(audioVO.AssetName, PreloadCallback); //} } } }
/// <summary> /// 技能是不是多轮的 /// </summary> public bool SkillHasMultiShot(int skillID) { SkillSystemGrow grow = GetSkillGrow(skillID); return(grow.CastWay == (int)SkillCategory.Charge_MultiShot || grow.CastWay == (int)SkillCategory.Immediate_MultiShot); }
/// <summary> /// 技能是不是有Trigger机制 /// Trigger: 按住技能按键持续释放 /// </summary> public bool IsTriggerSkill(int skillID) { SkillSystemGrow grow = GetSkillGrow(skillID); return(grow.CastWay == (int)SkillCategory.Immediate_Trigger || grow.CastWay == (int)SkillCategory.Chanting_Trigger); }