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尺寸

       CGSizes = ((CAMetalLayer*)self.layer).drawableSize

       // 得到点击坐标

        CGPoint p = [self convertPoint:point toView:self];

        

        // 坐标转换

       CGFloatbw = self.bounds.size.width;

       CGFloatbh = self.bounds.size.height;

       CGFloatbox = self.bounds.origin.x;

       CGFloatboy = self.bounds.origin.y;

        CGFloat x = (p.x - box)/bw * s.width;

        CGFloat y = (p.y - boy)/bh * s.height;

        

       // 得到上一次渲染的Texture

       MTLTextureReflastTex = 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;

        }

    }

   returnYES;

}

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);


   MTLPixelFormatcolorFormat = surface->srgb?MTLPixelFormatBGRA8Unorm_sRGB:MTLPixelFormatBGRA8Unorm;


    surface->layer.presentsWithTransaction=NO;

    surface->layer.drawsAsynchronously=YES;


#if UNITY_OSX

    MetalUpdateDisplaySync();

#endif

   //修改代码位置

    CGFloat backgroundColorValues[] = {0, 0, 0, 0};

   CGColorSpaceRefcolorSpaceRef =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;

}