XRoom_Unity/Assets/videoPlayerManager.cs
2025-05-31 10:20:20 +03:30

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;
}
}