目录
1.1.1 2D(built-in-Render pipeline)
1.1.3 这次选择 2D(built-in-Render pipeline)
5.4 把bg的 order in layer修改为很小的数,放在最底层,避免遮挡前面的内容
7.2 调整layer的order, 让ground 显示在的pipe上层
7.4 给空的父物体,增加一个 collider 2D, 并修改为触发器
10.2 每个地面ground 挂一个管道,作为地面ground的子物体
10.4 把pipeUp pipeDown的collider都弄到空的父物体身上
11.2.2 bg移动更换脚本时,需要生成随机高度的新pipe
学习参考
1 创建1个unity 2D项目
1.1 2D项目模板选择
1.1.1 2D(built-in-Render pipeline)
This is an empty project configured for 2D apps. It uses Unity's built-in renderer.
这是一个为2D应用程序配置的空项目。它使用Unity的内置渲染器。
1.1.2 universe 2D
This is an empty project configured for 2D apps. It uses Unity’s Universal Render Pipeline pre-configured with 2D Renderer.
这是一个为2D应用程序配置的空项目。它使用预先配置了2D渲染器的Unity通用渲染管道。
1.1.3 这次选择 2D(built-in-Render pipeline)
因为之前3D项目也是选择 universe 3D ,结果在asset store里下载的资源是紫色贴图报错
怀疑是不是轻量级的和大多数人的项目不匹配,这次用传统的这个2D(built-in-Render pipeline)
1.2 创建项目
1.2.1 注意点
- 注意,创建前,记得修改项目名
- 否则比较麻烦
1.2.2 如果想修改项目名
- 如果想修改项目名
- 右键,show in exolporer /浏览器中打开
- 修改项目文件夹的名字
- 然后unityhub里就找不到了
- 需要重新再打开就可以了
2 导入美术资源包
2.1 下载一个flappy bird的资源包
- 其实没有也可以,就是自己做,对于没美术基础的比较麻烦,比如我
- 可以先丑一点
- 我之后打算替代掉这些资源
2.2 导入资源包
- 双击unity资源包,即可import
- 点击import
2.3 记得把UNITY视图修改为经典的2*3模式
主要跟着各种视频,文章都是这么学的,习惯了
换个格式看的难受
2.4 先把界面整理成熟悉的2*3,然后开始整
舒服了开始整
2.5 还要把项目 设置修改为安卓,因为是手机游戏
一般不修改默认是windows
切换完毕
3 开始整:基础调整准备
3.1 先新建1个 288*512的屏幕分辨率
- 好像原游戏的地图分辨率,屏幕图就这么大
- 需要再下面的game窗口,新建这么一个
3.2 图片UI素材太大的问题
- 没搞明白,为啥这个bg这么大
- 可能是因为导入的素材包里是别人已经设置过的UI,而不是原图吧?
- 而且我看不到图片的原始尺寸??比如288*512
- 管他呢,先改
3.3 修改摄像机size,而不是素材尺寸
- 修改摄像机size,而不是素材尺寸
- 这样可以避免,后面每个资源都要修改,
- 只需要修改摄像机1次,去适配资源即可
- 拖到摄像机的白色控制点,但是好像只能 按照摄像机的宽高比一起调整,不能自由调整。
4 地图背景bg
4.1 创建第2个bg,复制即可
- 且保证2个bg的y是一致的,就是 transform里的y要一致
4.2 更科学的修改方法
- 是知道图片的尺寸
- 按照1米=100pixel来换算
- 图片是按像素,比如288*512,而unity里是填写米
- 然后把bg2,也和bg叠在一起,也就是,重置 transform为000,然后把X修改为288/100=2.88即可刚好两张平铺错开
4.3 尝试间接计算bg的像素大小
- 上下叠一张,左右叠一张
- 虽然都是看 pviot之间的距离,实际也就是图片的大小
- 而这个资源上写的16比
- 换算下来 23.2*16=371.2像素
- 换算下来 23.2*16=533.6像素
- 和我现在用的288*512 还是有些区别的
后来发现,双击UI里图片可以看到实际大小 378*537
4.4 关于3D和2D的最标准,新手要记住
unity里默认的
3D的是 水平平面(X right ,Z front),Y up 纵 ---立体
2D的是 竖直平面 (X horizontal,Y vectical 纵 )
4.5 创建1个空物体bg
把之前的bg图,分别改名bg1 bg2放入其作为子物体
5 创建地图背景bg脚本
5.1 脚本文件夹
这里出现了很诡异的问题
不让我在unity里创建c#脚本,每次创建都一闪而过
气得我差点准备删了重建
我后来想,可能是导入资源包做了点手脚限制了
我干脆绕了过去。直接在 windows对于的assets里创建脚本是OK的
5.2 给bg空物体挂一个脚本,实现bg自动滚动
5.3 脚本内容
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class bgControl : MonoBehaviour
{
//bg移动速度,方便外面修改
public float speed1=0.2f;
//use this for initialization;
void Start()
{
}
//Update is called once per frame;
void Update()
{
//遍历bg
foreach(Transform trans1 in transform)
{
//移动bg
Vector2 v1=trans1.position;
v1.x=v1.x+speed1*Time.deltaTime;
trans1.position=v1;
}
}
}
实测OK,但是动的特别慢,因为是远景的原因
- 速度的原因,怀疑是因为这里是按16:1的像素/米,得搞快点
- 往右移动,是+
- 可以修改为往左边移动,更符合一般视角感觉,修改为-
修改
- 如100:1是速度0.2,16:1 速度为1.25,
- 同时改成向左移动试试
- 而且,因为 speed1是public 变量,unity脚本外面修改得优先级高,只改脚本不生效,外面还是0.2f,记得修改unity里的speed1得值。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class bgControl : MonoBehaviour
{
//bg移动速度,方便外面修改
public float speed1=1.25f;
//use this for initialization;
void Start()
{
}
//Update is called once per frame;
void Update()
{
//遍历bg
foreach(Transform trans1 in transform)
{
//移动bg
Vector2 v1=trans1.position;
v1.x=v1.x-speed1*Time.deltaTime;
trans1.position=v1;
}
}
}
bg移动速度
那如果把宽度严格得定义为23.625,还有2个匹配修改
- bg1本身图片是左边和右边是刚好可以相接的
- bg2 距离bg1,也就是bg2的x 也要刚好是23.625,否则会有缝隙或叠加
- 现在bg可以无缝的向左边后退滚动了
5.4 把bg的 order in layer修改为很小的数,放在最底层,避免遮挡前面的内容
6 地面 ground
同样新建空物体,建2个ground
6.1 修改地面ground的配置
- 地面应该是336*112
- 但是这里的是 800*392
把ground的scale 调整为 0.6x 0.4y差不多
让2个ground相距离X为30
其中一个x=-3。 另外一个x=27
6.2 共用bg的脚本,只修改公共变量
- bg的脚本继续挂载ground空物体上
- 修改参数
- 实测🆗
6.3 记得营造视觉差效果
- 也就是地面移动速度快,近景
- 城市移动速度慢,远景
6.4 给地面增加碰撞
7 管子pipe
7.1 新建空物体和up down的pipe
- 并且设置到00后调整空缺位置
7.2 调整layer的order, 让ground 显示在的pipe上层
- 让ground 显示在的pipe上层
- ground的order更高即可
7.3 给pipe增加碰撞
- 新增 collider 2D
7.4 给空的父物体,增加一个 collider 2D, 并修改为触发器
这样没有碰撞,但是会有触发判断
且弄到后半段
8 小鸟bird
8.1 创建小鸟动画
多个图片一起拖过去
8.2 给小鸟增加碰撞 和刚体,控制小鸟往下掉
限制小鸟自己Z轴移动,就是X,Y 之外的翻滚,滚动
8.3 脚本控制小鸟向上飞
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class birdControl : MonoBehaviour
{
//以下都是按1/16算的
//外界给小鸟向上飞得外力
public float force1=10f;
//定义一个新刚体
public Rigidbody2D rbody1;
//use this for initialization;
void Start()
{
// 获取小鸟得刚体
rbody1=GetComponent<Rigidbody2D>();
}
//Update is called once per frame;
void Update()
{
//判断点击则给小鸟向上 0左,1右键,2鼠标中键
if(Input.GetMouseButtonDown(0))
{
rbody1.velocity=new Vector2(0,force1);
}
}
}
9 控制小鸟的头的朝向
9.1 注意unity里的欧拉角
unity里是用的0-360度,都是正数的角度
但是unity外面面板上填的不是,是正数和负数
9.2 修改脚本
增加头部转向
限制角度
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class birdControl : MonoBehaviour
{
//以下都是按1/16算的
//外界给小鸟向上飞得外力
public float force1=10f;
//定义一个新刚体
public Rigidbody2D rbody1;
//定义一个最大角度
public float maxAngle=40;
//use this for initialization;
void Start()
{
// 获取小鸟得刚体
rbody1=GetComponent<Rigidbody2D>();
}
//Update is called once per frame;
void Update()
{
//判断点击则给小鸟向上 0左,1右键,2鼠标中键
if(Input.GetMouseButtonDown(0))
{
rbody1.velocity=new Vector2(0,force1);
}
//获取当前的角度.Z表示旋转
Vector3 angle1 =transform.eulerAngles;
//旋转
//只给Y轴的,不给X轴的?
angle1.z=angle1.z+rbody1.velocity.y;
//将旋转Z同步面板上的值,如果不做这个可以直接用360角度去做也可以
angle1.z=angle1.z-180;
if(angle1.z>0)
{
angle1.z=angle1.z-180;
}
else
{
angle1.z=angle1.z+180;
}
Debug.Log(angle1.z);
//限制翻转
angle1.z=Mathf.Clamp(angle1.z,-maxAngle,+maxAngle);
transform.eulerAngles=angle1;
}
}
10 管道pipe
10.1 创建pipe
- 同样是空物体下挂实际的图片,这里创建一个pipe空物体
- 下面分别挂2个,一个pipe up 一个pipe down
10.2 每个地面ground 挂一个管道,作为地面ground的子物体
10.3 增加pipe脚本
- 增加pipe脚本
- 并且挂在pipe上
10.4 把pipeUp pipeDown的collider都弄到空的父物体身上
- 把pipeUp pipeDown的collider都弄到空的父物体身上,相当于它有3个碰撞盒
- 使用 copy component
- 然后 paste component as new
- 然后因为父物体身上有3个碰撞盒,需要再调整3个盒子的高度,和图片相匹配
- 这里是+19.5 和 -19.25
- 然后还要把子物体上自身的collider给勾选掉
10.4.1 一个小BUG插曲和解决
- 如果在管道上挂了2个相同的脚本,这个管道会运行2次脚本,比如计分就会加2次。
- 要小心
- 出现了去查查可以从这个角度看看
10.5 小鸟过 pipe的计分脚本
实测可以加分
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class pipeControl : MonoBehaviour
{
//最好搞UI上显示
static int score1;
//use this for initialization;
void Start()
{
}
//Update is called once per frame;
void Update()
{
}
//把pipe up down的碰撞都挪到空的父物体身上?脚本更好写?
private void OnCollisionEnter2D(Collision2D Collision) //中间不要加逗号
{
//小鸟失败
}
private void OnTriggerEnter2D(Collider2D Collision) //中间不要加逗号
{
//增加分数
score1++;
Debug.Log(score1);
}
}
11 让管道pipe 高度,生成前高度随机
11.1 让管道pipe 高度,生成前高度随机
- 也有的游戏做成管道一直在动
- 这里还是做出简单的,管道生成后就不变化了,生成前变化
11.2 设置修改
11.2.1 增加一个 标志开关
- 增加一个 标志开关,是否需要 reset pipe height。这样可以在外面勾选
- 因为bgcontrol 是bg 和 ground 共用,不能2边都影响pipe
11.2.2 bg移动更换脚本时,需要生成随机高度的新pipe
//bgControl.cs里需要添加如下内容
//在这个时机
if(v1.x<-width1)
{
v1.x=v1.x+width1*2;
//重置高度
if(resetPipeHeight)
{
pipeControl pipe=trans1.GetComponentInChildren<pipeControl>();
pipe.ResetHeight();
}
}
11.2.3 增加一个随机调整高度的函数
- 而且是在父物体上,整体调整高度
- 这样,即使缺口永远一样大
- 但是2个管子,组成的整体会高低不同
public void ResetHeight()
{
Vector2 v1=transform.localPosition;
v1.y=Random.Range(25f,45f);
transform.localPosition=v1;
}
11.3 脚本
实测OK
11.3.1 bgControl.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class bgControl : MonoBehaviour
{
//以下都是按1/16算的
//bg移动速度,方便外面修改
public float speed1=1.25f;
//bg宽度
public float width1=23f;
public bool resetPipeHeight=false;
//use this for initialization;
void Start()
{
}
//Update is called once per frame;
void Update()
{
//遍历bg
foreach(Transform trans1 in transform)
{
//移动bg
Vector2 v1=trans1.position;
v1.x=v1.x-speed1*Time.deltaTime;
//如果需要切换到新位置
if(v1.x<-width1)
{
v1.x=v1.x+width1*2;
//重置高度
if(resetPipeHeight)
{
pipeControl pipe=trans1.GetComponentInChildren<pipeControl>();
pipe.ResetHeight();
}
}
trans1.position=v1;
}
}
}
11.3.2 pipeControl.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class pipeControl : MonoBehaviour
{
//最好搞UI上显示
static int score1;
//use this for initialization;
void Start()
{
}
//Update is called once per frame;
void Update()
{
}
//把pipe up down的碰撞都挪到空的父物体身上?脚本更好写?
private void OnCollisionEnter2D(Collision2D Collision) //中间不要加逗号
{
//小鸟失败
}
private void OnTriggerEnter2D(Collider2D Collision) //中间不要加逗号
{
//增加分数
score1++;
Debug.Log(score1);
}
public void ResetHeight()
{
Vector2 v1=transform.localPosition;
v1.y=Random.Range(25f,45f);
transform.localPosition=v1;
}
}