using System.Collections; using GameNetcodeStuff; using Unity.Netcode; using UnityEngine; public class InteractTrigger : NetworkBehaviour { [Header("Aesthetics")] public Sprite hoverIcon; public string hoverTip; [Space(5f)] public Sprite disabledHoverIcon; public string disabledHoverTip; [Header("Interaction")] public bool interactable = true; public bool oneHandedItemAllowed = true; public bool twoHandedItemAllowed; [Space(5f)] public bool holdInteraction; public float timeToHold = 0.5f; public float timeToHoldSpeedMultiplier = 1f; public string holdTip; public bool isBeingHeldByPlayer; public InteractEventFloat holdingInteractEvent; private float timeHeld; private bool isHoldingThisFrame; [Space(5f)] public bool touchTrigger; public bool triggerOnce; private bool hasTriggered; [Header("Misc")] public bool interactCooldown = true; public float cooldownTime = 1f; [HideInInspector] public float currentCooldownValue; public bool disableTriggerMesh = true; [Space(5f)] public bool RandomChanceTrigger; public int randomChancePercentage; [Header("Events")] public InteractEvent onInteract; public InteractEvent onInteractEarly; public InteractEvent onStopInteract; [Header("Special Animation")] public bool specialCharacterAnimation; public bool stopAnimationManually; public string stopAnimationString = "SA_stopAnimation"; public bool hidePlayerItem; [HideInInspector] public bool isPlayingSpecialAnimation; public float animationWaitTime = 2f; public string animationString; [Space(5f)] public bool lockPlayerPosition; public Transform playerPositionNode; private Transform lockedPlayer; private bool usedByOtherClient; private StartOfRound playersManager; private float updateInterval = 1f; [Header("Ladders")] public bool isLadder; public Transform topOfLadderPosition; public Transform bottomOfLadderPosition; public Transform ladderHorizontalPosition; [Space(5f)] public Transform ladderPlayerPositionNode; public bool usingLadder; private bool atBottomOfLadder; private Vector3 moveVelocity; private PlayerControllerB playerScriptInSpecialAnimation; private Coroutine useLadderCoroutine; private int playerUsingId; public void StopInteraction() { if (isBeingHeldByPlayer) { isBeingHeldByPlayer = false; onStopInteract.Invoke(null); } } public void HoldInteractNotFilled() { Debug.Log("Holding interact"); holdingInteractEvent.Invoke(HUDManager.Instance.holdFillAmount / timeToHold); if (!specialCharacterAnimation && !isLadder) { if (!isBeingHeldByPlayer) { onInteractEarly.Invoke(null); } isBeingHeldByPlayer = true; } } public void Interact(Transform playerTransform) { if ((triggerOnce && hasTriggered) || StartOfRound.Instance.firingPlayersCutsceneRunning) { return; } hasTriggered = true; if (RandomChanceTrigger && Random.Range(0, 101) > randomChancePercentage) { return; } if (!interactable || isPlayingSpecialAnimation || usingLadder) { if (usingLadder) { CancelLadderAnimation(); } return; } PlayerControllerB component = playerTransform.GetComponent(); if (component.inSpecialInteractAnimation && !component.isClimbingLadder) { return; } if (interactCooldown) { if (currentCooldownValue >= 0f) { return; } currentCooldownValue = cooldownTime; } if (!specialCharacterAnimation && !isLadder) { onInteract.Invoke(component); return; } component.ResetFallGravity(); if (isLadder) { ladderPlayerPositionNode.position = new Vector3(ladderHorizontalPosition.position.x, Mathf.Clamp(component.thisPlayerBody.position.y, bottomOfLadderPosition.position.y + 0.3f, topOfLadderPosition.position.y - 2.2f), ladderHorizontalPosition.position.z); if (!LadderPositionObstructed(component)) { if (useLadderCoroutine != null) { StopCoroutine(useLadderCoroutine); } useLadderCoroutine = StartCoroutine(ladderClimbAnimation(component)); } } else { StartCoroutine(specialInteractAnimation(component)); } } private bool LadderPositionObstructed(PlayerControllerB playerController) { RaycastHit hitInfo2; if (playerController.transform.position.y >= topOfLadderPosition.position.y - 0.5f) { if (Physics.Linecast(playerController.gameplayCamera.transform.position, ladderPlayerPositionNode.position + Vector3.up * 2.8f, out var _, StartOfRound.Instance.collidersAndRoomMaskAndDefault, QueryTriggerInteraction.Ignore)) { return true; } } else if (Physics.Linecast(playerController.gameplayCamera.transform.position, ladderPlayerPositionNode.position, out hitInfo2, StartOfRound.Instance.collidersAndRoomMaskAndDefault, QueryTriggerInteraction.Ignore)) { return true; } return false; } private IEnumerator ladderClimbAnimation(PlayerControllerB playerController) { onInteractEarly.Invoke(null); lockedPlayer = playerController.thisPlayerBody; playerScriptInSpecialAnimation = playerController; if (hidePlayerItem && playerScriptInSpecialAnimation.currentlyHeldObjectServer != null) { playerScriptInSpecialAnimation.currentlyHeldObjectServer.EnableItemMeshes(enable: false); } SetUsingLadderOnLocalClient(isUsing: true); hoverTip = "Let go : [LMB]"; if (!playerController.isTestingPlayer) { playerController.UpdateSpecialAnimationValue(specialAnimation: true, (short)ladderPlayerPositionNode.eulerAngles.y); } playerController.enteringSpecialAnimation = true; playerController.inSpecialInteractAnimation = true; playerController.currentTriggerInAnimationWith = this; playerController.isCrouching = false; playerController.playerBodyAnimator.SetBool("crouching", value: false); playerController.playerBodyAnimator.SetTrigger("EnterLadder"); float timer2 = 0f; while (timer2 <= animationWaitTime) { yield return null; timer2 += Time.deltaTime; playerController.thisPlayerBody.position = Vector3.Lerp(playerController.thisPlayerBody.position, ladderPlayerPositionNode.position, Mathf.SmoothStep(0f, 1f, timer2 / animationWaitTime)); lockedPlayer.rotation = Quaternion.Lerp(lockedPlayer.rotation, ladderPlayerPositionNode.rotation, Mathf.SmoothStep(0f, 1f, timer2 / animationWaitTime)); } playerController.TeleportPlayer(ladderPlayerPositionNode.position, withRotation: false, 0f, allowInteractTrigger: true); Debug.Log("Finished snapping to ladder"); playerController.playerBodyAnimator.SetBool("ClimbingLadder", value: true); playerController.isClimbingLadder = true; playerController.enteringSpecialAnimation = false; playerController.ladderCameraHorizontal = 0f; playerController.clampCameraRotation = bottomOfLadderPosition.eulerAngles; int finishClimbingLadder = 0; while (finishClimbingLadder == 0) { yield return null; yield return null; if (playerController.thisPlayerBody.position.y < bottomOfLadderPosition.position.y) { finishClimbingLadder = 1; } else if (playerController.thisPlayerBody.position.y + 2f > topOfLadderPosition.position.y) { finishClimbingLadder = 2; } } playerController.isClimbingLadder = false; playerController.playerBodyAnimator.SetBool("ClimbingLadder", value: false); if (finishClimbingLadder == 1) { ladderPlayerPositionNode.position = bottomOfLadderPosition.position; } else { ladderPlayerPositionNode.position = topOfLadderPosition.position; } timer2 = 0f; float shorterWaitTime = animationWaitTime / 2f; while (timer2 <= shorterWaitTime) { yield return null; timer2 += Time.deltaTime; playerController.thisPlayerBody.position = Vector3.Lerp(playerController.thisPlayerBody.position, ladderPlayerPositionNode.position, Mathf.SmoothStep(0f, 1f, timer2 / shorterWaitTime)); playerController.thisPlayerBody.rotation = Quaternion.Lerp(playerController.thisPlayerBody.rotation, ladderPlayerPositionNode.rotation, Mathf.SmoothStep(0f, 1f, timer2 / shorterWaitTime)); playerController.gameplayCamera.transform.rotation = Quaternion.Slerp(playerController.gameplayCamera.transform.rotation, playerController.gameplayCamera.transform.parent.rotation, Mathf.SmoothStep(0f, 1f, timer2 / shorterWaitTime)); } playerController.gameplayCamera.transform.localEulerAngles = Vector3.zero; Debug.Log("Finished ladder sequence"); playerController.UpdateSpecialAnimationValue(specialAnimation: false, 0); playerController.inSpecialInteractAnimation = false; SetUsingLadderOnLocalClient(isUsing: false); hoverTip = "Use ladder : [LMB]"; lockedPlayer = null; currentCooldownValue = cooldownTime; onInteract.Invoke(null); } public void CancelAnimationExternally() { if (isLadder) { CancelLadderAnimation(); } else { StopSpecialAnimation(); } } public void CancelLadderAnimation() { if (useLadderCoroutine != null) { StopCoroutine(useLadderCoroutine); } playerScriptInSpecialAnimation.currentTriggerInAnimationWith = null; playerScriptInSpecialAnimation.isClimbingLadder = false; playerScriptInSpecialAnimation.playerBodyAnimator.SetBool("ClimbingLadder", value: false); playerScriptInSpecialAnimation.gameplayCamera.transform.localEulerAngles = Vector3.zero; playerScriptInSpecialAnimation.UpdateSpecialAnimationValue(specialAnimation: false, 0); playerScriptInSpecialAnimation.inSpecialInteractAnimation = false; SetUsingLadderOnLocalClient(isUsing: false); lockedPlayer = null; currentCooldownValue = cooldownTime; if (hidePlayerItem && playerScriptInSpecialAnimation.currentlyHeldObjectServer != null) { playerScriptInSpecialAnimation.currentlyHeldObjectServer.EnableItemMeshes(enable: true); } onInteract.Invoke(null); } private void SetUsingLadderOnLocalClient(bool isUsing) { usingLadder = isUsing; if (isUsing) { hoverTip = "Let go : [LMB]"; } else { hoverTip = "Climb : [LMB]"; } } private IEnumerator specialInteractAnimation(PlayerControllerB playerController) { UpdateUsedByPlayerServerRpc((int)playerController.playerClientId); onInteractEarly.Invoke(null); isPlayingSpecialAnimation = true; lockedPlayer = playerController.thisPlayerBody; playerScriptInSpecialAnimation = playerController; if (hidePlayerItem && playerScriptInSpecialAnimation.currentlyHeldObjectServer != null) { playerScriptInSpecialAnimation.currentlyHeldObjectServer.EnableItemMeshes(enable: false); } playerController.Crouch(crouch: false); playerController.UpdateSpecialAnimationValue(specialAnimation: true, (short)playerPositionNode.eulerAngles.y); playerController.inSpecialInteractAnimation = true; playerController.currentTriggerInAnimationWith = this; playerController.playerBodyAnimator.ResetTrigger(animationString); playerController.playerBodyAnimator.SetTrigger(animationString); HUDManager.Instance.ClearControlTips(); if (!stopAnimationManually) { yield return new WaitForSeconds(animationWaitTime); StopSpecialAnimation(); } } public void StopSpecialAnimation() { if (isPlayingSpecialAnimation && stopAnimationManually) { StopUsingServerRpc(); } if (lockedPlayer != null) { PlayerControllerB component = lockedPlayer.GetComponent(); Debug.Log("STOPPING SPECIAL ANIMATION ON LOCAL CLIENT"); if (hidePlayerItem && component.currentlyHeldObjectServer != null) { component.currentlyHeldObjectServer.EnableItemMeshes(enable: true); } isPlayingSpecialAnimation = false; component.inSpecialInteractAnimation = false; component.currentTriggerInAnimationWith = null; if (component.isClimbingLadder) { CancelLadderAnimation(); component.isClimbingLadder = false; } if (stopAnimationManually) { component.playerBodyAnimator.SetTrigger(stopAnimationString); } component.UpdateSpecialAnimationValue(specialAnimation: false, 0); lockedPlayer = null; currentCooldownValue = cooldownTime; onInteract.Invoke(null); if (component.isHoldingObject && component.currentlyHeldObjectServer != null) { component.currentlyHeldObjectServer.SetControlTipsForItem(); } } } [ServerRpc(RequireOwnership = false)] private void UpdateUsedByPlayerServerRpc(int playerNum) { NetworkManager networkManager = base.NetworkManager; if ((object)networkManager != null && networkManager.IsListening) { if (__rpc_exec_stage != __RpcExecStage.Server && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams serverRpcParams = default(ServerRpcParams); FastBufferWriter bufferWriter = __beginSendServerRpc(1430497838u, serverRpcParams, RpcDelivery.Reliable); BytePacker.WriteValueBitPacked(bufferWriter, playerNum); __endSendServerRpc(ref bufferWriter, 1430497838u, serverRpcParams, RpcDelivery.Reliable); } if (__rpc_exec_stage == __RpcExecStage.Server && (networkManager.IsServer || networkManager.IsHost)) { UpdateUsedByPlayerClientRpc(playerNum); } } } [ClientRpc] private void UpdateUsedByPlayerClientRpc(int playerNum) { NetworkManager networkManager = base.NetworkManager; if ((object)networkManager == null || !networkManager.IsListening) { return; } if (__rpc_exec_stage != __RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams clientRpcParams = default(ClientRpcParams); FastBufferWriter bufferWriter = __beginSendClientRpc(3458599252u, clientRpcParams, RpcDelivery.Reliable); BytePacker.WriteValueBitPacked(bufferWriter, playerNum); __endSendClientRpc(ref bufferWriter, 3458599252u, clientRpcParams, RpcDelivery.Reliable); } if (__rpc_exec_stage == __RpcExecStage.Client && (networkManager.IsClient || networkManager.IsHost)) { if (hidePlayerItem && StartOfRound.Instance.allPlayerScripts[playerNum].currentlyHeldObjectServer != null) { StartOfRound.Instance.allPlayerScripts[playerNum].currentlyHeldObjectServer.EnableItemMeshes(enable: false); playerUsingId = playerNum; } if (stopAnimationManually) { isPlayingSpecialAnimation = true; } else { StartCoroutine(isSpecialAnimationPlayingTimer()); } } } private IEnumerator isSpecialAnimationPlayingTimer() { isPlayingSpecialAnimation = true; yield return new WaitForSeconds(animationWaitTime); isPlayingSpecialAnimation = false; } [ServerRpc(RequireOwnership = false)] private void StopUsingServerRpc() { NetworkManager networkManager = base.NetworkManager; if ((object)networkManager != null && networkManager.IsListening) { if (__rpc_exec_stage != __RpcExecStage.Server && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams serverRpcParams = default(ServerRpcParams); FastBufferWriter bufferWriter = __beginSendServerRpc(4027596885u, serverRpcParams, RpcDelivery.Reliable); __endSendServerRpc(ref bufferWriter, 4027596885u, serverRpcParams, RpcDelivery.Reliable); } if (__rpc_exec_stage == __RpcExecStage.Server && (networkManager.IsServer || networkManager.IsHost)) { StopUsingClientRpc(); } } } [ClientRpc] private void StopUsingClientRpc() { NetworkManager networkManager = base.NetworkManager; if ((object)networkManager == null || !networkManager.IsListening) { return; } if (__rpc_exec_stage != __RpcExecStage.Client && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams clientRpcParams = default(ClientRpcParams); FastBufferWriter bufferWriter = __beginSendClientRpc(1213869773u, clientRpcParams, RpcDelivery.Reliable); __endSendClientRpc(ref bufferWriter, 1213869773u, clientRpcParams, RpcDelivery.Reliable); } if (__rpc_exec_stage != __RpcExecStage.Client || (!networkManager.IsClient && !networkManager.IsHost)) { return; } isPlayingSpecialAnimation = false; if (playerUsingId >= 0) { if (StartOfRound.Instance.allPlayerScripts[playerUsingId].currentlyHeldObjectServer != null) { StartOfRound.Instance.allPlayerScripts[playerUsingId].currentlyHeldObjectServer.EnableItemMeshes(enable: true); } playerUsingId = -1; } } private void LateUpdate() { if (isPlayingSpecialAnimation && lockedPlayer != null && !playerScriptInSpecialAnimation.isPlayerDead && lockPlayerPosition) { lockedPlayer.position = Vector3.Lerp(lockedPlayer.position, playerPositionNode.position, Time.deltaTime * 20f); lockedPlayer.rotation = Quaternion.Lerp(lockedPlayer.rotation, playerPositionNode.rotation, Time.deltaTime * 20f); } } private void Update() { if (currentCooldownValue >= 0f) { currentCooldownValue -= Time.deltaTime; } if (isPlayingSpecialAnimation) { if (lockedPlayer != null && playerScriptInSpecialAnimation.isPlayerDead) { StopSpecialAnimation(); } } else if (usingLadder && playerScriptInSpecialAnimation != null && playerScriptInSpecialAnimation.isPlayerDead) { CancelLadderAnimation(); } } private void OnTriggerEnter(Collider other) { if (touchTrigger && other.gameObject.CompareTag("Player") && (bool)other.gameObject.GetComponent() && other.gameObject.GetComponent().IsOwner) { Interact(other.gameObject.GetComponent().thisPlayerBody); } } private void Start() { if (disableTriggerMesh && (bool)base.gameObject.GetComponent()) { base.gameObject.GetComponent().enabled = false; } playersManager = Object.FindObjectOfType(); } public void SetInteractionToHold(bool mustHold) { holdInteraction = mustHold; } public void SetInteractionToHoldOpposite(bool mustHold) { holdInteraction = !mustHold; } public void SetRandomTimeToHold(float min, float max) { timeToHold = Random.Range(min, max); } protected override void __initializeVariables() { base.__initializeVariables(); } [RuntimeInitializeOnLoadMethod] internal static void InitializeRPCS_InteractTrigger() { NetworkManager.__rpc_func_table.Add(1430497838u, __rpc_handler_1430497838); NetworkManager.__rpc_func_table.Add(3458599252u, __rpc_handler_3458599252); NetworkManager.__rpc_func_table.Add(4027596885u, __rpc_handler_4027596885); NetworkManager.__rpc_func_table.Add(1213869773u, __rpc_handler_1213869773); } private static void __rpc_handler_1430497838(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { NetworkManager networkManager = target.NetworkManager; if ((object)networkManager != null && networkManager.IsListening) { ByteUnpacker.ReadValueBitPacked(reader, out int value); target.__rpc_exec_stage = __RpcExecStage.Server; ((InteractTrigger)target).UpdateUsedByPlayerServerRpc(value); target.__rpc_exec_stage = __RpcExecStage.None; } } private static void __rpc_handler_3458599252(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { NetworkManager networkManager = target.NetworkManager; if ((object)networkManager != null && networkManager.IsListening) { ByteUnpacker.ReadValueBitPacked(reader, out int value); target.__rpc_exec_stage = __RpcExecStage.Client; ((InteractTrigger)target).UpdateUsedByPlayerClientRpc(value); target.__rpc_exec_stage = __RpcExecStage.None; } } private static void __rpc_handler_4027596885(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { NetworkManager networkManager = target.NetworkManager; if ((object)networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = __RpcExecStage.Server; ((InteractTrigger)target).StopUsingServerRpc(); target.__rpc_exec_stage = __RpcExecStage.None; } } private static void __rpc_handler_1213869773(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { NetworkManager networkManager = target.NetworkManager; if ((object)networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = __RpcExecStage.Client; ((InteractTrigger)target).StopUsingClientRpc(); target.__rpc_exec_stage = __RpcExecStage.None; } } protected internal override string __getTypeName() { return "InteractTrigger"; } }