这一周我们花了很多时间研究Askutron。由于虚幻引擎对我来说还很新,我每天都在学习。这篇短文是关于我如何弄清楚如何生成和显示QR码。 如果你想节省时间,你可以试试虚幻商城上任何二维码插件的运气。但这些插件普遍缺乏评论,同时作为程序员的骄傲阻止了我抛出50欧元。 下面是我的研究步骤:计算二维码在运行时从QR码生成纹理使用图像在UI中显示该纹理1、计算二维码 就像你可能期望的那样,我的旅程始于网络搜索CQRcode。第一个结果得出了这样的结果: 事实上,这个拥有1600颗星的GitHub仓库从一开始就看起来很有希望。此外,文档简明扼要,重要的是,包含简单的示例。 因此,我继续漫不经心地将CPP文件(QrCode。hpp和QrCode。cpp)复制到虚幻项目的代码文件夹中。这对我来说总是关键时刻。它会编译吗?或者,我将不得不在神秘的C错误消息上撕掉我的头发。幸运的是,它编译没有任何问题。 按照网站上的例子和一些基本的虚幻C知识,计算QR码就像馅饼一样简单:UTexture2DUWebBuzzers::GenerateQrCode(UObjectparent,FStringstring){autoerrorCorrectionLevelqrcodegen::QrCode::Ecc::LOW;qrcodegen::QrCodeqrqrcodegen::QrCode::encodeText(TCHARTOUTF8(string),errorCorrectionLevel);uint8sizeqr。getSize();TArrayFCpixels。SetNumZeroed(sizesize);FColorblackFColor::BFColorwhiteFColor::Wfor(uint8x0;x){for(uint8y0;y){FColorcolorqr。getModule(x,y)?white:pixels〔xysize〕}}TODO:Generatetexturefromcolorarray(seebelow)} 实际的QR计算发生在对encodeText的一次调用中。请注意,我选择简单地使用低纠错级别,这使得QR码更小。这是因为在屏幕上显示QR码不太可能受到障碍物或失真的太大影响。 这非常简单直观。向Nayuki致敬,为这个伟大的库而欢呼!2、在运行时从QR码生成纹理 下一步是将该颜色数组转换为可以显示的纹理。这甚至更简单,至少在一开始是这样:FCreateTexture2DPUTexture2DtextureFImageUtils::CreateTexture2D(size,size,pixels,parent,QRCode,EObjectFlags::RFTransient,params);dontinterpolatetexelstogetsharpedges(otherwisetheimagewouldlookblurry)textureFilterTextureFilter::TFN 我正在使用FImageUtils:CreateTexture2D在运行时生成纹理。它的文档极度缺少示例代码,就像整个虚幻文档一样。但我最终想出了一组有效的参数:前两个参数只是以像素为单位的大小,我简单将其设置为QR码的大小(模组的数量)像素是上面的FColor数组parent是任何可以传入的UObject对象,例如通过蓝图。这很重要!如果没有设置parent,纹理将立即被垃圾回收,或者至少我认为这是正在发生的事情。不设置它将导致编辑器崩溃并出现诸如对象未打包之类的错误。QRCode是纹理的名称,可以自由选择对于flags,我不太确定这里需要传递什么。但根据稀疏的文档我选择RFTransient不保存对象,因为纹理只应该在运行时存在。最后一个参数params允许更改其他一些我什么都不知道的选项,所以我将它们保留为默认值。 将纹理滤镜设置为NEAREST(最近邻插值)也很重要。默认滤镜在像素之间使用某种插值,这意味着当纹理被拉伸时,它会变得非常非常模糊。生成的纹理大小仅在1717和144144像素之间,具体取决于编码字符串的长度和纠错级别。 在编辑器中完美运行。我们完成了,对吧?恐怕不是。虽然此代码在编辑器中按预期运行,但它实际上会在打包的构建中崩溃,并出现以下错误:控制台不支持构造texture2D,正如我刚刚发现的那样。 这个解决方案并不漂亮,虚幻的文档再次毫无帮助。所以回到网络搜索。不幸的是,论坛或AnswerHub上关于虚幻引擎的许多问题都没有得到解答。Unity社区似乎处于更好的状态。无论如何,我最终找到了一个带有解决方案的帖子(尽管没有解释):UTexture2DtextureUTexture2D::CreateTransient(size,size,EPixelFormat::PFB8G8R8A8,QRCode);voiddatatexturePlatformDataMips〔0〕。BulkData。Lock(LOCKWRITE);FMemory::Memcpy(data,pixels。GetData(),sizesize4);texturePlatformDataMips〔0〕。BulkData。Unlock();textureUpdateResource(); 作为一个之前使用DirectX和OpenGL编写C程序的人,对于控制台不支持初始解决方案这个问题,我依然没有任何线索,。也许是因为非方形的纹理大小,但我懒得去测试这个理论。 无论如何,这是最终代码(另请参阅此Gist):includeQrCode。hppfromhttps:github。comnayukiQRCodegeneratorincludeImageUtils。hfromUnrealEngine(4。24)summaryGeneratesaQRcodetexturefromastring。summaryparamnameparentUEparent(required)paramparamnamestringStringtoencodeparamUTexture2DUWebBuzzers::GenerateQrCode(UObjectparent,FStringstring){qrcodegen::QrCodeqrqrcodegen::QrCode::encodeText(TCHARTOUTF8(string),qrcodegen::QrCode::Ecc::LOW);uint8sizeqr。getSize();TArrayFCpixels。SetNumZeroed(sizesize);FColorblackFColor::BFColorwhiteFColor::Wfor(uint8x0;x){for(uint8y0;y){FColorcolorqr。getModule(x,y)?white:pixels〔xysize〕}}UTexture2DtextureUTexture2D::CreateTransient(size,size,EPixelFormat::PFB8G8R8A8,QRCode);voiddatatexturePlatformDataMips〔0〕。BulkData。Lock(LOCKWRITE);FMemory::Memcpy(data,pixels。GetData(),sizesize4);texturePlatformDataMips〔0〕。BulkData。Unlock();textureUpdateResource();textureFilterTextureFilter::TFN} 我在这里没有展示的是,我将此函数作为蓝图代码库的一部分公开。如何做到这一点,我不打算在这里介绍,因为这是一种标准的虚幻的东西,应该被文档所涵盖。3。使用Image在UI中显示该纹理 要在UI中显示生成的QR码纹理,只需抓取图像,从上面调用蓝图函数,并使用从纹理设置画笔将结果设置为图像的纹理。 大功告成!这就是你在虚幻引擎中生成和显示QR码的方式,就像一个对虚幻引擎几乎一无所知的人一样。如果有一天我学会了更好的方法来做到这一点,我会确保更新这篇文章。 原文链接:http:www。bimant。comblogue4qrcode