using System.Collections; using Games.AnimationModule; using Games.GlobeDefine; using GCGame.Table; using Module.Log; using UnityEngine; using Games.Events; using System; namespace Games.MountModule { public struct MountParam { //public const int Max_MountCollect_Count = 40; //当前骑乘ID public int AdvanceMountId { get; set; } //双人 public int _MountState; public ulong _LinkID; private int m_AutoFlagMountID; public int AutoFlagMountID { get { return m_AutoFlagMountID; } set { m_AutoFlagMountID = value; if (AdvanceMountPanelCtr.Instance) AdvanceMountPanelCtr.Instance.fashionPanel.RefreshAdvanceItemState(); } } public void CleanUp() { AdvanceMountId = -1; AutoFlagMountID = -1; } public void SyncMoutCollectedFlag(GC_MOUNTCOLLECTED_FLAG data) { Module.Log.LogModule.DebugLog("SyncMoutCollectedFlag"); m_AutoFlagMountID = data.AutoMountFlag; } public bool GetMountCollectFlag(int nMountID) { return false; } } } namespace Games.LogicObj { ////////////////////////////////////////////////////////////////////////// // 坐骑相关 ////////////////////////////////////////////////////////////////////////// public partial class Obj_OtherPlayer : Obj_Character { public GameEvent UnMountEventCallBack { get; set; } public const int FashionTabId = 100000; private const int _mountEffectId = 2003; private int m_AdvanceMountID = -1; public float mount_DeltaHeigh { get; private set; } private AnimationLogic MountAnimaLogic; public virtual int AdcaneMountId { get { return m_AdvanceMountID; } set { m_AdvanceMountID = value; } } public ObjModelRecord mountModel = new ObjModelRecord(); public Tab_CharMount mountData { get; private set; } private Transform _mountEffectPoint; public Obj_OtherPlayer _MountClientObj; public override Transform effectPoint { // get { return _mountEffectPoint == null ? base.effectPoint : _mountEffectPoint; } } public override float DeltaHeight { get { return m_DeltaHeight + mount_DeltaHeigh; } } public float GetMountNameBoardHeight() { if (m_AdvanceMountID == -1) return 0; var mountId = -1; if (m_AdvanceMountID >= FashionTabId) { var advanceFashion = TableManager.GetAdvanceFashionByID(m_AdvanceMountID, 0); if (advanceFashion == null) return 0; mountId = advanceFashion.ModelId; } else { var advanceBase = TableManager.GetAdvanceBaseByID(m_AdvanceMountID, 0); if (advanceBase == null) return 0; mountId = advanceBase.ModelId; } var mountBase = TableManager.GetMountBaseByID(mountId, 0); if (null == mountBase) return 0; var mountTable = TableManager.GetCharMountByID(mountBase.ModelID, 0); if (mountTable == null) return 0; //司机乘客职业名称高度修正 float fFixHeight = 0; if (DoubleRidingState == 2) { if (Profession >= 0 && Profession < mountTable.getHeadInfotCount()) fFixHeight = mountTable.GetHeadInfotbyIndex(Profession); return fFixHeight; } else { if (Profession >= 0 && Profession < mountTable.getHeadInfoAddHeightCount()) fFixHeight = mountTable.GetHeadInfoAddHeightbyIndex(Profession); return fFixHeight; } } protected override void Awake() { base.Awake(); mountModel.onModelCreate += OnMountCreate; mountModel.onModelDestroy += OnMountDestroy; magicItem.onModelCreate += OnMagicCreate; magicItem.onModelDestroy += OnMagicDestroy; } protected override void OnHideMaskUpdate(int previousMask) { base.OnHideMaskUpdate(previousMask); var mount = GetHideMaskUpdateForPart(ModelPart.mount, previousMask); if (mount > 0) { if (AdcaneMountId > GlobeVar.INVALID_ID) RideMount(AdcaneMountId); } else if (mount < 0) RemoveMount(); } protected virtual void OnMountCreate(ObjPartRoot mountObj, object dataTable) { // 注:坐骑会绑定其他物体,必须立刻初始化 InitAttachmentMatInfo(ModelPart.mount, mountObj); mountData = dataTable as Tab_CharMount; var modelTransform = mountObj.transform; modelTransform.SetParent(m_ObjTransform); modelTransform.localPosition = Vector3.zero; modelTransform.localRotation = Quaternion.identity; modelTransform.localScale = Vector3.one; if (ObjEffectLogic != null) { if (mountData != null) { var mountPoint = mountObj.transform.Find(mountData.BindPoint[0]); //司机乘客绑定点 if (DoubleRidingState == 2) { mountPoint = mountObj.transform.Find(mountData.BindPoint[1]); } else { mountPoint = mountObj.transform.Find(mountData.BindPoint[0]); } if (mountPoint != null) { const string effectPointName = "MountEffectPoint"; var effectTrans = mountPoint.Find(effectPointName); if (effectTrans == null) { // 额外增加一个特效挂点 var effectObj = new GameObject(effectPointName); effectTrans = effectObj.transform; effectTrans.SetParent(mountPoint); // 不能继续自动校正方向 - 有些动画会导致重用时的坐骑挂点不处于初始位置 effectTrans.localPosition = Vector3.down * 0.99f; effectTrans.localRotation = Quaternion.identity; effectTrans.localScale = Vector3.one; } _mountEffectPoint = effectTrans; } } ObjEffectLogic.ResetNormalEffectPoint(); //播放骑乘特效 ObjEffectLogic.PlayEffect(_mountEffectId); } mountObj.gameObject.name = "Model"; var layer = gameObject.layer; mountObj.gameObject.SetLayerRecursively(layer); // 注:原始mount已经被标记为摧毁,但是实际没有摧毁 // 因此playerModel还可以正常移动到新的坐骑节点 var playerModel = ModelNode.model; if (playerModel != null) SetModelBoundPoint(playerModel); // var mountAnimTrans = transform.Find(_mountAnimObjName); // if (mountAnimTrans == null) // { // var mountAnimObj = new GameObject(_mountAnimObjName); // mountAnimTrans = mountAnimObj.transform; // mountAnimTrans.SetParent(m_ObjTransform, false); // } MountAnimaLogic = CreateAnimLogic(mountObj); if (CurObjAnimState == GameDefine_Globe.OBJ_ANIMSTATE.STATE_INVAILD) CurObjAnimState = GameDefine_Globe.OBJ_ANIMSTATE.STATE_NORMOR; else OnSwithObjAnimState(CurObjAnimState); mount_DeltaHeigh = GetMountNameBoardHeight(); } protected virtual void OnMountDestroy(ObjPartRoot mountObj) { // 注:需要维持先移除_mountEffectPoint引用,然后重置特效位置,最后摧毁_mountEffectPoint这个流程。 var mountPoint = _mountEffectPoint; _mountEffectPoint = null; if (ObjEffectLogic != null) ObjEffectLogic.ResetNormalEffectPoint(); if (mountPoint != null) { Destroy(mountPoint.gameObject); } if (MountAnimaLogic != null) { DisableAnimLogic(MountAnimaLogic); MountAnimaLogic = null; } // if (MountAnimaLogic != null) // { // MountAnimaLogic.enabled = false; // MountAnimaLogic.Clear(); // MountAnimaLogic = null; // } DestroyAttachmentMatInfo(ModelPart.mount); } //骑乘相关------------------------------------------------------------- public int DoubleRidingState = 0; public UInt64 _LinkID = 0; public virtual void GetMountData(GC_MOUNT_DATA data) { DoubleRidingState = data.State; _LinkID = data.LinkId; RideOrUnMount(data.MountID); } //是否双人坐骑乘客 public bool IsMountClient() { return Games.GlobeDefine.GlobeVar.IsGUIDValid(_LinkID) && DoubleRidingState == 2; } // 上马下马 统一接口 public virtual void RideOrUnMount(int nMountID) { Tab_MountBase mountBase = TableManager.GetMountBaseByID(nMountID, 0); //#if UNITY_ANDROID //当前其他玩家处于不可见状态时,记录 MountID if (!m_bVisible && m_ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_OTHER_PLAYER) { m_AdvanceMountID = nMountID; return; } StopAllCoroutines(); //双人坐骑,乘客 if (IsMountClient()) { StartCoroutine(SetModelBoundPoint2(ModelNode.model, _LinkID)); return; } if (nMountID > 0) RideMount(nMountID); else UnMount(); if (OrnamentFootPrintID != -1) ReloadOrnamentFootPrint(nMountID > 0 ? true : false); } /// <summary> /// 骑马 /// </summary> /// <param name="nMountID">模型ID</param> protected virtual void RideMount(int nMountID) { m_AdvanceMountID = nMountID; if (m_ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_MAIN_PLAYER) GameManager.gameManager.PlayerDataPool.m_objMountParam.AdvanceMountId = nMountID; // 注:这里保存当前坐骑id,但是变身状态下不加载模型 if (ForceUseModel == null) { //显示坐骑模型 if (IsShowModel(ModelPart.mount)) { int mountId; //当前坐骑是活动坐骑 if (m_AdvanceMountID >= FashionTabId) { var advanceFashion = TableManager.GetAdvanceFashionByID(m_AdvanceMountID, 0); if (advanceFashion == null) return; mountId = advanceFashion.ModelId;//活动坐骑模型 } else { var advanceBase = TableManager.GetAdvanceBaseByID(m_AdvanceMountID, 0); if (advanceBase == null) return; mountId = advanceBase.ModelId;//基础坐骑模型 } //骑乘基础 var mountBase = TableManager.GetMountBaseByID(mountId, 0); if (null == mountBase) { LogModule.DebugLog("MountBase.txt has not Line ID=" + mountId); return; } //骑乘表 var mountTable = TableManager.GetCharMountByID(mountBase.ModelID, 0); if (mountTable == null) { LogModule.DebugLog("CharMount.txt has not Line ID=" + mountBase.ModelID); return; } //哈希表参数 var hashParam = new Hashtable { { modelDataHashName, mountTable } }; //加载模型 (模型资源包,坐骑模型名字,哈希表参数) mountModel.LoadModel(LoadAssetBundle.BUNDLE_PATH_MODEL, mountTable.MountModel, hashParam, null); } } else RemoveMount();//退出骑乘 } /// <summary> /// 设定模型绑定点 /// </summary> /// <param name="modelObj">模型对象</param> protected override void SetModelBoundPoint(ObjPartRoot modelObj) { Transform modelParent = null; if (mountModel.model != null && mountData != null) { //司机乘客绑定点 if (DoubleRidingState == 0 || DoubleRidingState == 1) { modelParent = mountModel.model.transform.Find(mountData.BindPoint[0]); } if (DoubleRidingState == 2) { modelParent = mountModel.model.transform.Find(mountData.BindPoint[1]); } #if UNITY_EDITOR if (modelParent == null) { if (DoubleRidingState == 2) { LogModule.ErrorLog(string.Format("无法获得坐骑{0}绑定位置{1}", mountData.Id, mountData.BindPoint[1])); } else { LogModule.ErrorLog(string.Format("无法获得坐骑{0}绑定位置{1}", mountData.Id, mountData.BindPoint[0])); } } #endif } if (modelParent == null) base.SetModelBoundPoint(modelObj); //如果父节点本身匹配 else if (modelParent != modelObj.transform.parent) { var charModel = TableManager.GetCharModelByID(ModelID, 0); var scale = charModel == null ? 1f : charModel.Scale; scale *= ModelScale; //玩家位置信息更新 var modelTransfrom = modelObj.transform; modelTransfrom.SetParent(null); modelTransfrom.localScale = m_ObjTransform.localScale * scale; modelTransfrom.SetParent(modelParent); modelTransfrom.localPosition = Vector3.zero; modelTransfrom.localRotation = Quaternion.identity; } PlayMountPlayerAnima(); } /// <summary> /// 设定模型绑定点--乘客 /// </summary> /// <param name="modelObj">模型对象</param> private float _StartTime; private float _WaitMaxTime = 30; protected IEnumerator SetModelBoundPoint2(ObjPartRoot modelObj, ulong linkID) { _StartTime = Time.time; Obj_OtherPlayer driverPlayer = null; Transform modelParent = null; while (true) { driverPlayer = Singleton<ObjManager>.Instance.FindOtherPlayerByGuid(linkID); //等待司机模型 if (driverPlayer != null && driverPlayer.mountModel != null && driverPlayer.mountModel.model != null) { break; } else { //等30s,实在没有则退出 if (Time.time - _StartTime > _WaitMaxTime) { yield break; } yield return null; } } mountData = driverPlayer.mountData; modelParent = driverPlayer.mountModel.model.transform.Find(driverPlayer.mountData.BindPoint[1]); #if UNITY_EDITOR if (modelParent == null) { if (DoubleRidingState == 2) { LogModule.ErrorLog(string.Format("无法获得坐骑{0}绑定位置{1}", mountData.Id, mountData.BindPoint[1])); } else { LogModule.ErrorLog(string.Format("无法获得坐骑{0}绑定位置{1}", mountData.Id, mountData.BindPoint[0])); } } #endif if (modelParent == null) base.SetModelBoundPoint(modelObj); //如果父节点本身匹配 else if (modelParent != modelObj.transform.parent) { var charModel = TableManager.GetCharModelByID(ModelID, 0); var scale = charModel == null ? 1f : charModel.Scale; scale *= ModelScale; //玩家位置信息更新 var modelTransfrom = modelObj.transform; modelTransfrom.SetParent(null); modelTransfrom.localScale = m_ObjTransform.localScale * scale; modelTransfrom.SetParent(modelParent); modelTransfrom.localPosition = Vector3.zero; modelTransfrom.localRotation = Quaternion.identity; m_headUIObj.SetVirtualModelTarget(modelTransfrom); driverPlayer._MountClientObj = this; } PlayMountPlayerAnima(); } /// <summary> /// 下马 /// </summary> protected virtual void UnMount() { m_AdvanceMountID = GlobeVar.INVALID_ID; if (m_ObjType == GameDefine_Globe.OBJ_TYPE.OBJ_MAIN_PLAYER) GameManager.gameManager.PlayerDataPool.m_objMountParam.AdvanceMountId = m_AdvanceMountID; RemoveMount(); } /// <summary> /// 删除坐骑 /// </summary> protected virtual void RemoveMount() { mountData = null; mount_DeltaHeigh = 0; if (ModelNode.model != null) base.SetModelBoundPoint(ModelNode.model); if (IsMountClient()) { m_headUIObj.SetVirtualModelTarget(null); } if (_MountClientObj != null) { _MountClientObj.m_headUIObj.SetVirtualModelTarget(null); } mountModel.RemoveModel(); if (!IsUsingSkill) OnSwithObjAnimState(CurObjAnimState); } /// <summary> /// 行走动画 /// </summary> protected override void ProcessWalkAnimState() { if (MountAnimaLogic == null && !IsMountClient()) base.ProcessWalkAnimState(); else PlayMountPlayerAnima(); } /// <summary> /// 空闲状态 /// </summary> protected override void ProcessIdleAnimState() { if (MountAnimaLogic == null && !IsMountClient()) base.ProcessIdleAnimState(); else PlayMountPlayerAnima(); } /// <summary> /// 播放骑乘玩家动画 /// </summary> public void PlayMountPlayerAnima() { if (mountData != null) { switch (CurObjAnimState) { case GameDefine_Globe.OBJ_ANIMSTATE.STATE_NORMOR: if (AnimLogic != null) { if (IsMountClient()) { //播放乘客骑乘待机动画 AnimLogic.Play(mountData.IdlePlayerAnimationId[1]); } else { //播放司机骑乘待机动画 AnimLogic.Play(mountData.IdlePlayerAnimationId[0]); } } if (MountAnimaLogic != null) //站立 MountAnimaLogic.Play((int)CharacterDefine.CharacterAnimId.Stand); break; case GameDefine_Globe.OBJ_ANIMSTATE.STATE_WALK: if (AnimLogic != null) { if (IsMountClient()) { //播放乘客骑乘行走动画 AnimLogic.Play(mountData.RunPlayerAnimationId[1]); } else { //播放司机骑乘行走动画 AnimLogic.Play(mountData.RunPlayerAnimationId[0]); } } if (MountAnimaLogic != null) //步行 MountAnimaLogic.Play((int)CharacterDefine.CharacterAnimId.Walk); break; } } // 有MountData就不瞎折腾了 //int mountId; //if (m_AdvanceMountID >= FashionTabId) //{ // var advanceFashion = TableManager.GetAdvanceFashionByID(m_AdvanceMountID, 0); // if (advanceFashion == null) return; // mountId = advanceFashion.ModelId; //} //else //{ // var advanceBase = TableManager.GetAdvanceBaseByID(m_AdvanceMountID, 0); // if (advanceBase == null) return; // mountId = advanceBase.ModelId; //} //var mountBase = TableManager.GetMountBaseByID(mountId, 0); //if (mountBase == null) // return; //var mountTable = TableManager.GetCharMountByID(mountBase.ModelID, 0); //if (mountTable == null) // return; } /// <summary> /// 删除模型 /// </summary> public override void RemoveModels() { AdcaneMountId = GlobeVar.INVALID_ID; mountModel.RemoveModel(); MagicID = GlobeVar.INVALID_ID; magicItem.RemoveModel(); base.RemoveModels(); } /// <summary> /// 释放所有模型 /// </summary> /// <param name="isDestroy">是否释放</param> public override void ReleaseAllModel(bool isDestroy) { base.ReleaseAllModel(isDestroy); mountModel.Release(); magicItem.Release(); if (isDestroy) DestroyAttachmentMatInfo(ModelPart.mount); } /// <summary> /// 删除目标 /// </summary> protected override void OnObjDestroy() { mountModel.ReduceCount(); // 注:特殊处理法宝 - 不确定法宝是否会同时被删除; // 如果是切换场景的流程,法宝将无法被回收,因此统一处理为手动摧毁流程; if (magicItem.model != null) { magicItem.ReduceCount(); Destroy(magicItem.model); } base.OnObjDestroy(); } } }