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 textureDataList = new List(); // برای ذخیره داده‌های چانک‌ها 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(); if (renderer != null) { if(!Runner.IsServer) renderer.GetComponent().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); } }