Unity中的2D层级显示问题
1.层级显示
使用素材为免费或自制
本文章只用于学习和记录
在Unity2D游戏中可能出现以下情况
贴图的前后关系不正确
可以通过控制图片的层级来解决
本示例中杰西卡和树木都是搭载了图片的空物体,背景为Tilemap
新建脚本PositionSortRenderer
public class PositionSortRenderer : MonoBehaviour
{
[SerializeField] //序列化,私有变量也能显示在Inspector面板中
private int sortingOrderBase = 5000; //大参数方便后续计算
private Renderer myRenderer; //声明一个Renderer
private void Awake()
{
myRenderer = gameObject.GetComponent<Renderer>();
}
private void LateUpdate() //在角色和场景内所有物体(包括摄像机)完成移动后进行
{
myRenderer.sortingOrder = (int)(sortingOrderBase - transform.position.y);//根据y左边方向计算
//这里个人感觉sortingOrderBase用0也行,但正数方便计算且节省性能
//个人感觉可以将减法优化为加法
}
}
注意这里是在LateUpdate()
中进行层级运算
Unity应当在层级内的所有物体运动完成和所有物理计算如碰撞这些完成之后再进行与图片等渲染有关的处理,否则图片在运动和碰撞检测时会不断抽搐,这里不深入细讲,LateUpdate()
会在FixedUpdate()
和Update()
之后运行。
注意这里需要将代码搭载到需要排序且有Sprite Renderer的图片上,而非空物体
运行后发现有效果
但仍有问题
这是参与计算的是图片的中心点(锚点)位置的原因
那么解决方法存在两种
2.通过代码解决
因为图片默认为中心点,那么只需要在计算时减去中心点到图片底部这一段距离即可
优化PositionSortRenderer
//public class PositionSortRenderer : MonoBehaviour
//{
//[SerializeField]
//private int sortingOrderBase = 5000;
[SerializeField]
private int offset = 0;
//private Renderer myRenderer;
//private void Awake()
//{
//myRenderer = gameObject.GetComponent<Renderer>();
//}
//private void LateUpdate() //在角色和场景内所有物体(包括摄像机)完成移动后进行
//{
myRenderer.sortingOrder = (int)(sortingOrderBase - transform.position.y - offset);
//}
//}
这里Offset可以每个图片微调,直接获取图片高度一半的方法还在尝试
3.通过修改图片的锚点来修改
也可以直接修改图片的中心点
单体图片点击即可修改
分割的图片需要打开Sprite Editor选中修改,但单体图片也可进行相同操作
中间的蓝色圆圈即为图片的中心,可以直接拖拽进行修改
修改后如下
4.继续优化
其实那些位置不变的物体只需要计算一次层级,只有类似玩家这类不断移动的物体才需要持续计算层级,静止物体只计算一侧层级能节省许多性能开销
继续优化PositionSortRenderer
//public class PositionSortRenderer : MonoBehaviour
//{
......
[SerializeField]
private bool runOnlyOnce = false;
//private Renderer myRenderer;
......
//private void LateUpdate() //在角色和场景内所有物体(包括摄像机)完成移动后进行
//{
//myRenderer.sortingOrder = (int)(sortingOrderBase - transform.position.y - offset);
if (runOnlyOnce)
{
Destroy(this); //这里摧毁了脚本
}
//}
//}
这样勾选了Run Only Once的图片进行一次层级运算后便会销毁
这里层级信息被直接赋值给了Unity
因为大部分静态对象没有必要每帧都进行层级运算,避免后续计算导致性能开销
角色这类需要运动的对象不要勾选,需要一直对其进行层级运算
5.再次优化
角色的层级运算也不必每帧进行,因为大部分玩家其实是观察不出来的,如果我们通过计时器来定时计算玩家这类会移动的图片还能省下不少性能。
继续优化PositionSortRenderer
//public class PositionSortRenderer : MonoBehaviour
//{
......
private float timer;
private float timerMax = 0.1f;
//private Renderer myRenderer;
......
//private void LateUpdate() //在角色和场景内所有物体(包括摄像机)完成移动后进行
//{
timer -= Time.deltaTime;
if (timer <= 0f)
{
timer = timerMax;
//myRenderer.sortingOrder = (int)(sortingOrderBase - transform.position.y - offset);
//if (runOnlyOnce)
//{
//Destroy(this);
//}
}
//}
//}
这里我设置为0.1秒计算一次,也可自行修改
这样就能得到正确的显示结果
Unity中的2D层级显示问题的更多相关文章
- 关于Unity中的删除、显示和隐藏节点
一.删除节点和组件 1.删除一个节点,以及节点上面所有的组件全部删除了//删除一个节点的时候,节点上面所有的组件也会被删除:MonoBehaviour.Destroy(this.gameObject) ...
- Unity中2D和UGUI图集的理解与使用
图集 什么是图集? 在使用3D技术开发2D游戏或制作UI时(即使用GPU绘制),都会使用到图集,而使用CPU渲染的2D游戏和UI则不存在图集这个概念(比如Flash的原生显示列表),那么什么是图集呢? ...
- Unity中调用Windows窗口句柄以及根据需求设置并且解决扩展屏窗体显示错乱/位置错误的Bug
问题背景: 现在在搞PC端应用开发,我们开发中需要调用系统的窗口以及需要最大化最小化,缩放窗口拖拽窗口,以及设置窗口位置,去边框等功能 解决根据: 使用user32.dll解决 具体功能: Unity ...
- 介绍用C#和VS2015开发基于Unity架构的2D、3D游戏的技术
[Unity]13.3 Realtime GI示例 摘要: 分类:Unity.C#.VS2015 创建日期:2016-04-19 一.简介 使用简单示例而不是使用实际示例的好处是能让你快速理解光照贴图 ...
- 【unity shaders】:Unity中的Shader及其基本框架
shader和Material的基本关系 Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等组合作用,然后输出.绘图单元可以依据这个输出来将图 ...
- Unity中Mesh分解与边缘高亮加上深度检测
一个比较简单的需求,不过遇到些坑,记录下. 房间有多个模型,每个模型可能多个SubMesh,点击后,需要能具体到是那个SubMesh,并且在这个SubMesh上显示边缘高光,以及能个性这单个SubMe ...
- Unity中简单使用Opengl
简介 由于项目特殊需求,需要在unity中使用一些OpenGL的东西来绘制图形(PS:其实就是有一个拖尾算法只有OpenGL版本~~~懒得改了,直接在unity中使用OpenGL算了).所以琢磨咯下如 ...
- 在Unity中高效工作(上)
原地址:http://www.unity蛮牛.com/thread-19974-1-1.html 编的话:感谢做编程的IT朋友,帮我翻译文章,我又稍稍做了些修改.给点儿掌声哩.欢迎大家多多评论呦. 我 ...
- Unity 4.3 2D 教程:新手上路
这篇文章译自 Christopher LaPollo 先生的 Unity 4.3 2D 教程的第一部分 Unity 4.3 2D Tutorial: Getting Started 感谢这套优秀教程的 ...
随机推荐
- Window7环境下安装Scrapy 方法
Window7环境下安装Scrapy Scrapy在CPython(默认Python实现)和PyPy(从PyPy 5.9开始)下运行Python 2.7和Python 3.4或更高版本. 如果您使用的 ...
- notepad++给每一列数据加单引号及逗号结尾
原始数据: 对列操作--先加前引号(光标放在第一行哦):编辑-->列块编辑 再加后引号和逗号(文本尾端不齐,就用替换): 打开替换窗口:ctrl+F(其实就是查找) 加完引号和逗号效果:(如果最 ...
- KVM 虚拟化基本知识,virtio工作原理
KVM虚拟化的基本知识,virtio的工作流程及原理,virtio-vhost, virtio-vhost-user pci 配置空间,是谁在kick 写pci配置空间的?又是通过什么机制通知给qem ...
- 实习项目1-串口IP升级调试
设计目标:设计一个串口IP,要求1:输入时钟频率任意,如0-400M时钟频率:要求2:波特率超过常见的115200,要求达到4M. 设计核心思路:波特率计算公式,divp10x = (10 * fsy ...
- bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp)
bzoj2084/luoguP3501 [Poi2010]Antisymmetry(回文自动机+dp) bzoj Luogu 对于一个01字符串,如果将这个字符串0和1取反后,再将整个串反过来和原串一 ...
- 如何移植sshserver到嵌入式平台
ssh解释说明 SSH 为 Secure Shell 的缩写,由 IETF 的网络小组(Network Working Group)所制定:SSH 为建立在应用层基础上的安全协议.SSH 是较可靠,专 ...
- Bean实例化方式
https://blog.csdn.net/diaosinixiheixiu/article/details/78919395 https://www.cnblogs.com/deng-cc/p/89 ...
- 什么是MVC模式?
MVC (Model View Controller) 是一个设计模式,使用MVC应用程序被分成三个核心部件:模型.视图.控制器.它们各自处理自己的任务.M是指数据模型,V是指用户界面,C则是控制器. ...
- 什么是 FutureTask?使用 ExecutorService 启动任务?
在 Java 并发程序中 FutureTask 表示一个可以取消的异步运算.它有启动和取消 运算.查询运算是否完成和取回运算结果等方法.只有当运算完成的时候结果才 能取回,如果运算尚未完成 get 方 ...
- 为什么要使用 rabbitmq?
(1)在分布式系统下具备异步,削峰,负载均衡等一系列高级功能; (2)拥有持久化的机制,进程消息,队列中的信息也可以保存下来. (3)实现消费者和生产者之间的解耦. (4)对于高并发场景下,利用消息队 ...