程式中有兩個UIView,高德地圖的View在下層,Unity的View在上層,當滑鼠點選到Unity中的UI或其他對象時,Unity截獲點選消息,否則高德地圖處理點選消息。
一:Unity設定NGUI Camera
Clear Flags 設定為:Solid Color
Background設定為黑色,alpha=0,完全透明
二:打包導出Xcode工程:
1.在Classes/UI/UnityView.mm中添加代碼:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
//判斷一下渲染API是否為metal,OpenGLES暫未實作
if(UnitySelectedRenderingAPI() == apiMetal)
{
// 擷取渲染surface
UnityDisplaySurfaceMTL* surf = (UnityDisplaySurfaceMTL*)GetMainDisplaySurface();
// 渲染surface尺寸
CGSize s = ((CAMetalLayer*)self.layer).drawableSize;
// 得到點選坐标
CGPoint p = [self convertPoint:point toView:self];
// 坐标轉換
CGFloat bw = self.bounds.size.width;
CGFloat bh = self.bounds.size.height;
CGFloat box = self.bounds.origin.x;
CGFloat boy = self.bounds.origin.y;
CGFloat x = (p.x - box)/bw * s.width;
CGFloat y = (p.y - boy)/bh * s.height;
// 得到上一次渲染的Texture
MTLTextureRef lastTex = surf->lastSystemColorRB;
// 擷取Texture中此坐标的顔色值
MTLRegion region = MTLRegionMake2D(x, y, 1, 1);
Byte byteBuff[4];
[lastTex getBytes:byteBuff bytesPerRow:_surfaceSize.width*4 fromRegion:region mipmapLevel:0];
// 判斷Alpha值
int a = byteBuff[3];
if(a > 0 )
{
return YES;
}
else
{
return NO;
}
}
return YES;
}
2:在Classes/Unity/UnityRendering.h中的UnityDisplaySurfaceMTL結構聲明中,添加 OBJC_OBJECT_PTR MTLTextureRef lastSystemColorRB,用來儲存上一幀渲染Texture。
unsigned colorFormat; // [MTLPixelFormat]
unsigned depthFormat; // [MTLPixelFormat]
OBJC_OBJECT_PTR MTLTextureRef lastSystemColorRB;
END_STRUCT(UnityDisplaySurfaceMTL)
3:在每次渲染前儲存lastSystemColorRB,修改Classes/Unity/MetalHelper.mm的StartFrameRenderingMTL函數
extern "C" void StartFrameRenderingMTL(UnityDisplaySurfaceMTL* surface)
{
// in case of skipping present we want to nullify prev drawable explicitly to poke ARC
surface->drawable = nil;
surface->drawable = [surface->layer nextDrawable];
// on A7 SoC nextDrawable may be nil before locking the screen
if (!surface->drawable)
return;
surface->systemColorRB = [surface->drawable texture];
surface->lastSystemColorRB = surface->systemColorRB;
// screen disconnect notification comes asynchronously
// even better when preparing render we might still have [UIScreen screens].count == 2, but drawable would be nil already
if (surface->systemColorRB)
4:修改Classes/Unity/MetalHelper.mm的CreateSystemRenderingSurfaceMTL函數代碼:
extern "C" void CreateSystemRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface)
{
DestroySystemRenderingSurfaceMTL(surface);
MTLPixelFormat colorFormat = surface->srgb ? MTLPixelFormatBGRA8Unorm_sRGB : MTLPixelFormatBGRA8Unorm;
surface->layer.presentsWithTransaction = NO;
surface->layer.drawsAsynchronously = YES;
#if UNITY_OSX
MetalUpdateDisplaySync();
#endif
//修改代碼位置
CGFloat backgroundColorValues[] = {0, 0, 0, 0};
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGColorRef backgroundColorRef = CGColorCreate(colorSpaceRef, backgroundColorValues);
surface->layer.backgroundColor = backgroundColorRef; // retained automatically
CGColorRelease(backgroundColorRef);
CGColorSpaceRelease(colorSpaceRef);
surface->layer.device = surface->device;
surface->layer.pixelFormat = colorFormat;
//添加代碼位置
surface->layer.opaque=NO;
surface->layer.framebufferOnly = NO;
surface->colorFormat = colorFormat;
}