Files
dungeons/Assets/Scripts/Components/PlayerComponent.cs
2025-06-26 21:27:54 +02:00

199 lines
4.9 KiB
C#

using HurricaneVR.Framework.Components;
using HurricaneVR.Framework.ControllerInput;
using HurricaneVR.Framework.Core.Player;
using HurricaneVR.Framework.Core.UI;
using Meta.XR.MultiplayerBlocks.NGO;
using Sirenix.OdinInspector;
using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using Unity.Netcode.Components;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Rendering.Universal;
using UnityEngine.UIElements;
using Zenject;
public class PlayerComponent : NetworkBehaviour
{
[SerializeField]
[Inject]
private HVRInputModule inputModule;
[SerializeField]
private NetworkObject networkObject;
[SerializeField]
private HVRTeleporter teleporter;
[SerializeField]
private HVRPlayerController controller;
[SerializeField]
private CharacterController characterController;
[SerializeField]
private AudioListener audioListener;
[ReadOnly]
[SerializeField]
private float fadeDuration = 2f;
private GameObject[] dependencies => new GameObject[] {
controller.RightHand.ForceGrabber._anchor.gameObject,
controller.LeftHand.ForceGrabber._anchor.gameObject,
controller.LeftHand._anchor,
controller.RightHand._anchor
};
public Vector3 Position => controller.transform.position;
public Vector3 Rotation => controller.Camera.forward;
private bool isSoloRig => !networkObject.IsPlayerObject;
private bool isLocalRig => networkObject.IsLocalPlayer;
private bool isRemoteRig => !networkObject.IsOwner && networkObject.IsPlayerObject;
// Teleport information after player is loaded into scene
private Vector3 teleportPosition;
private Vector3 teleportRotation;
private bool teleportAfterLoad;
private bool isLoaded;
private void Start()
{
this.Inject();
StartCoroutine(AddDontDestroyToDependencies());
if (isSoloRig)
{
AddPointersToInputModule();
name = "Player - SP";
StartCoroutine(DestroyComponentsNotNeededForSolo());
DontDestroyOnLoad(gameObject);
}
else if (isLocalRig)
{
AddPointersToInputModule();
name = $"Player - MP {networkObject.OwnerClientId} (local)";
}
else if (isRemoteRig)
{
name = $"Player - MP {networkObject.OwnerClientId}";
StartCoroutine(DestroyComponentsNotNeededForRemoteRigs());
}
isLoaded = true;
if (teleportAfterLoad)
{
Teleport(teleportPosition, teleportRotation);
}
}
private void AddPointersToInputModule()
{
foreach (var pointer in GetComponentsInChildren<HVRUIPointer>())
{
inputModule.AddPointer(pointer);
}
}
private IEnumerator DestroyComponentsNotNeededForRemoteRigs()
{
yield return new WaitForEndOfFrame();
DestroyDependencies();
foreach (var t in new[]
{
typeof(UniversalAdditionalCameraData),
typeof(HandMenuUI)
})
{
foreach (var component in GetComponentsInChildren(t))
{
Destroy(component);
}
}
controller.RemoveMultiplayerComponents();
}
private IEnumerator DestroyComponentsNotNeededForSolo()
{
yield return new WaitForEndOfFrame();
foreach (var t in new[]
{
typeof(NetworkObject),
typeof(NetworkTransform)
})
{
foreach (var component in GetComponentsInChildren(t))
{
Destroy(component);
}
}
}
private IEnumerator AddDontDestroyToDependencies()
{
yield return new WaitForEndOfFrame();
foreach (var d in dependencies)
{
DontDestroyOnLoad(d);
}
}
public void DestroyDependencies()
{
foreach (var d in dependencies)
{
Destroy(d);
}
}
public void Teleport(Vector3 position, Vector3 direction)
{
StartCoroutine(TeleportAtTheEndOfFrame(position, direction));
}
private IEnumerator TeleportAtTheEndOfFrame(Vector3 position, Vector3 direction)
{
yield return new WaitForEndOfFrame();
if (isLoaded)
{
teleporter.Teleport(position, direction);
}
else
{
teleportPosition = position;
teleportRotation = direction;
teleportAfterLoad = true;
}
}
public void FadeScreen(float to, float duration)
{
controller.ScreenFader.Fade(to, duration);
}
public void FadeIn()
{
controller.ScreenFader.Fade(1, fadeDuration);
}
public void FadeOut()
{
controller.ScreenFader.Fade(0, fadeDuration);
}
}