1.添加飘分动画
新建text,命名为singText,并修改其位置
2,重新开始
命名空间
using UnityEngine.SceneManagement;
public void Restart()
{
SceneManager.LoadScene(0);//重新开始
}
/// <summary>
/// 显示飘分动画
/// </summary>
void ShowScoreAnimation()
{
singText.gameObject.SetActive(true);//显示Text
_isUpdateScore = true;
_ScoreAnimationTime = Time.time;//记录飘分动画开始的时间
singText.text = "+" + LastScore;
}
/// <summary>
/// 飘分动画
/// </summary>
void UpdateScoreAnimation()
{
//一秒钟之后,执行语句
if(Time.time-_ScoreAnimationTime>1)
{
_isUpdateScore = false;
singText.gameObject.SetActive(false);//Text消失
}
var playScorePos = RectTransformUtility.WorldToScreenPoint(_Camera.GetComponent<Camera>(), transform.position);
//playScorePosde 位置在屏幕正中心
//屏幕是一个矩形,如果是一个1920*1080的屏幕,则屏幕的左下角是(0,0) ,右上角是(1920,1080)
//如果物体的在一个摄像机cam1的正中心,也就是在屏幕的正中心,那么算出来的结果就是(1920 / 2,1080 / 2,z)
singText.transform.position = playScorePos+Vector2.Lerp(Vector2.zero,new Vector2(0,200),Time.time-_ScoreAnimationTime);
//将singText的位置向上飘
singText.color = Color.Lerp(Color.red,new Color(0,0,0),Time.time-_ScoreAnimationTime);
//singText颜色变化
Debug.Log(playScorePos);
}
完整代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;//DOTween命名空间
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class Playermove : MonoBehaviour
{
Rigidbody rigidbody_;
//初始时间
float Starttime;
//力
public float Fac = 4f;
//用于生成随机方向
Vector3 _direction;
//初始物体
public GameObject state;
//当前脚下物体
GameObject currentState;
//人物身体
public GameObject Head;
public GameObject Body;
//物块数组
public GameObject[] BoxTemplates;
//生成物块的最大距离
float maxdistance = 4f;
//摄像机距离小人的位置差
Vector3 _CameraRelativePosition;
//相机位置
public Transform _Camera;
//用于控制小人能不能跳
bool isbool = true;
public Image ImgGameOver;
//游戏失败
public Button restart_;
public GameObject lizi;
//蓄力效果
public Text text;
Vector3 vector;
int _Score = 0;
//下一次所加积分
int LastScore = 1;
public AudioClip Jump;//跳跃音效
public AudioClip Power;//蓄力音效
public AudioClip Fail;//失败音效
public AudioSource music;//声明一个静态的音频来源
//显示所加分数
public Text singText;
bool _isUpdateScore = false;
//记录人物踩下时的时刻
float _ScoreAnimationTime = 0;
void Start()
{
restart_.onClick.AddListener(Restart);
music = GetComponent<AudioSource>();
rigidbody_ = GetComponent<Rigidbody>();
_CameraRelativePosition = _Camera.transform.position - transform.position;//相机位置减去小人的位置
currentState = state;//设置当前脚下物体为初始物体
RandomDirection();//调用随机方向函数
SpawnState();//调用生成盒子函数
lizi.SetActive(false);
}
/// <summary>
/// 相机移动
/// </summary>
void MoveCamera()
{
_Camera.transform.DOMove(transform.position + _CameraRelativePosition,1);
}
void Update()
{
//飘分动画
if(_isUpdateScore == true)
{
UpdateScoreAnimation();
}
if (isbool)
{
//点击鼠标左键
if (Input.GetMouseButtonDown(0))
{
Starttime = Time.time;//记录游戏开始至按键的时间
}
//持续按下鼠标左键
if (Input.GetMouseButton(0))
{
//添加限定,压缩物体,最多减少一半
if (currentState.transform.localScale.y > 0.25f)//当小方块的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轴下降
lizi.SetActive(true);
music.clip = Power;
music.Play();
}
}
//抬起鼠标左键
if (Input.GetMouseButtonUp(0))
{
//物块和小人恢复原状
currentState.transform.DOLocalMoveY(0.25f, 0.2f);//0.2秒内y坐标变到0.25
currentState.transform.DOScaleY(0.5f, 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;//使小人在跳跃期间不可以使用此方法
lizi.SetActive(false);
}
}
}
/// <summary>
/// 跳跃
/// </summary>
/// <param name="time"></param>
void _OnJump(float time)
{
rigidbody_.AddForce(new Vector3(0,5f, 0) + (vector) * Fac * time, ForceMode.Impulse);//使小人向前跳向中心方向跳
transform.DOLocalRotate(new Vector3(0, 0, -360), 0.5f, RotateMode.LocalAxisAdd);//利用Dotweening进行360度翻转(自身轴)
music.clip = Jump;
music.Play();
}
/// <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(1, maxdistance);
//获取人与下一个盒子同一平面的单位向量的向量差
//normalized:返回大小为1时的该向量,当前向量保持不变,返回一个新的标准化向量,把一个向量拿到或者改变成 归一化向量,所谓归一化就是
//把原来某个向量变成 x,y,z平方之和的平方根为1,也就是新向量长度为1.但是!方向与原向量一样!
vector = (new Vector3(stage.transform.position.x, transform.position.y, stage.transform.position.z) - transform.position).normalized;
//改变大小
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")
{
ImgGameOver.gameObject.SetActive(true);
music.clip = Fail;
music.Play();
GameOver();
}
else
{
//获取碰撞点
//当前脚下物块不是碰撞体,小人没有落到原物块上,落到了下一物块上
if (currentState != collision.gameObject)
{
ContactPoint[] contacts = collision.contacts;//将碰撞点赋给contacts
if (contacts.Length == 1 && contacts[0].normal.y ==1.0)
{
//检测碰撞点向上
currentState = collision.gameObject;//将碰撞体物块赋给当前物块
RandomDirection();//随机方向
SpawnState();//生成预制体
MoveCamera();//移动相机
AddScore(contacts);//积分增加
isbool = true;//isbool改为true,小人可以继续向前跳跃
ShowScoreAnimation();//显示飘分动画
}
else
{
Debug.Log("游戏结束");
}
}
//小人跳到了原物块上
else
{
var contacts = collision.contacts;
if (contacts.Length == 1 && contacts[0].normal == Vector3.up)
{
currentState = collision.gameObject;//将碰撞体物块赋给当前物块
isbool = true;//isbool改为true,小人可以继续向前跳跃
}
else
{
Debug.Log("游戏结束");
}
}
}
}
/// <summary>
/// 增加积分,精准降落积分翻倍
/// </summary>
private void AddScore(ContactPoint[] contacts)
{
if(contacts.Length>0)
{
//小人与盒子的碰撞点位置
Vector3 hitpoint = contacts[0].point;
//脚下盒子的位置 所碰撞的盒子的中心点的位置
Vector3 stagePos = currentState.transform.position;
hitpoint.y = 0;
stagePos.y = 0;
//碰撞点到中心点的位置
float prection = Vector3.Distance(hitpoint, stagePos);
if(prection<0.1f)
{
Debug.Log("精准降落");
LastScore *= 2;
}
else
{
LastScore = 1;
Debug.Log("偏远降落");
}
_Score += LastScore;
text.text = "" + _Score;
}
}
/// <summary>
/// 显示飘分动画
/// </summary>
void ShowScoreAnimation()
{
singText.gameObject.SetActive(true);//显示Text
_isUpdateScore = true;
_ScoreAnimationTime = Time.time;//记录飘分动画开始的时间
singText.text = "+" + LastScore;
}
/// <summary>
/// 飘分动画
/// </summary>
void UpdateScoreAnimation()
{
//一秒钟之后,执行语句
if(Time.time-_ScoreAnimationTime>1)
{
_isUpdateScore = false;
singText.gameObject.SetActive(false);//Text消失
}
var playScorePos = RectTransformUtility.WorldToScreenPoint(_Camera.GetComponent<Camera>(), transform.position);
//playScorePosde 位置在屏幕正中心
//屏幕是一个矩形,如果是一个1920*1080的屏幕,则屏幕的左下角是(0,0) ,右上角是(1920,1080)
//如果物体的在一个摄像机cam1的正中心,也就是在屏幕的正中心,那么算出来的结果就是(1920 / 2,1080 / 2,z)
singText.transform.position = playScorePos+Vector2.Lerp(Vector2.zero,new Vector2(0,200),Time.time-_ScoreAnimationTime);
//将singText的位置向上飘
singText.color = Color.Lerp(Color.red,new Color(0,0,0),Time.time-_ScoreAnimationTime);
//singText颜色变化
Debug.Log(playScorePos);
}
public void Restart()
{
SceneManager.LoadScene(0);//重新开始
}
}