如何制作一个Unity2D闯关游戏(一)
项目说明
此项目为开源教学项目,也是我的学习日常记录,欢迎大家一起来探讨关于这个项目的内容以及一些修改意见,项目内的美术资源位Unity Store上免费资源。此教学适合有Unity和C#基础的同学,后期可能会更新添加一些API讲解。
前期准备
我用的 **Unity **版本是2021.3.16,然后编辑器是 JetBrains Rider ,这个编译器我感觉还是很棒的,强烈推荐(学生可以免费使用)。
这是美术素材的链接 ,免费下载。商店里也有许多素材是免费的,可以拿来练手。
那么话不多说,开始第一天的制作!
项目创建
首先打开Unity创建一个 2D(URP) 项目。
在 Unity 上方选项卡中选择 Windows 打开 Package Manager ,选择 Sunny Land ,点击 Download 之后导入素材。
导入素材之后打开素材自带的 Starter_Scene 场景。
将Player放入场景
首先我们根据路径“Assets\2D Platformer Assets\Graphics\Player”在导入的素材包内找到Player的相关素材,然后我们点击 Player_Idle ,根据我给的图片设置。
说明:1、Pixels Per Unit:含义是每个 Unity 单位显示多少个像素,我们设置为 16 ,使其大小合适。
2、Compression:我们选择 None ,因为想让小狐狸的图像完美显示而是不进行压缩。
然后点击 Sprite Editor ,进入编辑模式,我们将小狐狸图像进行裁切。
完成之后我们就可以将小狐狸作为一个Player放入场景中了。
设置场景画面的位置关系
有时候我们的场景会出现上下关系不正确,比如天空背景覆盖了树林等情况。这时候我们需要创建 Sorting Layers ,来控制不同图层的位置关系。
我们创建 Background,World,Player 三个 Sorting Layers ,并将 back和middle的Sorting Layers 设置 为Background ,simple_setup_level设置为World ,Player设置为Player 。
这样不同的图层的位置关系就处理好了,不会出现位置关系错误的情况了。
设置Player的组件
我们想要让Player与场景中的地面进行碰撞,我们给他添加 Rigidbody 2D,Capsule Collider 2D组件 ,按照图片设置。
将Rigidbody 2D的Freeze Rotation勾上,放置角色因为碰撞发生旋转。
创建一个Physics Material添加到Capsule Collider上,并将其Friction的值调为0,防止后续角色与墙碰撞出现卡墙情况。
编写Player的移动脚本
创建一个名为 PlayerController 的CS脚本,并将其添加到Player上。
角色移动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 private const float playerMoveSpeed = 6f ;private Rigidbody2D rBody; void Start () { rBody = GetComponent<Rigidbody2D>(); } void Update (){ rBody.velocity = new Vector2(playerMoveSpeed * Input.GetAxis("Horizontal" ), rBody.velocity.y); }
角色跳跃
1 2 3 4 5 6 7 8 9 10 11 12 13 private const float playerJumpForce = 8f ;void Update (){ if (Input.GetButtonDown("Jump" )) { rBody.velocity = new Vector2(rBody.velocity.x, playerJumpForce); } }
制作二段跳(这个可以根据需求选择)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 private int playerJumpCount = 1 ;private bool isGrounded = true ; private Transform groundPoint;public LayerMask groundLayerMask; void Start () { groundPoint = transform.GetChild(0 ).gameObject.transform; } void Update (){ isGrounded = Physics2D.OverlapCircle(groundPoint.position, .2 f, groundLayerMask); if (Input.GetButtonDown("Jump" ) && playerJumpCount>0 ) { isGrounded = false ; playerJumpCount--; rBody.velocity = new Vector2(rBody.velocity.x, playerJumpForce); } if (isGrounded) { playerJumpCount = 1 ; } }
角色转向
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 private SpriteRenderer spriteRenderer;void Start (){ spriteRenderer = GetComponent<SpriteRenderer>(); } void Update (){ if (rBody.velocity.x < 0 ) { spriteRenderer.flipX = true ; } else if (rBody.velocity.x > 0 ) { spriteRenderer.flipX = false ; } }
最后就上完整的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 using System;using System.Collections;using System.Collections.Generic;using Unity.VisualScripting;using UnityEngine;using UnityEngine.Serialization;public class PlayerController : MonoBehaviour { private const float playerMoveSpeed = 6f ; private const float playerJumpForce = 8f ; private Rigidbody2D rBody; private int playerJumpCount = 1 ; private bool isGrounded = true ; private Transform groundPoint; public LayerMask groundLayerMask; private SpriteRenderer spriteRenderer; void Start () { rBody = GetComponent<Rigidbody2D>(); groundPoint = transform.GetChild(0 ).gameObject.transform; spriteRenderer = GetComponent<SpriteRenderer>(); } void Update () { rBody.velocity = new Vector2(playerMoveSpeed * Input.GetAxis("Horizontal" ), rBody.velocity.y); isGrounded = Physics2D.OverlapCircle(groundPoint.position, .2 f, groundLayerMask); if (Input.GetButtonDown("Jump" ) && playerJumpCount>0 ) { isGrounded = false ; playerJumpCount--; rBody.velocity = new Vector2(rBody.velocity.x, playerJumpForce); } if (isGrounded) { playerJumpCount = 1 ; } if (rBody.velocity.x < 0 ) { spriteRenderer.flipX = true ; } else if (rBody.velocity.x > 0 ) { spriteRenderer.flipX = false ; } } }
总结
第一篇完成了Player角色的移动代码和组件设置,以及一些场景的基本设置。如果文章有什么问题可以在评论区留言。