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

}

}

}

}

相关推荐
AA陈超7 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 P06-14 属性菜单 - 文本值行
c++·游戏·ue5·游戏引擎·虚幻
future_studio12 小时前
聊聊 Unity(小白专享、C# 小程序 之 联机对战)
unity·小程序·c#
AA陈超19 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 P06-13 属性菜单 - 边框值
c++·游戏·ue5·游戏引擎·虚幻
shandianchengzi21 小时前
【记录】Unity|Unity从安装到打开一个Github项目(以我的世界(仿)为例)
unity·c#·游戏引擎·github·我的世界·mc
yi碗汤园1 天前
【超详细】C#自定义工具类-StringHelper
开发语言·前端·unity·c#·游戏引擎
野奔在山外的猫2 天前
【案例】Unity 平台访问文件浏览器(汇总)
unity
WaWaJie_Ngen2 天前
【OpenGL】模板测试(StencilTest)
c++·算法·游戏·游戏引擎·游戏程序·图形渲染
开发游戏的老王3 天前
虚幻引擎虚拟制片入门教程目录
游戏引擎·虚幻
future_studio3 天前
聊聊 Unity(小白专享、C# 小程序 之 自动更新)
unity·小程序·c#
心疼你的一切3 天前
Unity开发利器:ScriptableObject的数据容器设计与内存优化原理
microsoft·unity·c#·游戏引擎