求教如何在Unity中为2D游戏制作技能特效

发布网友 发布时间:2022-04-20 12:06

我来回答

2个回答

懂视网 时间:2022-04-12 00:25

在Unity中可能需要在纹理上面绘制文字、图像等。比如游戏中的显示器,手机等等等等等。太多了。 Unity的Textute2D类提供了设置像素的操作, 但是这效率实在不敢恭维。 汉字数量巨大,全部贴在一张图上既耗空间,不方便改变字体样式。 使用FreeType2等CPU计算

在Unity中可能需要在纹理上面绘制文字、图像等。比如游戏中的显示器,手机等等等等等。太多了。

Unity的Textute2D类提供了设置像素的操作,但是这效率实在不敢恭维。


汉字数量巨大,全部贴在一张图上既耗空间,不方便改变字体样式。

使用FreeType2等CPU计算的文字库一帧又画不了多少,毕竟还要提交到显存


于是瞄准了Direct2D,当初学习这图像接口时就被微软说的“能与Direct3D进行完美交互”所吸引。

好在Unity支持DX11了,我们能够在Unity上面使用Direct2D了。所以只能在支持DX11的机器上面运行。


首先得说一下授权许可,毕竟Unity是一款商业软件。

Unity明确指出:Unity Pro才能使用Plug-in,即插件。Unity Free版本是不可以使用的。

但是,它说的是“插件”,而不是“本地代码”。

有童鞋肯定就会说我这是咬文嚼字了。非也非也,“插件”是指遵循当前环境并按照其对接口的相关规定写的代码。


那么,Unity插件有什么规定呢?

需要提供UnitySetGraphicsDevice与UnityRenderEvent

前者获取图形设备信息与图像设备相关事件,后者提供渲染事件。这两个接口是Unity自动调用的(或者也算半自动),

不能显式调用——因为没意义.....


你的本地代码提供了这两个接口就算插件,否则就是普通的本地代码库。

作为本地代码库不能放在plugin文件夹内,不能调用,因为Unity会认为是个插件,而应该直接放在工厂目录下。


再者,假设你写了个插件却放在这个目录下,那么那两个接口不能自动被调用。



好了,就这样可以创建Direct2D了,那个版本的?1.0?1.1?甚至1.2?随意啦!


但是,我建议这样做:

[cpp] view plaincopyprint?

  1. #include "windows.h"
  2. HMODULE WINAPI LoadLibraryWrapA(char* file_name){
  3. return LoadLibraryA(file_name);
  4. }
  5. HMODULE WINAPI LoadLibraryWrapW(wchar_t* file_name){
  6. return LoadLibraryW(file_name);
  7. }
  8. BOOL WINAPI FreeLibraryWrap(HMODULE hLibModule){
  9. return FreeLibrary(hLibModule);
  10. }
  11. FARPROC WINAPI GetProcAddressWrap(HMODULE hModule, char* lpProcName){
  12. return GetProcAddress(hModule, lpProcName);
  13. }

#include "windows.h"

HMODULE WINAPI LoadLibraryWrapA(char* file_name){
 return LoadLibraryA(file_name);
}

HMODULE WINAPI LoadLibraryWrapW(wchar_t* file_name){
 return LoadLibraryW(file_name);
}

BOOL WINAPI FreeLibraryWrap(HMODULE hLibModule){
 return FreeLibrary(hLibModule);
}

FARPROC WINAPI GetProcAddressWrap(HMODULE hModule, char* lpProcName){
 return GetProcAddress(hModule, lpProcName);
}


面的代码封装成dll文件,这样像C++一样显式调用dll文件。

好处如下:

1. 方便: 不知道是不是Unity的原因,反正假设你想一般dll一样使用Unity C#中的DllImport,

使用后除非关闭Unity,否则不能再次修改dll文件。这简直蛋疼,修改一行代码就需要:

关闭Unity -> 复制dll -> 打开Unity

2. 方便调试,在VS Express 2013 for Windows Desktop中,选择


工具——附加到进程,选择Unity进程


就能直接调试dll文件了,很方便。


使用GetProcAddressWrap获取函数指针之后使用C#中的

