【unity学习笔记】大三下学期 跳一跳小游戏制作

游戏需实现的功能:
1、小方块的生成
2、小人跳跃与碰撞检测
3、小人与小方块放大缩小动作
4、摄像机跟随
5、分数生成以及分数增加的飘分动画
6、玩家每次跳跃都会跳到小木块中心
【新知识整理】

1、摄像机的跟随

由于小人跳跃时会360度翻跟头,直接把摄像机拖到玩家子对象下影响观感(相当于玩家也会翻跟头哈哈哈),所以只需要每次跟随时缩短一下与小人的距离即可。
郭老师选择了游戏开始时记录一下当前camera与小人的距离,暂设为s,小人每次跳跃到新的小方块上时将camera的位置加上s即可。

 //摄像机距离小人的位置差
 Vector3 cameraLocation;
 
 void Start()
    {
        cameraLocation = Camera.main.transform.position - transform.position;
    }
    
    //当小人落在新的小木块上时执行此函数
     void moveCamera()
    {
        Camera.main.transform.DOMove(transform.position + cameraLocation, 1);
    }

2、有关小人跳跃

首先玩家按下鼠标左键给小人蓄力,松开时小人向前跳跃。小人蓄力时身体以及盒子会压缩,跳跃时回缩模拟蓄力过程。
蓄力时就是改变GameObject的localScale

//鼠标按下时执行此函数
void compress()
    {
        //盒子压缩
        if (currentStage.transform.localScale.y > 2f)//缩放范围 缩到2f就不缩了
        {
            currentStage.transform.localScale -= new Vector3(1, 1, 0) * 0.2f * Time.deltaTime;
            currentStage.transform.localPosition -= new Vector3(0, 1, 0) * 0.2f * Time.deltaTime;//竖直位置也要缩放,不然就悬空了
        }
        //玩家身体也压缩一下 头部和身体分别压缩
        playerHead.transform.localScale -= new Vector3(-1, 1, -1) * 0.2f * Time.deltaTime;
        playerBody.transform.localScale -= new Vector3(-1, 1, -1) * 0.2f * Time.deltaTime;
    }

有关小人跳跃方向,应往新生成小格子的中心点的位置跳跃,中心点的位置跳跃就是它的坐标轴的位置,如下在这里插入图片描述

但是呢咱们需要的位置其实是小格子上表面的中心点位置,所以Y轴大小可以提高到跟小人一样的高度,即小人这个可以朝(小格子的x,小人的y轴,小人的z轴)这个方向跳跃,这样小人跳过去正好能落到小格子表面上。
小人跳跃时同时360度旋转

//这句话是生成盒子的方法里面的,stage就是新生成的小盒子
//获取人物与下一个盒子同一平面的单位向量差,最后.normalized是为了获得单位长度的方向,毕竟咱们只要方向不是要的距离差
 playerDirection = ((new Vector3(stage.transform.position.x,transform.position.y,stage.transform.position.z))- 	transform.position).normalized;

//跳跃,即鼠标松开时执行
    void _onJump(float force)
    {
        //跳起的力大小是根据鼠标按下的时间长短决定的 即传过来的force
        _playerRB.AddForce(new Vector3(0, 10f, 0) + playerDirection* Speed*force,ForceMode.Impulse);
       //玩家跳起时沿世界坐标系z轴旋转-360
        transform.DOLocalRotate(new Vector3(0, 0, -360), 0.6f, RotateMode.LocalAxisAdd);
    }

3、有关小格子的生成

一个重要的点是小格子的生成方向,它可以沿当前格子的Z轴生成,也可以沿X轴生成,可以利用随机函数定一个随机方向。新生成的小格子的位置就是上一个小格子的位置生成方向加上随机的一段距离

stage.transform.position = currentStage.transform.position + _direction * Random.Range(13, 19);

生成的小格子模型在预置体列表里随机挑选,其次还要设置小格子的大小,颜色等。

