当前位置: 首页 > news >正文

unity 读取PPT显示到屏幕功能

1.准备一份PPT文件 和System.Drawing,Aspose.Slides这些dll文件,如图

2.unity默认设置,在Player下面找到api兼容级别 改成.NETFrameWork 如图

3.创建这些东西,并挂载脚本,脚本是其他大佬分享的,挺好使

4.运行即可  页数多的情况得另外搞

5.参考大佬的地址

⭐ Unity 异步加载PPT页面 并 首帧无卡顿显示_unity 加载ppt-CSDN博客

这个也能使用,有案例 694fe · 万能工具箱/PPT加载插件v2.0Unity - GitCode

6.dll的话可以去上面工程找下,有报错也是dll的问题和项目设置的问题 

7.PPTCtrl脚本在这里

using Aspose.Slides;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;

public class PPTCtrl : MonoBehaviour
{
    public UnityEngine.UI.Image ShowImg;//展示图片
    public Text pagetext;//页数
    public GameObject LastBtn, NextBtn;
    public Sprite PlaceholderSprite; // 设置一个默认占位图 可以用ppt第一张图

    private Presentation presentation = null;
    private int NowPage = 0;
    private bool isLoading = false;

    private Dictionary<int, Sprite> slideSprites = new Dictionary<int, Sprite>();

    private async void Start()
    {
        UnityMainThreadDispatcher.Instance(); // 初始化主线程调度器

        string PPTPath = Application.dataPath + "/Plugins/Aspose.Slides.NET.18.10.0(Crack)/165.pptx";
        presentation = new Presentation(PPTPath);

        // 用占位图先顶上 UI
        ShowImg.sprite = PlaceholderSprite;

        // 优先加载第一页
        await LoadAndCacheSlideAsync(0);

        // 延迟一帧再刷新 UI,避免卡顿
        await Task.Delay(100);
        SwitchPage(0);

        // 后台加载其他页
        _ = Task.Run(() => PreloadOtherSlidesAsync());
    }

    private void OnEnable()
    {
        LastBtn.GetComponent<Button>().onClick.AddListener(ClickLast);
        NextBtn.GetComponent<Button>().onClick.AddListener(ClickNext);
    }

    private void OnDisable()
    {
        LastBtn.GetComponent<Button>().onClick.RemoveListener(ClickLast);
        NextBtn.GetComponent<Button>().onClick.RemoveListener(ClickNext);
    }


    private async Task PreloadOtherSlidesAsync()
    {
        int total = presentation.Slides.Count;

        for (int i = 1; i < total; i++)
        {
            if (!slideSprites.ContainsKey(i))
                await LoadAndCacheSlideAsync(i);
        }
    }

    private async Task LoadAndCacheSlideAsync(int page)
    {
        var slide = presentation.Slides[page];
        var bitmap = slide.GetThumbnail(1f, 1f);
        var bytes = GetBitMapBytes(bitmap);

        await Task.Yield(); // 推出当前线程

        UnityMainThreadDispatcher.Instance().Enqueue(() =>
        {
            var tex = new Texture2D(bitmap.Width, bitmap.Height, TextureFormat.RGBA32, false);
            tex.LoadImage(bytes);
            var sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero);
            slideSprites[page] = sprite;
        });
    }

    public void SwitchPage(int page)
    {
        if (isLoading || page < 0 || page >= presentation.Slides.Count)
            return;

        NowPage = page;
        pagetext.text = (page + 1) + " / " + presentation.Slides.Count;
        LastBtn.SetActive(page > 0);
        NextBtn.SetActive(page < presentation.Slides.Count - 1);

        if (slideSprites.TryGetValue(page, out Sprite sprite))
        {
            ShowImg.sprite = sprite;
        }
        else
        {
            ShowImg.sprite = PlaceholderSprite;
            StartCoroutine(LoadSlideAsync(page));
        }
    }

    private IEnumerator LoadSlideAsync(int page)
    {
        isLoading = true;

        yield return Task.Run(async () =>
        {
            await LoadAndCacheSlideAsync(page);
            UnityMainThreadDispatcher.Instance().Enqueue(() =>
            {
                if (NowPage == page && slideSprites.ContainsKey(page))
                {
                    ShowImg.sprite = slideSprites[page];
                }
                isLoading = false;
            });
        });
    }

    private byte[] GetBitMapBytes(Bitmap bm)
    {
        try
        {
            using (MemoryStream ms = new MemoryStream())
            {
                bm.Save(ms, ImageFormat.Png);
                return ms.ToArray();
            }
        }
        catch (Exception e)
        {
            Debug.LogWarning("Get Bytes failed: " + e);
            return null;
        }
    }

    public void ClickNext() => SwitchPage(NowPage + 1);
    public void ClickLast() => SwitchPage(NowPage - 1);
}

