Unity3d开发之实现在Unity3d层C#脚本和在Xcode层Objective-c语言的通信以及NGUI的屏幕适配问题
来源:互联网 发布:小蜜软件怎么样 编辑:程序博客网 时间:2024/05/21 11:28
几日前,笔者碰到一个NGUI的屏幕尺寸的适配问题。情况是这样子的:Unity3d编译了一个iPhone版的Xcode工程,非Universal版,进入真机测试的时候,发现当该iPhone版的工程在iPad2真机上NGUI出现了问题,如下图:
由图片可分析出,NGUI的位置都是正确的,但是大小不正确;显然这是由于屏幕分辨率导致的问题,因为NGUI用的是高清图,并且iPad屏幕是非retina屏幕,NGUI的底层代码根据这个屏幕分辨率来缩放,如果屏幕是全屏的,基本上没啥问题;进一步可以锁定问题出在编译的Iphone版工程运行在iPad上面,由于Unity3d的摄像头视野大小是iPhone的屏幕大小,但是实际的屏幕分辨率却是非retina,而图片却是retina导致在非retina屏幕上显示出了retina图片的真实像素尺寸(本来应该缩小一倍)。找到问题的原因后,就可以着手解决了。
由于查看Unity3d的Screen这个类提供的API没有查询屏幕的分辨率是否是retina屏幕的,只能通过Objective-c的API查询。在这里,笔者的思路是,通过在Unity3d层的NGUI的底层NGRoot.cs(NGUI负责屏幕分辨率适配的类)这个类的C#脚本中向Xcode层的Objective-c语言发送消息查询当前的屏幕是非retina屏,是否iPad硬件,再加上一个根据当前Xcode的版本的开关变量(比如是iPhone版就打开,如果是iPad版或者Universal版就关闭)一起判断,决定是否要将当前屏幕的分辨率乘以2(NGUI底层是用某个常量除以当前屏幕的分辨率来适配屏幕的)再来计算缩放。这涉及到Uinty3d层与Xcode层的通信问题。
幸好,C#给我们提供了多平台适应的API,使用System.Runtime.InteropServices,可以定义一个接口,在c#项目外实现。这里可以在C#脚本里定义在需要在Xcode里实现的接口,在接口前加上[DllImport(
"__Internal"
)]即可。代码实例如下:
在Unity3d层的代码:
//----------------------------------------------// NGUI: Next-Gen UI kit// Copyright © 2011-2012 Tasharen Entertainment//----------------------------------------------using UnityEngine;using System.Runtime.InteropServices;/// <summary>/// This is a script used to keep the game object scaled to 2/(Screen.height)./// If you use it, be sure to NOT use UIOrthoCamera at the same time./// </summary>[ExecuteInEditMode][AddComponentMenu("NGUI/UI/Root")]public class UIRoot : MonoBehaviour{public bool automatic = true;public int manualHeight = 800;[DllImport ("__Internal")]public static extern bool isDoubleScreen ();bool isIPhonePlatform = false;Transform mTrans;void Start (){mTrans = transform;UIOrthoCamera oc = GetComponentInChildren<UIOrthoCamera> ();if (oc != null) {Debug.LogWarning ("UIRoot should not be active at the same time as UIOrthoCamera. Disabling UIOrthoCamera.", oc);Camera cam = oc.gameObject.GetComponent<Camera> ();oc.enabled = false;if (cam != null)cam.orthographicSize = 1f;}if (Application.platform == RuntimePlatform.IPhonePlayer) {isIPhonePlatform = true;} }void Update (){manualHeight = Mathf.Max (2, automatic ? Screen.height : manualHeight);if (isIPhonePlatform) {if (UIRoot.isDoubleScreen()) {manualHeight *= 2;}}float size = 2f / manualHeight;Vector3 ls = mTrans.localScale;if (!Mathf.Approximately (ls.x, size) ||!Mathf.Approximately (ls.y, size) ||!Mathf.Approximately (ls.z, size)) {mTrans.localScale = new Vector3 (size, size, size);}}}
在Xcode层的代码:
#pragma mark - logic#define isRetina ([UIScreen mainScreen].currentMode.size.width / [UIScreen mainScreen].bounds.size.width == 2 ? YES : NO)//定义高清图片的开关 ,1打开,0关闭#define isRetinaPicture 1//是否是iPhone程序运行在iPad上#define isPhoneAppOnPad (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone && [[[UIDevice currentDevice] model] hasPrefix:@"iPad"])bool isDoubleScreen () { if (!isRetina && isPhoneAppOnPad && isRetinaPicture) { return true; } return false;}
解决后的NGUI在iPad屏幕上的显示如下图:
好了,上边介绍了如何在Unity3d层向Xcode层发送查询消息解决了NGUI屏幕分辨率适配的问题。接下来再介绍如何在Xcode层向Unity3d层发送消息,在这里,Unity3d提供了一个API来实现,即
void UnitySendMessage(const char* obj, const char* method, const char* msg);
这个API有三个参数,第一个参数是Unity3d里接收消息的物体的名称,第二个参数是Unity3d绑定的物体的脚本里实现的方法名称,第三个参数是是第二个参数的实现方法里需要接收传递的数据参数。代码实例如下:
Xcode层的代码:
NSString *param = @"param";UnitySendMessage("XcodeAdapter", "methodFromXcode", [param cStringUsingEncoding:NSUTF8StringEncoding]);
Unity3d层的代码:
using UnityEngine;using System.Collections;using System.Runtime.InteropServices; //该脚本绑定在Unity3d场景里一个叫XcodeAdapter的GameObject上public class XcodeAdapter : MonoBehaviour {public void methodFromXcode (string param){Debug.Log(param + "~~~~!!!!");}}
本文结束~~~~
- Unity3d开发之实现在Unity3d层C#脚本和在Xcode层Objective-c语言的通信以及NGUI的屏幕适配问题
- Unity3D开发之NGUI分辨率适配的UIStretch中Clipping的屏幕缩放问题
- Unity3D的NGUI图层显示顺序不正确
- Unity3D开发之NGUI结合粒子系统的遮挡问题
- Unity3D开发之NGUI的ScrollView在部分手机显示不正常的解决办法
- Unity3D游戏开发之在Unity3D中视频播放功能的实现
- Android开发之fsl在HAL层Camera的实现
- Android开发之fsl在HAL层Camera的实现
- [脚本] C#虚函数在UNITY3D里的应用
- Unity3D之NGUI的优化
- Unity3D插件NGUI的屏幕自适应
- Unity3D之NGUI的5种点击事件的实现方式及在3D场景中点透的情况
- C++服务器和unity3d的C#通信乱码问题
- Unity3D游戏开发之在Unity3D中实现视频播放
- Unity3d C# 脚本单体模式的实现
- Unity3D学习之(用NGUI创建动画以及冷却效果的实现)
- iphone开发之C++和Objective-C混编 如何在xcode中用C++的STL
- iphone开发之C++和Objective-C混编 如何在xcode中用C++的STL
- android.graphics.Path
- 使用JCONSOLE监控远程LINUX运行的JAVA进程,总是在报连接失败的错误。
- 【★更新★】高性能 Windows Socket 服务端与客户端组件(HP-Socket v2.0.1 源代码及测试用例下载)
- 4_8
- 大数系列——高精度乘法
- Unity3d开发之实现在Unity3d层C#脚本和在Xcode层Objective-c语言的通信以及NGUI的屏幕适配问题
- spring基础开发框架搭建简记
- MFC一些问题的解决方法
- leetcode 122: Palindrome Partitioning
- DVR硬盘存储
- 实例化Spring Ioc文件的三种方式(硬编码)
- 图像编程学习笔记7——图像缩放
- 理解 Proc 文件系统
- 从oracle数据库上传、下载文件