<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[【Unity】2D像素游戏中让UI与世界的像素大小保持一致]]></title><description><![CDATA[<p dir="auto">在使用Unity制作2D像素游戏时，经常会遇到Canvas中的Image与世界中的Sprite大小不一致的情况，即使是同一素材也会有差别：</p>
<p dir="auto"><img src="/assets/uploads/files/1728119128280-pasted-image-20241005122322.png" alt="Pasted image 20241005122322.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">特别是对于像素游戏，这会导致画面中的逻辑像素大小不统一，影响观感。</p>
<p dir="auto">由于Unity使用了不同的方式来处理它们，首先要了解它们的大小是如何计算的。</p>
<h2>Pixels Per Unit</h2>
<p dir="auto">图片导入选项中的Pixels Per Unit（以下简称PPU），表示多少个实际像素为1个Unity单位。</p>
<p dir="auto"><img src="/assets/uploads/files/1728119195005-pasted-image-20241005120656-resized.png" alt="Pasted image 20241005120656.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">例如PPU设置为16，则一张16×16像素的图片在世界中的大小为1×1个单位，一张32×8像素的图片在世界中的大小为2×0.5个单位。</p>
<p dir="auto">一张16×16像素的图片Unit.png作为Sprite在世界中显示的情况：</p>
<p dir="auto"><img src="/assets/uploads/files/1728119207940-pasted-image-20241005120801.png" alt="Pasted image 20241005120801.png" class=" img-responsive img-markdown" /></p>
<h2>相机大小</h2>
<p dir="auto">正交相机的Size表示半个屏幕/窗口高度中能显示多少Unity单位的内容。</p>
<p dir="auto"><img src="/assets/uploads/files/1728119235549-pasted-image-20241005120814-resized.png" alt="Pasted image 20241005120814.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">例如Size设置为3，则屏幕纵向有3×2=6个单位，图中每个地块大小为1个单位，纵向显示了6个地块。</p>
<p dir="auto"><img src="/assets/uploads/files/1728119254935-pasted-image-20241005121934.png" alt="Pasted image 20241005121934.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">在Size不变的情况下，无论显示分辨率、宽高比如何变化，纵向显示的内容总是不变的，都是6个地块。</p>
<p dir="auto"><img src="/assets/uploads/files/1728119270488-pasted-image-20241005120842.png" alt="Pasted image 20241005120842.png" class=" img-responsive img-markdown" /></p>
<h2>Canvas的Reference Pixels Per Unit与缩放模式</h2>
<p dir="auto">新建一个Canvas，Canvas Scaler中有一个Reference Pixels Per Unit参数（以下简称RPPU），默认为100。</p>
<p dir="auto"><img src="/assets/uploads/files/1728119282902-pasted-image-20241005121333.png" alt="Pasted image 20241005121333.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">此时将上面的Unit.png图片作为Image放到UI中，会发现与世界中Sprite的大小有差别。</p>
<p dir="auto"><img src="/assets/uploads/files/1728119292361-pasted-image-20241005122322.png" alt="Pasted image 20241005122322.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">和世界中的Sprite不同，Canvas中不直接使用Unity单位，而是适用于Canvas的像素大小。在没有缩放的情况下，</p>
<p dir="auto">Canvas像素大小 = 图片像素大小 / (PPU / RPPU)</p>
<p dir="auto">例如这里的Unit.png，它的大小为16×16像素，PPU为16，Canvas Scaler的RPPU为100，则它在Canvas中的像素大小为100。</p>
<p dir="auto">需要注意的是，Canva像素大小并不是实际显示的像素大小，它受Canvas Scaler的UI Scale Mode（缩放模式）以及其他缩放参数影响。</p>
<p dir="auto">当UI Scale Mode设置为Constant Pixel Size（固定像素大小）时，无论显示分辨率、宽高比如何变化，图片的大小都不变。Scale Factor（缩放因子）参数影响图片的缩放倍率，例如Scale Factor为1时，Image的显示大小始终固定为100×100，为2时，固定为200×200。</p>
<p dir="auto"><img src="/assets/uploads/files/1728119310265-pasted-image-20241005124142.png" alt="Pasted image 20241005124142.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">当UI Scale Mode设置为Scale With Screen Size（随屏幕大小缩放）时，图片的显示大小受显示分辨率、Reference Resolution（参考分辨率），和Match（宽高匹配）影响。</p>
<p dir="auto"><img src="/assets/uploads/files/1728119320896-pasted-image-20241005124337.png" alt="Pasted image 20241005124337.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">听起来很复杂，实际上可以理解成是另一种Constant Pixel Size模式，但Scale Factor会根据某些规则自动变化，缩放适应不同分辨率和宽高比的屏幕。</p>
<p dir="auto">例如显示分辨率为1920×1080，Reference Resolution也是1920×1080，此时可以认为内置的缩放因子为1，Image的显示大小为100×100；</p>
<p dir="auto">当显示分辨率变为1680×720（21:9），Reference Resolution依然是1920×1080，当Match参数拉到Height端为1时，此时的缩放因子为720÷1080=2/3，Image的显示大小变为66×66；当Match参数拉到Width端为0时，缩放因子为1680÷1920=7/8，Image的显示大小变为87×87。</p>
<p dir="auto"><img src="/assets/uploads/files/1728119327755-pasted-image-20241005131259.png" alt="Pasted image 20241005131259.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">还有一种缩放模式Constant Physical Size（固定物理大小）个人从来没用过，就不讨论了。</p>
<h2>统一大小</h2>
<p dir="auto">以结果来看，最终需要统一的是图片在世界和UI中的实际显示大小，例如一张16×16的图片，如果在UI中作为Image显示的实际像素大小是100×100，那么它在世界中作为Sprite的实际像素大小也应该是100×100，反之亦然，要么调整UI相关参数让它匹配世界，要么调整世界相关参数让它匹配UI。在此基础上，还要确保不同显示分辨率和宽高比下的缩放情况，以及处理相机自身的缩放。</p>
<p dir="auto">由于不同项目情况不同，这里只介绍一种思路，只要清楚了原理其他都是相通的。</p>
<p dir="auto">首先确定并统一所有图片素材的PPU，像素素材在制作过程中通常会有一个参考大小，例如8×8、16×16、32×32，不同参考大小可表现的细节也不同。</p>
<p dir="auto"><img src="/assets/uploads/files/1728119333618-pasted-image-20241005152315.png" alt="Pasted image 20241005152315.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">使用这个参考大小作为PPU是一个不错的选择，例如素材中每个地块的大小为16×16，PPU也设置为16，1个地块刚好为1个Unity单位。</p>
<p dir="auto">然后确定一个设计分辨率，也就是以此分辨率为基准，其他分辨率都在它基础上缩放，例如确定设计分辨率为1920×1080，将显示分辨率和Canvas Scaler的参考分辨率都调整为这个值，此时 设计分辨率 = 实际显示分辨率。</p>
<p dir="auto">接下来有两种选择，调整UI适配相机，或调整相机以适配UI。</p>
<h3>调整UI适配相机</h3>
<p dir="auto">这种方式适合一屏显示的内容有固定要求的情况，例如要求屏幕中必须显示32×18个地块，那么相机的大小不能变化。</p>
<p dir="auto">根据相机大小一节，屏幕纵向共有相机Size×2个Unity单位，用设计分辨率高度除以它，可以得到1Unity单位对应的实际像素大小，即：</p>
<p dir="auto">屏幕高度(Unity单位) = 相机Size * 2</p>
<p dir="auto">屏幕高度(像素) = 设计分辨率高度</p>
<p dir="auto">1Unity单位对应像素 = 屏幕高度(像素) / 屏幕高度(Unity单位)</p>
<p dir="auto">然后根据图片的PPU，可以计算出图片中的1个像素，实际显示在屏幕上是多少像素，也就是像素比率(Pixel Ratio)：</p>
<p dir="auto">像素比率 = 1Unity单位对应像素 / PPU</p>
<p dir="auto">举个例子，当设计分辨率为1920×1080，相机的Size设置为6，图片大小16×16，PPU为16，此时的像素比率：</p>
<p dir="auto">像素比率 = 1080÷(6×2)÷16 = 5.625</p>
<p dir="auto">也就是图片素材的1个像素，显示在屏幕上为5.625个像素，因为是设计分辨率，有小数是正常的，实际显示时Unity会帮我们处理好。</p>
<p dir="auto">得到的像素比率有什么用呢？它可以用来确定UI中图片的大小，如果UI的显示也能符合这个像素比率，那么就做到UI和世界显示大小一致了。</p>
<p dir="auto">将UI Scale Mode改为Scale With Screen Size，Reference Resolution设置为设计分辨率，Match调整为Height为1。当显示分辨率与设计分辨率一致时，Canvas不会有缩放。</p>
<p dir="auto"><img src="/assets/uploads/files/1728119345396-pasted-image-20241005124337.png" alt="Pasted image 20241005124337.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">根据Canvas一节，在没有缩放的情况下：</p>
<p dir="auto">实际显示像素大小 = Canvas像素大小 = 图片像素大小 / (PPU / RPPU)</p>
<p dir="auto">由此可以得出UI的像素比率：</p>
<p dir="auto">UI像素比率 = 图片像素大小 / 实际显示像素大小 = RPPU / PPU</p>
<p dir="auto">为了让UI的像素比率和世界的像素比率一致，我们唯一还能调整的只有RPPU。按上面的例子，当像素比率为5.625时，RPPU应该调整为16×5.625=90，调整后需要点击Image的Set Native Size重置大小。</p>
<p dir="auto"><img src="/assets/uploads/files/1728119356378-pasted-image-20241005162448.png" alt="Pasted image 20241005162448.png" class=" img-responsive img-markdown" /></p>
<p dir="auto"><img src="/assets/uploads/files/1728119361591-pasted-image-20241005162655.png" alt="Pasted image 20241005162655.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">调整好后，由于Canvas按高度缩放，相机也是按高度缩放，所以在不同分辨率和宽高比下都能保持一致：</p>
<p dir="auto"><img src="/assets/uploads/files/1728119366234-pasted-image-20241005163006.png" alt="Pasted image 20241005163006.png" class=" img-responsive img-markdown" /></p>
<p dir="auto">如果项目不符合这种情况，例如需要按宽度缩放，可以试着按类似的原理调整相机大小和UI缩放。</p>
<h3>调整相机适配UI</h3>
<p dir="auto">了解了上面的方法后，另一种情况依葫芦画瓢就行，先计算出UI的像素比率，然后调整相机大小匹配这个比率。</p>
<p dir="auto">另外在使用Pixel Perfect Camera的情况下，相机大小不可直接调整，Pixel Perfect Camera会根据当前各项参数计算出像素比率（图中为实际显示像素 : 图片素材像素），按照这个值调整UI的像素比率即可。</p>
<p dir="auto"><img src="/assets/uploads/files/1728119371468-pasted-image-20241005165519.png" alt="Pasted image 20241005165519.png" class=" img-responsive img-markdown" /></p>
]]></description><link>http://designhub.top/topic/74/unity-2d像素游戏中让ui与世界的像素大小保持一致</link><generator>RSS for Node</generator><lastBuildDate>Sun, 12 Jul 2026 00:21:37 GMT</lastBuildDate><atom:link href="http://designhub.top/topic/74.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 05 Oct 2024 09:09:52 GMT</pubDate><ttl>60</ttl></channel></rss>