Files
JJBB/Assets/Project/Script/Obj/Obj_Characters/Obj_JumpPoint.cs
2024-08-23 15:49:34 +08:00

170 lines
5.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/********************************************************************************
* 文件名: 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;
}
}
}