请教unity5.2做2Dunity 随机生成地图地图的显示问题

程序写累了,就来玩玩酷跑小游戏吧,嘿嘿。
雨松MOMO送你一首歌曲,嘿嘿。
Unity2D研究院之精灵Sprite与屏幕之间的关系(二)
Unity2D研究院之精灵Sprite与屏幕之间的关系(二)
围观22169次
编辑日期: 字体:
继续学习一下unity2d,上一篇说了怎么自动生成Unity的Sprite动画。有朋友在下面给我留言说,怎么设置锚点?其实很简单。如下图所示,选择精灵然后在右边设置 pivot 就可以了。这里我设置的是左下角对齐。
锚点这东西挺怀念的,N年前我在做J2ME手游的时候。屏幕整体的坐标是左上角是00点。X轴向右递增,Y轴向下递增。所有的image也是这个原理。只是unity的触摸屏坐标不是左上角,而是左下角。 所以这里我把精灵的锚点也设置成了左下角,注意上图中的pixels to units 请设置成100。
触摸屏坐标:就是用Input.mousePosition 获取用户触摸屏幕手指 或者 鼠标的位置。
实际坐标:unity的实际坐标是笛卡尔坐标系,00点是在正中心,X轴向右是正,向左是负。Y轴向上是正,向下是负。
这样问题也就来了,我怎么把触摸屏的坐标换算到实际坐标系上?解决这个问题之前我们要先解决一个更重要的问题–摄像机的参数。
我开发时的分辨率设置成宽960高640.如下图所示,在Game视图下面,我选择了960X640的分辨率,下面提示的 using reslution 717×478 是因为此时Game视图的比960X640小,所以这里等比例缩小了一点所以是 717X478。
这时选择你的摄像机。如下图所示,把Projection改成Orthographic 也就是正交摄像机。 然后要说的就是size = 3.2。这个3.2是怎么来的呢?想想我们的分辨率的高是多少?高是640.
640/2/100 = 3.2. 除以2就是屏幕高的一半,除以100就是上面我们设置的 pixels to units =100 . 再举个例子如果你开发时的分辨率是 那么此时你的高就是720了。 720/2/100 = 3.6 那么此时摄像机的size 就应该写成3.6了。。 再唠叨一句,手游的分辨率自适应基本都是这样修改摄像机的size来实现的了。
摄像机的参数搞清楚了,我们在来看看之前提出的问题?我怎么把触摸屏的坐标换算到实际坐标系上? 把如下代码挂在一个Sprite对象上。
1234567891011121314151617181920212223242526272829303132
using UnityEngine;using System.Collections;&public class FishCommon : MonoBehaviour {& private float camHalfHeight; private float camHalfWidth; & void Awake() {
this.camHalfHeight = Camera.main.orthographicSize;
this.camHalfWidth = Camera.main.aspect * camHalfHeight;
}& void Update () {
//手指 或者 鼠标的坐标传进去
Move(Input.mousePosition); }& public void Move(Vector2 postions){
Move(new Vector3(postions.x,postions.y,0)); } public void Move(Vector3 postions){
//在这里进行坐标的换算
transform.position = ScreenToWorld(postions); }& private Vector3 ScreenToWorld(Vector3 postion){&
Camera.main.ScreenToWorldPoint(postion); }}
如下图所示,小鱼会跟着我的鼠标同时移动。
今天就到这里,感谢大家阅读,嘿嘿。如果有意见或者建议的换欢迎在下面留言,大家一起探讨unity2d开发。 希望unity4.6早日正式版发布呀,呼呼~~~
本文固定链接:
转载请注明:
雨松MOMO提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。
您可能还会对这些文章感兴趣!unity, 由5.2.1f1升级到5.3.5f1,2d物理不正常解法 - wantnon - 博客园
随笔 - 365, 文章 - 0, 评论 - 22, 引用 - 0
由5.2.1f1升级到5.3.5f1,物理不正常。
最后发现问题出在我的游戏中的下面一段代码:
  & Vector2 targetPosition=...;
  & Vector2 targetVelocity=...;
  & GetComponent&Rigidbody2D& ().MovePosition (targetPosition);&& &&& &float mass = GetComponent&Rigidbody2D& ().&& &&& &GetComponent&Rigidbody2D& ().AddForce (targetVelocity*mass,ForceMode2D.Impulse);
