Unity投屏功能简单实现(udp)

实现思路:

使用udp协议将渲染图像数据发送给另一个设备。

实现重点:

① 压缩图像尺寸后再发送(源尺寸图像的数据太大)

② udp分包发送(udp单个包最多64k,需要分成小包发送)

demo下载


实现代码:

投屏数据 发起端:

挂载到一个Camera上

using Newtonsoft.Json;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine;




public class Sender : MonoBehaviour
{
    public class VideoImaData
    {
        public bool end;
        public byte[] data;

        public VideoImaData(byte[] data, bool end)
        {
            this.data = data;
            this.end = end;
        }
    }

    public string tarIP = "127.0.0.1";//目标主机IP
    public int tarPort = 8888;//目标主机端口
    private IPEndPoint tarEP;
    private UdpClient udpClient;

    [Header("每秒发送多少张图像(约大约流畅)")]
    [Range(10, 60)]
    public int sendFPS = 25;
    private float delTime = 0f;
    [Header("画质(越大约清晰)")]
    [Range(0.1f, 0.75f)]
    public float huaZhi = 0.25f;
    private int perByteCount = 2048;//单个包字节数
    private RenderTexture renderTexture;


    void Start()
    {
        renderTexture = new RenderTexture(Screen.width, Screen.height, 24);
        GetComponent<Camera>().targetTexture = renderTexture;
        tarEP = new IPEndPoint(IPAddress.Parse(tarIP), tarPort);
        udpClient = new UdpClient();
    }


    private void Update()
    {
        if ((delTime += Time.deltaTime) >= 1f / sendFPS)//每积累一定时间发送一次
        {
            delTime = 0f;
            //将渲染贴图转换为字节序列
            byte[] bytes = ScaleTexture(renderTexture, huaZhi);//发送的图像
            int sendCount = Mathf.CeilToInt(bytes.Length / (float)perByteCount);//分割发送的总次数
            int minCount = bytes.Length % perByteCount;//最小发送字节数
            for (int i = 0; i < sendCount; i++)
            {
                int c = (i == sendCount - 1) ? minCount : perByteCount;
                var imaBytes = new ArraySegment<byte>(bytes, i * perByteCount, c).ToArray();
                var objBytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new VideoImaData(imaBytes, i == sendCount - 1)));
                udpClient.Send(objBytes, objBytes.Length, tarEP);
            }
        }
    }


    //根据一张渲染贴图、缩放倍数
    //生成缩略的图
    private static byte[] ScaleTexture(RenderTexture source, float scale)
    {
        // 计算缩放后的宽高
        int width = (int)(source.width * scale);
        int height = (int)(source.height * scale);

        // 创建一个新的RenderTexture,用于存储缩放后的结果  
        RenderTexture scaled = RenderTexture.GetTemporary(width, height);

        // 激活新的RenderTexture
        RenderTexture.active = scaled;

        // 将源RenderTexture绘制到新的RenderTexture上,实现缩放
        Graphics.Blit(source, scaled);

        // 创建一个新的Texture2D,用于存储最终结果
        Texture2D result = new Texture2D(width, height);

        // 读取RenderTexture的像素数据到Texture2D中
        result.ReadPixels(new Rect(0, 0, width, height), 0, 0);
        //result.Apply();

        RenderTexture.active = null;
        // 释放临时的RenderTexture
        RenderTexture.ReleaseTemporary(scaled);

        // 返回缩放后的Texture2D
        return result.EncodeToJPG();
    }

    private void OnDestroy()
    {
        udpClient.Close();
    }
}

投屏数据 接收端:

挂载到一个RawImage上

using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using UnityEngine;
using UnityEngine.UI;

public class Receiver : MonoBehaviour
{
    public class ImaData
    {
        public bool end;//是否为“最后一块”数据
        public byte[] data;

        public ImaData(byte[] data, bool end)
        {
            this.data = data;
            this.end = end;
        }
    }

    private UdpClient udpClient;
    private RawImage rawImage;
    private Texture2D t2d;
    private List<byte> bytes = new List<byte>();
    private Queue<ImaData> videoImaDatas = new Queue<ImaData>();



    void Start()
    {
        rawImage = GetComponent<RawImage>();
        t2d = new Texture2D(2, 2);
        rawImage.texture = t2d;
        udpClient = new UdpClient(8888);
        UdpRece();
    }
    void Update()
    {
        if (videoImaDatas.TryDequeue(out ImaData d))
        {
            bytes.AddRange(d.data);
            if (d.end)
            {
                t2d.LoadImage(bytes.ToArray());
                bytes.Clear();
            }
        }
    }
    public async void UdpRece()
    {
        while (true)
        {
            byte[] buffer = (await udpClient.ReceiveAsync()).Buffer;
            ImaData obj = JsonConvert.DeserializeObject<ImaData>(Encoding.UTF8.GetString(buffer));
            videoImaDatas.Enqueue(obj);
        }
    }
}

