using UnityEngine; using System.Collections; using System.Collections.Generic; using System; namespace YLBattle { /// /// 技能控制器 /// //[RequireComponent(typeof(SkillReady))] //[RequireComponent(typeof(SkillShoot))] //[RequireComponent(typeof(SkillExplode))] public partial class SkillControl : MonoBehaviour { /// /// 技能准备. /// private SkillReady skillReady; /// /// 技能发射. /// private SkillShoot skillShoot; /// /// 技能爆炸. /// private SkillExplode skillExplode; /// /// 地图中心位置(特效 type=2 敌方) /// private Vector3 mMapCenter = Vector3.zero; /// /// 地图中心位置(特效 type=2 己方) /// private Vector3 mUICenter = Vector3.zero; /// /// 实例 /// public static SkillControl mInstance; /// /// 数据交互接口 /// private IBattleGlobalOper mBattleFeildAdapter = null; /// /// 子弹字典 /// private Dictionary ProjectileBases = new Dictionary(); /// /// 爆炸字典 /// private Dictionary ExplodeBases = new Dictionary(); /// /// 准备阶段 技能字典 /// public Dictionary mCommonBaseObjs = new Dictionary(); /// /// 画布 /// private Canvas m_Canvas = null; /// /// /// public Canvas SkillCanvas { get { return m_Canvas; } } /// ///坐标 /// private RectTransform rectTransform; /// /// 获取单键 /// /// 单键实例 public static SkillControl Instance { get { if (mInstance == null) { GameObject obj = GameObject.Find("SkillControl"); if (obj != null) { mInstance = obj.AddComponent(); } } return mInstance; } } /// /// Start /// private void Start() { this.gameObject.AddComponent(); this.gameObject.AddComponent(); this.gameObject.AddComponent(); skillReady = GetComponent(); skillShoot = GetComponent(); skillExplode = GetComponent(); m_Canvas = GetComponent(); rectTransform = m_Canvas.transform as RectTransform; this.mMapCenter = transform.Find("MapEffectPoint").transform.position; this.mUICenter = transform.Find("UIEffectPoint").transform.position; } /// /// 设置数据交互接口. /// /// Op. public void SetOp(IBattleGlobalOper op) { mBattleFeildAdapter = op; } /// /// /// /// /// public void createPosEffect(string resName, Vector3 pos, Action ac) { ResourceHelper.Instance.LoadAssetBundle(resName, ab => { if (ab != null) { GameObject comUIEff = (GameObject)Instantiate(ab.LoadAsset(resName)); comUIEff.SetActive(false); this.TranformHandle(comUIEff.transform, pos); if (ac != null) { ac.Invoke(comUIEff); } } }); } /// /// 在目标位置(UI层)上创建特效 /// /// 目标Id /// 资源名称 /// 位置类型 0=transform脚底 1=shoot/hit 2=指定位置 public void createPosEffect(string Id, string resName, Vector3 pos, int posType = 0, float time = 1.0f) { Fighter target = FightingManager.Instance.GetFighter(Id); #region 加载准备阶段光效 ResourceHelper.Instance.LoadAssetBundle(resName, ab => { if (ab != null) { GameObject comUIEff = (GameObject)Instantiate(ab.LoadAsset(resName)); Vector3 targetPos = Vector3.zero; if (posType == 2) { targetPos = WorldToGUI(pos); } else if (target != null) { if (posType == 1) { if (target.mTeam == EBattleTeam.REDTEAM) { targetPos = WorldToGUI(target.mBodyCenterPos); } else { targetPos = target.mBodyCenterPos; } } else { if (target.mTeam == EBattleTeam.REDTEAM) { targetPos = WorldToGUI(target.mBodyRootPos); } else { targetPos = target.mBodyRootPos; } } } this.TranformHandle(comUIEff.transform, targetPos); ExplodeBase exloreScript = comUIEff.GetComponent(); if (exloreScript != null) { exloreScript.enabled = false; } ///(用于非战斗的定点位置爆炸跟踪使用) ExplodeTraceBase explode = comUIEff.GetComponent(); if (explode == null) { explode = comUIEff.AddComponent(); } explode.lifeTime = time; explode.TargetId = Id; explode.posType = posType; } else { LogHelper.LogWarning("特效模版数据有误!!! " + resName); } }); #endregion } /// /// 创建UI屏幕特效(例如,boss出现[全屏]) /// /// /// public void createUIScreenEffect(string Id, string resName) { ResourceHelper.Instance.LoadAssetBundle(resName, ab => { if (ab != null) { GameObject uiEff = (GameObject)Instantiate(ab.LoadAsset(Id)); uiEff.transform.SetParent(transform); uiEff.transform.position = Vector3.zero; uiEff.transform.rotation = Quaternion.identity; uiEff.transform.localScale = new Vector3(1, 1, 1); this.mCommonBaseObjs.Add(Id, uiEff); } } ); } /// /// Tranform的处理,3D->UI /// /// /// public void TranformHandle(Transform model, Vector3 trgPos) { Transform[] all = model.GetComponentsInChildren(); ///默认UI相机照射所有特效 ///如果是bomb在敌人身上(3D)身上,则使用3D摄像机; foreach (Transform rc in all) { rc.gameObject.layer = LayerMask.NameToLayer("UI"); //指定Layer } model.transform.SetParent(transform); model.transform.position = trgPos; model.transform.rotation = Quaternion.identity; model.transform.localScale = new Vector3(1, 1, 1); } /// /// 创建子弹. /// /// 子弹参数 public void createProjectile(BulletLoadParam _bulletLoadParam) { ///发起者 Fighter tempCaster = FightingManager.Instance.GetFighter(_bulletLoadParam.uid); if (tempCaster == null) { LogHelper.Log("发起者 id=" + _bulletLoadParam.uid + " 不存在(死亡),反射失败"); return; } Vector3 point = tempCaster.mBodyCenterPos; #region 弹道设定 ///无弹道->模拟 if (_bulletLoadParam.traject == EBulletTrajectoryType.EBULLET_TRAJECT_NONE) { CreateNoneTrajectBullet(_bulletLoadParam, point); return; } CreatePrebBullet(_bulletLoadParam, point, tempCaster.mTeam == EBattleTeam.BLUETEAM); #endregion } /// /// 查找Transform /// /// 父级 /// 名称 /// Transform private Transform FindTransform(Transform tran, string name) { Transform[] trans = tran.GetComponentsInChildren(); for (int i = 0; i < trans.Length; i++) { if (trans[i].name.Trim().IndexOf(name.Trim(), 0, trans[i].name.Trim().Length) != -1) { return trans[i]; } } return null; } /// /// 创建外部预置物体类型子弹 /// /// /// 发射点 void CreatePrebBullet(BulletLoadParam _bulletLoadParam, Vector3 muzzplePos, bool isScreen) { ///弹道效果 GameObject projectileEff = null; ResourceHelper.Instance.LoadAssetBundle(_bulletLoadParam.res + "_sending", ab => { if (ab != null) { projectileEff = (GameObject)Instantiate(ab.LoadAsset(_bulletLoadParam.res)); } else { projectileEff = new GameObject(); projectileEff.name = _bulletLoadParam.tid + "_sending"; } this.TranformHandle(projectileEff.transform, muzzplePos); AddProjectileComponent(_bulletLoadParam, projectileEff); }); } /// /// 子弹增加轨道组件 /// /// /// public void AddProjectileComponent(BulletLoadParam _bulletLoadParam, GameObject projectileEff) { ProjectileBase Projectile = null; switch (_bulletLoadParam.traject) { /// 无弹道,直接出现在目标位置处 case EBulletTrajectoryType.EBULLET_TRAJECT_NONE: ///不会走到这里滴~~ Debug.LogError("擦,真没数据啊。。。。。"); break; /// 抛物线子弹 case EBulletTrajectoryType.EBULLET_TRAJECT_PARABOLA: Projectile = projectileEff.AddComponent() as ProjectileArcGUI; break; case EBulletTrajectoryType.EBULLET_TRAJECT_LINE: Projectile = projectileEff.AddComponent() as ProjectileArcLine; break; /// 屏幕 } ///创建子弹完毕,隐藏,待shoot调用 if (Projectile != null) { projectileEff.SetActive(false);///关闭对象显示 Projectile.bulletLoadParam = _bulletLoadParam; if (ProjectileBases.ContainsKey(_bulletLoadParam.id) == false) { ProjectileBases.Add(_bulletLoadParam.id, Projectile); } else { ProjectileBases[_bulletLoadParam.id] = Projectile; } } } /// /// 创建无弹道轨迹的子弹 /// /// /// 发射点 void CreateNoneTrajectBullet(BulletLoadParam _bulletloadParam, Vector3 muzzplePos) { GameObject projNoneObj = new GameObject(_bulletloadParam.res + "+_ProjectileNONE"); projNoneObj.transform.SetParent(transform); ProjectileBase ProjectileNONE = projNoneObj.AddComponent(); ProjectileNONE.isHit = true; ProjectileNONE.bulletLoadParam = _bulletloadParam; if (ProjectileBases.ContainsKey(_bulletloadParam.id)) { ProjectileBases[_bulletloadParam.id] = ProjectileNONE; } else { ProjectileBases.Add(_bulletloadParam.id, ProjectileNONE); } } /// /// 创建发射阶段效果. /// /// 目标 /// 目标位置 /// 目标trans /// 是否为(地图坐标型)全屏特效 public void createSkillShoot(string id, Vector3 _targetPoint, string targetID, bool isMapProjectile, int posType) { Fighter temp = FightingManager.Instance.GetFighter(targetID);//获取目标对象 if (temp == null && isMapProjectile == false) { ///角色已死亡 return; } ///根据id获取子弹对象 if (ProjectileBases.ContainsKey(id)) { ProjectileBase _projectileBase = ProjectileBases[id]; _projectileBase.bulletLoadParam.targetId = targetID; ///bulletlaunch时设定是否为地图定点子弹,主要根据其子弹目标类型 ///地图坐标型子弹. _projectileBase.isMapProjectile = isMapProjectile; _projectileBase.posType = posType; ///无弹道直接爆炸/全屏特效无坐标 if (_projectileBase.bulletLoadParam.traject == EBulletTrajectoryType.EBULLET_TRAJECT_NONE || _targetPoint == Vector3.zero) //|| // isMapProjectile == true) { createSkillExplode(_targetPoint, _projectileBase.bulletLoadParam, isMapProjectile, posType); } else { skillShoot.Shoot(_projectileBase, _targetPoint, temp != null ? temp.transform : null);//发射弹道 } } else { SkillControl.Instance.removeExplode(id); } } /// /// 创建爆炸阶段效果. /// /// 目标位置 /// 参数 /// 是否为场景坐标轨迹型子弹 /// 位置类型 public void createSkillExplode(Vector3 point, BulletLoadParam _bulletLoadParam, bool isMapProjectile, int posType = 0) { ///发起者 Fighter temp = FightingManager.Instance.GetFighter(_bulletLoadParam.uid); ///加载爆炸光效 ResourceHelper.Instance.LoadAssetBundle(_bulletLoadParam.res + "_bomb", ab => { GameObject explodeEff = null; ExplodeBase newExplode = null; if (ab != null) { if (temp == null) { ///角色已死亡 return; } explodeEff = (GameObject)Instantiate(ab.LoadAsset(_bulletLoadParam.res)); newExplode = explodeEff.GetComponent(); } else { explodeEff = new GameObject(); explodeEff.name = _bulletLoadParam.res + "_bomb"; } if (newExplode == null) { newExplode = explodeEff.AddComponent(); } ///子弹参数 newExplode.bulletId = _bulletLoadParam.id; newExplode.OnDestoryAction = removeExplode; //***************************位置处理*************************** //Debug.LogError("子弹模板:"+_bulletLoadParam.tid); if (posType == 3) ///全屏特效 屏幕中心 { if (_bulletLoadParam.team == EBattleTeam.BLUETEAM) { this.TranformHandle(explodeEff.transform, this.mUICenter); } else { this.TranformHandle(explodeEff.transform, this.mMapCenter); } } else if (posType == 4) { this.TranformHandle(explodeEff.transform, Vector3.zero); } else if (posType == 2) //地图跟随 { if (_bulletLoadParam.team == EBattleTeam.BLUETEAM) { this.TranformHandle(explodeEff.transform, this.mUICenter); } else { this.TranformHandle(explodeEff.transform, WorldToGUI(FightingMap.Instance.MapPos)); ///如果是蓝队,则会出现镜头转向时,特效被旋转偏移 ///子弹(附加)追踪脚本 ExplodeTrace newExplodeTrace = explodeEff.AddComponent(); newExplodeTrace.SetMapFollow((int)_bulletLoadParam.hitpoint, this.rectTransform, this.m_Canvas); newExplodeTrace.gameObject.SetActive(false); } } else//角色跟随 { this.TranformHandle(explodeEff.transform, point); ///如果是蓝队,则会出现镜头转向时,特效被旋转偏移 ///子弹(附加)追踪脚本 ExplodeTrace newExplodeTrace = explodeEff.AddComponent(); newExplodeTrace.SetFighterFollow(_bulletLoadParam.id, _bulletLoadParam.targetId, (int)_bulletLoadParam.hitpoint); newExplodeTrace.gameObject.SetActive(false); } //***************************位置处理结束 *************************** if (!ExplodeBases.ContainsKey(_bulletLoadParam.id)) { ExplodeBases.Add(_bulletLoadParam.id, newExplode); } else { LogHelper.LogError("error: uid=" + _bulletLoadParam.uid + "、tid " + _bulletLoadParam.tid + "、targetId" + _bulletLoadParam.targetId + "、id" + _bulletLoadParam.id ); } Fighter trgFighter = FightingManager.Instance.GetFighter(_bulletLoadParam.targetId); if ((trgFighter != null && !trgFighter.IsDead) || isMapProjectile) { //LogHelper.LogError(_bulletLoadParam.tid + ".............................bomb"); skillExplode.create(_bulletLoadParam.tid, explodeEff); } else { LogHelper.Log("角色死亡 " + _bulletLoadParam.targetId + "/" + _bulletLoadParam.tid + ".............................bomb"); //if (!isMapProjectile) //{ SkillControl.Instance.removeExplode(_bulletLoadParam.id); return; //} } if (_bulletLoadParam.audio.Length >= 3) { AudioManager.Instance.PlaySkillSoundEffect(_bulletLoadParam.audio[2]); } else { //LogHelper.LogError("audio :"+_bulletLoadParam.tid+" 没有音效数据[cfg_bullet无此模板数据,请添加]"); } //LogHelper.LogError(_bulletLoadParam.tid + ".............................bomb"); ///通知子弹碰撞 if (mBattleFeildAdapter != null) { mBattleFeildAdapter.OnBulletCollideEvent(_bulletLoadParam.id, _bulletLoadParam.uid); } }); } /// /// /// /// public Vector3 WorldToGUI(Vector3 orgPos) { Vector2 pos; Vector3 screenPos = CameraManager.Instance.SenceCamara.WorldToScreenPoint(orgPos); RectTransformUtility.ScreenPointToLocalPointInRectangle(this.rectTransform, screenPos, CameraManager.Instance.SenceUICamera, out pos); return pos; } /// /// 清理当前运行时的技能数据 /// public void ClearRuningSkill() { /// 子弹字典 List projectileBases = new List(ProjectileBases.Values); for (int i = 0; i < projectileBases.Count; i++) { Destroy(projectileBases[i].gameObject); } ProjectileBases.Clear(); ///爆炸字典 List explodeBase = new List(ExplodeBases.Values); for (int i = 0; i < explodeBase.Count; i++) { Destroy(explodeBase[i].gameObject); } ExplodeBases.Clear(); } /// /// 清除所有技能特效 /// public void ClearAllSkill() { this.ClearRuningSkill(); List commReses = new List(mCommonBaseObjs.Values); /// 准备阶段 for (int i = 0; i < commReses.Count; i++) { Destroy(commReses[i]); } mCommonBaseObjs.Clear(); } } }