8.主线程调度的脚本在这

using System;
using System.Collections.Generic;
using UnityEngine;

public class UnityMainThreadDispatcher : MonoBehaviour
{
    private static readonly Queue<Action> _executionQueue = new Queue<Action>();
    private static UnityMainThreadDispatcher _instance = null;

    public static UnityMainThreadDispatcher Instance()
    {
        if (_instance == null)
        {
            var go = GameObject.Find("MainThreadDispatcher");
            if (go == null)
            {
                go = new GameObject("MainThreadDispatcher");
                DontDestroyOnLoad(go);
                _instance = go.AddComponent<UnityMainThreadDispatcher>();
            }
            else
            {
                _instance = go.GetComponent<UnityMainThreadDispatcher>();
                if (_instance == null)
                    _instance = go.AddComponent<UnityMainThreadDispatcher>();
            }
        }
        return _instance;
    }

    public void Enqueue(Action action)
    {
        if (action == null) return;

        lock (_executionQueue)
        {
            _executionQueue.Enqueue(action);
        }
    }

    private void Update()
    {
        lock (_executionQueue)
        {
            while (_executionQueue.Count > 0)
            {
                _executionQueue.Dequeue()?.Invoke();
            }
        }
    }
}

http://www.dtcms.com/a/438112.html

相关文章:

  • Django - 让开发变得简单高效的Web框架
  • C# 判断语句详解
  • 新建一个网站需要多少钱舟山专业做网站
  • JVM中的垃圾回收机制
  • 【计算机视觉】概述
  • 【第五章:计算机视觉-项目实战之生成对抗网络实战】2.基于SRGAN的图像超分辨率实战-(2)实战1:DCGAN模型搭建
  • 【精品资料鉴赏】大型企业网络安全整体解决方案
  • 重庆建设医院官方网站wordpress中文社区
  • [优选算法专题三.二分查找——NO.23搜索旋转排序数组中的最⼩值]
  • 【个人修养】商务礼仪教程
  • 报告派研读:2025年全球PC/主机游戏洞察报告
  • 用jquery做的书籍网站discuz做服务网站
  • Linux 驱动开发入门:LCD 驱动与内核机制详解
  • [Linux基础——Lesson9.调试器GDB]
  • 网站 推送中国万网域名官网
  • 主窗口(QMainWindow)如何放入文本编辑器(QPlainTextEdit)等继承自QWidget的对象--(重构版)
  • 和 AI 一起修 Bug 心得体会
  • 网站建设科技公司外部环境分析网站首页没有权重
  • 【大语言模型】—— Transformer的QKV及多头注意力机制图解解析
  • SYN VISION韩国发布会:获评非小号Alpha,战略合作PrompTale
  • 安徽工程建设造价信息网站html网站开发视频
  • 图书馆自习室|基于SSM的图书馆自习室座位预约小程序设计与实现(源码+数据库+文档)
  • Ollama 使用详解:本地部署大语言模型的指南
  • 手机上哪个网站浙江省嘉兴市建设局网站
  • 秒杀系统崩溃?Redis分片+Sentinel熔断架构设计指南
  • 【开题答辩全过程】以 J2EE技术在在线购物分享应用中的应用为例,包含答辩的问题和答案
  • 【深入理解计算机网络03】计算机网络的分层结构,OSI模型与TCP/IP模型
  • 网站怎么做移动的窗口达州市建设规划网站
  • #计算 c^d mod n
  • AI与现代数据科学的融合