//小格子生成函数
void SpawnState()
    {
        GameObject prefab;
        if (boxPrefab.Length>0)//若预置体列表里面有东西
        {
            prefab = boxPrefab[Random.Range(0, boxPrefab.Length)];
        }
        else
        {
            prefab = currentStage;
        }

        GameObject stage = Instantiate(prefab);
        //改变大小
        float rangeSclate = Random.Range(0.8f, 1);
        stage.transform.localScale = new Vector3(prefab.transform.localScale.x*rangeSclate, prefab.transform.localScale.y, prefab.transform.localScale.z*rangeSclate);
        //改变位置
        stage.transform.position = currentStage.transform.position + _direction * Random.Range(13, 19);
        //改变颜色
        stage.GetComponent<Renderer>().material.color = new Color(Random.Range(0, 1f), Random.Range(0, 1f), Random.Range(0, 1f));
        //获取人物与下一个盒子同一平面的单位向量差
        playerDirection = ((new Vector3(stage.transform.position.x,transform.position.y,stage.transform.position.z))-transform.position).normalized; 
    }

4、有关分数奖励机制

郭老师表示若小人落在格子的中心位置,则可以加双倍分,一直落在中心位置一直双倍累加,但若没有落在中心位置,则累加分数归一。怎么判断小人是否落在了小盒子的中心位置呢?可以求一下小人碰撞到小盒子的位置和被碰撞的小盒子的位置的相对距离,若距离小就算是落在中心点了。当然俩距离Y轴都归0,因为只看水平距离嘛~

 private void addScore(ContactPoint[] contacts)
    {
        if (contacts.Length > 0)
        {
            //小人与盒子碰撞点的位置
            Vector3 hitpiont = contacts[0].point;
            //所碰撞盒子的中心位置
            Vector3 stagePos = currentStage.transform.position;
            //求中心距离
            hitpiont.y = 0;
            stagePos.y = 0;
            float precision = Vector3.Distance(hitpiont, stagePos);
            if (precision <= 0.1f)
            {
                Debug.Log("精准降落~~");
                lastScore *= 2;
               
            }
            else
            {
                lastScore = 1;
                Debug.Log("偏远降落");
            }
            _Score += lastScore;
        }
    }

5、有关分数生成的飘分动画

 /// <summary>
    /// 显示飘分动画
    /// </summary>
    void ShowScoreAnimation()
    {
        showText.gameObject.SetActive(true);
        _isUpdate = true;
        _ScoreAnimationTime = Time.time;
       showText.text = "+" + lastScore;
    }
    void UpdateScore()
    {
        if (Time.time - _ScoreAnimationTime >= 1)
        {
            _isUpdate = false;
            showText.gameObject.SetActive(false);
        }
        //获取人物在屏幕上的二维坐标
        //var playScorePos = RectTransformUtility.WorldToScreenPoint(cam.gameObject.GetComponent<Camera>(), transform.position);
        var playScorePos = RectTransformUtility.WorldToScreenPoint(Camera.main, transform.position);
        //从playScorePos 加上【(0,0),(0,200)】之间变化
        showText.transform.position = playScorePos + Vector2.Lerp(Vector2.zero, new Vector2(0, 200), Time.time - _ScoreAnimationTime);

        showText.color = Color.Lerp(new Color(1, 1, 1), new Color(0, 0, 0), Time.time - _ScoreAnimationTime);
    }

