Unity-2D
Unity-2D
1.Unity中的2D模式:
1)游戏在二维上展示
启用 2D 模式时将会设置正交(即无透视)视图:摄像机沿 Z 轴观察,而 Y 轴向上增加。因此可以轻松可视化场景并放置 2D 对象。
2)设置项目默认模式:Edit > Project Settings > Default Behavior Mode
在 2D 项目模式下:
所有图像(images)都会被当做 2D 图片,并设置成 sprite mode 精灵模式
Sprite Packer 会被启动
Scene 视图默认为 2D
默认游戏对象没有实时方向光。
摄像机的默认位置为 0,0,–10。(在 3D 模式下为 0,1,–10。)
The camera projection is set to be Orthographic. (In 3D Mode it is Perspective.)摄像机投射模式被设置为正交(没有远小近大,没有距离之分),而在 3D 模式下,是透视(远小近大,有距离之分)
在 Lighting 窗口中:
Skybox is disabled for new scenes:天空盒默认关闭
Ambient Source is set to Color. (With the color set as a dark grey: RGB: 54, 58, 66.) 保围光源设置为 color ,默认为灰色
Realtime Global Illumination (Enlighten) is set to off.关闭实时光照
Baked Global Illumination is set to off.关闭全局光照烘焙
Auto-Building set to off.自动创建关闭
2.在Unity中创建2D游戏
1)Player的创建与控制:
使用静态精灵创建Player:
精灵 Sprite 是 Unity 中 2D 素材的默认存在形式,是 Unity 中的 2D 图形对象。
在 2D 游戏中,使用 2D 素材的过程: PNG(JPG 等)----> Sprite ----> GameObject
2)Player的移动脚本:
铺垫:
Vector2 二维向量
在数学中,Vector 向量/矢量指的是带方向的线段
在 Unity 中,Transform 值使用 x 表示水平位置,使用 y 表示垂直位置,使用 z 表示深度。这 3 个数值组成一个坐标。由于此游戏是 2D 游戏,你无需存储 z 轴位置,因此你可以在此处使用 Vector2 来仅存储 x 和 y 位置。
Transform 中 position 的类型,也是 Vector2。C# 这种强类型语言,赋值时,左右必须是同一类型才能进行
Unity 默认 Input Manager 设置
在 Unity 项目设置中,可以通过 Input Manager 进行默认的游戏输入控制设置 Edit > Project Settings > Input
键盘按键,以 2 个键来定义轴:
负值键 negative button,被按下时将轴设置为 -1
正值键 positive button ,被按下时将轴设置为 1
Axis 轴 Axes 是它的负数形式
Horizontal Axis: 水平轴 对应 X 轴
Vertical Axis:纵轴 对应 Y 轴
Input类
使用该类来读取传统游戏输入中设置的轴/鼠标/按键,以及访问移动设备上的多点触控/加速度计数据。若要使用输入来进行任何类型的移动行为,请使用 Input.GetAxis。 它为您提供平滑且可配置的输入 - 可以映射到键盘、游戏杆或鼠标。 请将 Input.GetButton 仅用于事件等操作。不要将它用于移动操作。Input.GetAxis 将使脚本代码更简洁。
时间和帧率
当前的代码中,帧数越高,同一时间内,执行 Update 的次数越多,角色移动速度越快。如果游戏以每秒 60 帧的速度运行,那么 Ruby 将移动 0.1 _ 60,因此每秒移动 6 个单位。但是,如果游戏以每秒 10 帧的速度运行,就像刚刚让游戏运行的那样,那么 Ruby 仅移动 0.1 _ 10,因此每秒移动 1 个单位!
如果一个玩家的计算机非常陈旧,只能以每秒 30 帧的速度运行游戏,而另一个玩家的计算机能以每秒 120 帧的速度运行游戏,那么这两个玩家的主角的移动速度会有很大差异。这样就会使游戏的难易程度提高或降低,具体取决于运行游戏的计算机。
而帧数是由硬件水平影响的(越好越高),不同电脑中,会导致游戏效果完全不同
新建Player后,选中Player,在Inspector窗口中Add Component,自定义一个脚本,移动脚本的代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RubyMover : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
public float speed = 0.1f;
// speed访问权限设置为public,在Unity中可修改属性。
// Update is called once per frame
void Update()
{
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
Vector2 position = transform.position;
position.x += 0.1f * x * speed * Time.deltaTime;
position.y += 0.1f * y * speed * Time.deltaTime;
transform.position = position;
}
}3)2D游戏中瓦片地图的创建和使用:
瓦片地图工作流程
预处理 sprite 资源:将图片资源拖拽到 project 中,生成 sprite;然后一般需要进行切割 slice ,将其配置成需要的各个 tile;
创建要在其上绘制瓦片的瓦片地图。此过程中还会自动创建 Grid 游戏对象作为瓦片地图的父级。
直接创建瓦片资源,或者通过将用作瓦片素材的精灵带入 Tile Palette 窗口自动生成瓦片。
创建一个包含瓦片资源的 Tile Palette,并使用各种笔刷来绘制到瓦片地图上。
瓦片地图的高级使用
使用普通的瓦片地图,构建整个世界,一个一个格子用笔刷来填充,非常费时,Unity 在不断地升级中,添加了很多种快速构建瓦片地图的方式,掌握了这些方法,能够极大减少绘制地图所用的时间。
编程瓦片 Scriptable Tile
Unity 支持用代码创建自己的 Tile 类,自己书写瓦片的绘制规则。还可以为瓦片创建自定义编辑器。这与脚本化对象的自定义编辑器的工作方式相同。创建一个继承自 TileBase(或 TileBase 的任何有用子类,如 Tile)的新类。重写新的 Tile 类所需的所有方法。
编程画笔 Scriptable Brush
Unity 也支持创建自己的 Brush 类,设计适合自己游戏的网格画笔。
创建一个继承自 GridBrushBase(或 GridBrushBase 的任何有用子类,如 GridBrush)的新类。重写新的 Brush 类所需的所有方法。创建可编程画笔后,画笔将列在 Palette 窗口的 Brushes 下拉选单 中。默认情况下,可编程画笔脚本的实例将经过实例化并存储在项目的 Library 文件夹中。对画笔属性的任何修改都会存储在该实例中。如果希望该画笔有多个具备不同属性的副本,可在项目中将画笔实例化为资源。这些画笔资源将在 Brush 下拉选单中单独列出。
2D Tilemap Extras (2D 瓦片地图扩展)
Animated Tile 动画瓦片
动画瓦片在游戏运行时,按顺序显示 Sprite 列表以创建逐帧动画
Rule Tile 规则瓦片
可以为每个瓦片创建规则,在绘制时,unity 会自动响应这些规则,绘制地图时更加智能
RuleTile 使用步骤:
准备 Tile 素材,配置素材属性,分割素材;
新建 RuleTile,为其添加规则,设置每个 Tile 的相邻规则;
将设置好的 RuleTile 拖拽到 Tile Palette 中,就可以使用了。
Rule Override Tile / Advanced Rule Override Tile 规则覆盖瓦片
可以用已经生成好的 Rule Tile,作为 Rule Override Tile 的规则来源,只替换对应的瓦片素材,而沿用原先的规则,可以快速的创建规则瓦片的方法。
4)场景中的图形顺序:
伪透视图
透视图指的是有深度、距离感的图,一般要三维中的深度轴来表现场景的深度,而二维游戏中没有这个深度,只能通过前后来仿造深度效果,称为“伪透视图”
先前通过调整瓦片的 Order in Layer 属性来解决了瓦片地图的排序问题,但并非总是希望一个游戏对象在另一个游戏对象之上,比如,在同一个瓦片地图中,玩家角色在一个物体之前(比如一棵树)时,应该是玩家遮挡树,而玩家移动到树后时,应该是树遮挡玩家,这就需要“伪造”透视图。
在 2D 游戏中,场景里的 “前后” 是由 Y 轴决定的,需要让 Unity 根据游戏对象的 y 坐标来绘制游戏对象Y 轴 y 坐标值越小,越靠前,应该遮挡 y 坐标值较大的游戏对象,也就是 y 坐标较小的游戏对象后绘制,就会位于上层
在游戏中,如果要设置 2D 伪透视试图,需要在项目设置中进行更改:
Edit > Project Settings > Graphics > Camera Settings > Transparency Sort Mode = Custom Axis > Transparency Sort Axis x = 0 / y = 1 / z = 0
此设置告诉 Unity 在 y 轴上基于精灵的位置来绘制精灵。
按 Play 以进入运行模式并测试你的更改。现在,你的角色比箱子高时,角色应该会绘制在箱子的后面;而角色比箱子低时,绘制在箱子的前面。
Sprite 轴心 pivot
每个 Sprite 都有一个轴心(中心点),Unity 根据 pivot 对 sprite 进行定位,这个 pivot 可以在 sprite editor 中调整,可以将其设置到 sprite 上任意位置
在 2D Rpg 游戏场景中的游戏对象,如果想要实现较为真实的 “伪透视” 效果,最好将游戏对象的 sprite 中 pivot 都设置到素材的最下方正中。
然后将游戏对象的 Sprite Sort Point 由 Center 改为 Pivot 即可.
5 )物理系统:
铺垫:
Unity中内置的物理系统可以模仿地球上的物理系统,使Unity中创建的一切精灵都具有类似地球上的物理属性。
物理系统中比较重要的脚本组件:
Rigidbody :项目中的刚体组件
定义了对象收到外力后,如何模拟其行为,如翻滚,掉落。当为一个对象添加了 Rigidbody 组件后,就会模拟受重力而掉落。如果再加上collider组件,则会响应外部的力,而运动。添加 Rigidbody后,我们就不能通过 transform 组件来移动物体了,只能由物理系统来模拟驱动。当然这不是绝对的,某些特定情境,需要关掉物理模拟,将物体摆放到指定位置,再重新打开物理模拟。有时,我们希望对象参与物理模拟,但是其行为还是由逻辑控制,比如,对于游戏内的NPC,我们需要由代码控制其运动,同时又需要添加rigidbody,这样才能被Trigger检测到,对于这种情况,可以将 Rigidbody 设置为动力学物体(Is Kinemiac)。
···collider : 项目中碰撞体组件:
定义了物体的形状来进行碰撞模拟。物理碰撞体的形状不需要严格和物体一致,只要能表示其物理形状即可。比如一个复杂的人,我们可以用一个胶囊体来定义其碰撞形状。
Unity内建了很多碰撞体,以下时常用的碰撞体:
BoxCollider 立方体碰撞体 SphereCollider 球形碰撞体 CapsuleCollider 胶囊碰撞体 MeshCollider 从对象的网格创建碰撞体。MeshCollider之间不支持碰撞检测,效率太低。可以将MeshCollider的Convex选项打开,则能支持MeshCollider之间的碰撞检测,同时提高性能。 WheelCollider 创建载具的轮子的碰撞体 TerrainCollider 处理Unity地形系统的碰撞
2D中相应的BoxCollider2D,CircleCollider2D,CapsuleCollider2D,以及其它转为2D建立的碰撞体类型,如PolygonCollider2D。
Box,Sphere,Circle,Capsule这些简单碰撞体的效率相对都是较高的,建议使用这些简碰撞体。
当一个精灵比较复杂时(如创建的一个人物角色),可以采用组合碰撞体的方式,对角色不同的身体部位分别采用不同的碰撞体组件。
触发器:
为碰撞体组件选中is Trigger复选框,会发现碰撞体不再组织移动了。触发器用于检测碰撞但不产生碰撞。在2D项目中要使用OnTriggerEnter2D方法。
code:
private void OnTriggerEnter2D(Collider2D collision)
{
Debug.Log($"与{collision}发生碰撞了!");
}
OnColliderEnter(2D) 和OnTriggerEnter(2D):
OnCollisionEnter方法必须是在两个碰撞物体都不勾选isTrigger的前提下才能进入,反之只要勾选一个isTrigger那么就能进入OnTriggerEnter方法。
OnCollisionEnter和OnTriggerEnter是冲突的不能同时存在的。
OnTriggerEnter和OnCollisionEnter的选择。
如果想实现两个刚体物理的实际碰撞效果时候用OnCollisionEnter,Unity引擎会自动处理刚体碰撞的效果。
如果想在两个物体碰撞后自己处理碰撞事件用OnTriggerEnter。
6)Unity中的世界交互:
可收集的对象:
例如玩家通过触发器实现回血或者扣血的操作:
//扣血的类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class collectibleHealth : MonoBehaviour
{
public int healther = -1;
private void OnTriggerEnter2D(Collider2D collision)
{
Debug.Log($"与{collision}发生碰撞了!");
//获取主角游戏对象
RubyMover RM = collision.GetComponent<RubyMover>();
if(RM!=null)
{
//调用改变血量的方法时,建议再加一层判断,血满时无法调用这个方法。
RM.ChangeHealth(healther);
Destroy(gameObject);
}
}
}
//玩家类
//玩家类中的一些属性(例如血量或者其他的一些私有属性)建议设置为私有,并提供get/set方法。
public class RubyMover : MonoBehaviour
{
public float speed = 0.1f;
Rigidbody2D rigidbody;
float x;
float y;
int CurHealth;
int MaxHealth;
// Start is called before the first frame update
void Start()
{
rigidbody = GetComponent<Rigidbody2D>();
MaxHealth = CurHealth = 5;
}
// Update is called once per frame
void Update()
{
x = Input.GetAxis("Horizontal");
y = Input.GetAxis("Vertical");
}
private void FixedUpdate()
{
Vector2 position = rigidbody.position;
position.x += 0.1f * x * speed * Time.deltaTime;
position.y += 0.1f * y * speed * Time.deltaTime;
rigidbody.MovePosition(position);
}
//有关血量更改的代码
public void ChangeHealth(int HCer)
{
CurHealth = Mathf.Clamp(CurHealth + HCer, 0, MaxHealth);
Debug.Log("当前生命值:" + CurHealth + "/" + MaxHealth);
}
}
设置摄像机跟随Player移动(使用自带脚本的的方式):
现在package manager里面安装Cinemachine,新建一个camera对象,找到CinemachineVirtualCamera,在Extension中选择自己需要的脚本组件类型。在Hierarchy中新建一个游戏对象,为这个游戏对象添加Collider组件、新建layer,同时在这个游戏对象中选中新建的Layer,在Edit->project settings->Physics 2D中取消新建Layer与所有的物体的碰撞。
2D游戏详细教程可参考:
7)U2D中的精灵动画:
参考网页教程,百度资源。
8)一些问题及解决方式:
创建的角色在于环境中的一些组件发生碰撞时角色发生旋转、抖动的问题:
旋转:在2D项目中,选中创建的角色,在Inspector面板中找到添加的Rigidbody 2D脚本,在Constrains勾选Freeze Rotation Z。
抖动:引起抖动的原因可能是你在角色移动脚本里写代码是利用的transform来移动角色。此时脚本移动角色的位置会和碰撞体矛盾从而引起抖动。(说白了就是你在脚本中强行将角色移到一个碰撞体的碰撞范围内,这个碰撞体又将角色弹了回来)。解决的方法是:利用刚体的移动代替transfoem的移动方式。代码脚本如下:
//原transform移动方式见上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RubyMover : MonoBehaviour
{
public float speed = 0.1f;
Rigidbody2D rigidbody;
float x;
float y;
// Start is called before the first frame update
void Start()
{
rigidbody = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
x = Input.GetAxis("Horizontal");
y = Input.GetAxis("Vertical");
}
//使物理计算保持稳定,定期更新。只要你想直接影响物体组件或刚体,就要使用这个函数。
private void FixedUpdate()
{
Vector2 position = rigidbody.position;
position.x += 0.1f * x * speed * Time.deltaTime;
position.y += 0.1f * y * speed * Time.deltaTime;
rigidbody.MovePosition(position);
}
}
Unity-2D的更多相关文章
- unity 2d 和 NGUI layer
http://blog.csdn.net/xtxy/article/details/37876825 在使用unity2d开发游戏的时候,使用了NGUI作为界面,本来二者配合得还挺好,但是一个使用场景 ...
- Ubuntu 11.10 安装GMONE3,卸载 UNITY和UNITY 2D
Ubuntu 11.10安装GNOME3: 1)sudo apt-get install gnome-shell sudo apt-get install gnome-themes* (或者 ...
- Mastering Unity 2D Game Development
Mastering Unity 2D Game Development will give your game development skills a boost and help you begi ...
- Unity 2D游戏开发教程之精灵的死亡和重生
Unity 2D游戏开发教程之精灵的死亡和重生 精灵的死亡和重生 目前为止,游戏项目里的精灵只有Idle和Walking这两种状态.也就是说,无论精灵在游戏里做什么,它都不会进入其它的状态,如死亡.于 ...
- Unity 2D游戏开发教程之摄像头追踪功能
Unity 2D游戏开发教程之摄像头追踪功能 上一章,我们创建了一个简单的2D游戏.此游戏中的精灵有3个状态:idle.left和right.这看起来确实很酷!但是仅有的3个状态却限制了精灵的能力,以 ...
- Unity 2D游戏开发教程之2D游戏的运行效果
Unity 2D游戏开发教程之2D游戏的运行效果 2D游戏的运行效果 本章前前后后使用了很多节的篇幅,到底实现了怎样的一个游戏运行效果呢?或者说,游戏中的精灵会不会如我们所想的那样运行呢?关于这些疑问 ...
- Unity 2D游戏开发教程之使用脚本实现游戏逻辑
Unity 2D游戏开发教程之使用脚本实现游戏逻辑 使用脚本实现游戏逻辑 通过上一节的操作,我们不仅创建了精灵的动画,还设置了动画的过渡条件,最终使得精灵得以按照我们的意愿,进入我们所指定的动画状态. ...
- Unity 2D游戏开发教程之游戏精灵的开火状态
Unity 2D游戏开发教程之游戏精灵的开火状态 精灵的开火状态 “开火”就是发射子弹的意思,在战争类型的电影或者电视剧中,主角们就爱这么说!本节打算为精灵添加发射子弹的能力.因为本游戏在后面会引入敌 ...
- Unity 2D游戏开发教程之游戏中精灵的跳跃状态
Unity 2D游戏开发教程之游戏中精灵的跳跃状态 精灵的跳跃状态 为了让游戏中的精灵有更大的活动范围,上一节为游戏场景添加了多个地面,于是精灵可以从高的地面移动到低的地面处,如图2-14所示.但是却 ...
- Unity 2D游戏开发教程之为游戏场景添加多个地面
Unity 2D游戏开发教程之为游戏场景添加多个地面 为游戏场景添加多个地面 显然,只有一个地面的游戏场景太小了,根本不够精灵四处活动的.那么,本节就来介绍一种简单的方法,可以为游戏场景添加多个地面. ...
随机推荐
- suse 12 二进制部署 Kubernetets 1.19.7 - 第10章 - 部署kube-proxy组件
文章目录 1.10.部署kube-proxy 1.10.0.创建kube-proxy证书 1.10.1.生成kube-proxy证书和秘钥 1.10.2.创建kube-proxy的kubeconfig ...
- CentOS8安装启用telnet服务
CentOS8默认只安装telnet的客户端,其服务端telnet-server由于安全原因由用户自主选择安装.下面为实践安装启动telnet-server,注意其与vsftp服务安装的异同. 1.查 ...
- 【Elastic-2】SpringBoot整合ELK、SpringBoot写ES
ELK相关TODO 快速开始文档(https://www.cnblogs.com/lbhym/p/15934416.html) SpringBoot整合ELK ELK接入Kafka(待Kafka快速开 ...
- CobaltStrike逆向学习系列(14):CS功能分析-DotNet
这是[信安成长计划]的第 14 篇文章 0x00 目录 0x01 DotNet功能分析 0x02 DotNet功能执行 0x03 写在最后 在上两篇文章中,讲述了 CS 中的一种功能执行方式 RDI, ...
- 中了勒索病毒的win7系统
- 记一次阿里云oss文件上传服务假死
引言 记得以前刚开始学习web项目的时候,经常涉及到需要上传图片啥的,那时候都是把图片上传到当前项目文件夹下面,每次项目一重启图片就丢了.虽然可以通过修改/tomcat/conf/server.xml ...
- .net 底层运行机制
1. CLR C#.NET 平台下,代码是怎么运行的 源代码-->托管模块-->程序集-JIT->编程CPU指令 1.1 在.NET框架下,首先将源代码编 ...
- SpringBoot进阶教程(七十三)整合elasticsearch
Elasticsearch 是一个分布式.高扩展.高实时的搜索与数据分析引擎.它能很方便的使大量数据具有搜索.分析和探索的能力.充分利用Elasticsearch的水平伸缩性,能使数据在生产环境变得更 ...
- C语言刷“矩阵”类题目(2维矩阵/2级指针)
566. 重塑矩阵 int** matrixReshape(int** mat, int matSize, int* matColSize, int r, int c, int* returnSize ...
- 开机弹出一下Visual Studio Just-In-Time对话框的问题
开机弹出一下Visual Studio Just-In-Time对话框 开机弹出一下Visual studio just-in-time对话框,出现一下问题,且点击确定后又弹出第二个对话框, 解决方法 ...