unity3d Ngui uispriteunity ngui坐标系怎么跟随鼠标unity ngui坐标系

程序写累了,就来玩玩酷跑小游戏吧,嘿嘿。
雨松MOMO送你一首歌曲,嘿嘿。
NGUI研究院之自适应屏幕(十)
NGUI研究院之自适应屏幕(十)
围观64474次
编辑日期: 字体:
现在用unity做项目 90%都是用NGUI,并且我个人觉得NGUI应该算是比较成熟的UI插件,虽然他也存在很多问题,但是至少这么多游戏都在用,它目前是能hold住的,嘿嘿。 这篇文章说说我现在是怎么自适应UI 和 3D 游戏的。。
1.获取屏幕的宽高
Screen.width
Screen.height 可以回去设备屏幕的宽高,但是它并不是NGUI的宽高。比如你想做一个全屏的UISprite 。
这样的代码是错误的。
sprite.width = Screen.
sprite.height =
Screen.height
正确的方法应该是:
UIRoot root = GameObject.FindObjectOfType&UIRoot&();
if (root != null) {
float s = (float)root.activeHeight / Screen.height;
int height =&&Mathf.CeilToInt(Screen.height * s);
int width = Mathf.CeilToInt(Screen.width * s);
Debug.Log("height = " + height);
Debug.Log("width = " + width);
我建议在项目中你可以封装两个只读的方法来获取NGUI 的宽和高。
2.自适应NGUI屏幕
在Hierarchy视图中选择UI Root (2D)然后在Inspector视图中、
Scaling Style :如果是手机游戏的就选择FixedSizeOnMobiles,它的意思就是开启UI整体缩放的支持。
Manual Height:这个属性就比较重要的,因为我们的自适应屏幕,原理就是根据Screen.width 和Screen.height来动态的计算它的实际高度,动态的修改这个值。
Min/Max inum Height:这就是支持的最大高度,和最小高度一般都是 640 到 1536。
开始做UI的时候就需要定制游戏主版本的屏幕分辨率,我定的分辨率是960X640,所以我屏幕的实际高度是640 。那么在Manual Height的参数我就需要写640.
如下图所示,我在960X640的屏幕上布置了我的简单界面。
我举个典型的例子,这时候我把屏幕分辨率改成. 因为960X640 是3:2的屏幕,而:3的屏幕。所以屏幕就会变成那面这个样子。
然后,我们就需要来修改Manual Height这个参数,如果是的分辨率,那么此时它的Maunal Height应该是720。
在看看,如下图所示,界面整体布局居中显示了。但是布局的位置是没有发生任何改变的。
我个人觉得根本就是没有完美自适应的方法。除非你可以接收屏幕上的某些元素被拉伸变形。。 如上图所示,在这里我们只需要把背景的白框拉伸成屏幕的宽高即可。
说了半天就是一个简单的数学算法,根据布置UI时的分辨率,加上现在屏幕的分辨率根据这两个参数,动态的计算出现在manualHeight的高度。
我在Unity圣典上已经看到有人写了这个算法。
/forum/read.php?tid=9230&ds=1
找一个合适的地方调用一下如下方法。 960 /640换成你布置屏幕时的宽高即可。
12345678910111213
static private void AdaptiveUI() {
int ManualWidth = 960;
int ManualHeight = 640;
UIRoot uiRoot = GameObject.FindObjectOfType&UIRoot&();
if (uiRoot != null)
if (System.Convert.ToSingle(Screen.height) / Screen.width & System.Convert.ToSingle(ManualHeight) / ManualWidth)
uiRoot.manualHeight = Mathf.RoundToInt(System.Convert.ToSingle(ManualWidth) / Screen.width * Screen.height);
uiRoot.manualHeight = ManualHeight;
UI整体布局 “居中” 并不是一个好的处理办法,这时候就需要策划人员的头脑风暴了,不过可以参考一下别的游戏自适应的方法。如果你的UI布局比较简单的话,比如战斗UI。一般都是4个角有东西,可以用Anchor把它固定在屏幕上。或者用新版本的NGUI提供的UIWidget也可以设置固定的位置。
3.3D方面的自适应
我们在说说3D方面的自适应,比如游戏里面的人物。。我举个例子,比如我们游戏是960X640屏幕,在屏幕的边缘放一个3D的角色,那么此时屏幕变成8那么这个小人可能就跑到屏幕外面了。。解决这个问题就需要3D 摄像机的自适应。
如下图所示,我在960X640屏幕的边缘放了一个3D的立方体对象。
然后我把屏幕设置成。如下图所示,可以看到这个立方体对象以后超出了屏幕。。。
有一个非常俏巧妙的方法可以解决它。就是修改Camera的Field of View的参数,找一个合适的地方调用一下这个方法。这里我借助了刚刚自适应NGUI屏幕的参数。这里我用到了UIRoot的manualHeight ,所以UI需要你是用上面介绍的方法来自适应,640表示我制作时屏幕的高度,拥着两个数相除那么就可以得到Camera缩放的系数了。
static public float getCameraFOV(float currentFOV) {
UIRoot root = GameObject.FindObjectOfType&UIRoot&();
float scale =Convert.ToSingle(root.manualHeight / 640f);
return currentFOV * scale; }
找一个合适的地方调用,60表示默认的参数,getCameraFOV这个方法的原理就是根据默认的FOV参数加上当前屏幕的系数以及布置屏幕时的系数,动态计算出一个新的FieldOfView。
Camera.main.fieldOfView = getCameraFOV(60);
说到这里其实修改射线机的Z轴也可以达到自适应的效果,但是我觉得最好用fieldofView,因为游戏中你的摄像机可能位置会发生变化,总不能一直去改Z轴的属性吧,而FiewldOfView你只需要设置一次就可以了。嘿嘿。
4.拉伸变形
你可以让所有的摄像机在初始化的时候调用一下这个方法,它会完完整整的拉伸屏幕 ,大家可以试试,不过千万不要用,因为变形了太难看。。。。
foreach(Camera camera in Camera.allCameras)
camera.aspect&&= 640f/960f;
本文固定链接:
转载请注明:
雨松MOMO提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。
您可能还会对这些文章感兴趣!1169人阅读
unity(9)
根据&Unity插件之NGUI学习(2),创建一个UI Root,在UI Root下创建一个Texture作为背景图,并设置图片,在Wiget下调整大小;然后在UI Root下再创建一个Panel。
在Hierarchy窗口选中Panel,然后选择菜单Component-&NGUI-&Interaction-&Table,查看Inspector窗口,在Panel的属性中增加了UITable。
Columns 表示每行有几个元素
Direction 表示超过每列的元素后添加元素的方向
Sorting 元素排序的方式
Hide Inactive 默认勾选,所有看不到的子节点在排列时被忽略
Padding x,y方向的间隔,这里的值是基于NGUI的
创建一个Level的Prefab,在Hierarchy窗口下,添加多个Level,然后选中Panel,在Inspector中,用鼠标右击UITable,并执行Execute,就可以在预览窗口看到排列好的Table界面了。
因为Panel在Inspector窗口的坐标是可以调整的,但是它的大小也是基于NGUI的,为了能使整个Tabel界面居中放置,我必须计算其大小,然后将调整整个Panel的位置。
这里遇到一个问题,Level是用UISprite创建的,所以获得的高度和宽度也是基于NGUI的,并非是基于世界坐标系的,UITable的Padding也同样是。
问题的关键在于,所有的NGUI控件都是基于UIWidget的,所以从源码入手,会发现:
public override Vector3[] worldCorners
Vector2 offset = pivotO
float x0 = -offset.x * mW
float y0 = -offset.y * mH
float x1 = x0 + mW
float y1 = y0 + mH
Transform wt = cachedT
mCorners[0] = wt.TransformPoint(x0, y0, 0f);
mCorners[1] = wt.TransformPoint(x0, y1, 0f);
mCorners[2] = wt.TransformPoint(x1, y1, 0f);
mCorners[3] = wt.TransformPoint(x1, y0, 0f);
其坐标和尺寸都是通过Transform.TransformPoint()方法转换的——变换位置从自身坐标到世界坐标。好了,下面就是我创建的TableTest 脚本,是挂在Panel上面的。
using UnityE
using System.C
public class TableTest : MonoBehaviour {
private UIS
private UIT
private float tableWidth, tableH
// Use this for initialization
void Start () {
table = GetComponent&UITable&();
level = GetComponentInChildren&UISprite&();
int columns = table.
// 计算Table的row
int count = transform.childC
int rows = count % columns == 0 ? count / columns : count / columns + 1;
// 计算Table的宽度和高度,基于NGUI也就是自身原本的尺寸
tableWidth = columns * (level.width + 2 * table.padding.x);
tableHeight = rows * (level.height + 2 * table.padding.y);
Debug.Log(&level width=& + level.width + &, height=& + level.height);
Debug.Log(&table width=& + tableWidth + &, height=& + tableHeight);
// 将Table的宽度高度转换到世界坐标系的偏移
Vector3 delta = transform.TransformPoint(new Vector3(-tableWidth / 2, tableHeight / 2, 0));
transform.Translate(delta);
// Update is called once per frame
void Update () {
这样再运行游戏的话,就能看到整个Table会居中在整个预览窗口。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:52816次
排名:千里之外
原创:27篇
评论:12条
(1)(2)(1)(1)(5)(10)(1)(1)(3)(1)(1)(2)(1)(1)(3)23167人阅读
Unity3D开发(8)
不论是游戏中的UI,还是应用中的UI,纹理九宫格拉伸都是必不可少的,因为采用这种拉伸方式,可以最大化的节省纹理资源,还能保证良好的表现效果!
<span style="color:#.原理
把纹理用4条线分割成9部分(如上图),通过观察可以发现,5是最规则的形状(矩形),其次是2,6,8,4(矩形,但是和四个角有公共边),最后是四个角1,3,9,7(圆角矩形)
规则的图形在拉伸之后的效果是比较好的,如果是不规则的图形,则会在拉伸之后变形!
根据上图做拉伸制定规则:
(1)保证四个角1,3,9,7不做任何拉伸
(2)与四个角有公共边的四个矩形2,6,8,4做单向拉伸,即保证与四个角的公共边不拉伸,例如2,8只进行横向拉伸,4,6只进行纵向拉伸
(3)中间部分5做双向拉伸,即横向,纵向同事拉伸
<span style="color:#.NGUI中Sliced用法
(1)选中制作完成的Atlas文件,在其Inspector面板中设置四条切线的位置(像素为单位)
(2)使用Sliced类型的UISprite
<span style="color:#.实现原理
在UISprite中,对于不同类型有不同填充Shader定点的方法,参照UISprite.OnFill()
public override void OnFill (BetterList&Vector3& verts, BetterList&Vector2& uvs, BetterList&Color32& cols)
switch (type)
case Type.Simple:
SimpleFill(verts, uvs, cols);
case Type.Sliced:
SlicedFill(verts, uvs, cols);
case Type.Filled:
FilledFill(verts, uvs, cols);
case Type.Tiled:
TiledFill(verts, uvs, cols);
基本的Sprite是一个矩形纹理,即两个三角形,4个顶点,参照
protected void SimpleFill (BetterList&Vector3& verts, BetterList&Vector2& uvs, BetterList&Color32& cols)
九宫&#26684;拉伸的Sprite相当于9个矩形纹理拼合而成,并且有部分矩形做拉伸操作,根据Shader渲染三角形,需要传4x9=36个顶点,参照
protected void SlicedFill (BetterList&Vector3& verts, BetterList&Vector2& uvs, BetterList&Color32& cols)
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:883388次
积分:8161
积分:8161
排名:第2144名
原创:70篇
转载:23篇
评论:400条
阅读:232359
文章:27篇
阅读:373366
(3)(1)(3)(2)(1)(5)(1)(2)(4)(3)(2)(5)(4)(4)(5)(5)(6)(4)(2)(8)(2)(1)(2)(3)(6)(2)(1)(1)(2)(3)用NGUI做拖拽装备物品的功能,如何解决坐标偏移的问题?_unity3d吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:69,839贴子:
用NGUI做拖拽装备物品的功能,如何解决坐标偏移的问题?收藏
我是仿NGUI官方例子做的,但是使用不同分辨率时,游戏里物品坐标和鼠标坐标就会产生偏移,如何解决?(红圈圈是我拖动时鼠标的位置,而图片已经移到右下角了)
UI视觉,原画,插画,影视动画,VR/AR,影视后期,游戏特效,游戏设计
不出意外,应该是用Anchor(锚点)固定。
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或当前位置: >
unity插件:浅谈NGUI中UISprite和UITexture
时间: 14:06 来源:互联网 作者:网络 浏览:
NGUI的三大组件,UILabel、UISprite、UITexture,它们三个同时都继承UIWidget。先回到一个很郁闷的话题上,到底是优化DrawCall还是优化内存。UISprite :& NGUI引入图集的概念,不考虑ABA叠层的情况下,一个图集内的图片用UISprite,那么它就是一个DrawCall。但是如果你做了一个图集是的。此时你的界面上只用了图集中的一张很小的图,那么很抱歉这张大图都需要载入你的内存里面,1024就是4M的内存,如果你做了10个1024的图集,你的界面上刚好都只用了每个图集里面的一张小图,那么再次抱歉你的内存直接飙40M。另外生成出来的Atlas我记得默认会打开mipMap的选项,mipMap是摄像机离得远近用不同的图片,用来减少渲染,可是UI绝对不会出现远近之分,mipMap会让你的包占更大的容量,因为是两张图。如下图所示,Atlas图集生成完以后,选择Advanced,不要勾选Generate Mip Maps ,也不要勾选Read/Write Enabled ,不然1024在内存里就不4M了将变成8M。。那么NGUI的内存怎么施放呢?我建议最好不要手动施放,因为Unity有一套非常完善自动施放内存的方法。如果你的项目不变态,切场景的时候就用异步切换场景。yield&return&Application.LoadLevelAsync(name);我发现很多人喜欢切场景的时候,在调用一下Resources.unloadunnsedAssets,这是多此一举的。Resources.UnloadUnusedAssets&();当场景切换完毕后,Unity会自动施放没有被引用的内存。 我记得NGUI3.X某一个版本是存在内存泄漏的问题,后来我们专门升级了新版本,扯远了,回到正题!UITexture:它完全没有图集的概念,使用起来非常的灵活,只需要把图片挂上去就行了。这样内存里只会占用你这一张图的大小,内存虽然小了但是DrawCall就上去了。因为每一张UITexture就是一次DrawCall。如果你发现你的UITexture图片大小不对了,是因为图片拖进Unity默认图片的格式会设置成Texture,它的NonPower of2 是默认打开的,所以他会缩放你的图片成2的幂次方,所以你可以把图片格式改成GUI。图片格式: NGUI生成的图集的图片格式是PNG,但是无论是什么格式的图片,Unity都会自己搞一套格式,并且打包的时候也不会用你文件夹下图片的格式,而是Unity自己的格式。如果你用UITexture你可以真对每一张图来修改它的格式,比如一些颜色数比较少的图片,你可以直接用16bit,如果你的图片没有用到透明,你可以用pvr或者etc,这样你的图片会更小。可是UISprite就不行,只要其中有一张小图用了透明,你就得用RGBA32,不然UI就会很难看,你可以自己试试。除了UITexture 和 Atlas的图片没办法以外(因为必须有透明),不是建议是必须,你的贴图无论如何都必须是2的幂次方。因为只有2的幂次方图片 并且没有透明通道才会被压缩,IOS会压缩成pvr格式,Android会压缩成ETC格式,压缩以后图片会小很多的,好几倍的小。人物贴图、场景贴图、特效贴图、一定要2的幂次方!切记!!如下图所示,同样的贴图大小。我觉得界面中那些重复性比较高的图片最好打成图集,而一些原画,或者背景图建议直接使用UITexture。还有NGUI的图集其实很占用内存,也很占用空间,为了优化效率尽量让策划拖妥协让UI尽可能的复用。所以做项目初期就要好好的管理自己的图集,这也是个很郁闷的话题,因为需求一直都在变所以你很难规划你的图集,你不知道美术会设计出来什么样的图,你也不知道策划会设计出来什么样的界面,所以你很难去确定你的公共图集 还有 界面特有图集该如何来规划。因为一不小心你的图集就会超过1024,你也不知道那些资源复用性最高。。这也是我觉得NGUI最郁闷的一点。。如果那一天做UI不用自己去规划图集而是运行时系统最优选择,那该多好呀!!!
(责任编辑:脚印)
免责声明:Unity之家部分内容来源于互联网,如有侵权,请联系我们,本站将立即进行处理。
猜你也喜欢看这些 ??????
其他类型的Unity入门 ??????

我要回帖

更多关于 ngui uisprite 的文章

 

随机推荐