以下是总代码
//0401更新 更新了飘分动画

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class PlayerMove : MonoBehaviour
{

    Rigidbody _playerRB;
    
    //玩家跳跃速度
    public float Speed=10f;
    
    //玩家每次开始跳跃的时间
    public float startTime;
    
    //最开始的小木块
    public GameObject startStage;
   
    //player脚下的小木块(实时)
    public GameObject currentStage;

    //player的头和身体
    public GameObject playerHead;
    public GameObject playerBody;

    //新小木块生成方向
    Vector3 _direction=new Vector3(0,0,1);
    
    //预备生成的木块预置体列表
    public GameObject[] boxPrefab;

    //player是否可以跳跃 
    public bool isJump=true;

    //摄像机距离小人的位置差
    Vector3 cameraLocation;

    //所加分数
    int lastScore =1;
    int _Score = 0;

    public Text scoreText;

    //player的跳跃方向
    Vector3 playerDirection;

    bool isStart = true;//是否是游戏开始阶段

    public Text showText;
    public bool _isUpdate=false;
    public Camera cam;

    //记录人物踩下来的时刻
    float _ScoreAnimationTime = 0;

    public Image gameoverImage;
    void Start()
    {
       
        //初始小木块脚下的木块就是一开始的木块
        currentStage = startStage;

        _playerRB = GetComponent<Rigidbody>();

        cameraLocation = Camera.main.transform.position - transform.position;
 
    }
    void Update()
    {
        scoreText.text = "分数:" + _Score;
        if (_isUpdate == true)
        {
            UpdateScore();
        }

        
        if (isJump == true)
        {
            if (Input.GetMouseButtonDown(0))
            {
                startTime = Time.time;        
            }
            if (Input.GetMouseButton(0))
            {
                //按下鼠标,即蓄力时,小木块和玩家收缩
                compress();
            }
            if (Input.GetMouseButtonUp(0))
            {
                isJump = false;
               
                //记录一下这次跳跃的时间
                float endTime = Time.time - startTime;
                //player跳起时的动作
                _onJump(endTime);
                
                //盒子和玩家回缩
                compressBack();
            }
        }
    }

    /// <summary>
    /// 碰撞检测
    /// </summary>
    /// <param name="collision"></param>
    private void OnCollisionEnter(Collision collision)
    {
        string tag = collision.gameObject.tag;
        var contacts = collision.contacts;//ContactPoint[]类型
        Debug.Log(contacts.Length);//????????????????
        if (tag == "Ground")//落在地上
        {
            gameOver();
        }
        else if (tag == "cube0"&&isStart==true)//初始状态
        {
            isJump = true;
            isStart = false;
            SpawnState();//初始时生成一个小木块
          
        }
        else if(collision.gameObject== currentStage.gameObject)//落在旧的小方块上
        {
            //不作处理
            isJump = true;

        }
        else if (tag == "cube")//落在新的小方块上
        {
            
            if (contacts.Length == 1 && contacts[0].normal == Vector3.up)//若垂直落在了小方块上
            {

                isJump = true;
                addScore(contacts);
                //则更新
                currentStage = collision.gameObject;
                randomDirection();
                SpawnState();
                moveCamera();
            }
            else
            {
                gameOver();
            }
        }
    }
    /// <summary>
    /// player准备跳跃时压缩player和小木块
    /// </summary>
    void compress()
    {
        //盒子压缩
        if (currentStage.transform.localScale.y > 2f)//缩放范围 缩到2f就不缩了
        {
            currentStage.transform.localScale -= new Vector3(1, 1, 0) * 0.2f * Time.deltaTime;
            currentStage.transform.localPosition -= new Vector3(0, 1, 0) * 0.2f * Time.deltaTime;//竖直位置也要缩放,不然就悬空了
                                                                                                 //玩家身体也压缩一下 头部和身体分别压缩
            playerHead.transform.localScale -= new Vector3(-1, 1, -1) * 0.2f * Time.deltaTime;
            playerBody.transform.localScale -= new Vector3(-1, 1, -1) * 0.2f * Time.deltaTime;
        }
       
    }
    void compressBack()
    {
        currentStage.transform.DOLocalMoveY(1, 0.4f);//Y轴移动回原来的位置
        currentStage.transform.DOScale(new Vector3(8, 3, 8), 0.4f);//整体缩放回原来的位置

        playerHead.transform.DOScale(new Vector3(1, 1, 1), 0.4f);
        playerBody.transform.DOScale(new Vector3(1, 1, 1), 0.4f);
    }
    /// <summary>
    /// player跳起时的动作
    /// </summary>
    /// <param name="force"></param>
    void _onJump(float force)
    {
        //跳起的力大小是根据鼠标按下的时间长短决定的 即传过来的force
        _playerRB.AddForce(new Vector3(0, 10f, 0) + playerDirection* Speed*force,ForceMode.Impulse);
       //玩家跳起时沿世界坐标系z轴旋转-360
        transform.DOLocalRotate(new Vector3(0, 0, -360), 0.6f, RotateMode.LocalAxisAdd);
    }
    void randomDirection()
    {
        float seed = Random.Range(0, 2);
        _direction = seed == 0 ? new Vector3(1, 0, 0) : new Vector3(0, 0, 1);
        //改变小人的正方向 即将小人X轴对准将要前进的方向
        transform.right = _direction;
    }

    /// <summary>
    /// 生成一个小盒子
    /// </summary>
    void SpawnState()
    {
        GameObject prefab;
        if (boxPrefab.Length>0)//若预置体列表里面有东西
        {
            prefab = boxPrefab[Random.Range(0, boxPrefab.Length)];
        }
        else
        {
            prefab = currentStage;
        }

        GameObject stage = Instantiate(prefab);
        //改变大小
        float rangeSclate = Random.Range(0.8f, 1);
        stage.transform.localScale = new Vector3(prefab.transform.localScale.x*rangeSclate, prefab.transform.localScale.y, prefab.transform.localScale.z*rangeSclate);
        //改变位置
        stage.transform.position = currentStage.transform.position + _direction * Random.Range(13, 19);
        //改变颜色
        stage.GetComponent<Renderer>().material.color = new Color(Random.Range(0, 1f), Random.Range(0, 1f), Random.Range(0, 1f));
        //获取人物与下一个盒子同一平面的单位向量差
        playerDirection = ((new Vector3(stage.transform.position.x,transform.position.y,stage.transform.position.z))-transform.position).normalized;

       
    }

   public void gameReStart()
    {
        SceneManager.LoadScene(0);
    }
    private void gameOver()
    {
        isJump = false;
        gameoverImage.gameObject.SetActive(true);
        Debug.Log("游戏结束");
    }

    /// <summary>
    /// 移动摄像机
    /// </summary>
    void moveCamera()
    {
        Camera.main.transform.DOMove(transform.position + cameraLocation, 1);
    }
    private void addScore(ContactPoint[] contacts)
    {
        ShowScoreAnimation();
        if (contacts.Length > 0)
        {
            //小人与盒子碰撞点的位置
            Vector3 hitpiont = contacts[0].point;
            //所碰撞盒子的中心位置
            Vector3 stagePos = currentStage.transform.position;
            //求中心距离
            hitpiont.y = 0;
            stagePos.y = 0;
            float precision = Vector3.Distance(hitpiont, stagePos);
            if (precision <= 0.1f)
            {
                Debug.Log("精准降落~~");
                lastScore *= 2;
               
            }
            else
            {
                lastScore = 1;
                Debug.Log("偏远降落");
            }
            _Score += lastScore;

        }
    }
    /// <summary>
    /// 显示飘分动画
    /// </summary>
    void ShowScoreAnimation()
    {
        showText.gameObject.SetActive(true);
        _isUpdate = true;
        _ScoreAnimationTime = Time.time;
       showText.text = "+" + lastScore;
    }
    void UpdateScore()
    {
        if (Time.time - _ScoreAnimationTime >= 1)
        {
            _isUpdate = false;
            showText.gameObject.SetActive(false);
        }
        //获取人物在屏幕上的二维坐标
        //var playScorePos = RectTransformUtility.WorldToScreenPoint(cam.gameObject.GetComponent<Camera>(), transform.position);
        var playScorePos = RectTransformUtility.WorldToScreenPoint(Camera.main, transform.position);
        //从playScorePos 加上【(0,0),(0,200)】之间变化
        showText.transform.position = playScorePos + Vector2.Lerp(Vector2.zero, new Vector2(0, 200), Time.time - _ScoreAnimationTime);

        showText.color = Color.Lerp(new Color(1, 1, 1), new Color(0, 0, 0), Time.time - _ScoreAnimationTime);
    }
}

