196 lines
5.9 KiB
C#
196 lines
5.9 KiB
C#
using System.Collections.Generic;
|
|
using Fusion;
|
|
using UnityEngine;
|
|
|
|
public class RenderTextureSender : NetworkBehaviour
|
|
{
|
|
public Camera targetCamera;
|
|
public GameObject OtherWhiteBoard;
|
|
private bool isInitialized = false;
|
|
|
|
private const int MaxPayloadSize = 450; // حداکثر اندازه چانک
|
|
private Texture2D previousTexture; // ذخیره تکسچر قبلی برای مقایسه
|
|
public GameObject back;
|
|
private float resendTimer;
|
|
private List<byte> textureDataList = new List<byte>(); // برای ذخیره دادههای چانکها
|
|
|
|
public override void Spawned()
|
|
{
|
|
base.Spawned();
|
|
|
|
if (Object == null)
|
|
{
|
|
Debug.LogError("[Photon Fusion] NetworkObject مقداردهی نشده است!");
|
|
return;
|
|
}
|
|
|
|
isInitialized = true;
|
|
Debug.Log("[Photon Fusion] RenderTextureSender Initialized.");
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
if (targetCamera == null)
|
|
{
|
|
Debug.LogError("[Photon Fusion] Target Camera مقداردهی نشده است!");
|
|
}
|
|
resendTimer = Time.time;
|
|
}
|
|
public int timerLoad = 60;
|
|
private void Update()
|
|
{
|
|
if (isInitialized && Time.time > resendTimer)
|
|
{
|
|
resendTimer = Time.time + timerLoad;
|
|
SendRenderTexture();
|
|
Remove();
|
|
}
|
|
}
|
|
|
|
public void Remove()
|
|
{
|
|
if (back != null)
|
|
{
|
|
back.gameObject.SetActive(false);
|
|
}
|
|
}
|
|
|
|
[Rpc(RpcSources.StateAuthority, RpcTargets.All)]
|
|
public void RPC_SendRenderTexture(byte[] textureData, int chunkIndex, int totalChunks)
|
|
{
|
|
Debug.Log("Received Chunk: " + chunkIndex + "/" + totalChunks);
|
|
|
|
if (!isInitialized)
|
|
{
|
|
Debug.LogError("[Photon Fusion] هنوز مقداردهی نشده است!");
|
|
return;
|
|
}
|
|
|
|
textureDataList.AddRange(textureData);
|
|
|
|
if (chunkIndex == totalChunks - 1) // دریافت کامل چانکها
|
|
{
|
|
Texture2D receivedTexture = new Texture2D(2, 2);
|
|
receivedTexture.LoadImage(textureDataList.ToArray());
|
|
ApplyTexture(receivedTexture);
|
|
textureDataList.Clear();
|
|
}
|
|
}
|
|
|
|
public void SendRenderTexture()
|
|
{
|
|
if (Object == null)
|
|
{
|
|
Debug.LogError("[Photon Fusion] NetworkObject مقداردهی نشده است!");
|
|
return;
|
|
}
|
|
|
|
//if (!Object.HasInputAuthority)
|
|
{
|
|
// Debug.LogWarning("[Photon Fusion] شما دسترسی لازم برای ارسال RPC ندارید!");
|
|
// return;
|
|
}
|
|
|
|
if (targetCamera == null || targetCamera.targetTexture == null)
|
|
{
|
|
Debug.LogError("[Photon Fusion] Target Camera یا RenderTexture مقداردهی نشده است!");
|
|
return;
|
|
}
|
|
|
|
Texture2D currentTexture = GetTextureFromRenderTexture(targetCamera.targetTexture);
|
|
|
|
if (previousTexture != null && AreTexturesEqual(previousTexture, currentTexture))
|
|
{
|
|
return; // عدم ارسال در صورت نبود تغییرات
|
|
}
|
|
|
|
previousTexture = currentTexture;
|
|
|
|
byte[] textureData = RenderTextureUtils.RenderTextureToByteArray(targetCamera.targetTexture);
|
|
int totalChunks = Mathf.CeilToInt(textureData.Length / (float)MaxPayloadSize);
|
|
|
|
for (int i = 0; i < totalChunks; i++)
|
|
{
|
|
int chunkSize = Mathf.Min(MaxPayloadSize, textureData.Length - i * MaxPayloadSize);
|
|
byte[] chunkData = new byte[chunkSize];
|
|
System.Array.Copy(textureData, i * MaxPayloadSize, chunkData, 0, chunkSize);
|
|
|
|
RPC_SendRenderTexture(chunkData, i, totalChunks);
|
|
}
|
|
}
|
|
|
|
private void ApplyTexture(Texture2D texture)
|
|
{
|
|
if (OtherWhiteBoard == null)
|
|
{
|
|
OtherWhiteBoard = GameObject.FindGameObjectWithTag("whiteboard");
|
|
}
|
|
|
|
if (OtherWhiteBoard == null)
|
|
{
|
|
Debug.LogError("[Photon Fusion] OtherWhiteBoard مقداردهی نشده است!");
|
|
return;
|
|
}
|
|
|
|
Renderer renderer = OtherWhiteBoard.GetComponent<Renderer>();
|
|
if (renderer != null)
|
|
{
|
|
if(!Runner.IsServer)
|
|
renderer.GetComponent<MeshRenderer>().enabled = true;
|
|
renderer.material.mainTexture = texture;
|
|
}
|
|
}
|
|
|
|
private Texture2D GetTextureFromRenderTexture(RenderTexture renderTexture)
|
|
{
|
|
Texture2D texture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.RGB24, false);
|
|
RenderTexture.active = renderTexture;
|
|
texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
|
|
texture.Apply();
|
|
RenderTexture.active = null;
|
|
|
|
return texture;
|
|
}
|
|
|
|
private bool AreTexturesEqual(Texture2D texture1, Texture2D texture2)
|
|
{
|
|
if (texture1.width != texture2.width || texture1.height != texture2.height)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Color[] pixels1 = texture1.GetPixels();
|
|
Color[] pixels2 = texture2.GetPixels();
|
|
|
|
for (int i = 0; i < pixels1.Length; i++)
|
|
{
|
|
if (pixels1[i] != pixels2[i])
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public static class RenderTextureUtils
|
|
{
|
|
public static byte[] RenderTextureToByteArray(RenderTexture renderTexture)
|
|
{
|
|
if (renderTexture == null)
|
|
{
|
|
Debug.LogError("[RenderTextureUtils] RenderTexture مقداردهی نشده است!");
|
|
return null;
|
|
}
|
|
|
|
Texture2D texture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.RGB24, false);
|
|
RenderTexture.active = renderTexture;
|
|
texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
|
|
texture.Apply();
|
|
RenderTexture.active = null;
|
|
|
|
return texture.EncodeToJPG(75);
|
|
}
|
|
}
|