实现效果:

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Unity投屏插件是一种为Unity引擎开发的应用程序提供屏幕共享和投屏功能的扩展工具。它可以让开发者轻松地将Unity应用程序的内容投射到其他设备上,如电视、电脑和移动设备。 Unity投屏插件的主要作用是实现实时屏幕共享和投屏功能。开发者可以使用这个插件将Unity应用程序的画面影像传输到其他设备上,实现多屏互动和多用户共享的需求。例如,可以将游戏画面实时投射到电视上供大家观看,或者将应用程序内容分享给其他人进行协作编辑。 Unity投屏插件还可以支持不同设备之间的互动。在投屏过程中,用户可以通过其他设备与Unity应用程序进行交互,控制游戏操作或修改应用程序的设置,实现多设备之间的数据传递和互动。例如,用户可以使用手机作为遥控器来控制在电视上投屏的游戏,或者在电脑上对Unity应用程序进行远程编辑和设置。 Unity投屏插件的开发通常涉及网络传输和图像处理等技术。通过网络传输,插件可以将Unity应用程序的内容实时传输到其他设备上,并确保传输速度和稳定性。而图像处理则涉及对Unity画面的截取、编码和解码等操作,以保证投屏的流畅和质量。 总的来说,Unity投屏插件是一种能够实现Unity应用程序屏幕共享和投屏功能的工具,可以实现多屏互动和多用户共享的需求,通过网络传输和图像处理等技术来实现实时画面传输和互动控制。这是一个非常有用的插件,可以为Unity开发者提供更多的应用场景和用户体验。 ### 回答2: Unity投屏插件是Unity开发引擎的一种额外功能,它允许开发者在Unity中快速、方便地实现将游戏画面投射到其他设备上的功能Unity投屏插件的实现原理是通过网络传输来实现设备间的图像传递。开发者可以将投屏插件集成到自己的项目中,并选择合适的投屏设备,比如手机、平板电脑、电视等等。 Unity投屏插件的应用场景广泛。在游戏开发中,开发者可以利用Unity投屏插件将游戏画面投射到手机或平板上,实现手机游戏的操作和显示。这样,玩家便可以在手机或平板上操作游戏,并享受更加便捷的游戏体验。 除了游戏开发外,Unity投屏插件还可用于其他领域。比如,在培训教育领域,教师可以通过Unity投屏插件将教学内容投射到学生的设备上,实现课堂上的互动和演示。在企业培训中,也可以利用Unity投屏插件将培训材料和演示内容投射到员工的个人设备上,提高培训效果。 总之,Unity投屏插件是一种功能强大且灵活多样的插件,它能够很好地满足开发者在游戏开发以及其他领域中的投屏需求。通过使用Unity投屏插件,开发者可以将图像传输到各种设备上,使得用户能够更加方便地享受到游戏和其他应用带来的乐趣和便利。 ### 回答3: Unity投屏插件是一种在Unity开发环境下使用的插件,用于将Unity游戏或应用程序投屏到外部设备上,如电视、手机、平板或投影仪等。 Unity投屏插件具有以下几个主要的功能和特点: 1. 设备兼容性:Unity投屏插件能够与各种外部设备进行兼容,包括不同品牌和型号的电视、手机和平板等。 2. 多平台支持:Unity投屏插件适用于多种不同操作系统平台,包括Windows、iOS和Android等。 3. 实时投屏Unity投屏插件能够实时将Unity游戏或应用程序在编辑器中的场景投射到外部设备上,使开发者能够实时预览和调试游戏效果。 4. 交互控制:Unity投屏插件还可以实现与外部设备的交互控制,使用户能够通过设备上的控制器、触摸屏或遥控器等进行游戏操作。 5. 分辨率和画质调整:Unity投屏插件支持对投屏画面的分辨率和画质进行调整,以适应不同设备的要求和性能。 总结来说,Unity投屏插件是一种方便开发者将Unity游戏或应用程序在外部设备上进行投屏展示和调试的工具。它提供了设备兼容性、多平台支持、实时投屏、交互控制以及分辨率和画质调整等功能,使开发者能够更方便地测试和优化游戏效果,提高开发效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值