//0325更新 更新了56功能

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using UnityEngine.UI;

public class PlayerMove : MonoBehaviour
{

    Rigidbody _playerRB;
    
    //玩家跳跃速度
    public float Speed=10f;
    
    //玩家每次开始跳跃的时间
    public float startTime;
    
    //最开始的小木块
    public GameObject startStage;
   
    //player脚下的小木块(实时)
    public GameObject currentStage;

    //player的头和身体
    public GameObject playerHead;
    public GameObject playerBody;

    //新小木块生成方向
    Vector3 _direction=new Vector3(0,0,1);
    
    //预备生成的木块预置体列表
    public GameObject[] boxPrefab;

    //player是否可以跳跃 
    public bool isJump=true;

    //摄像机距离小人的位置差
    Vector3 cameraLocation;

    //所加分数
    int lastScore =1;
    int _Score = 0;

    public Text scoreText;

    //player的跳跃方向
    Vector3 playerDirection;

    bool isStart = true;//是否是游戏开始阶段
    void Start()
    {
       
        //初始小木块脚下的木块就是一开始的木块
        currentStage = startStage;

        _playerRB = GetComponent<Rigidbody>();

        cameraLocation = Camera.main.transform.position - transform.position;
 
    }
    void Update()
    {
        scoreText.text = "分数:"+_Score;
        if (isJump == true)
        {
            if (Input.GetMouseButtonDown(0))
            {
                startTime = Time.time;        
            }
            if (Input.GetMouseButton(0))
            {
                //按下鼠标,即蓄力时,小木块和玩家收缩
                compress();
            }
            if (Input.GetMouseButtonUp(0))
            {
                isJump = false;
               
                //记录一下这次跳跃的时间
                float endTime = Time.time - startTime;
                //player跳起时的动作
                _onJump(endTime);
                
                //盒子和玩家回缩
                compressBack();
            }
        }
    }

