feat(iOS): 新增原生相机对焦插件并适配扫码页面
1. 新增iOS平台原生相机对焦辅助插件,支持开启连续自动对焦和点击单点对焦 2. 适配扫码页面,iOS平台使用原生插件实现对焦功能,修复Unity自带autoFocusPoint无效问题 3. 添加点击屏幕触发单点对焦,1.5秒后自动恢复连续对焦 4. 新增定时维护对焦状态的协程,防止系统重置对焦模式
This commit is contained in:
parent
8972a69e86
commit
807f940cfb
71
Assets/Plugins/iOS/CameraFocusHelper.mm
Normal file
71
Assets/Plugins/iOS/CameraFocusHelper.mm
Normal file
@ -0,0 +1,71 @@
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
/// 获取当前正在使用的后置摄像头设备
|
||||
static AVCaptureDevice *GetActiveRearCamera(void)
|
||||
{
|
||||
// 遍历所有正在运行的 AVCaptureSession,找到后置摄像头的输入
|
||||
if (@available(iOS 10.0, *)) {
|
||||
AVCaptureDeviceDiscoverySession *session = [AVCaptureDeviceDiscoverySession
|
||||
discoverySessionWithDeviceTypes:@[AVCaptureDeviceTypeBuiltInWideAngleCamera]
|
||||
mediaType:AVMediaTypeVideo
|
||||
position:AVCaptureDevicePositionBack];
|
||||
for (AVCaptureDevice *d in session.devices) {
|
||||
if (d.deviceType == AVCaptureDeviceTypeBuiltInWideAngleCamera) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
}
|
||||
return [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
/// 开启连续自动对焦
|
||||
void _EnableContinuousAutoFocus(void)
|
||||
{
|
||||
AVCaptureDevice *device = GetActiveRearCamera();
|
||||
if (!device) return;
|
||||
|
||||
NSError *error = nil;
|
||||
if ([device lockForConfiguration:&error]) {
|
||||
if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
|
||||
device.focusMode = AVCaptureFocusModeContinuousAutoFocus;
|
||||
NSLog(@"[CameraFocusHelper] 已开启连续自动对焦");
|
||||
}
|
||||
if ([device isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) {
|
||||
device.exposureMode = AVCaptureExposureModeContinuousAutoExposure;
|
||||
}
|
||||
[device unlockForConfiguration];
|
||||
} else {
|
||||
NSLog(@"[CameraFocusHelper] 配置失败: %@", error.localizedDescription);
|
||||
}
|
||||
}
|
||||
|
||||
/// 触发单次自动对焦(点击对焦用)
|
||||
void _TriggerAutoFocus(float normalizedX, float normalizedY)
|
||||
{
|
||||
AVCaptureDevice *device = GetActiveRearCamera();
|
||||
if (!device) return;
|
||||
|
||||
NSError *error = nil;
|
||||
if ([device lockForConfiguration:&error]) {
|
||||
if ([device isFocusPointOfInterestSupported]) {
|
||||
device.focusPointOfInterest = CGPointMake(normalizedX, normalizedY);
|
||||
device.focusMode = AVCaptureFocusModeAutoFocus;
|
||||
}
|
||||
if ([device isExposurePointOfInterestSupported]) {
|
||||
device.exposurePointOfInterest = CGPointMake(normalizedX, normalizedY);
|
||||
device.exposureMode = AVCaptureExposureModeAutoExpose;
|
||||
}
|
||||
[device unlockForConfiguration];
|
||||
|
||||
// 1.5秒后恢复连续对焦
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)),
|
||||
dispatch_get_main_queue(), ^{
|
||||
_EnableContinuousAutoFocus();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
33
Assets/Plugins/iOS/CameraFocusHelper.mm.meta
Normal file
33
Assets/Plugins/iOS/CameraFocusHelper.mm.meta
Normal file
@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bfac996797a54a14fa60abaaaf887145
|
||||
PluginImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
iconMap: {}
|
||||
executionOrder: {}
|
||||
defineConstraints: []
|
||||
isPreloaded: 0
|
||||
isOverridable: 0
|
||||
isExplicitlyReferenced: 0
|
||||
validateReferences: 1
|
||||
platformData:
|
||||
- first:
|
||||
Any:
|
||||
second:
|
||||
enabled: 0
|
||||
settings: {}
|
||||
- first:
|
||||
Editor: Editor
|
||||
second:
|
||||
enabled: 0
|
||||
settings:
|
||||
DefaultValueInitialized: true
|
||||
- first:
|
||||
iPhone: iOS
|
||||
second:
|
||||
enabled: 1
|
||||
settings:
|
||||
AddToEmbeddedBinaries: false
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using Kill.UI.Components;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
@ -41,6 +42,15 @@ namespace Kill.UI.Pages
|
||||
public bool enableAutoFocus = true;
|
||||
[Tooltip("对焦间隔(秒)")]
|
||||
public float focusInterval = 1f;
|
||||
|
||||
#if UNITY_IOS && !UNITY_EDITOR
|
||||
[DllImport("__Internal")]
|
||||
private static extern void _EnableContinuousAutoFocus();
|
||||
|
||||
[DllImport("__Internal")]
|
||||
private static extern void _TriggerAutoFocus(float normalizedX, float normalizedY);
|
||||
#endif
|
||||
|
||||
// 摄像头相关
|
||||
private WebCamTexture webCamTexture;
|
||||
private WebCamDevice currentDevice;
|
||||
@ -60,6 +70,22 @@ namespace Kill.UI.Pages
|
||||
StopScan();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
#if UNITY_IOS && !UNITY_EDITOR
|
||||
if (isScanning && Input.touchCount > 0)
|
||||
{
|
||||
Touch touch = Input.GetTouch(0);
|
||||
if (touch.phase == TouchPhase.Began)
|
||||
{
|
||||
float normX = touch.position.x / Screen.width;
|
||||
float normY = touch.position.y / Screen.height;
|
||||
_TriggerAutoFocus(normX, normY);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始扫描
|
||||
/// </summary>
|
||||
@ -151,17 +177,21 @@ namespace Kill.UI.Pages
|
||||
}
|
||||
}
|
||||
RectTransform cameraPreviewRect=cameraPreview.GetComponent<RectTransform>();
|
||||
// 使用较低的扫描分辨率以提高性能
|
||||
int targetWidth = 2160;
|
||||
|
||||
// 创建摄像头纹理
|
||||
webCamTexture = new WebCamTexture(deviceName, targetWidth, 30);
|
||||
// 使用 1080p 分辨率
|
||||
webCamTexture = new WebCamTexture(deviceName, 1920, 1080, 30);
|
||||
|
||||
// 开始播放
|
||||
webCamTexture.Play();
|
||||
|
||||
// 等待摄像头启动
|
||||
yield return new WaitUntil(() => webCamTexture.width > 100);
|
||||
|
||||
#if UNITY_IOS && !UNITY_EDITOR
|
||||
// iOS: 通过原生插件开启连续自动对焦(autoFocusPoint 在 iOS 无效)
|
||||
_EnableContinuousAutoFocus();
|
||||
// 定期维护对焦状态,防止被系统重置
|
||||
StartCoroutine(IOsFocusMaintainCoroutine());
|
||||
#endif
|
||||
webCamTexture.autoFocusPoint = new Vector2(0.5f, 0.5f);
|
||||
// 调整预览画面比例
|
||||
AdjustPreviewAspect();
|
||||
@ -216,6 +246,20 @@ namespace Kill.UI.Pages
|
||||
Debug.Log($"[ScanQRcode] 预览调整 - 相机: {cameraWidth}x{cameraHeight}, 预览: {previewWidth}x{previewHeight}");
|
||||
}
|
||||
|
||||
#if UNITY_IOS && !UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// iOS 对焦维护协程 — 定期重新设置连续自动对焦,防止被系统重置
|
||||
/// </summary>
|
||||
private IEnumerator IOsFocusMaintainCoroutine()
|
||||
{
|
||||
while (isScanning)
|
||||
{
|
||||
yield return new WaitForSeconds(3f);
|
||||
_EnableContinuousAutoFocus();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private Texture2D previewTexture;
|
||||
|
||||
/// <summary>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user