/******************************************************************************** * 文件名: TeleportPoint.cs * 全路径: \Script\Player\TeleportPoint.cs * 创建人: 李嘉 * 创建时间:2013-10-25 * * 功能说明:游戏传送点逻辑 * 修改记录: *********************************************************************************/ using Games.GlobeDefine; using Games.Scene; using GCGame.Table; using UnityEngine; namespace Games.LogicObj { public class Obj_JumpPoint_Init_Data : ObjParent_Init_Data { public Tab_Jump jumpData; public override void CleanUp() { base.CleanUp(); jumpData = null; } } public class Obj_JumpPoint : ObjParent { public Tab_Jump jumpData; private GameObject _rootObj; private TeleportDistanceModule _distanceModule; //缓存数据 private Obj_MainPlayer _mainPlayer; public Obj_JumpPoint() { m_ObjType = GameDefine_Globe.OBJ_TYPE.OBJ_JUMPPOINT; } public override UIPathData HeadUiPath { get { return Obj_NPCHeadUI.pathData; } } public int GetJumpId() { return jumpData.JumpId; } public void LockDistanceCheck() { _distanceModule.RefreshTime(); } public override bool Init(ObjParent_Init_Data initData) { var result = base.Init(initData); if (!result) return false; var jumpInitData = initData as Obj_JumpPoint_Init_Data; if (jumpInitData == null || jumpInitData.jumpData == null) { Destroy(gameObject); return false; } enabled = false; //gameObject.AddComponent(); jumpData = jumpInitData.jumpData; gameObject.name = "JumpPoint_" + jumpData.JumpId; _distanceModule = new TeleportDistanceModule(m_ObjTransform, jumpData.RangeRadius); var finalJumpData = jumpData.GetFinialJumpData(); // 如果是同场景跳跃,增加OffMeshLink以供寻路机使用 var destination = ActiveScene.GetTerrainPosition(new Vector3(finalJumpData.EndPosX, 0f, finalJumpData.EndPosZ)); CreateOffmeshLink(gameObject, destination); return true; } protected override void Awake() { base.Awake(); _rootObj = transform.GetChild(0).gameObject; } protected void OnBecameVisible() { enabled = true; if (_rootObj) _rootObj.SetActive(true); } protected void OnBecameInvisible() { enabled = false; if (_rootObj) _rootObj.SetActive(false); } private void Update() { var mainPlayer = _distanceModule.UpdateDistance(); // 仅允许主角主动行为触发 // 变身状态不允许跳跃 if (mainPlayer != null && !mainPlayer.IsFollowTeam && mainPlayer.ForceUseModel == null) mainPlayer.MainPlayerStartJumpWait(jumpData.JumpId); } private static UnityEngine.AI.OffMeshLink CreateOffmeshLink(GameObject gameObject, Vector3 endPoint) { // 如果是同场景跳跃,增加OffMeshLink以供寻路机使用 var offMeshLink = gameObject.EnsureComponent(); offMeshLink.autoUpdatePositions = false; offMeshLink.biDirectional = false; // 优先使用传送点 //offMeshLink.costOverride = 0f; offMeshLink.area = GameDefine_Globe.NavMeshLayer.jump; // 不知道Init和Awake哪个快,安全点还是用transform offMeshLink.startTransform = gameObject.transform; if (offMeshLink.endTransform == null) offMeshLink.endTransform = new GameObject(gameObject.name + "_EndPoint").transform; offMeshLink.endTransform.position = endPoint; offMeshLink.UpdatePositions(); return offMeshLink; } } public class TeleportDistanceModule { // 同一个传送点3秒内只能用一次 private readonly float _distanceSqr; private readonly Transform _root; private float _nextJumpTime; public TeleportDistanceModule(Transform root, float distance) { _distanceSqr = distance.ToSquare(); _root = root; } public void RefreshTime() { // JumpWait解除后,玩家有反应时间来避开锁定 _nextJumpTime = Time.unscaledTime + Obj_MainPlayer.MainPlayerJumpWait.maxWaitTime * 2f; } public Obj_MainPlayer UpdateDistance() { Obj_MainPlayer mainPlayer = null; if (Time.unscaledTime > _nextJumpTime) { mainPlayer = Singleton.Instance.MainPlayer; if (mainPlayer != null) // 死亡和变身不允许跳跃 if (mainPlayer.IsDie()) mainPlayer = null; else if ((mainPlayer.Position - _root.position).RemoveY().sqrMagnitude < _distanceSqr && mainPlayer.MovementState == MoveState.Static) RefreshTime(); else mainPlayer = null; } return mainPlayer; } } }