天天看點

Unity中接入高德地圖 UI疊加與消息處理

程式中有兩個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;

}

繼續閱讀