(1)creat->3D objict->plane 并重命名为ground,做为地面(如下图)
(2)并调整颜色,大小至适合(如下图)
调正颜色:创建material(project:creat->Material)用与当作groud的材质,调整颜色,并赋到ground上
(1)创建盒子:creat,调整盒子大小及位置,并将其拖入到事先建立好的prefabs文件夹中,使之作为一个预制体
(2)创建人物:
建立一个空物体(Creat empty),并将其重命名为player
在player里建立一个圆柱和球体,给player添加刚体组件,调正颜色(过程和标题1中ground的调色差不多),调正大小比例使其形成下图模样(图中transform参数可作为参考)
至此我们游戏所需模型制作完毕
创建Scripts文件夹,在其中创建C#脚本(C# Script)
打开编辑(话不多说,上代码)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class player : MonoBehaviour
{
public float maxDis;//生成盒子与上一个盒子的最大距离
public GameObject _box;//获取生成的盒子对应的预制体
private Vector3 _dir = new Vector3(1, 0, 0);//生成第二个盒子的方向变量
private Rigidbody rig1;//获取player刚体组件
// Start is called before the first frame update
void Start()
{
rig1 = GetComponent();//获取player的Rigidbody组件,因为此脚本挂在player上,所以默认获取player的刚体组件,可以查资料学习一下怎样获取指定物体组件
putBox();//调用生成盒子函数
}
// Update is called once per frame
void Update()
{
}
void putBox()
{
var box = Instantiate(_box);//实例化盒子
box.transform.position = _box.transform.position + _dir * Random.Range(3f, maxDis);//设置盒子位置
var a = Random.Range(1f, 2);//生成一个随机数
box.transform.localScale = new Vector3(a, 1.108432f, a);//改变盒子scale(尺寸)中的x(长)与z(宽)全部为生成的随机数
}
void Random_dir()//随机盒子生成方向
{
var a = Random.Range(0, 2);//随机生成0,1两个数
if (a == 0)
{
_dir = new Vector3(1, 0, 0);
}
else
{
_dir = new Vector3(0, 0, 1);
}
}
}
编辑完后 ctrl+s保存,返货到unity界面执行下面操作
运行结果如图
至此我们完成了生成盒子的操作
在脚本中updata中添加如下代码
if (Input.GetKeyDown(KeyCode.Space))//判断是否按下space
{
start_time = Time.time;//记录按下space的时间
}
if (Input.GetKeyUp(KeyCode.Space))//判断是否松开按键
{
var time = Time.time - start_time;//计算按键时间
jump(time);
}
创建使player跳跃函数
void jump(float time)
{
//给player添加瞬间力
//Factor为控制player跳跃速度的控制基数
rig1.AddForce((new Vector3(0, 2, 0) + _dir) * time * Factor, ForceMode.Impulse);
}
我们发现此实player跳跃后容易摔倒,所以我们要经过下面操作调整player重心,使其不倒
、
首先在player上建立空物体,并将其位置移动到player最低端
if (Input.GetKeyDown(KeyCode.Space))//判断是否按下space
{
_head = head.transform.localPosition;//记录缩放前头部位置
_body = body.transform.localScale;//记录缩放前身体大小
_stand_box = stand_box.transform.localScale;//记录盒子大小
start_time = Time.time;//记录按下space的时间
}
if (Input.GetKeyUp(KeyCode.Space))//判断是否松开按键
{
var time = Time.time - start_time;//计算按键时间
jump(time);
body.transform.localScale = _body;//身体还原
head.transform.localPosition = _head;
stand_box.transform.localScale = _stand_box;//盒子还原
}
if (Input.GetKey(KeyCode.Space))
{
head.transform.localPosition += new Vector3(0, -1, 0) * 0.1f * Time.deltaTime;//头动画缩小
body.transform.localScale += new Vector3(1, -1, 1) * 0.05f * Time.deltaTime;//身体动画缩小
stand_box.transform.localScale += new Vector3(1, -1, 1) * 0.05f * Time.deltaTime;//盒子动画缩小
}
当判断player落在盒子上时,要使用碰撞事件函数,而碰撞事件函数的基条件是存在碰撞器,所以我们要在player和盒子上添加碰撞器(collider)
然后调成碰撞其大小及位置使其将player完全笼罩
(盒子碰撞器添加方法和player相似 在此不多说,注意:盒子添加完碰撞器后要将prefab中的盒子替换)
然后我们需要添加碰撞事件的函数
void OnCollisionEnter(Collision collision)//碰撞事件函数
{
Debug.Log(collision.gameObject.name);//打印与player碰撞的物体的名字
Collider collider_box = stand_box.GetComponent();//获取player原来所在盒子的碰撞器
if (collision.gameObject.name.Contains("Cube") && collider_box != collision.collider)//判断是否与盒子碰撞且碰撞的盒子是否不同于上一个盒子
{
GameObject destory_box = stand_box;//定义将要销毁的盒子
stand_box = new_box;//将player所在盒子进行刷新
putBox();//生成新的盒子
Destroy(destory_box);
}
if (collision.gameObject.name == "ground")
{
SceneManager.LoadScene(0);//重新开始游戏,需要引入头文件:using UnityEngine.SceneManagement;
}
}
运行了一下,发现盒子生成时可能会产生bug:盒子会形成相互重叠,原因是盒子大小和生成距离的范围有关,自行进行调整即可
还有一个bug就是盒子总是按照一个方向生成,原因是在生成盒子函数中未调用随机生成方向函数,自己填补即可
首先需要定义一个相机的位置的公共变量和一个相机与player位之差的常量
然后在脚本执行开始时计算相机与player的位置差
随后添加相机移动函数
void MoveCamera()//相机跟随函数
{
Camera.position = transform.position + _cameraRelativeTranfrom;//移动相机:相机位置等于小人目前位置加相对位置
}
创建text 并将其位置进行调整,然后在属性栏中进行自适应(途中将其设置为左上角显示)
自适应之后无论装口大小怎样改变,其位置依然在左上角
添加下面两个变量
在start中初始化
在成功跳跃后分数加一
在player中添加例子特效(如图),并对其在属性栏中进行大小形状设置
在代码中定义public Object lizi;
开启代码:lizi.SetActive(true);
关闭代码:lizi.SetActive(false);
整个程序源码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class player : MonoBehaviour
{
public GameObject stand_box;//当前player所在盒子
public float maxDis;//生成盒子与上一个盒子的最大距离
public GameObject _box;//获取生成的盒子对应的预制体
public float Factor;//实现速度基数
public Transform transform1;//获取player中空物体的位置
public Transform head;//记录player的头部位置
public Transform body;//记录player的身体位置
public Transform Camera;//相机位置,实现相机跟随时用到
public Text sco;//记录分数,需要添加:using UnityEngine.UI;
public GameObject lizi;//例子特效
private Vector3 _dir = new Vector3(1, 0, 0);//生成第二个盒子的方向变量
private Rigidbody rig1;//获取player刚体组件
private float start_time;//记录按下开始space的时间
private GameObject new_box;//新生成的盒子
private static Vector3 _cameraRelativeTranfrom;//相机需要移动距离
//记录player位置和大小及当前盒子大小
Vector3 _head = new Vector3(0, 0, 0);
Vector3 _body = new Vector3(0, 0, 0);
Vector3 _stand_box = new Vector3(0, 0, 0);
private int _sco;
// Start is called before the first frame update
void Start()
{
lizi.SetActive(false);//默认粒子特效为关闭状态
_sco = 0;//分数初始化
sco.text = _sco.ToString();//分数更新
_cameraRelativeTranfrom = Camera.position - transform.position;//计算相机对于player的相对位置
rig1 = GetComponent();//获取player的Rigidbody组件,因为此脚本挂在player上,所以默认获取player的刚体组件,可以查资料学习一下怎样获取指定物体组件
rig1.centerOfMass = transform1.localPosition;//将物体重心放在playwe中空物体的位置
putBox();//调用生成盒子函数
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))//判断是否按下space
{
lizi.SetActive(true);//开启粒子特效
_head = head.transform.localPosition;//记录缩放前头部位置
_body = body.transform.localScale;//记录缩放前身体大小
_stand_box = stand_box.transform.localScale;//记录盒子大小
start_time = Time.time;//记录按下space的时间
}
if (Input.GetKeyUp(KeyCode.Space))//判断是否松开按键
{
lizi.SetActive(false);//关闭粒子特效
var time = Time.time - start_time;//计算按键时间
jump(time);
body.transform.localScale = _body;//身体还原
head.transform.localPosition = _head;
stand_box.transform.localScale = _stand_box;//盒子还原
}
if (Input.GetKey(KeyCode.Space))
{
head.transform.localPosition += new Vector3(0, -1, 0) * 0.1f * Time.deltaTime;//头动画缩小
body.transform.localScale += new Vector3(1, -1, 1) * 0.05f * Time.deltaTime;//身体动画缩小
stand_box.transform.localScale += new Vector3(1, -1, 1) * 0.05f * Time.deltaTime;//盒子动画缩小
}
}
void putBox()
{
Random_dir();//调用随机生成盒子方向函数
new_box = Instantiate(_box);//实例化盒子
new_box.transform.position = stand_box.transform.position + _dir * Random.Range(4.5f, maxDis);//设置盒子位置
var a = Random.Range(1f, 2);//生成一个随机数
new_box.transform.localScale = new Vector3(a, 1.108432f, a);//改变盒子scale(尺寸)中的x(长)与z(宽)全部为生成的随机数
}
void Random_dir()//随机盒子生成方向
{
var a = Random.Range(0, 2);//随机生成0,1两个数
if (a == 0)
{
_dir = new Vector3(1, 0, 0);
}
else
{
_dir = new Vector3(0, 0, 1);
}
}
void jump(float time)
{
//给player添加瞬间力
//Factor为控制player跳跃速度的控制基数
rig1.AddForce((new Vector3(0, 2, 0) + _dir) * time * Factor, ForceMode.Impulse);
}
void OnCollisionEnter(Collision collision)//碰撞事件函数
{
Debug.Log(collision.gameObject.name);//打印与player碰撞的物体的名字
Collider collider_box = stand_box.GetComponent();//获取player原来所在盒子的碰撞器
if (collision.gameObject.name.Contains("Cube") && collider_box != collision.collider)//判断是否与盒子碰撞且碰撞的盒子是否不同于上一个盒子
{
_sco++;//分数加一
sco.text = _sco.ToString();//将分数更新
MoveCamera();
GameObject destory_box = stand_box;//定义将要销毁的盒子
stand_box = new_box;//将player所在盒子进行刷新
putBox();//生成新的盒子
Destroy(destory_box);
}
if (collision.gameObject.name == "ground")
{
SceneManager.LoadScene(0);//重新开始游戏,需要引入头文件:using UnityEngine.SceneManagement;
}
}
void MoveCamera()//相机跟随函数
{
Camera.position = transform.position + _cameraRelativeTranfrom;//移动相机:相机位置等于小人目前位置加相对位置
}
}
工程下载地址:链接:https://pan.baidu.com/s/16_drASFV6Fk5ILGQU5QGlA
提取码:ew0g
unity开发跳一跳至此告一段落
留给大家些许bug,评论区见,欢迎大家前来指点