原来Rigidbody2D.MovePosition的行为在5.2.1f1和5.3.5f1中发生了变化。在5.3.5f1中
MovePosition的实现原理是产生一个在一帧之内由当前位置移动到目标位置的速度,则到下一帧,刚体就会按此速度移动到目标位置了。在5.2.1f1中,当刚体移到目标位置后此速度会被保留,而5.3.5f1中&修正&了这个&bug&,当刚体到达目标位置后,会将刚体的速度恢复为调用MovePosition之前的速度。
但是看来,这样&修正&带来了新的问题,即如果在MovePosition之后立即调用了修改刚体速度的代码,似乎会被覆盖掉。
我目前的避坑办法是将
GetComponent&Rigidbody2D& ().MovePosition (targetPosition);
GetComponent&Rigidbody2D& ().position= targetP
这样就在5.2.1f1和5.3.5f1中都正常了。
参考: /threads/5-0-2f-rigidbody2d-moveposition-setting-the-velocity-now.325655/Unity5学习心得-2D
Unity5学习心得-2D
Unity5学习心得-2D
聊聊2D和3D
自从手机游戏走上历史舞台,先后出现了无数优秀的2D游戏和3D游戏。而在引擎大战中,大家心里也就有了定论,Cocos2d-x做2D,Unity做3D。不过从2014年开始,Cocos2d-x也开始发力3D市场,而Unity也开始垂涎2D领域。那么在技术角度2D和3D到底有什么区别。
笔者看来,它们的相同点是:都还是使用OpenGL ES语言来进行绘制,那么区别就在于2D没有Z值(其实Cocos2d-x的sprite是有Z值的,但是Z值只是用于排绘制的前后顺序,优化绘制性能使用,想想确实在2D中Z值也就只有这么点用了),且摄像机视角固定(在3D中,每帧可能都需要更新摄像机位置,而在2D中,摄像机可以一直保持不动)。
本质上貌似也就只有这么点区别,但是Cocos2d-x针对2D做了很多的优化,Unity在3D中使用到了大量的先进图形学技术。这些,我认为是它们之内无法短时间战胜对方的。
对于游戏开发者来说,用哪个引擎,当然是习惯用哪个就用哪个。
对于引擎开发者来说,多看点总是好的。
Unity中的2D
Unity目前已经支持创建2D或者3D项目了,方式也就是在创建项目的时候进行选择,选择的结果会致使Unity编辑器进行不同设置(比如图片是按照texture导入,还是sprite)。即使选择错了也没关系,开发者可以在任意时间。
3D游戏一般都是使用3D几何体,使用材质和纹理渲染在这些物体的表面,使得它们作为立体的环境、人物、物件,从而组成你的游戏世界。摄像机可以自由的穿梭其中,环境中的光和阴影也以一个真实的方式显示在这个世界中。
3D游戏经常以透视投影的方式进行渲染,这使得距离摄像机近的物体显得更大一些。
这种类型的游戏,请以3D模式开发。
正交3D Orthographic 3D
有一些游戏使用3D几何体,但是会使用正交投影而非透视投影,这是一种常用的游戏开发技术,给玩家一个上帝视角,常被人称为2.5D。
这种类型的游戏,依然需要使用3D模式开发,因为你依然是使用的3D物件。然而,需要将摄像机和scene view调整至正交模式。
2D游戏一般都是图片,也可以称为sprite,没有3D几何体。这些图片直接被绘制到场景中,摄像机也不存在透视投影模式。
这种类型的游戏,请以2D模式开发。
2D gameplay with 3D graphics
有一些2D游戏使用3D几何体作为环境和角色,但是把gameplay限制在2D模式。比如,摄像机可以放大缩小移动,但是玩家只能在2D空间移动,游戏中的物品使用3D模式,摄像机也使用3D透视投影模式。这些游戏有时也被称为2.5D。
这种类型的游戏,虽然gameplay为2D的,但是依然请以3D模式开发。
2D gameplay and graphics,with a perspective camera
这种2D游戏使用2D图像,但是使用透视投影摄像机,看上去图片都是扁平的,但是距离摄像机的位置不同。
这种类型的游戏,2D模式就足以满足开发需要,然而摄像机要调整到透视投影模式,scene view要切换到3D模式。
除了以上这些游戏类型,当然开发者可能还会有自己不同的创意和想法,希望以上这些可以给开发者一些灵感,当然,要记住的是你可以在任意时间随意切换模式。
我的热门文章
即使是一小步也想与你分享程序写累了,就来玩玩酷跑小游戏吧,嘿嘿。
雨松MOMO送你一首歌曲,嘿嘿。
Unity3D研究院之2D游戏开发制作原理(二十一)
Unity3D研究院之2D游戏开发制作原理(二十一)
围观51104次
编辑日期: 字体:
经过了4个月不懈的努力,我和图灵教育合作的这本3D游戏开发书预计下个月就要出版了。这里MOMO先打一下广告,图灵的出版社编辑成员都非常给力,尤其是编辑小花为这本书付出了很大的努力,还有杨海玲老师,不然我也无法完成这本书的编写。等这本书出版了大家记得买喔,哇咔咔~ 下面,这篇文章是MOMO 3D游戏开发书籍中的一小段章节的修改版本,本篇文章我们将探讨一下Unity3D中如何来制作2D游戏。目前市面上已经有非常成熟的2D游戏引擎,比如cocos2d 或cocos2d-x等,并且都是免费的开发者可以直接用来制作2D游戏。然而使用3D引擎来制作2D游戏会让游戏画面更加附有立体感,因为2D游戏中Z轴永远是0,而3D游戏中Z轴是可变化的。
接着说说在Unity3D中制作2D游戏的原理。在Unity3D中绘制贴图的方式大致可分为两种,第一种是在GUI中绘制贴图,第二种是在网格面上绘制贴图。先说说第一种,GUI主要用来制作简单的游戏2D界面,比如游戏主界面中绘制的“游戏名称”、“开始游戏”、“保存游戏”、“退出游戏”一些按钮或界面中一切其它的高级控件,文本框,输入框等等、GUI只能制作简单的图形化界面,因为它的渲染效率非常低,它与3D世界中网格模型的渲染机制完全不一样。第二种的属于将图片绘制在3D中网格平面中,它的渲染效率远远高于GUI中,在制作2D游戏时都是将所有贴图绘制在平面模型对象之上,最后用摄像机以90度垂直的角度照射这这些平面。
下面我们开始学习在Unity3D中制作2D游戏的原理。2D游戏又可以分为两种,区别是物体碰撞时带物理引擎或不带物理引擎。带物理引擎就好比《奋斗的小鸟》一样,大家应该都玩过,小鸟发射后下落击落其它物体将发生物理的碰撞。(我没有细看这款游戏,但是我知道2D 与3D引擎都都可制作),不带物理引擎的就好比《捕鱼达人》这种游戏,游戏中碰撞都是由代码自己来完成的,经典的2D碰撞监测包括:矩形与矩形的碰撞、点与矩形的碰撞、圆与圆的碰撞等。今天这篇文章我们主要讨论第二种不带物理引擎的2D游戏。
如下图所示,我们盘点一下2D游戏中必备的几个元素。
摄像机:无论是3D游戏还是2D游戏摄像机都是非常重要的属性,移动摄像机即可更改屏幕中显示的内容,游戏地图的坐标永远都不会发生改变。
地图:2D游戏中的地图一般是由tile拼接而成,它可由地图编辑器生成然后将每一块tile绘制在整个贴图中,最后将贴图贴在平面网格面之上即可。还有一种作法是将两个或两个以上屏幕大小平面以队列的形式排在屏幕后面,当摄像机移动超出第一块面显示范围时,将它的坐标移动在第二块面后面,此时地图就形成了一个排序的队列。为了让地图的效果更加完美,一般地图可以由好几层来组成,比如背景层、与主角的遮挡曾、物理层等等。
地图拼接:地图的排序队列中两张图应当是可以无缝拼接,这个应当是由美术来提供资源,这里我就不那么细致了将远离说明白即可。
主角:它的范围就比较广的,敌人、物品等等出现在地图之上的都可以使用它。如果控制主角移动,摄像机移动的同时主角也当跟随移动,并且保持屏幕中的移动比例,除非摄像机无法移动,这时将直接移动主角在屏幕中的坐标。 说的有点绕了呵呵,大家仔细想想哈哈。。
然而上面的一切面是由Plane面来完成。
再Unity层次视图中选择摄像机对象,右侧监测面板视图中我们看看摄像机组件的一些属性,如下图所示。需要注意的就是Projection 投影类型。
首先我们应当修改摄像机的属性,默认摄像机投影的类型是Perspective,它保持摄像机以扩散的的形式照射着不利于2D平面的展示。这里我们应当选择Orthographic,这样摄像机将直直的照射在显示的区域。
Perspective类型
Orthographic
从侧面观察摄像机,通过这两张图我相信大家应当能看懂为什么2D游戏要用Orthographic了吧,摄像机的投影类型是可以在代码中动态的修改的。
<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b
//得到游戏中摄像机对象
Camera camera = Camera.mainCamera;
//设置摄像机投影类型OrthoGraphic
camera.isOrthoGraphic = true;
//设置摄像机投影类型Perspective
camera.isOrthoGraphic = false;
在代码中取得摄像机投影的区域大小,它也可以动态的修改,这样就可是实现摄像机拉近与拉远的效果。根据投影区域的大小配合着整个地图的宽高来写判断条件,避免移动摄像机时超过地图的范围。
Camera camera = Camera.mainCamera;
Debug.Log(camera.orthographicSize);
接着我们使用代码来得到地图面的宽高,这段代码写的就比较精细,因为网格面是可以缩放的,首先得到网格面的宽与高,然后分别乘以缩放系数就可以得到真实面的宽与高,然而Unity中的坐标是以“米”为单位。下面代码中用到了中文,如果要想在编辑器中显示中文C#语言需要修改编码格式为UTF-16。JavaScript修改编码格式UTF-8或UTF-16即可。
<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b<div class="crayon-num crayon-striped-num" data-line="crayon-583f6b<div class="crayon-num" data-line="crayon-583f6b
using UnityEngine;using System.Collections;&public class Test : MonoBehaviour {& void Start ()
{& &&&&GameObject plane = GameObject.Find("Plane0");
//得到面默认宽度
float size_x = plane.GetComponent&MeshFilter&().mesh.bounds.size.x;
//得到面宽度的缩放比例
float scal_x = plane.transform.localScale.x;
//得到面默认高度
float size_z = plane.GetComponent&MeshFilter&().mesh.bounds.size.z;
//得到面高度缩放比例
float scal_z = plane.transform.localScale.z;&
//原始宽度乘以缩放比例计算出真实宽度
float mapWidth = size_x * scal_x;
float mapHeight = size_z * scal_z;&
Debug.Log("得到面的位置:"+plane.transform.position);
Debug.Log("得到面的宽度:"+ mapWidth);
Debug.Log("得到面的高度:"+ mapHeight); }&}
有了摄像机照射的区域以及背景地图的宽高尺寸那么就可以在代码中编写逻辑判断条件啦。下面我们来使用简单的代码控制摄像机移动以及主角移动。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
using UnityEngine;using System.Collections;&public class Controller : MonoBehaviour {& //动画数组 private Object[] anim; //主角对象 private GameObject hero; //限制一秒多少帧 private float fps = 10; //帧序列 private int nowFram; //记录当前时间 private float time;& void Start () {
//得到资源名称为down文件夹中的所有对象资源
anim = Resources.LoadAll("down");
//得到主角的对象
hero = GameObject.Find("hero");
}& void FixedUpdate ()
//上、下、左、右平移摄像机
if (Input.GetKey (KeyCode.A))
transform.Translate(-0.01f,0,0);&&&
if(Input.GetKey (KeyCode.D))
transform.Translate(0.01f,0,0);&&
if (Input.GetKey (KeyCode.W))
transform.Translate(0,0.01f,0);&&
if(Input.GetKey (KeyCode.S))
transform.Translate(0,-0.01f,0);&&
//上、下、左、右平移主角 &&&&if (Input.GetKey (KeyCode.J))
&&&&hero.transform.Translate(0.001f,0,0);&&
if(Input.GetKey (KeyCode.L))
&&&&hero.transform.Translate(-0.001f,0,0);&&
if (Input.GetKey (KeyCode.I))
hero.transform.Translate(0,0,-0.001f);&&
if(Input.GetKey (KeyCode.K))
hero.transform.Translate(0,0,0.001f);&&&&
DrawAnimation(anim); }& void&&DrawAnimation(Object[] tex) {&
//计算限制帧的时间
time += Time.deltaTime;
//超过限制帧切换贴图
if(time &= 1.0 / fps){
//帧序列切换&&&&&&
nowFram++;
//限制帧清空&&&&&&
//超过帧动画总数从第0帧开始&&&&&&
if(nowFram &= tex.Length)&&&&&&
nowFram = 0;&&&&&&
}&&&&&&&&}
//将对应的贴图赋予主角对象,强制将资源文件转换成贴图&&&&&&&&hero.renderer.material.mainTexture = (Texture)tex[nowFram];
代码中我们使用 Resources.LoadAll(&#8220;down&#8221;);来加载主角动画资源,这里将主角一组4帧的行走动画放在项目资源视图中 Resources文件夹中的down文件夹内。值得注意的是,使用Resources来加载资源就必须将资源放在Resources文件夹中,否则提示无法找到喔。在书中我以将人物四宫格行走动画加入在其中,因为这里只是一个是示例,所以我只加载了向下行走的4帧动画。我们看看资源在项目资源视图中的保存结构。
还有一个比较重要的地方就是要修改材质的shder类型,因为默认的材质是Diffuse,它是不支持透明的。如果材质不支持透明。主角的背景将会是白色。如下图所示,这里选择Transparent/Diffuse。保存为Transparent家族中的材质都是支持透明的。
最后2D游戏效果图映入我们眼帘了哦。按键W、S、A、D控制摄像机移动,按键J、K、I、L、控制主角移动。
总结一下这篇文章,本文我们在多个Plane对象身上贴上材质资源,再让摄像机直直的照射着它。实现2D游戏的基本原理,本文没有涉及到Unity3D的物理引擎,不要紧在下章中我将向大家介绍一下Unity3D中的刚体组件与角色控制器组件如何来实现模型的物理效果,包括物理引擎与3D或2D游戏的结合。另外大家一定要期待我的新书喔,哇咔咔~嘿嘿。
本文固定链接:
转载请注明:
雨松MOMO提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。
您可能还会对这些文章感兴趣!

我要回帖

更多关于 unity 随机生成地图 的文章

 

随机推荐