    /// <summary>
    /// 碰撞检测
    /// </summary>
    /// <param name="collision"></param>
    private void OnCollisionEnter(Collision collision)
    {
        string tag = collision.gameObject.tag;
        var contacts = collision.contacts;//ContactPoint[]类型
        Debug.Log(contacts.Length);//????????????????
        if (tag == "Ground")//落在地上
        {
            gameOver();
        }
        else if (tag == "cube0"&&isStart==true)//初始状态
        {
            isJump = true;
            isStart = false;
            SpawnState();//初始时生成一个小木块
          
        }
        else if(collision.gameObject== currentStage.gameObject)//落在旧的小方块上
        {
            //不作处理
            isJump = true;

        }
        else if (tag == "cube")//落在新的小方块上
        {
            addScore(contacts);
            isJump = true;
            if (contacts.Length == 1 && contacts[0].normal == Vector3.up)//若垂直落在了小方块上
            {
                //则更新
                currentStage = collision.gameObject;
                randomDirection();
                SpawnState();
                moveCamera();
            }
            else
            {
                gameOver();
            }
        }
    }
    /// <summary>
    /// player准备跳跃时压缩player和小木块
    /// </summary>
    void compress()
    {
        //盒子压缩
        if (currentStage.transform.localScale.y > 2f)//缩放范围 缩到2f就不缩了
        {
            currentStage.transform.localScale -= new Vector3(1, 1, 0) * 0.2f * Time.deltaTime;
            currentStage.transform.localPosition -= new Vector3(0, 1, 0) * 0.2f * Time.deltaTime;//竖直位置也要缩放,不然就悬空了
        }
        //玩家身体也压缩一下 头部和身体分别压缩
        playerHead.transform.localScale -= new Vector3(-1, 1, -1) * 0.2f * Time.deltaTime;
        playerBody.transform.localScale -= new Vector3(-1, 1, -1) * 0.2f * Time.deltaTime;
    }
    void compressBack()
    {
        currentStage.transform.DOLocalMoveY(1, 0.4f);//Y轴移动回原来的位置
        currentStage.transform.DOScale(new Vector3(8, 3, 8), 0.4f);//整体缩放回原来的位置

        playerHead.transform.DOScale(new Vector3(1, 1, 1), 0.4f);
        playerBody.transform.DOScale(new Vector3(1, 1, 1), 0.4f);
    }
    /// <summary>
    /// player跳起时的动作
    /// </summary>
    /// <param name="force"></param>
    void _onJump(float force)
    {
        //跳起的力大小是根据鼠标按下的时间长短决定的 即传过来的force
        _playerRB.AddForce(new Vector3(0, 10f, 0) + playerDirection* Speed*force,ForceMode.Impulse);
       //玩家跳起时沿世界坐标系z轴旋转-360
        transform.DOLocalRotate(new Vector3(0, 0, -360), 0.6f, RotateMode.LocalAxisAdd);
    }
    void randomDirection()
    {
        float seed = Random.Range(0, 2);
        _direction = seed == 0 ? new Vector3(1, 0, 0) : new Vector3(0, 0, 1);
        //改变小人的正方向 即将小人X轴对准将要前进的方向
        transform.right = _direction;
    }