Marshal.GetDelegateForFunctionPointer

就能将函数指针换成C#中的托管方法。


比如先定义:

[csharp] view plaincopyprint?

  1. // 初始化 D2D 管理器
  2. publicdelegate System.UInt32 D2DManagerInit();
  3. public D2DManagerInit m_D2DManagerInit;

 // 初始化 D2D 管理器
 public delegate System.UInt32 D2DManagerInit();
 public D2DManagerInit m_D2DManagerInit;

使用:

[csharp] view plaincopyprint?

  1. proc = GetProcAddressWrap(m_unityd2ddll, "D2DManagerInit");
  2. m_D2DManagerInit = (D2DManagerInit)Marshal.GetDelegateForFunctionPointer(proc, typeof(D2DManagerInit));

  proc = GetProcAddressWrap(m_unityd2ddll, "D2DManagerInit");
  m_D2DManagerInit = (D2DManagerInit)Marshal.GetDelegateForFunctionPointer(proc, typeof(D2DManagerInit));

之后使用m_D2DManagerInit()就能调用dll文件中的D2DManagerInit函数了。


最后在OnApplicationQuit里面释放即可。




创建 D2D 1.0 的 流程:


首先创建一个公共的 D2D工厂 ,毕竟可能创建多个


Unity中 Texture2D::GetNativeTextureID在DX11环境下就能获取一个ID3D11Texture2D的指针


这个指针能获取 D3D11设备 ,D3D11设备 能获取当前 D3D11设备上下文。


D3D与D2D交互要D3D设备有D3D11_CREATE_DEVICE_BGRA_SUPPORT(D3D11环境下)




D3D11设备 -------> 创建Texture2D,D3D11_TEXTURE2D_DESC参考如下:

[cpp] view plaincopyprint?

  1. sharedTextureDesc.Width = 512;
  2. sharedTextureDesc.Height = 512;
  3. sharedTextureDesc.MipLevels = 1;
  4. sharedTextureDesc.ArraySize = 1;
  5. sharedTextureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  6. sharedTextureDesc.SampleDesc.Count = 1;
  7. sharedTextureDesc.Usage = D3D11_USAGE_DEFAULT;
  8. sharedTextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;

  sharedTextureDesc.Width = 512;
  sharedTextureDesc.Height = 512;
  sharedTextureDesc.MipLevels = 1;
  sharedTextureDesc.ArraySize = 1;
  sharedTextureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  sharedTextureDesc.SampleDesc.Count = 1;
  sharedTextureDesc.Usage = D3D11_USAGE_DEFAULT;
  sharedTextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;

必须有D3D11_BIND_RENDER_TARGET,否则不能创建渲染目标呈现器。记得保留这个指针。



然后对 D3D11Textue2D 使用QueryInterface获取 Dxgi表面

使用这个Dxgi表面利用D2D工厂CreateDxgiSurfaceRenderTarget创建RT

就好了,记得释放这个Dxgi表面:



渲染D2D

如同一般那样,不过由于变成了dll,可能一些习惯要改成C语言那样。


呈现D2D

渲染完成后,使用

D3D11设备上下文的CopyResource方法就能拷贝渲染结果到目标纹理了:


DirectWrite简直不错:




稍微写点代码就能模仿某游戏那样的效果:


嗯,看来还不够完善,再加油吧:


话说自带的Sprite着色器很不错,简直赞


热心网友 时间:2022-04-11 21:33

主要学习AE、3D MAX等特效,再加上PHOTOSHOP、ILLUSION等辅助,熟悉以上基础的并能做出简单的动画
通过MAX制作,AE的合成,实现2D特效的完美配合,这其中会涉及到特效的一个较强的节奏感,并且熟练的运用到光效的效果,例如golw,shine等,让我们能自己制作2D场景,道具,技能的特效然后结合各自辅助,插件,来实现更加高端的2D特效的表现方法。三维游戏学习则是学习游戏引擎技术,主要涉及到粒子的运用,并且结合3DMAX,来实现模型的导入,动画的创建等,熟练掌握游戏3D引擎粒子特效的制作,并且结合unity的shader以及材质UV的变换,来实现一些高端的3D特效的表现手法。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com