XRoom_Unity/Assets/videoPlayerManager.cs

277 lines
7.3 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;
using UnityEngine.EventSystems;
using Fusion;
using System.Collections;
using System.Collections.Generic;
public class VideoPlayerManager : NetworkBehaviour
{
public VideoPlayer videoPlayer;
public RawImage raw;
public Material sample;
public GameObject loadingScreen;
public Slider videoSlider;
public Image play;
public GameObject cast;
public Transform startPoint;
public Transform Player;
private GameObject nearestTV;
public float detectionRadius = 4f;
public LineRenderer lineRenderer;
private float lastSyncTime = 0f;
private bool isDraggingSlider = false;
public string videoUrl;
[Networked]
private bool isPlaying { get; set; }
[Networked]
private float videoTime { get; set; }
void Start()
{
if (videoPlayer == null)
videoPlayer = GetComponent<VideoPlayer>();
videoPlayer.loopPointReached += OnVideoFinished;
if (lineRenderer == null)
{
lineRenderer = gameObject.AddComponent<LineRenderer>();
lineRenderer.startWidth = 0.05f;
lineRenderer.endWidth = 0.05f;
lineRenderer.positionCount = 20;
lineRenderer.material = new Material(Shader.Find("Sprites/Default"));
lineRenderer.material.color = Color.yellow;
}
raw.material = new Material(sample);
RenderTexture renderTexture = new RenderTexture(1920, 1080, 16);
videoPlayer.targetTexture = renderTexture;
raw.texture = renderTexture;
// Slider drag listeners
AddSliderDragHandlers();
videoSlider.onValueChanged.AddListener(OnSliderValueChanged);
}
void Update()
{
if (!isDraggingSlider && videoPlayer.isPlaying)
{
videoSlider.value = (float)videoPlayer.time;
}
play.color = videoPlayer.isPlaying ? Color.green : Color.white;
cast.SetActive(nearestTV);
FindNearestTV();
if (nearestTV != null)
DrawCurvedLine();
else
lineRenderer.enabled = false;
// Sync play state
if (videoPlayer.isPlaying != isPlaying)
{
if (isPlaying)
StartCoroutine(StartVideo());
else
videoPlayer.Pause();
}
}
private IEnumerator StartVideo()
{
videoPlayer.Prepare();
while (!videoPlayer.isPrepared)
{
yield return null;
}
loadingScreen.SetActive(false);
videoSlider.minValue = 0;
videoSlider.maxValue = (float)videoPlayer.length;
videoPlayer.Play();
}
public void send()
{
if (Object.HasStateAuthority)
{
Play();
InvokeRepeating(nameof(SyncVideoTime), 5f, 5f);
}
}
public void Cast()
{
if (Object.HasStateAuthority && nearestTV != null)
{
RPC_SetScreenTexture(Object.Id, nearestTV.GetComponent<NetworkObject>().Id);
}
}
public void Play()
{
if (Object.HasStateAuthority)
{
RPC_TogglePlayPause(videoUrl);
}
}
[Rpc(RpcSources.All, RpcTargets.All)]
private void RPC_TogglePlayPause(string url)
{
videoUrl = url;
if (!string.IsNullOrEmpty(videoUrl) && url != videoPlayer.url)
{
Player.parent.gameObject.SetActive(true);
Player.gameObject.SetActive(true);
loadingScreen.SetActive(true);
videoPlayer.url = videoUrl;
}
isPlaying = !isPlaying;
videoTime = (float)videoPlayer.time;
RPC_SyncVideoState(isPlaying, videoTime);
}
[Rpc(RpcSources.StateAuthority, RpcTargets.All)]
private void RPC_SyncVideoState(bool playState, float syncTime)
{
isPlaying = playState;
videoTime = syncTime;
videoPlayer.time = syncTime;
if (isPlaying) videoPlayer.Play();
else videoPlayer.Pause();
}
private void SyncVideoTime()
{
if (Object.HasStateAuthority && videoPlayer.isPlaying)
{
float currentTime = (float)videoPlayer.time;
RPC_SyncVideoState(isPlaying, currentTime);
}
}
[Rpc(RpcSources.StateAuthority, RpcTargets.All)]
private void RPC_SetScreenTexture(NetworkId playerId, NetworkId tvId)
{
GameObject[] allTVs = GameObject.FindGameObjectsWithTag("tv");
foreach (var tv in allTVs)
{
if (tv.GetComponent<NetworkObject>().Id == tvId)
{
RawImage tvScreen = tv.GetComponentInChildren<RawImage>();
if (tvScreen != null)
{
tvScreen.texture = raw.texture;
tvScreen.material = raw.material;
}
}
}
}
private void FindNearestTV()
{
GameObject[] tvObjects = GameObject.FindGameObjectsWithTag("tv");
float minDistance = detectionRadius;
nearestTV = null;
foreach (var tv in tvObjects)
{
float distance = Vector3.Distance(transform.position, tv.transform.position);
if (distance < minDistance)
{
minDistance = distance;
nearestTV = tv;
}
}
}
private void DrawCurvedLine()
{
if (nearestTV == null || startPoint == null) return;
lineRenderer.enabled = true;
Vector3 start = startPoint.position;
Vector3 end = nearestTV.transform.position;
Vector3 middle = (start + end) / 2 + Vector3.up * 1;
List<Vector3> curvePoints = new List<Vector3>();
for (float t = 0; t <= 1; t += 0.05f)
{
Vector3 point = Mathf.Pow(1 - t, 2) * start + 2 * (1 - t) * t * middle + Mathf.Pow(t, 2) * end;
curvePoints.Add(point);
}
lineRenderer.positionCount = curvePoints.Count;
lineRenderer.SetPositions(curvePoints.ToArray());
}
private void OnVideoFinished(VideoPlayer vp)
{
isPlaying = false;
}
public void Show(string u)
{
videoUrl = u;
Invoke("send", 1);
}
public void OnSliderValueChanged(float value)
{
if (isDraggingSlider)
{
videoPlayer.time = value;
}
}
private void AddSliderDragHandlers()
{
EventTrigger trigger = videoSlider.gameObject.GetComponent<EventTrigger>();
if (trigger == null)
trigger = videoSlider.gameObject.AddComponent<EventTrigger>();
trigger.triggers = new List<EventTrigger.Entry>();
// Pointer Down
EventTrigger.Entry entryDown = new EventTrigger.Entry();
entryDown.eventID = EventTriggerType.PointerDown;
entryDown.callback.AddListener((data) => { isDraggingSlider = true; });
trigger.triggers.Add(entryDown);
// Pointer Up
EventTrigger.Entry entryUp = new EventTrigger.Entry();
entryUp.eventID = EventTriggerType.PointerUp;
entryUp.callback.AddListener((data) =>
{
isDraggingSlider = false;
if (Object.HasStateAuthority)
{
videoTime = (float)videoPlayer.time;
RPC_SyncVideoState(isPlaying, videoTime);
}
});
trigger.triggers.Add(entryUp);
}
}