    /// <summary>
    /// 生成一个小盒子
    /// </summary>
    void SpawnState()
    {
        GameObject prefab;
        if (boxPrefab.Length>0)//若预置体列表里面有东西
        {
            prefab = boxPrefab[Random.Range(0, boxPrefab.Length)];
        }
        else
        {
            prefab = currentStage;
        }

        GameObject stage = Instantiate(prefab);
        //改变大小
        float rangeSclate = Random.Range(0.8f, 1);
        stage.transform.localScale = new Vector3(prefab.transform.localScale.x*rangeSclate, prefab.transform.localScale.y, prefab.transform.localScale.z*rangeSclate);
        //改变位置
        stage.transform.position = currentStage.transform.position + _direction * Random.Range(13, 19);
        //改变颜色
        stage.GetComponent<Renderer>().material.color = new Color(Random.Range(0, 1f), Random.Range(0, 1f), Random.Range(0, 1f));
        //获取人物与下一个盒子同一平面的单位向量差
        playerDirection = ((new Vector3(stage.transform.position.x,transform.position.y,stage.transform.position.z))-transform.position).normalized;

       
    }

   
    private void gameOver()
    {
        isJump = false;
        Debug.Log("游戏结束");
    }

    /// <summary>
    /// 移动摄像机
    /// </summary>
    void moveCamera()
    {
        Camera.main.transform.DOMove(transform.position + cameraLocation, 1);
    }
    private void addScore(ContactPoint[] contacts)
    {
        if (contacts.Length > 0)
        {
            //小人与盒子碰撞点的位置
            Vector3 hitpiont = contacts[0].point;
            //所碰撞盒子的中心位置
            Vector3 stagePos = currentStage.transform.position;
            //求中心距离
            hitpiont.y = 0;
            stagePos.y = 0;
            float precision = Vector3.Distance(hitpiont, stagePos);
            if (precision <= 0.1f)
            {
                Debug.Log("精准降落~~");
                lastScore *= 2;
               
            }
            else
            {
                lastScore = 1;
                Debug.Log("偏远降落");
            }
            _Score += lastScore;
        }
    }
}

