
Sky Tycoon中的对象选择不是使用碰撞器以及OnMouse
或IPointer
事件以传统的Unity方式处理的。
相反,为了实现对像素的完美选择而对性能的影响最小,游戏使用了一种自定义解决方案,该解决方案基于将可选对象渲染到RenderTexture
并在每一帧期间从中获取选择信息。
访问 http://blog.celestial-static-games.de/ 上的 Sky Tycoon, 以找到有关Unity开发的游戏技术文章的更多信息!
理论上
我最近遇到了在最近玩《模拟人生4》时通过着色器输出执行对象选择的想法。
检出此游戏片段,其中选择在接收器和计数器之间交替。 如果涉及到碰撞器(甚至是网状碰撞器),那么当您移入水槽的插入区域时,您可能希望选择无法正常工作。

请注意,我已经增加了选择纹理的对比度,因为由于Alpha通道也用于编码值(在这种情况下非常低),否则它几乎是不可见的。
本身呈现选择颜色的着色器非常简单。 如前所述,由于Sky Tycoon将Instancing用于对象,演员等可选对象,因此着色器可以通过MaterialPropertyBlock
访问选择颜色。 然后,着色器所做的全部工作就是将该颜色渲染到屏幕上,覆盖以前渲染的所有片段。 着色器默认情况下启用Z-Writing,因此它始终呈现最前面的对象的选择ID。
着色器“自定义/选择ID” {
SubShader {
标签{“ RenderType” =“透明”}
通过{
CG程序
#pragma顶点vert
#pragma片段片段
#include“ UnityCG.cginc”
UNITY_INSTANCING_CBUFFER_START(道具)
UNITY_DEFINE_INSTANCED_PROP(fixed4,_SelectionColor)
UNITY_INSTANCING_CBUFFER_END
float4 vert(float4顶点:POSITION):SV_POSITION {
返回UnityObjectToClipPos(vertex);
}
fixed4 frag():SV_Target {
返回UNITY_ACCESS_INSTANCED_PROP(_SelectionColor);
}
ENDCG
}
}
}
确定选择
每帧检查生成的RenderTexture
以检查当前鼠标光标位置下的颜色。 如果结果不是’no selection’( RGBA(0, 0, 0, 0)
( RGBA(0, 0, 0, 0)
),游戏可以将颜色转换回id并进行查找。 如果有效(例如,存在于游戏世界中),我们将决定如何处理该信息。
通常,我们会显示某种指示符来告诉用户对此对象执行操作。 左键单击时,我们将当前选定的对象更改为鼠标光标下方的对象,并告知该对象。 然后,它可以单独决定采取哪些操作(打开对话框等)。
最终选择行为如下所示:
结论
如您在本文中所见,着色器不仅对最终用户图形计算有用,而且还可以用于提供更复杂的游戏逻辑。 使用着色器执行像素完美的对象选择是解决此问题的一种有趣方法,当您的场景中放置太多对象时,通常会导致性能下降。
我希望本文能为Sky Tycoon的一些更好的内部原理提供一些启示。 如果您对文章或《 Sky Tycoon》总体上有任何疑问,请随时在Twitter @CelestialStatic上发表评论或与我联系。
访问 http://blog.celestial-static-games.de/ 上的 Sky Tycoon, 以找到有关Unity开发的游戏技术文章的更多信息!
如果您喜欢阅读这篇文章,请考虑在Twitter和其他您认为有用的地方分享该文章!