UNITY 2D - SideScroller Gameplay(上篇)
(本文所用素材下载链接)
本教程涵盖侧卷轴平铺/视差环境,玩家移动(带跳墙),近战战斗,与NPC交谈,以及设置库存模块。其中许多元素可以在其他游戏模式中使用。
设置和播放器移动:
创建新的Unity 2D项目。导入到资源文件夹:背景天空和城市,以及人物图像。
第一步。设置:精灵层和四边形
在Unity中,2D艺术被添加为精灵。要确定哪些精灵出现在其他精灵的前面,它们可以占用不同的排序层,或者在排序层中可以为它们指定不同的层顺序。开始时唯一的排序层是默认的。单击Default添加排序层。该列表中的层越低,其内容在场景中显示的越靠前。在一个排序层中,多个精灵可以通过在层编号中以更高的顺序放在前面来排列。
EXAMPLE: This project has three Sprites for the sky:
tileSky_blue, tileSky_clouds, and tileSky_wave.
We can drag them all into the Hierarchy and select one to find Sorting Layer in the Inspector.
Click “Default,” add new Sorting Layer “BG_Sky.” Move the Layer above Default (so it is furthest back).
Select each of these 3 sky sprites to add them to that Sorting Layer.
Select tilingSky_blue to set Order in Layer to 2. Set tileSky_wave to Order in Layer 4 (to be in front of tileSky_blue), and set tileSky_clouds to 6.
(To start the next tutorial, delete these sprites from Hierarchy).
第二步。天空无限滚动(来源:精灵设置和滚动)
创建一个视差效果,将3个天空精灵分别应用于四边形并以不同的速度滚动。注意:此脚本不适用于普通精灵;它们需要应用于三维四边形网格(3D Quad mesh):
a、 选择项目中的每个天空图像,将网格类型从“Tight”更改为“Full Rect”,将包裹模式从“Clamp”更改为“Repeat”,compression=none,(点击[Apply])。
b、 右键单击层次以创建三维对象>四边形。缩放X=18和Y=10以填充舞台。
c、 选中四边形后,将天空精灵拖到“检查器”上以创建和应用材质。将“材质着色器”(Material Shader)设置为“取消照明/纹理”(Unlight/Texture)以获得全亮度。在“材质”文件夹中找到此材质并复制两次:选中它并按[Cmd/Ctr]+[d]。选中这两种其他材质后,在检查器中按[select]添加其他精灵。
d、 在Hieraerchy中,复制四元体两次,然后应用另外两个精灵,这样每个精灵都有一个四元体。
e、 若要将四边形推到其他四边形后面,请将位置Z设置得略高(如0.1)。
f、 拖动背景_滚动脚本BG_Scroll.cs到每个天空四边形sky Quads。
g、 在Inspector中,更改不同速度的BGspeed值。
h、 清理:创建一个空的,称之为背景天空。将天空四边形拖到上面,使其成为孩子。
using System.Collections;
using UnityEngine;
public class BG_Scroll : MonoBehaviour {
public float BGspeed = 0.5f;
public Renderer BGrend;
void Start(){
BGrend = GetComponent<Renderer>();
//Change the GameObject's Material Color to red
//BGrend.material.color = Color.red;
}
void Update () {
Vector2 hOffset = new Vector2 (Time.time * BGspeed, 0);
BGrend.material.mainTextureOffset = hOffset;
}
}
第三步。城市视差对摄像机运动的影响
通过3个城市背景层,我们可以使视差运动响应玩家的运动:
a、 创建一个空的游戏对象,命名为Background\u City。拖到相机上,使其成为孩子。
b、 将每个城市精灵拖到层次结构中,然后拖到背景城市中,使其成为子对象。
c、 将层中的顺序设置为2(城市\后面)、4(城市\中间)和6(城市\前面)。在四边形前面,将Z位置设置为高于四边形(注意:这些城市精灵被添加到默认排序层,因此所有城市精灵都自动位于BG\ U天空排序层上任何天空精灵的前面)。
d、 将图层复制两次。将这些副本移动到原始图像的任一侧(如果图像长度为2000像素,则默认的每单位像素数=100表示它们可以是位置X=20和X=-20)。将每个副本拖到原始副本上,使其成为子副本(将city\u向后(1)和city\u向后(2)拖到city\u向后,等等)。
e、 选择每个原始城市精灵,拖动脚本BG_Scroll.cs将摄影机拖到脚本槽中。对于BG_天空(空围棋举行四边形),只需将它拖到相机上,使它完全遵循相机。
f、 为每个视差效果槽设置不同的值:city\u Front=0(因此它移动最多)、city\u Mid=0.3、city\u Back=0.7、BG\u Sky=1(因此它根本不移动)。
g、 点击播放并在场景中来回拖动相机,以查看脚本工作!
创建测试平台:创建一个空的游戏对象,命名为“TestPlatform”。添加Physics2D>BoxCollider2D。将碰撞器大小X设置为原始背景的宽度,Y设置为0.5。设置位置Z=-3,以匹配玩家。
步骤4a.玩家创建和移动
将精灵添加到玩家角色的层次结构中(二次方幂:64x64、128x128、256x256等)。
a、 在层中设置order=50,位置Z=-3。把它命名为playerart。
b、 添加一个空的游戏对象,命名为Player,重置位置,设置tag=Player。将PlayerArt拖到player上,使其成为子级。添加到player:
c、 添加碰撞组件Component ,Physics2D>BoxCollider2D并缩放以适合上半部分。添加Physics2D>CircleCollider2D并缩放以适合下半部分(以更平滑地与坡道合并)。
d、 添加刚体组件Component, Physics2D>Rigidbody2D,将“约束>冻结旋转Z”(Constraints>Freeze Rotation Z)设置为启用,并将碰撞检测从“离散”(Discrete)更改为“连续”(Continuous)。
第4b步。玩家的动作
f、 拖动playermove.cs脚本到你的player上(参见上面的player创建)。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour {
private bool FaceRight = true; // determine which way player is facing.
public float runSpeed = 10f;
void Update () {
//Horizontal axis: [a]/left arrow is -1, [d]/right arrow is 1
Vector3 hMove = new Vector3(Input.GetAxis ("Horizontal"), 0.0f, 0.0f );
transform.position = transform.position + hMove * runSpeed * Time.deltaTime;
// if input is moving player right and player faces left, turn, and vice-versa
if ((hMove.x < 0 && !FaceRight) || (hMove.x > 0 && FaceRight)){
Turn();
}
}
private void Turn()
{
// Switch player facing label
FaceRight = !FaceRight;
// Multiply player's x local scale by -1.
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
g、 拖动BetterJump.cs公司把剧本放到你的player上。此脚本使用跳转输入,默认情况下,跳转设置为键盘空格键和控制器操纵杆按钮3(在XBox控制器上:(Y))。更改这些或添加更多选项:打开“编辑>项目设置>输入Edit > Project Settings > Inputs.”。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BetterJump : MonoBehaviour
{
public float fallMultiplier = 2.5f;
public float lowJumpMultiplier = 2f;
Rigidbody rb;
void Awake(){
rb = GetComponent<Rigidbody>();
}
void Update(){
if (rb.velocity.y < 0) {
rb.velocity += Vector3.up * Physics.gravity.y * (fallMultiplier - 1) * Time.deltaTime;
} else if (rb.velocity.y > 0 && !Input.GetButton ("Jump")){
rb.velocity += Vector3.up * Physics.gravity.y * (lowJumpMultiplier - 1) * Time.deltaTime;
}
}
}
h、 你的玩家角色的对撞机会卡住吗?尝试添加一个光滑的新物理材质到播放器碰撞器材质槽,摩擦和反弹设置为零。
第五步。摄影机跟踪播放器脚本:
基本跟随
a、 拖动CameraFollowX.cs公司脚本到相机上的一个侧面滚动游戏(注:这个脚本只遵循X轴,滚动背景。确保玩家有玩家标签)。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraFollowX : MonoBehaviour {
// this script is aplied to a camera meant to folow the player, without LERP.
public GameObject player; // reference to player object
private Vector3 offset; // distance we want to maintain from the player
void Start () {
// get player by tag
if (GameObject.FindGameObjectWithTag ("Player") != null) {
player = GameObject.FindGameObjectWithTag ("Player");
}
// camera position - object position before first frame
offset = transform.position - player.transform.position;
}
// LateUpdate is called after all other Scene Object scripts finish their Updates
void LateUpdate () {
Vector3 newPos = new Vector3 ((player.transform.position.x + offset.x), transform.position.y, transform.position.z);
transform.position = newPos;
}
}
b、 点击播放并通过移动玩家player来测试所有脚本。
c、 试试这个CameraFollow.cs公司如果需要摄影机(或其他对象)在所有方向上跟随 。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraFollow : MonoBehaviour {
// this script is aplied to a camera meant to folow the player, without LERP.
public GameObject player; // reference to player object
private Vector3 offset; // distance we want to maintain from the player
void Start () {
// get player by tag
if (GameObject.FindGameObjectWithTag ("Player") != null) {
player = GameObject.FindGameObjectWithTag ("Player");
}
// camera position - object position before first frame
offset = transform.position - player.transform.position;
}
// LateUpdate is called after all other Scene Object scripts finish their Updates
void LateUpdate () {
transform.position = player.transform.position + offset;
}
}
跟随LERP
运动延迟: 优秀的LERP教程
拖动CameraControl2DLERP.cs公司在摄影机上编写脚本(或使用Rigidbody2D和重力比例=0的新精灵对象)。将玩家精灵拖到目标脚本槽上。通过移动玩家来点击播放和测试脚本。
using UnityEngine;
public class CameraControl2DLERP : MonoBehaviour {
public GameObject target;
void FixedUpdate () {
Vector2 pos = Vector2.Lerp ((Vector2)transform.position, (Vector2)target.transform.position, Time.fixedDeltaTime);
//transform.position = new Vector3 (pos.x, pos.y, transform.position.y);
transform.position = new Vector3 (pos.x, pos.y, transform.position.z);
}
}
(注意:对于三维项目,这里有一个三维摄影机跟随脚本:CameraControl3DLERP.cs公司).
using UnityEngine;
public class CameraControl3DLERP : MonoBehaviour {
public Transform target; // drag the intended target object into the Inspector slot
public float smoothSpeed = 10f;
public Vector3 offset; // set the offset in the editor
// Update is called once per frame
void FixedUpdate () {
Vector3 desiredPosition = target.position + offset;
Vector3 smoothPosition = Vector3.Lerp (transform.position, desiredPosition, smoothSpeed * Time.deltaTime);
transform.position = smoothPosition;
transform.LookAt (target);
}
}