//0319更新 整理后的

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class PlayerMove : MonoBehaviour
{

    Rigidbody _playerRB;
    
    //玩家跳跃速度
    public float Speed=10f;
    
    //玩家每次开始跳跃的时间
    public float startTime;
    
    //最开始的小木块
    public GameObject startStage;
   
    //player脚下的小木块(实时)
    public GameObject currentStage;

    //player的头和身体
    public GameObject playerHead;
    public GameObject playerBody;

    //新小木块生成方向,也是player的跳跃方向
    Vector3 _direction=new Vector3(0,0,1);
    
    //预备生成的木块预置体列表
    public GameObject[] boxPrefab;

    //player是否可以跳跃 
    public bool isJump=true;

    //摄像机距离小人的位置差
    Vector3 cameraLocation;

    bool isStart = true;
    void Start()
    {
        //初始小木块脚下的木块就是一开始的木块
        currentStage = startStage;

        _playerRB = GetComponent<Rigidbody>();

        cameraLocation = Camera.main.transform.position - transform.position;
 
    }
    void Update()
    {
        if (isJump == true)
        {
            if (Input.GetMouseButtonDown(0))
            {
                startTime = Time.time;        
            }
            if (Input.GetMouseButton(0))
            {
                //按下鼠标,即蓄力时,小木块和玩家收缩
                compress();
            }
            if (Input.GetMouseButtonUp(0))
            {
                isJump = false;
               
                //记录一下这次跳跃的时间
                float endTime = Time.time - startTime;
                //player跳起时的动作
                _onJump(endTime);
                
                //盒子和玩家回缩
                compressBack();
            }
        }
    }

    /// <summary>
    /// 碰撞检测
    /// </summary>
    /// <param name="collision"></param>
    private void OnCollisionEnter(Collision collision)
    {
        string tag = collision.gameObject.tag;
        var contacts = collision.contacts;
        Debug.Log(contacts.Length);//????????????????
        if (tag == "Ground")//落在地上
        {
            gameOver();
        }
        else if (tag == "cube0"&&isStart==true)//初始状态
        {
            isJump = true;
            isStart = false;//???????????????
            SpawnState();
          
        }
        else if(collision.gameObject== currentStage.gameObject)//落在旧的小方块上
        {
            //不作处理
            isJump = true;

        }
        else if (tag == "cube")//落在新的小方块上
        {
            isJump = true;
            if (contacts.Length == 1 && contacts[0].normal == Vector3.up)//若垂直落在了小方块上
            {
                //则更新
                currentStage = collision.gameObject;
                randomDirection();
                SpawnState();
                moveCamera();
            }
            else
            {
                gameOver();
            }
        }
    }
    /// <summary>
    /// player准备跳跃时压缩player和小木块
    /// </summary>
    void compress()
    {
        //盒子压缩
        if (currentStage.transform.localScale.y > 2f)//缩放范围 缩到2f就不缩了
        {
            currentStage.transform.localScale -= new Vector3(1, 1, 0) * 0.2f * Time.deltaTime;
            currentStage.transform.localPosition -= new Vector3(0, 1, 0) * 0.2f * Time.deltaTime;//竖直位置也要缩放,不然就悬空了
        }
        //玩家身体也压缩一下 头部和身体分别压缩
        playerHead.transform.localScale -= new Vector3(-1, 1, -1) * 0.2f * Time.deltaTime;
        playerBody.transform.localScale -= new Vector3(-1, 1, -1) * 0.2f * Time.deltaTime;
    }
    void compressBack()
    {
        currentStage.transform.DOLocalMoveY(1, 0.4f);//Y轴移动回原来的位置
        currentStage.transform.DOScale(new Vector3(8, 3, 8), 0.4f);//整体缩放回原来的位置

        playerHead.transform.DOScale(new Vector3(1, 1, 1), 0.4f);
        playerBody.transform.DOScale(new Vector3(1, 1, 1), 0.4f);
    }
    /// <summary>
    /// player跳起时的动作
    /// </summary>
    /// <param name="force"></param>
    void _onJump(float force)
    {
        //跳起的力大小是根据鼠标按下的时间长短决定的 即传过来的force
        _playerRB.AddForce(new Vector3(0, 10f, 0) +_direction* Speed*force,ForceMode.Impulse);
       //玩家跳起时沿世界坐标系z轴旋转-360
        transform.DOLocalRotate(new Vector3(0, 0, -360), 0.6f, RotateMode.LocalAxisAdd);
    }
    void randomDirection()
    {
        float seed = Random.Range(0, 2);
        _direction = seed == 0 ? new Vector3(1, 0, 0) : new Vector3(0, 0, 1);
        //改变小人的正方向 即将小人X轴对准将要前进的方向
        transform.right = _direction;
    }

    /// <summary>
    /// 生成一个小盒子
    /// </summary>
    void SpawnState()
    {
        GameObject prefab;
        if (boxPrefab.Length>0)//若预置体列表里面有东西
        {
            prefab = boxPrefab[Random.Range(0, boxPrefab.Length)];
        }
        else
        {
            prefab = currentStage;
        }

        GameObject stage = Instantiate(prefab);
        //改变大小
        float rangeSclate = Random.Range(0.8f, 1);
        stage.transform.localScale = new Vector3(prefab.transform.localScale.x*rangeSclate, prefab.transform.localScale.y, prefab.transform.localScale.z*rangeSclate);
        //改变位置
        stage.transform.position = currentStage.transform.position + _direction * Random.Range(13, 19);
        //改变颜色
        stage.GetComponent<Renderer>().material.color = new Color(Random.Range(0, 1f), Random.Range(0, 1f), Random.Range(0, 1f));
        
    }

   
    private void gameOver()
    {
        Debug.Log("游戏结束");
    }

    /// <summary>
    /// 移动摄像机
    /// </summary>
    void moveCamera()
    {
        Camera.main.transform.DOMove(transform.position + cameraLocation, 1);
    }
}

//原先的代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

public class PlayerMove : MonoBehaviour
{
    Rigidbody _playerRB;
    public float Speed=10f;
    public float startTime;
    public GameObject startStage;//开始阶段 的小方块
    public GameObject currentStage;//小方块 目前阶段

    public GameObject playerHead;
    public GameObject playerBody;

    Vector3 _direction=new Vector3(0,0,1);
    public GameObject[] boxPrefab;

    public bool isJump=true;

