You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中无法获取iPhone刘海精确尺寸的技术求助

iOS刘海/灵动岛尺寸与位置获取(Unity兼容方案)

问题核心:pt转px出错的原因

你遇到的转换后尺寸过小的问题,本质是未正确使用设备的屏幕缩放因子(UIScreen.main.scale)。iOS的pt是逻辑单位,Unity使用的是物理像素(px),正确转换公式是:物理像素值 = 逻辑pt值 × 屏幕缩放因子。不同设备的scale不同:

  • iPhone 8及以下:scale=2
  • iPhone X系列(除14 Pro):scale=3
  • iPhone 14 Pro/Max:scale=3

修正后的硬编码方案(含scale转换)

先在Xcode中通过设备型号判断对应的刘海/灵动岛逻辑尺寸,再乘以scale得到Unity可用的像素值:

// 定义设备类型枚举
enum NotchType {
    case large // iPhone X/XS/11 Pro/12 Pro/13 Pro
    case medium // iPhone XR/11/12/13/14
    case pill // iPhone 14 Pro/Max(灵动岛)
}

extension UIDevice {
    var notchType: NotchType {
        let modelName = self.modelName
        switch modelName {
        case "iPhone 14 Pro", "iPhone 14 Pro Max":
            return .pill
        case "iPhone XR", "iPhone 11", "iPhone 12", "iPhone 12 mini", "iPhone 13", "iPhone 13 mini", "iPhone 14":
            return .medium
        default:
            return .large
        }
    }
    
    // 获取设备型号名称
    var modelName: String {
        var systemInfo = utsname()
        uname(&systemInfo)
        let machineMirror = Mirror(reflecting: systemInfo.machine)
        let identifier = machineMirror.children.reduce("") { identifier, element in
            guard let value = element.value as? Int8, value != 0 else { return identifier }
            return identifier + String(UnicodeScalar(UInt8(value)))
        }
        return identifier
    }
    
    // 获取刘海/灵动岛的物理像素尺寸(Unity可用)
    var notchPixelSize: CGSize {
        let scale = UIScreen.main.scale
        switch notchType {
        case .large:
            let hasSmallNotch = modelName == "iPhone 12 Pro" || modelName == "iPhone 13 Pro"
            let ptSize = hasSmallNotch ? CGSize(width: 206.30, height: 29.10) : CGSize(width: 207.50, height: 31.30)
            return CGSize(width: ptSize.width * scale, height: ptSize.height * scale)
        case .medium:
            let ptSize = CGSize(width: 160.90, height: 33.20)
            return CGSize(width: ptSize.width * scale, height: ptSize.height * scale)
        case .pill:
            let ptSize = CGSize(width: 124, height: 35.20)
            return CGSize(width: ptSize.width * scale, height: ptSize.height * scale)
        }
    }
    
    // 获取刘海/灵动岛的物理像素位置(Unity可用,原点为屏幕左上角)
    var notchPixelFrame: CGRect {
        let size = notchPixelSize
        let screenWidth = UIScreen.main.bounds.width * UIScreen.main.scale
        let x = (screenWidth - size.width) / 2
        return CGRect(x: x, y: 0, width: size.width, height: size.height)
    }
}

传递数据到Unity

在Xcode中计算好后,通过UnitySendMessage把尺寸和位置传给Unity的C#脚本:

// 假设Unity中有一个名为"NotchManager"的GameObject,脚本中有ReceiveNotchInfo方法
let size = UIDevice.current.notchPixelSize
let frame = UIDevice.current.notchPixelFrame
UnitySendMessage("NotchManager", "ReceiveNotchInfo", "\(size.width),\(size.height),\(frame.x),\(frame.y)")

Unity端C#脚本示例:

using UnityEngine;

public class NotchManager : MonoBehaviour
{
    public void ReceiveNotchInfo(string data)
    {
        string[] parts = data.Split(',');
        float width = float.Parse(parts[0]);
        float height = float.Parse(parts[1]);
        float x = float.Parse(parts[2]);
        float y = float.Parse(parts[3]);
        
        Debug.Log($"刘海/灵动岛尺寸:{width}x{height},位置:({x},{y})");
        // 后续可根据这些值做UI布局
    }
}

关键说明

  • 硬编码的pt尺寸来自iOS官方设计规范,确保精确匹配设备
  • 必须使用设备实际的UIScreen.main.scale,不能用固定值,否则会出现尺寸偏差
  • 灵动岛的位置和尺寸会随系统状态变化(比如后台播放音乐时会变大),如果需要实时更新,需监听UIWindow的safeAreaInsets变化,重新计算

内容的提问来源于stack exchange,提问作者durazno

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 15:05:16