Files
JJBB/Assets/Project/Script/Obj/Obj_Characters/Obj_JumpPoint.cs

170 lines
5.5 KiB
C#
Raw Normal View History

2024-08-23 15:49:34 +08:00
/********************************************************************************
* 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;
}
}
}