170 lines
5.5 KiB
C#
170 lines
5.5 KiB
C#
/********************************************************************************
|
||
* 文件名: 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<ShaderFix>();
|
||
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<UnityEngine.AI.OffMeshLink>();
|
||
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<ObjManager>.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;
|
||
}
|
||
}
|
||
} |