unity 像素ui的适配问题

1.导入设置问题

像素ui的导入需要调整ppu值,一般是2的倍数

filter mode 改成point模式

format改成自动或者 rgba32 bit模式

压缩模式改为高质量或者none

2.ui缩放问题导致像素对不上

ui的缩放需要成整数的倍数的缩放,canvas模式改成scale content screen size 模式进行适配

调整好模板比例后再进行拼ui, ppu也要和图片的导入的ppu进行同步

3.效果图和ui拼后的不一样

美术要规范,要在指定的大小范围内进行拼效果,不能随性,图的大小规格要适配参考比例大小

图片导出的时候要仔细,不然图片和效果图之间有出入

4.ui的适配问题

需要调整锚点来控制缩放,根据屏幕的宽高比进行适配

5.脚本适配代码

挂载到canvas下即可,选择适合你的方式

using UnityEngine;

using UnityEngine.UI;

/// <summary>

/// 像素完美 Canvas 自动配置

/// 挂载到 Canvas 上,自动处理不同分辨率适配

/// </summary>

RequireComponent(typeof(Canvas))

RequireComponent(typeof(CanvasScaler))

public class PixelPerfectCanvasSetup : MonoBehaviour

{

Header("基准设置")

Tooltip("基准分辨率(美术资源设计的目标分辨率)")

public Vector2Int baseResolution = new Vector2Int(1920, 1080);

Tooltip("像素每单位(与 Sprite PPU 保持一致)")

public float pixelsPerUnit = 32f;

Header("缩放策略")

Tooltip("缩放模式")

public ScalingMode scalingMode = ScalingMode.IntegerScaling;

Tooltip("屏幕匹配权重(0=宽度优先,1=高度优先,0.5=平衡)")

Range(0f, 1f)

public float matchWidthOrHeight = 0.5f;

Header("像素对齐")

Tooltip("启用像素对齐(避免模糊)")

public bool enablePixelSnapping = true;

Tooltip("运行时动态调整")

public bool updateAtRuntime = true;

private Canvas canvas;

private CanvasScaler canvasScaler;

private int lastScreenWidth;

private int lastScreenHeight;

public enum ScalingMode

{

/// <summary>整数倍缩放(最清晰,但可能有黑边)</summary>

IntegerScaling,

/// <summary>自适应缩放(填满屏幕,可能略微模糊)</summary>

AdaptiveScaling,

/// <summary>固定像素尺寸(不缩放,可能裁剪)</summary>

ConstantPixelSize

}

void Awake()

{

canvas = GetComponent<Canvas>();

canvasScaler = GetComponent<CanvasScaler>();

ApplyPixelPerfectSettings();

}

void Start()

{

lastScreenWidth = Screen.width;

lastScreenHeight = Screen.height;

}

void LateUpdate()

{

if (!updateAtRuntime) return;

// 检测分辨率变化

if (Screen.width != lastScreenWidth || Screen.height != lastScreenHeight)

{

ApplyPixelPerfectSettings();

lastScreenWidth = Screen.width;

lastScreenHeight = Screen.height;

}

}

/// <summary>

/// 应用像素完美设置

/// </summary>

public void ApplyPixelPerfectSettings()

{

canvas.pixelPerfect = true;

switch (scalingMode)

{

case ScalingMode.IntegerScaling:

ApplyIntegerScaling();

break;

case ScalingMode.AdaptiveScaling:

ApplyAdaptiveScaling();

break;

case ScalingMode.ConstantPixelSize:

ApplyConstantPixelSize();

break;

}

Debug.Log($"[PixelPerfect] 分辨率: {Screen.width}x{Screen.height}, " +

$"缩放: {canvasScaler.scaleFactor:F2}x, " +

$"模式: {scalingMode}");

}

/// <summary>

/// 整数倍缩放(推荐用于像素艺术)

/// 优点:完美清晰

/// 缺点:可能有黑边

/// </summary>

private void ApplyIntegerScaling()

{

canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;

canvasScaler.referenceResolution = baseResolution;

canvasScaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;

canvasScaler.matchWidthOrHeight = matchWidthOrHeight;

canvasScaler.referencePixelsPerUnit = pixelsPerUnit;

// 计算整数倍缩放

int scaleX = Mathf.Max(1, Screen.width / baseResolution.x);

int scaleY = Mathf.Max(1, Screen.height / baseResolution.y);

int scale = Mathf.Min(scaleX, scaleY);

// 调整参考分辨率以实现整数倍缩放,确保为偶数避免像素完美渲染警告

int adjustedWidth = Screen.width / scale;

int adjustedHeight = Screen.height / scale;

// 强制转换为偶数(向下取整到最近的偶数)

adjustedWidth = MakeEven(adjustedWidth);

adjustedHeight = MakeEven(adjustedHeight);

Vector2 adjustedResolution = new Vector2(adjustedWidth, adjustedHeight);

canvasScaler.referenceResolution = adjustedResolution;

}

/// <summary>

/// 确保数值为偶数(向下取整到最近的偶数)

/// </summary>

private int MakeEven(int value)

{

return (value / 2) * 2;

}

/// <summary>

/// 自适应缩放(推荐用于混合风格)

/// 优点:填满屏幕

/// 缺点:可能轻微模糊

/// </summary>

private void ApplyAdaptiveScaling()

{

canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;

canvasScaler.referenceResolution = baseResolution;

canvasScaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;

canvasScaler.matchWidthOrHeight = matchWidthOrHeight;

canvasScaler.referencePixelsPerUnit = pixelsPerUnit;

}

/// <summary>

/// 固定像素尺寸(不推荐,仅特殊情况)

/// </summary>

private void ApplyConstantPixelSize()

{

canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ConstantPixelSize;

canvasScaler.scaleFactor = 1f;

canvasScaler.referencePixelsPerUnit = pixelsPerUnit;

}

/// <summary>

/// 获取当前像素缩放比例

/// </summary>

public float GetCurrentScale()

{

return canvasScaler.scaleFactor;

}

/// <summary>

/// 获取整数倍缩放级别

/// </summary>

public int GetIntegerScaleLevel()

{

int scaleX = Mathf.Max(1, Screen.width / baseResolution.x);

int scaleY = Mathf.Max(1, Screen.height / baseResolution.y);

return Mathf.Min(scaleX, scaleY);

}

void OnValidate()

{

// 编辑器中实时预览

if (Application.isPlaying && canvas != null && canvasScaler != null)

{

ApplyPixelPerfectSettings();

}

}

}

