此次尝试的游戏制作并不算难,同样是一款2D像素游戏,玩法类似于“是男人就下一百层”,为增加游戏的可玩性,添加了一些个人的想法,同样做一次总结,来记录学习的过程和收获。🤭
玩法和是男人就下一百层类似,因为素材有限,添加的游戏中的板子有三类,基础板,旋转板,弹力板,以及会对玩家造成伤害的摇摆刺球。每过5s游戏难度会上升一个等级,出现刺球的概率会上升,难度最高等级是七级。
Unity部分
1.Quad
- The quad primitive resembles the plane but its edges are only one unit long and the surface is oriented in the XY plane of the local coordinate space.
此次利用创建的Quad添加材质,实现的背景。 - 新建Quad,在Assets创建新的文件夹Material来统一保存创建的材质,右键新建Material,将其Shader改为 Unlit / Texture,我们只希望他是一个普通的图像,然后将需要添加的背景图片修改像素之后,选择背景图片的WrapMode修改为Repeat,代表他是一个重复的图像,拖动添加,在Tiling中可以设置图片的横纵数量。最后及那个材质拖动添加到Quad
2.Filter Mode
因为贴图在屏幕里肯定会存在放大,缩小的情况,这种时候就会出现锯齿。
- point :点采样模式,屏幕像素会需找最近的贴图像素点,来作为输出,这种比较生硬,但是性能好,不抗锯齿
- Bilinear :双线性采样模式, 采用最近的4个像素来做线性插值,有平缓的过渡。可以解决贴图放大的问题,但是贴图缩小依然有锯齿。 缩小可以用mip-map来解决。
- Trilinear :三线性采样模式,可以比较好的解决贴图缩小和放大。
3.Composite Collider 2D
- 因为顶端的一排尖刺由许多的素材拼接而成,在全选所有素材之后,由于其不规则的特性,先添加Polygon Collider 2D,然后添加Composite Collider 2D,并且勾选Used By Composite,其作用类似合并碰撞体。
The Composite Collider 2D uses the vertices (geometry) from any of these Colliders, and merges them together into new geometry controlled by the Composite Collider 2D itself.
4.Hinge Joint 2D
- The Hinge Joint 2D component allows a GameObject
controlled by RigidBody
2D physics to be attached to a point in space around which it can rotate. The rotation can be left to happen passively (for example, in response to a collision) or can be actively powered by a motor torque provided by the Joint 2D itself. You can set limits to prevent the hinge from making a full rotation, or make more than a single rotation. - 在这里希望添加这个组件在旋转板,使人物和板子发生碰撞之后,板子会做出相应的旋转被动反应,在勾选上Use Limits,在下面的Angle Limits中可以限制允许旋转的上下限,Break Force和Break Toreque分别表示破坏并进而删除关节的线性力水平和角度水平,我们将其设置为Infinity,表示关节牢不可摧。
- Motor,表示可以为2D关节提供动力的发电机,勾选Use Motor后可以设置Motor Speed,来控制2D物体沿着关节自旋转的速度,在这里旋转板属于被动旋转,不需要。
5.Line Renderer
- 线渲染器 (Line Renderer) 组件采用 3D 空间中两个或多个点的数组,在每个点之间绘制一条直线。可以使用线渲染器 (Line Renderer) 来绘制从简单直线到复杂螺旋线的任何线条。在此次使用当中,主要是将刺球的端点和刺球链接。新建脚本,获取LineRenderer组件,公开声明两个Transform,添加设置为端点和刺球,添加到Position数组中,序号分别是0,1(因为这是在脚本中值执行时才将两个点加入Position,所以在Scene中是看不到该线的,点开Position可以看到两点的位置还未加入)。在Alignment中设置线面向的方向为摄像机(View),
void Update()
{
line.SetPosition(0,startpoint.position);
line.SetPosition(1,endpoint.position);
}
- Widthd的图像,竖轴的值为线的宽度值,横轴为线的曲线值,(因为此次使用的只有两个顶点,曲线值改变不会有效果),曲线是在每个顶点处采样的,因此其精度受制于线中的顶点数量。
控制线在其开始和结束之间宽度的变化,平线就是没有变化,曲线看走向,曲线由高到低的话线条会从宽变细,在曲线坐标里右键可以新加Key来控制曲线
6.Distance Joint 2D
- 为刺球添加组件Distance Joint 2D,并在Connected Rigid Body中拖入端点(需要为端点添加RigidBody),取消勾选Max Distance Only,如果启用此选项,则 2D 距离关节仅强制执行最大距离,因此连接的游戏对象仍然可以彼此靠近,但不能超出 Distance 字段定义的距离。如果未启用,则游戏对象之间的距离为固定距离。
C#代码
1.显示检测点的属性
private void OnDrawGizmosSelected() {
Gizmos.color=Color.blue;
Gizmos.DrawWireSphere(groundcheck.transform.position,checkradius);
}
显示设置的监测点的范围
2.ComPareTag
两个方法接收的参数不一样 ,collider里包含CompareTag方法
void OnTriggerEnter2D(Collider2D other) {
if(other.CompareTag("Spike"))
{
anim.SetTrigger("dead");
}
}
void OnCollisionEnter2D(Collision2D other) {
if(other.gameObject.CompareTag("Fan"))
{
rb.velocity=new Vector2(rb.velocity.x,10f);
}
}
3.角色死亡到重开游戏
角色触发到Tag是Spike的碰撞器会,打开死亡动画的开关,播放死亡动画,在动画的最后一帧添加Event,选择编写的角色死亡代码,并且将判断角色死亡的bool值传递给GameManager,
public void PlayerDead()
{
playerdeath=true;
GameManager.GameOver(playerdeath);
}
在GameManager中判断传来的Bool值,如果为true,则修改死亡UI界面为可视,并且将时间比例调整为0;点击PlayAgain场景重新加载
public static void GameOver(bool dead)
{
if(dead)
{
instance.gameoverUI.SetActive(true);
Time.timeScale=0;
}
}
4.重启关卡重新计数
在Update中,将当前场景的加载时间传递给记录时间的文本
TimeScore.text=Time.timeSinceLevelLoad.ToString("00");
5.随机生成新的平台
- 公开声明一个平台的列表,添加所有希望生成的平台,可以重复添加(这样控制不同平台的生成概率不同),每隔固定的时间间隔,随机选取一范围内的数字,生成该数字对应序号的平台。核心代码如下:
//平台的列表,可以规定大小以及添加
public List<GameObject> platform =new List<GameObject>();
//随机一个范围内的数字
int index=Random.Range(0,platform.Count);
//生成新的平台,并且都作为子项目
GameObject newPlatform= Instantiate(platform[index],spawnPosition,Quaternion.identity);
newPlatform.transform.SetParent(this.gameObject.transform);
//可以简写为
Instantiate(platforms[index],spawnPoisition,Quaternion.identity,transform);
- 为增加游戏性,添加了一些个人的想法,游戏刚开始,Platform列表中元素较多,很多平台都有重复,生成刺球的概率很低,每过5s之后,会删除列表最后的一个元素,规定时间后停止删除。从而实现增大游戏难度。效果图以及实现代码如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spawner : MonoBehaviour
{
public List<GameObject> platform =new List<GameObject>();
public float spawnerTime;//间隔时间
private float countTime;//记录时间
private float time;
private Vector3 spawnPosition;//生成坐标
int spikeNum=0;
public int level=1;
// Update is called once per frame
void Update()
{
SpawnnPlatform();
}
void SpawnnPlatform()
{
countTime+=Time.deltaTime;
time+=Time.deltaTime;
spawnPosition=transform.position;
spawnPosition.x=Random.Range(-3f,3f);
if(countTime>=spawnerTime)
{
CreatPlatform();
countTime=0;
}
if(level<7)
{
if(time>level*5)
{
platform.RemoveAt(10-level);
level++;
}
}
}
void CreatPlatform()
{
int index=Random.Range(0,platform.Count);
if(index==0)
{
spikeNum++;
}
if(spikeNum>1)
{ //如果即将连续两次生成刺球,则第二次创建刺球不执行
//直接countTime=spawnerTime,刷新下一帧的同时创建新的平台
//如果新的非刺球平台创建成功,则刺球的重复计数归零
countTime=spawnerTime;
return;
}
GameObject newPlatform= Instantiate(platform[index],spawnPosition,Quaternion.identity);
newPlatform.transform.SetParent(this.gameObject.transform);
spikeNum=0;
}
}
暂存的问题/想法
移动完善
目前左右两边的黑色区域是,摄像机中空白的背景颜色,个人的想法是,在两边添加碰撞器,并且修改摄像头范围,当人物消失向左移动超出摄像机,会从在同一高度的右侧显示
角色选择
因为这次接触到List的概念,那么也同样可以创建声明一个Player的List,创建完成多个游戏角色,在游戏开始前进行选择
记录
希望可以实现一个排行榜的功能
多平台
目前只能在PC上游玩,希望可以移植到Android上
联想
1.平台消失的原理:是在地图外设置一个点,判断平台的y轴坐标是否超过该点,如果是,则删除平台的游戏项目。本人也尝试了另一种方法,添加碰撞器,并且添加Tag为TopLine,平台中函数OnTriggerEnter2D,判断触发碰撞的标签。同样可以实现功能