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();

}

}

}

}

相关推荐
reasonsummer2 小时前
【办公类-116-01】20250929家长会PPT(Python快速批量制作16:9PPT相册,带文件名,照片横版和竖版)
java·数据库·python·powerpoint
tiankongdeyige3 小时前
Unity学习之C#的反射机制
学习·unity·c#
HELLOMILI10 小时前
[UnrealEngine] 虚幻编辑器界面 | 虚幻界面详解 | UE5界面详解
游戏·ue5·编辑器·游戏引擎·虚幻·unreal engine
快乐觉主吖18 小时前
Unity内嵌浏览器插件:3DWebView,显示不支持的音频/视频格式解决办法
unity
AA陈超1 天前
虚幻引擎UE5专用服务器游戏开发-32 使用Gameplay Tags阻止连招触发
c++·游戏·ue5·游戏引擎·虚幻
workflower1 天前
将图片中的图形转换为可编辑的 PPT 图形
java·开发语言·tomcat·powerpoint·个人开发·结对编程
危险库1 天前
【UE4/UE5】在虚幻引擎中创建控制台指令的几种方法
c++·ue5·游戏引擎·ue4·虚幻
ellis19701 天前
toLua[四] Examples 03_CallLuaFunction分析
unity
大Mod_abfun1 天前
Unity游戏基础-4(人物移动、相机移动、UI事件处理 代码详解)
游戏·ui·unity·游戏引擎