【unity学习笔记】跑酷小游戏

1、需要的模型有玩家Player一名,一条跑道,若干障碍物
2、场景布置:
1)给跑道两侧加上空气墙
2)跑道靠近初始位置加个触发器当做此道路的抵达点(arrivePos)

在这里插入图片描述
3)给跑道某几个位置添加空物体,当做障碍物生成点 (bornPos)
在这里插入图片描述
3、然后就可以开始愉快的写代码了!
PS:具体关键知识点都在注释里,有时间再补充
1)首先需要玩家控制这一块的脚本,挂在玩家身上即可

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class moveController : MonoBehaviour {
    // 摄像机位置
    public Transform cameraTransform;
    // 摄像机距离人物的距离
    public float cameraDistance;
    // 游戏管理器
    public GameManager gameManager;
    // 前进移动速度
    float moveVSpeed;
    // 水平移动速度
    public float moveHSpeed = 5.0f;
    // 跳跃高度
    public float jumpHeight = 5.0f;
    // 动画播放器
    Animator m_animator;
    // 起跳时间
    double m_jumpBeginTime;
    // 跳跃标志
    int m_jumpState = 0;
    // 最大速度
    public float maxVSpeed = 8.0f;
    // 最小速度
    public float minVSpeed = 5.0f;

    // Use this for initialization
    void Start () {
        //使player碰撞时角度不会改变
        GetComponent<Rigidbody>().freezeRotation = true;
        m_animator = GetComponent<Animator>();
        if (m_animator == null)
            print("null");
        moveVSpeed = minVSpeed;
    }
	void Update () {
        // 游戏结束
        if (gameManager.isEnd)
        {
            return;
        }
        AnimatorStateInfo stateInfo = m_animator.GetCurrentAnimatorStateInfo(0);
        if (stateInfo.fullPathHash == Animator.StringToHash("Base Layer.run"))
        {
            //若player在跑的话,跳跃状态即为false
            m_jumpState = 0;
            if (Input.GetButton("Jump"))
            {
                // 起跳,开始执行跳跃动作
                m_animator.SetBool("Jump", true);
            }
            else
            {
                // 到地面
            }
        }
        //若正在执行跳跃动画
        else
        {
            // 掉下
            m_jumpState = 1;
            m_animator.SetBool("Jump", false);
        }
        //不按下时默认为0
        float h = Input.GetAxis("Horizontal");
        //this.transform.forward=(1,0,0)即向前,蓝色的轴
        Vector3 vSpeed = new Vector3(this.transform.forward.x, this.transform.forward.y, this.transform.forward.z) * moveVSpeed ;
        //this.transform.right=(0,0,-1) 向右,红色的轴
        Vector3 hSpeed = new Vector3(this.transform.right.x, this.transform.right.y, this.transform.right.z) * moveHSpeed * h;
        //this.transform.up=(0,1,0) 向上,绿色的轴
        Vector3 jumpSpeed = new Vector3(this.transform.up.x, this.transform.up.y, this.transform.up.z) * jumpHeight * m_jumpState;
        //此摄像机按X轴向前移动
        Vector3 vCameraSpeed = new Vector3(this.transform.forward.x, this.transform.forward.y, this.transform.forward.z) * minVSpeed;
        this.transform.position += (vSpeed + hSpeed + jumpSpeed) * Time.deltaTime;
        cameraTransform.position += (vCameraSpeed) * Time.deltaTime;

        //使player与摄像机的位置一直保持距离为:cameraDistance
        // 当人物与摄像机距离小于cameraDistance时 让其加速
        if (this.transform.position.x - cameraTransform.position.x < cameraDistance)
        {
            moveVSpeed += 0.1f;
            if (moveVSpeed > maxVSpeed)
            {
                moveVSpeed = maxVSpeed;
            }
        }
        // 超过时 让摄像机赶上
        else if(this.transform.position.x - cameraTransform.position.x > cameraDistance)
        {
            moveVSpeed = minVSpeed;
            cameraTransform.position = new Vector3(this.transform.position.x - cameraDistance, cameraTransform.position.y, cameraTransform.position.z);
        }
        // 摄像机超过人物
        if(cameraTransform.position.x - this.transform.position.x > 0.0001f)
        {
            Debug.Log("你输啦!!!!!!!!!!");
            gameManager.isEnd = true;
        }
    }

    void OnTriggerEnter(Collider other)
    {
        // 每条道路抵达点碰撞检测
        if (other.name.Equals("ArrivePos"))
        {
            //加载一条新的道路
            gameManager.changeRoad(other.transform);
         
        }

    }
}

2)还需要一个游戏状态机

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class GameManager : MonoBehaviour {
    // 生成障碍物点列表 
    public List<Transform> bornPosList = new List<Transform>();
    // 道路列表  三条道路的 transform
    public List<Transform> roadList = new List<Transform>();
    // 抵达点列表
    public List<Transform> arrivePosList = new List<Transform>();
    // 障碍物预置体列表
    public List<GameObject> objPrefabList = new List<GameObject>();
    // 目前的障碍物 字典类型,道路名称:此道路上的障碍物列表
    Dictionary<string, List<GameObject>> objDict = new Dictionary<string, List<GameObject>>();
    //道路距离
    public int roadDistance;
    //游戏状态
    public bool isEnd = false;
	// Use this for initialization
	void Start () {

        foreach(Transform road in roadList)
        {
            List<GameObject> objList = new List<GameObject>();
            //每条道路的名字:一个空障碍物列表,赋值给objDict
            objDict.Add(road.name, objList);  
        }
        //初始状态先更新道路0和道路1
        initRoad(0);
        initRoad(1);
    }
	// Update is called once per frame
	void Update () {
	
	}
    // 切出新的道路
    public void changeRoad(Transform arrivePos)
    {
        //获取arrivePos的index,此时的index是上一条道路的
        int index = arrivePosList.IndexOf(arrivePos);
        //Debug.Log(index);
        if (index >= 0)
        {
            //获取前一条道路的index
            int lastIndex = (index + roadList.Count - 1)% roadList.Count;
            //获取后一条道路的index
            int nextIndex= (index + 1) % roadList.Count;
            //则,我们需要把后一条道路的位置,变为前一条道路.位置+道路长度 完成道路更新   (因为就三条路,其实就是把后一条道路更新在最前面就行了)
            roadList[lastIndex].position = roadList[nextIndex].position + new Vector3(roadDistance, 0, 0);
            //再更新一下刚改变了位置的道路上的障碍物
            initRoad(lastIndex); 
        }
        else
        {
            Debug.LogError("arrivePos index is error");
            return;
        }
    }
    void initRoad(int index)
    {
        string roadName = roadList[index].name;
        // 清空已有障碍物
        foreach(GameObject obj in objDict[roadName])
        {
            Destroy(obj);
        }
        objDict[roadName].Clear();

        // ******************添加障碍物***************//
        //遍历索引为index的预制体指定生成位置
        foreach(Transform pos in bornPosList[index])
        {
            //随机生成一个障碍物prefab     Random.Range(min,max)
            GameObject prefab = objPrefabList[Random.Range(0, objPrefabList.Count)];
            //给prefab随机生成一个新角度
            Vector3 eulerAngle = new Vector3(0, Random.Range(0, 360), 0);

            GameObject obj = Instantiate(prefab, pos.position, Quaternion.Euler(eulerAngle)) as GameObject;
            obj.tag = "Obstacle";
            objDict[roadName].Add(obj);
        }
    }
}

3)同时,也需要在控制面板上把脚本里需要的引用拖过去
在这里插入图片描述
然后就完成啦~~~~

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值