概要
第一个Unity demo 记录一下,一个2D休闲过关小游戏
跟着这个up主操作的
https://www.bilibili.com/video/BV1k64y1N7MV/?spm_id_from=333.337.search-card.all.click&vd_source=c861e132f3eaa49aa9a51955095f5a4e
相关软件版本 Tuanjie Editor 1.0.4
1 资源收集
1.1 Unity商店找使用的资源
https://assetstore.unity.com/zh-CN
1.2 下载的资源包括
图片资源–> Pixel Adventure 1
音效资源–>FREE Casual Game SFX Pack
BGM–>Casual Game BGM #5
字体–>https://www.font.im/english 谷歌字体 搜索Press Start 2P,进行下载
1.3 资源导入
下载完成后在Unity的Package Manager 窗口导入资源,让资源成功在项目的Assets中显示,以备使用;字体文件下载后解压,将 ttf 格式文件拖拽到项目的Assets层级下,以备使用,可进行分类创建font文件夹存放
资源如下:
2 开始结束页面
2.1 创建开始结束页面
Project窗口Scenes文件夹中,将scene重命名为start,并且右键创建一个新场景scene,命名为end,两个页面为开始页面和结束页面
Project窗口是管理项目资源的地方,其中Scenes文件夹用于存放场景文件这里可以添加技术细节
2.2 开始页面添加文字,图片及按钮
-
在start场景,右侧Hierarchy层级窗口右键创建一个UI-Legacy-Text Button Image,创建时为了清晰功能可以进行相应的命名
-
创建好后,在主屏幕Scene窗口移动创建的几个元素,点击Scene 鼠标滑轮比例缩小看到全貌
-
点击几个元素,点击+W快捷键->移动 点击+R快捷键->调整大小 分别进行移动到合适位置及合适的大小
-
在下方Project窗口中选取下载的Pixel素材,找一个适合开始页面的图片,点击Image,将选好的图片拖拽到Image元素的Inspector窗口的Source Image处,让Image显示选中的图片,可以修改width和height再次调整比例大小
-
点击Text进行编辑,在Inspector窗口可以修改展示的文本内容、字体颜色、大小、位置等,将下载好的字体文件,拖拽到Font属性上进行应用
-
Button上的文字可以同样进行设置
-
右键创建一个panel控件,用于管理页面上的UI元素,可以设置panel的背景颜色,将Image、Button、Text三个编辑过的元素拖到panel上,让他们受控制于panel,此时,移动panel上面的元素会一起移动
应该先创建panel,在panel上创建其他节点的
2.3 在按钮上绑定启动关卡脚本
- 给Button上增加一个脚本,使其在点击时实现相应的功能,可以再Project窗口个下新建一个script文件夹,专门放脚本文件,在文件夹中创建C#脚本,命名为NextLevel 并打开文件编辑一个nextLevel方法
public void nextLevel()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
}
获取当前激活的场景(Active Scene)的构建索引(buildIndex),然后将其加1,接着加载新的场景。
- 脚本编辑完保存退出,两个拖拽:将脚本拖拽到Button对象上,点击Button让其显示Inspector页面,在Button的onClick处点击加号添加条件,将Button拖拽到为none的对象选择处。后面的Nofunction选择刚刚创建的方法nextLevel
在Insepector窗口on Click再次绑定Button才能选择function
2.4 添加背景BGM
在Hierarchy层级窗口创建一个空对象 Create Empty 可以命名为BGM,右侧Inspector窗口为其添加组件Audio Source;在Project窗口将准备好的BGM音频拖到Audio Source的AudioClip上,volume可以调节音量 提示:此时 简单的开始游戏页面制作完成,执行效果为有背景音效的开始页面,有按钮可以进行点击,此时点击会报错,因为只有一个页面跳转失败,是正常的
2.5 完善结束页面
- 在Project窗口点击end场景进入并编辑,可以在Hierarchy窗口对start场景的节点进行全部复制并粘贴到end场景,适当修改实现区分及不同功能的实现,复制一个button节点,一个按钮实现重新开始,一个按钮实现退出游戏
- 将end场景增加到project中:File----Build Setting----Add Open Scenes 进行添加
添加完成后,两个场景的编号分别是0和1
每增加一个场景 都要add一下,并可以拖动上下的顺序,及时add及时修改顺序
- 修改NextLevel脚本,增加重启和退出的实现方法
public void reLoad()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex - 1);
}
public void quit()
{
Application.Quit();
}
减一是由场景个数决定,quit方法在unity窗口没有明显反应
- 修改两个按钮在Inspector窗口onclick中function实现的方法为脚本中对应方法
- 此时开始页面和结束页面可实现相互跳转
3 创建地形
3.1 创建level1场景
-
Project窗口右键新建一个scene命名为level1,并进入编辑
-
在Hierarchy窗口右键新建两个2DObject----Tilemap----Rectangular节点,一个命名为BackGroud,点击Tilemap会有一个调色板窗口open tile palette,点开这个窗口
3.2 创建Tilemap图层设置平台地图
- 将palette窗口打开,并拖到屏幕的合适位置
- 点击palette窗口No Valid Palette创建一个新的palette
- 在Project窗口找到下载好的图片素材 找到土地的资源Terrain下的Terrain Sliced,在Inspector窗口修改这个图片的尺寸Pixels Per Unit为16,修改大小后保存,拖到palette上如图
- Hierarchy窗口点击Tilemap节点,使用palette窗口的paint选取背景涂到Tilemap上,为了方便区分,可以先选择Background节点Inspector窗口将Tilemap Renderer的对号勾选掉,这样主屏幕就只是Tilemap节点的画面
3.3 创建背景板background
- 找到background素材,选择喜欢的颜色,点击,图片的尺寸Pixels Per Unit为16,将改好大小的图片拖到new palette页面
- Tilemap节点Inspector窗口将Tilemap Renderer的对号勾选掉,使其不显示(临时操作,后面会恢复)
- Hierarchy窗口点击Background节点,使用palette窗口的paint选取背景涂到Background上
3.4 图层设置
-
设置图层:在Background的Inspector窗口Tilemap Renderer,点击sorting layer,默认是Default,点击创建一个图层Add Sorting Layer
-
点击进去,点击加号,会多一行Layer1 可以进行命名,此处命名为Background,并拖到最上面
最上面的在最底层显示 -
此时Background节点的sorting layer也设置为Background
-
最后将Tilemap节点Inspector窗口将Tilemap Renderer的对号勾选上(恢复之前的临时操作),此时Tilemap图层在Background图层的上面显示,效果如图
-
最后最后,将新建的level1场景添加到Project:File—Build Setting—Add Open Scenes,并将它移动到end上,此时试运行就会进入到level1的场景
4 主角闪亮登场
4.1 创建主角动画人物
- Hierarchy窗口右键新建一个2D Object–Sprite–Square,并命名为Player
- 在Project窗口个Pixel素材中找到主角人物图片
- 点击Player,将主角图片拖动到Player的Inspector窗口的sprite属性栏中,使其展示
- 调整Player位置大小
- 设置Tilemap使角色能够站在设置的路线上,点击Tilemap打开他的Inspector,Layer处点击
- 新建一个ground层,并将Tilemap设置为ground
- 设置同一图层的优先级:点击Player,在Inspector窗口设置Order in Layer为1,,此时他和Tilemap在一个图层,此数值越大越在上面优先展示
- 给人物和地面添加碰撞体,实现角色站立在地面上
- 点击Player,在Inspector检查窗口的最下面添加component:Box Collider 2D、Rigidbody 2D
Collide 碰撞体检测物体之间的碰撞情况 Box形状为盒形;Rigidbody 2D刚体组件物理模拟功能
- 点击Tilemap,添加组件Tilemap Collider 2D、Composite Collider 2D
Tilemap Collider 2D管理和处理瓦片地图的碰撞检测
Composite Collider 2D复合碰撞器,自动合并相邻碰撞器的范围 添加他刚体自动添加
- ilemap Collider 2D组件选中Used By Composite,将该Collider 2D组件纳入一个Composite Collider 2D组件的管理范围内;
- Rigidbody 2D选中Body Type为Static,让Tilemap静止状态
ilemap Collider 2D组件选中Used By Composite:他会自动连接所有瓦片资源更方便,刚体Static意为让Tilemap节点静止在画面上,否则Tilemap会在掉落 - Player的 Rigidbody 2D组件中,将Constrains 中Freeze Rotation Z选中 锁定Z轴,在操作中,人物就不会在Z轴旋转,只能XY轴移动
Tilemap的碰撞体是盒型,不锁定状态人物可进行垂直面移动,不符合游戏设置,为了更合理锁定Z轴
4.2 主角动画效果添加
-
在Project窗口右键新建Create一个Animation并命名为move
-
将move动画拖拽到Hierarchy的Player节点上
-
双击move进行编辑动画,窗口打开后,还需点一下Player进行激活,后才能操作
-
将Idle空闲状态图片全选拖拽到move中
-
将Samples调整到20,动作的频率会变慢一点,move动画在Inspector窗口中的loop打开让他动作循环
-
同样的方法创建run角色跑的动画 jump角色跳的动画 appear和desappear出现和消失的动画,只有run和move是循环的,其他不用循环看情况而定
-
将创建的所有动画移动到新建文件夹中,注意点,动画循环要勾选,动画要拖到角色身上
-
创建一个障碍物,当角色掉落时碰到障碍物执行death动画,在Hierarchy窗口右键新建一个2D Object-Sprites-Square命名为deadline,选择一个图片拖动到sprite属性处展示,调整大小到最下面,以备接住掉落的角色
-
给deadline加上碰撞体组件Box Collider 2D
4.3 新建人物移动脚本
- 在Project窗口script文件夹下右键新建C#脚本,命名为Camera
- 编写脚本,将编辑好的脚本保存退出,将Camera脚本拖拽到Hierarchy的Main Camera上
[SerializeField] private Transform player;
void Update()
{
transform.position = new Vector3(player.position.x, player.position.y, transform.position.z);
}
[SerializeField],用于在Unity的Inspector窗口中显示私有变量,可以直接设置和查看这个私有变量的值;
Update 方法会在每一帧被调用,用于更新游戏逻辑;
Transform 是Unity中用于表示游戏对象位置、旋转和缩放的类
当前游戏对象跟随定义的player变量的位置变动而变动
注意 z轴为对象本身的z轴,不是player的z轴,只有xy轴随着player的变化而变化 z轴不动
- 点击Main Camera 在Inspector检查窗口点击拖上去的脚本,将Hierarchy的Player节点拖拽到Main Camera 在Inspector检查窗口脚本的Player处,使实现Main Camera跟随Player移动
- 在Project窗口script文件夹下右键新建C#脚本,命名为Movement,并拖拽到Play节点上,使其生效
- 编写脚本
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Movement : MonoBehaviour
{
[SerializeField] private float moveSpeed = 7f;
[SerializeField] private float jumpForce = 7f;
[SerializeField] private LayerMask jumpGround;
private Rigidbody2D rb;
private Animator anim;
private BoxCollider2D coll;
private SpriteRenderer sprite;
private float dirX = 0f;
private enum MovementState { move, run, jump, fall }
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
coll = GetComponent<BoxCollider2D>();
sprite = GetComponent<SpriteRenderer>();
}
// Update is called once per frame
void Update()
{
dirX = Input.GetAxisRaw("Horizontal");
rb.velocity = new Vector2(dirX * moveSpeed, rb.velocity.y);
if (Input.GetButtonDown("Jump") && IsGround())
{
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
}
UpdateAnimationState();
}
private void UpdateAnimationState()
{
MovementState state;
if(dirX > 0f)
{
state = MovementState.run;
sprite.flipX = false;
}
else if(dirX < 0f)
{
state = MovementState.run;
sprite.flipX = true;
}
else
{
state = MovementState.move;
}
if(rb.velocity .y > .1f)
{
state = MovementState.jump;
}
if (rb.velocity.y < -.1f)
{
state = MovementState.fall;
}
anim.SetInteger("state", (int)state);
}
private bool IsGround()
{
return Physics2D.BoxCast(coll.bounds.center, coll.bounds.size, 0f, Vector2.down, .1f, jumpGround);
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.name == "deadline")
{
anim.SetTrigger("death");
}
}
private void RestartLevel()
{
anim.SetTrigger("appear");
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
显示三个变量 :moveSpeed移动速度、jumpForce跳跃高度、JumpGround跳跃的平台
MovementState 枚举值为四种状态 注意索引是从0开始的
SpriteRenderer对象的flipX方法 镜像对象,使其向左向右都会有动作,控制sprite是否在水平方向上翻转
update方法中,获取用户移动和跳跃键的意图,并将对象进行移动
UpdateAnimationState 更新对象状态的判断,判断结果通过animator的setInteger方法,给state赋值
rb.velocity .y > .1f 判断是否在垂直方向上以大于0.1单位每秒的速度向上或向下移动
4.4 动作转换
- 点击之前创建动画是生成的Animator Controller,调整各个动作的转换
避雷:AnimationEvent has no function name specified!AnimationEven存在动画事件没有指定函数名! 解决办法:找到动画中添加的多余空AnimationEvent,删除掉即可。
- 创建三个Parameters参数,一个是int数值类型的state,用于各个状态转换的标记,两个trigger触发器类型的death和appear,触发则执行相应动画
- 在Any State处右击Make Transition 连接到appear和disappear,其他连接都使用右键Make
- 过渡线的Inspector页面的Has Exit Time都不勾选(为true时只有当动画播放结束才会过渡到下一个)
- 下面的Fixed Duration勾选,固定秒数节省时间,Transition Duration可以都设置为0
- 动作间的转换,条件一定要准确,此处的state数值和代码中顺序要对应,才会执行成功
4.5 执行
Hierarchy窗口点击Player节点,Inspector窗口展示了脚本中暴露的可修改参数,可以在此修改移动速度和跳跃高度,选择跳跃的地面,选择ground(因为是Tilemap在的图层)
此时执行demo,效果为角色可以执行简单的移动,死亡后会起点重生
5 移动机关
6 设置奖励及主角收集
7 设置陷阱
8 检查点
9 场景跳跃
10 项目导出运行
报错总结
1 给Player节点加了刚体和碰撞体,人物还是掉落,掉落时会被Tilemap遮挡
解决:当只给Player加上碰撞体,而没有其他碰撞体,Play也相当于没有碰撞体,没有可以发生交互的物体;被Tilemap遮挡说明在同一图层或在他之下,修改order in Layer 的数值让其在上面
2 给Tilemap节点加了刚体和碰撞体组件,但是人物和地面一起下落
解决:加了碰撞体但没有进行相应的设置,要在刚体处设置为静止状态static,不设置默认为动态,碰撞体交给composite一起管理
3 挂载上相机,但运行画面为全蓝色
解决:代码中的位置只有x、y的数值随着Play的移动而移动,z轴不动
4 加上运动脚本设置好Animation的过渡后,人物运动不连贯或不按照设想的运动
解决:连接线的条件判断错误,代码中第一位的下标为0,所以连接线这边要从0开始,以此类推,条件要准确无误才会成功
5 人物行动至Tilemap的边缘会沿着边缘移动
解决:因为Tilemap设置的为盒型碰撞体,有z轴人物运动至此会沿着z轴旋转,可以在人物处设置刚体的锁定z轴,让人物无法在Z轴移动
6 人物无法实现跳跃
解决:只给人物挂载了脚本,脚本中暴露的地面参数,要进行选择后才能在地面上跳动文章来源:https://www.toymoban.com/news/detail-845766.html
第一次接触Unity,记录一下。 如有明显错误,欢迎指正!
文章来源地址https://www.toymoban.com/news/detail-845766.html
到了这里,关于Unity 2D 新手练习整理 FrogJump 上的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!