相关推荐
mocoding11 小时前
使用Flutter设置UI三方库card_settings_ui重构鸿蒙版天气预报我的页面
flutter·ui·harmonyos
雨季66612 小时前
Flutter 三端应用实战:OpenHarmony 简易点击计数器与循环颜色反馈器开发指南
开发语言·flutter·ui·ecmascript·dart
雨季66616 小时前
Flutter 三端应用实战:OpenHarmony 简易“动态主题切换卡片”交互模式
flutter·ui·交互·dart
雨季66617 小时前
Flutter 三端应用实战:OpenHarmony 简易“动态色盘生成器”交互模式深度解析
开发语言·前端·flutter·ui·交互
雨季66618 小时前
Flutter 三端应用实战:OpenHarmony 简易“可展开任务详情卡片”交互模式深度解析
开发语言·前端·javascript·flutter·ui·交互
GIS小小研究僧18 小时前
如何使用Photoshop扣透明底电子签名
ui·photoshop
不会代码的小测试19 小时前
UI自动化-下拉选择框多级联动情况进行选择
前端·javascript·python·ui·自动化
不会代码的小测试19 小时前
UI自动化-下拉元素被隐藏无法直接进行select选择情况解决
前端·javascript·ui·自动化
雨季66620 小时前
Flutter 三端应用实战:OpenHarmony 简易“圆形进度启动屏”交互模式深度解析
开发语言·前端·javascript·flutter·ui·交互
熊猫钓鱼>_>20 小时前
【开源鸿蒙跨平台开发先锋训练营】Day 14: React Native开发鸿蒙应用第二阶段复盘——从功能实现到工程化实践的跨越
react native·ui·开源·harmonyos·arkts·鸿蒙·flatlist