    //摄像机距离小人的位置差
    Vector3 cameraLocation;
    void Start()
    {
        currentStage = startStage;
        _playerRB = GetComponent<Rigidbody>();

        cameraLocation = Camera.main.transform.position - transform.position;
        //SpawnState();
        
    }
    void Update()
    {
        if (isJump == true)
        {
            if (Input.GetMouseButtonDown(0))
            {
                startTime = Time.time;        
            }
            if (Input.GetMouseButton(0))
            {
                //盒子压缩
                if (currentStage.transform.localScale.y > 2f)//缩放范围 缩到2f就不缩了
                {
                    currentStage.transform.localScale -= new Vector3(1, 1, 0) * 0.2f * Time.deltaTime;
                    currentStage.transform.localPosition -= new Vector3(0, 1, 0) * 0.2f * Time.deltaTime;//竖直位置也要缩放,不然就悬空了
                }
                //玩家身体也压缩一下 头部和身体分别压缩
                playerHead.transform.localScale -= new Vector3(-1, 1, -1) * 0.2f * Time.deltaTime;
                playerBody.transform.localScale -= new Vector3(-1, 1, -1) * 0.2f * Time.deltaTime;
            }
            if (Input.GetMouseButtonUp(0))
            {
                isJump = false;
                float endTime = Time.time - startTime;
                //  Debug.Log(endTime);
                _onJump(endTime);
                currentStage.transform.DOLocalMoveY(1, 0.4f);//Y轴移动回原来的位置
                currentStage.transform.DOScale(new Vector3(8, 3, 8), 0.4f);//整体缩放回原来的位置

                playerHead.transform.DOScale(new Vector3(1, 1, 1), 0.4f);
                playerBody.transform.DOScale(new Vector3(1, 1, 1), 0.4f);
            }
        }
        
    }
    
    //player跳起时的动作
    void _onJump(float force)
    {
        _playerRB.AddForce(new Vector3(0, 10f, 0) +_direction* Speed*force,ForceMode.Impulse);
        transform.DOLocalRotate(new Vector3(0, 0, -360), 0.6f, RotateMode.LocalAxisAdd);
    }
    void randomDirection()
    {
        float seed = Random.Range(0, 2);
        _direction = seed == 0 ? new Vector3(1, 0, 0) : new Vector3(0, 0, 1);
        //改变小人的正方向
        transform.right = _direction;
    }

    /// <summary>
    /// 生成一个小盒子
    /// </summary>
    void SpawnState()
    {
        GameObject prefab;
        if (boxPrefab.Length>0)//若预置体列表里面有东西
        {
            prefab = boxPrefab[Random.Range(0, boxPrefab.Length)];
        }
        else
        {
            prefab = currentStage;
        }

        GameObject stage = Instantiate(prefab);
        //改变大小
        float rangeSclate = Random.Range(0.8f, 1);
        stage.transform.localScale = new Vector3(prefab.transform.localScale.x*rangeSclate, prefab.transform.localScale.y, prefab.transform.localScale.z*rangeSclate);
        //改变位置
        stage.transform.position = currentStage.transform.position + _direction * Random.Range(13, 19);
        //改变颜色
        stage.GetComponent<Renderer>().material.color = new Color(Random.Range(0, 1f), Random.Range(0, 1f), Random.Range(0, 1f));
        
    }

    /// <summary>
    /// 碰撞检测
    /// </summary>
    /// <param name="collision"></param>
    private void OnCollisionEnter(Collision collision)
    {
        
        if (collision.collider.tag == "Ground")
        {
            gameOver();
        }
        else
        {
            isJump = true;
            //获取碰撞点
            Debug.Log(collision.gameObject.name);
           
            var contacts = collision.contacts;
            Debug.Log(contacts.Length);
            if (contacts.Length == 1 && contacts[0].normal == Vector3.up)//若垂直落在了小方块上
            {
                if (collision.gameObject != currentStage.gameObject || collision.gameObject == startStage.gameObject)//没有落在原来的方块上才能更新
                {
                    currentStage = collision.gameObject;
                    Debug.Log(true);
                    currentStage = collision.gameObject;
                    randomDirection();
                    SpawnState();
                    moveCamera();
                }  
            }
            else//若不是垂直落在了小方块上 例如斜着靠在了小方块上。。。
            {           
                    gameOver();     
            }
        }
    }
    private void gameOver()
    {
        Debug.Log("游戏结束");
    }

    /// <summary>
    /// 移动摄像机
    /// </summary>
    void moveCamera()
    {
        Camera.main.transform.DOMove(transform.position + cameraLocation, 1);
    }

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值