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.Slidespage;

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

slideSpritespage = 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 = slideSpritespage;

}

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

}

}

}

}

相关推荐
tealcwu1 天前
【Unity基础】为什么游戏需要物理按键映射?从 Unity Input Manager 到跨引擎输入设计
java·游戏·unity
tealcwu2 天前
【Unity高级】Unity URP:构建同时支持 2D 与 3D 场景的项目完全指南
3d·unity·游戏引擎
淡海水2 天前
10-01-互操作-C#与C++边界的内存管理
unity·c#·游戏引擎·.netcore·gc
死磕音视频2 天前
PowerPoint Copilot 入门:用 Interactive Slide 做出可点击讲解页
powerpoint·copilot·演示文稿·交互幻灯片
小小数媒成员2 天前
UGUI原理(一)
开发语言·游戏·unity·游戏引擎
暴走约伯2 天前
【VFX工具链源码拆解 04】拯救丢失的绑定:Timeline 一键克隆与层级相对路径重映射算法
unity·c#·游戏引擎·硬件工程
FinelyYang2 天前
uniapp使用kkfileview在线预览ppt,excel,word,pdf类型文件
pdf·uni-app·powerpoint
zhippt_10142 天前
截图、课件图、设计稿怎么变成可编辑PPT?图转PPT实测
powerpoint
小小数媒成员2 天前
Unity UGUI布局组件(LayoutGroup、ContentSizeFitter、LayoutElement)详解
unity·游戏引擎
tealcwu2 天前
【Unity基础】Unity输入与Time.deltaTime的使用原则
unity·游戏引擎