277 lines
7.3 KiB
C#
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);
|
|
}
|
|
}
|