创建一个小人
创建一个空物体,将小人的头和身体放到空物体下,注意调整小人的位置,小人是以空物体为坐标 。
给小人添加Rigidbody,如下图
创建起始物块和地板
添加DOTween插件
在资源商店中搜索
代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;//DOTween命名空间
public class Playermove : MonoBehaviour
{
Rigidbody rigidbody_;
//初始时间
float Starttime;
//力
public float Fac=3f;
//用于生成随机方向
Vector3 _direction;
//初始物体
public GameObject state;
//当前脚下物体
GameObject currentState;
//人物身体
public GameObject Head;
public GameObject Body;
//物块数组
public GameObject[] BoxTemplates;
//生成物块的最大距离
float maxdistance=6f;
//摄像机距离小人的位置差
Vector3 _CameraRelativePosition;
//相机位置
public Transform Camera;
//用于控制小人能不能跳
bool isbool = true;
void Start()
{
rigidbody_ = GetComponent<Rigidbody>();
_CameraRelativePosition = Camera.transform.position - transform.position;//相机位置减去小人的位置
currentState = state;//设置当前脚下物体为初始物体
RandomDirection();//调用随机方向函数
SpawnState();//调用生成盒子函数
}
/// <summary>
/// 相机移动
/// </summary>
void MoveCamera()
{
Camera.transform.DOMove(transform.position + _CameraRelativePosition,1);
}
void Update()
{
if (isbool)
{
//点击鼠标左键
if (Input.GetMouseButtonDown(0))
{
Starttime = Time.time;//记录游戏开始至按键的时间
}
//持续按下鼠标左键
if (Input.GetMouseButton(0))
{
//添加限定,压缩物体,最多减少一半
if (currentState.transform.localScale.y > 0.5f)//当小方块的y轴大小大于0.5时
{
Body.transform.localScale += new Vector3(1, -1, 1) * 0.05f * Time.deltaTime;//压缩人头部的大小
Head.transform.localScale += new Vector3(1, -1, 1) * 0.01f * Time.deltaTime;//压缩人身体大小
currentState.transform.localScale -= new Vector3(0, 1, 0) * 0.15f * Time.deltaTime;//压缩小方块大小
currentState.transform.localPosition -= new Vector3(0, 1, 0) * 0.15f * Time.deltaTime;//改变小方块位置,y轴下降
}
}
//抬起鼠标左键
if (Input.GetMouseButtonUp(0))
{
//物块和小人恢复原状
currentState.transform.DOLocalMoveY(3.75f, 0.2f);//0.2秒内y坐标变到3.75
currentState.transform.DOScaleY(1f, 0.2f);//0.2秒内y轴大小变为1
Body.transform.DOScale(0.2f, 0.2f);//0.2秒内Body大小变为0.2
Head.transform.DOScale(0.2f, 0.2f);//0.2秒内Head大小变为0.2
float elmap = Time.time - Starttime;//鼠标左键按下到抬起的时间
_OnJump(elmap);//调用跳跃函数
isbool = false;//使小人在跳跃期间不可以盗用此方法
}
}
}
/// <summary>
/// 跳跃
/// </summary>
/// <param name="time"></param>
void _OnJump(float time)
{
rigidbody_.AddForce(new Vector3(0, 10f, 0) + (_direction) * Fac * time, ForceMode.Impulse);//使小人向前跳
transform.DOLocalRotate(new Vector3(0, 0, -360), 0.5f, RotateMode.LocalAxisAdd);//利用Dotweening进行360度翻转(自身轴)
}
/// <summary>
/// 随机方向
/// </summary>
void RandomDirection()
{
float seed = Random.Range(0, 2);//[0,2);生成随机数,0或1
_direction = seed == 0 ? new Vector3(1, 0, 0):new Vector3(0, 0, 1);//如果随机数是0,方向为(1,0,0),如果为1,方向为(0,0,1)
transform.right = _direction;//使小人的延z轴翻滚的方向等于_direction(Right,Forword,Up代表三个轴)
}
/// <summary>
/// 生成盒子
/// </summary>
void SpawnState()
{
GameObject prefeb;//物块预制体
if(BoxTemplates.Length >0)//如果数组长度大于0
{
prefeb = BoxTemplates[Random.Range(0, BoxTemplates.Length)];//随机生成物块数组中的物体
}
else
{
prefeb = state;//使预制体为初始物块
}
GameObject stage = Instantiate(prefeb);//实例化预制体
//生成方块的距离
stage.transform.position = currentState.transform.position + _direction * Random.Range(3, maxdistance);
//改变大小
float randomScale = Random.Range(0.5f, 1);
stage.transform.localScale = new Vector3(randomScale, stage.transform.localScale.y, randomScale);
//改变颜色
stage.GetComponent<Renderer>().material.color = new Color(Random.Range(0, 1f), Random.Range(0, 1f), Random.Range(0, 1f));
}
/// <summary>
/// 游戏结束
/// </summary>
void GameOver()
{
Debug.Log("游戏结束");
}
/// <summary>
/// 检测碰撞
/// </summary>
/// <param name="collision"></param>
private void OnCollisionEnter(Collision collision)
{
//碰撞到地面
if (collision.collider.tag == "Ground")
{
GameOver();
}
else
{
//获取碰撞点
//当前脚下物块不是碰撞体,小人没有落到原物块上,落到了下一物块上
if (currentState != collision.gameObject)
{
var contacts = collision.contacts;//将碰撞点赋给contacts
if (contacts.Length == 1 && contacts[0].normal == Vector3.up)
{
//检测碰撞点向上
currentState = collision.gameObject;//将碰撞体物块赋给当前物块
RandomDirection();//随机方向
SpawnState();//生成预制体
MoveCamera();//移动相机
isbool = true;//isbool改为true,小人可以继续向前跳跃
}
else
{
GameOver();
}
}
//小人跳到了原物块上
else
{
var contacts = collision.contacts;
if (contacts.Length == 1 && contacts[0].normal == Vector3.up)
{
currentState = collision.gameObject;//将碰撞体物块赋给当前物块
isbool = true;//isbool改为true,小人可以继续向前跳跃
}
else
{
GameOver();
}
}
}
}
}
将脚本拖到小人上
将Prefabs下的预制体拖到数组中
给地板添加标签Ground