256 lines
7.1 KiB
C#
256 lines
7.1 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using UnityEngine.Video;
|
|
using Fusion;
|
|
using System.Collections.Generic;
|
|
using System.Collections;
|
|
|
|
public class VideoPlayerManager : NetworkBehaviour
|
|
{
|
|
public VideoPlayer videoPlayer;
|
|
private GameObject nearestTV;
|
|
public float detectionRadius = 4f;
|
|
public LineRenderer lineRenderer;
|
|
public Transform startPoint;
|
|
public Image play;
|
|
public GameObject cast;
|
|
public Slider videoSlider;
|
|
private float lastSyncTime = 0f;
|
|
public string videoUrl;
|
|
|
|
public Material sample;
|
|
|
|
[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;
|
|
|
|
}
|
|
public GameObject loadingScreen;
|
|
void Update()
|
|
{
|
|
if (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;
|
|
}
|
|
|
|
// بررسی وضعیت پخش ویدیو در کلاینتها
|
|
if (videoPlayer.isPlaying != isPlaying)
|
|
{
|
|
if (isPlaying)
|
|
{
|
|
StartCoroutine(StartVideo());
|
|
}
|
|
else videoPlayer.Pause();
|
|
}
|
|
}
|
|
|
|
private IEnumerator StartVideo()
|
|
{
|
|
videoPlayer.Prepare();
|
|
while (!videoPlayer.isPrepared)
|
|
{
|
|
yield return null;
|
|
|
|
// آپدیت کردن نوار پیشرفت
|
|
// progressBar.value = (float)(videoPlayer.frame / (double)videoPlayer.frameCount);
|
|
}
|
|
|
|
// وقتی ویدئو آماده بود، صفحه لودینگ را مخفی کرده و پخش ویدئو را آغاز میکنیم
|
|
loadingScreen.SetActive(false);
|
|
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);
|
|
|
|
|
|
|
|
|
|
}
|
|
public Transform Player;
|
|
|
|
[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);
|
|
videoSlider.minValue = 0;
|
|
videoSlider.maxValue = (float)videoPlayer.length;
|
|
videoSlider.onValueChanged.RemoveAllListeners();
|
|
// در صورتی که اسلایدر تغییر کند، موقعیت ویدئو تغییر میکند
|
|
videoSlider.onValueChanged.AddListener(OnSliderValueChanged);
|
|
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>();
|
|
// AudioSource audio = tv.GetComponentInChildren<AudioSource>();
|
|
if (tvScreen != null)
|
|
{
|
|
tvScreen.texture = raw.texture;
|
|
tvScreen.material = raw.material;
|
|
//if (audio)
|
|
//{
|
|
// audio.clip = GetComponent<AudioSource>().clip;
|
|
// audio.Play();
|
|
//}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public RawImage raw;
|
|
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);
|
|
}
|
|
void OnSliderValueChanged(float value)
|
|
{
|
|
videoPlayer.time = value;
|
|
}
|
|
}
|