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

}

}

}

}

相关推荐
jtymyxmz6 小时前
《Unity Shader》6.4.3 半兰伯特模型
unity·游戏引擎
AA陈超6 小时前
ASC学习笔记0001:处理目标选择系统中当Actor拒绝目标确认时的调用
c++·笔记·学习·游戏·ue5·游戏引擎·虚幻
我的golang之路果然有问题7 小时前
mac配置 unity+vscode的坑
开发语言·笔记·vscode·macos·unity·游戏引擎
于小汐在咯8 小时前
【虚拟现实技术】在Unity里创建一个简单的AR项目
unity·ar·vr
HahaGiver66611 小时前
Unity Shader Graph 3D 实例 - 一个简单的红外线扫描全身效果
3d·unity·游戏引擎
百事牛科技11 小时前
PPT如何添加logo?两种方法解决!
windows·powerpoint
o***Z44812 小时前
免费的WebAssembly游戏引擎,AssemblyScript
游戏引擎·wasm
雪下的新火1 天前
Blender:法线图&黑白图
游戏·unity·游戏引擎·blender·笔记分享
HahaGiver6661 天前
从0到1做一个“字母拼词”Unity小游戏(含源码/GIF)- 实现多单词顺序通关进度逻辑
unity·游戏引擎·游戏程序
alwaysuzybaiyy1 天前
物联网控制|计算机控制-刘川来胡乃平版|第4章:过程通道与人机接口-4.4Human-Machine Interface|课堂笔记|
笔记·物联网·powerpoint