赞
踩
需要源码和资源文件请点赞关注收藏后评论区留言私信~~~
下面我们将实现一个3D游戏 跑酷小子 类似于之前大火的神庙逃亡 效果展示和代码在文章末尾 下面为实现步骤
在项目开始前 需要新建项目 将模型资源导入 模型资源存放在资源文件夹中
新建项目 注意选择3D模板 导入后如下图
ParkourDemoModel.unitypackage是主角模型资源 RoadModel.unitypackage是路段及障碍物模型资源 将这两个资源包依次导入 全部导入后目录结构如下
在Project视图中的Models->SimpleRoadwoek->Prefabs文件夹中 可以找到需要的各类模型,包括路面 路标 障碍物等等 接下来我们进行路段摆放
将路段拖入Scenes视图后 进行复制摆放到镜像位置,然后复制十次依次摆放形成路面 效果如下
接下来在路面上摆放装饰物,读者可以按照自己的想法摆放 接着做一面特殊的墙,用来检测玩家是否到达路段的中端,如果玩家到达路段中端,就切换路段,切换的逻辑会在后面实现
然后把上述资源全部放在一个对象下然后复制两次,并且设置另外两个对象的开始值,分别是50,0,0和100,0,0 这样总共有三条路段拼接在一起
只有路段 我们还需要在上面摆放障碍物来增加难度
读者可以自行根据喜好摆放 效果如下图
接着我们将障碍物拖入一个物体下面进行复制 跟上面路段的操作类似 复制到后面的路段上
接下来就是最重要的主角设置,包括对模型的设置 动画切换 主角的移动和摄像机的跟随等等
将主角模型直接拖入Scenes视图中即可,接着设置主角动画,在Project视图中右击 选择Create-
> Animator Control命令 新建一个动画控制器 把主角的动画控制逻辑弄好 如下图所示
接下来还要设置主角移动 主角死亡判定以及摄像机跟随等等业务逻辑 由于用代码控制 此处不再赘述
运行程序 3D游戏效果如下
可以看到场景十分逼真 读者可以根据自己喜好进行修改
部分代码如下
1
- using System.Collections.Generic;
- using UnityEngine;
-
- public class Control_Scenes : MonoBehaviour
- {
- //是否到达第一段路
- bool m_ISFirst;
- //所有的路段对象
- public GameObject[] m_RoadArray;
- //障碍物数组对象
- public GameObject[] m_ObstacleArray;
- //障碍物的位置
- public List<Transform> m_ObstaclePosArray = new List<Transform>();
-
- void Start()
- {
- //游戏开始自动生成3组障碍物
- for (int i = 0; i < 3; i++)
- {
- Spawn_Obstacle(i);
- }
- }
-
- //根据传递的参数来决定切换那条路段
- public void Change_Road(int index)
- {
- //到达第一条路段不切换
- if (m_ISFirst && index == 0)
- {
- m_ISFirst = false;
- return;
- }
- else
- {
- int lastIndex = index - 1;
- if (lastIndex < 0)
- lastIndex = 2;
- //当前到达的路段的上一条路段进行切换,也就是说达到第二条路段,将第一条路段进行切换
- m_RoadArray[lastIndex].transform.position = m_RoadArray[lastIndex].transform.position + new Vector3(150, 0, 0);
- }
- }
-
- public void Spawn_Obstacle(int index)
- {
- //销毁原来的对象
- GameObject[] obsPast = GameObject.FindGameObjectsWithTag("Obstacle" + index);
- for (int i = 0; i < obsPast.Length; i++)
- {
- Destroy(obsPast[i]);
- }
- //生成障碍物 每个m_ObstaclePosArray对象中都存有三个坐标
- foreach (Transform item in m_ObstaclePosArray[index])
- {
- GameObject prefab = m_ObstacleArray[Random.Range(0, m_ObstacleArray.Length)];
- Vector3 eulerAngle = new Vector3(0, Random.Range(0, 360), 0);
- GameObject obj = Instantiate(prefab, item.position, Quaternion.Euler(eulerAngle));
- obj.tag = "Obstacle" + index;
- }
- }
- }
2
- using UnityEngine;
- public class Control_Player : MonoBehaviour
- {
- //前进速度
- public float m_ForwardSpeeed = 7.0f;
- //动画组件
- private Animator m_Anim;
- //动画现在状态
- private AnimatorStateInfo m_CurrentBaseState;
-
- //动画状态参照
- static int m_jumpState = Animator.StringToHash("Base Layer.jump");
- static int m_slideState = Animator.StringToHash("Base Layer.slide");
-
- void Start()
- {
- //获得主角身上的Animator组件
- m_Anim = GetComponent<Animator>();
- }
-
- void Update()
- {
- //主角向前跑
- transform.position += Vector3.right * m_ForwardSpeeed * Time.deltaTime;
- //获得现在播放的动画状态
- m_CurrentBaseState = m_Anim.GetCurrentAnimatorStateInfo(0);
- if (Input.GetKeyDown(KeyCode.W))
- {
- m_Anim.SetBool("jump", true);//切换跳状态
- }
- else if (Input.GetKeyDown(KeyCode.S))
- {
- m_Anim.SetBool("slide", true);//切换下滑状态
- }
- else if (Input.GetKeyDown(KeyCode.A))
- {
- Change_PlayerZ(true);//移动主角向左移动
- }
- else if (Input.GetKeyDown(KeyCode.D))
- {
- Change_PlayerZ(false);//移动主角向右移动
- }
- if (m_CurrentBaseState.fullPathHash == m_jumpState)
- {
- m_Anim.SetBool("jump", false);//改变动画状态
- }
- else if (m_CurrentBaseState.fullPathHash == m_slideState)
- {
- m_Anim.SetBool("slide", false);//改变动画状态
- }
- }
-
- public void Change_PlayerZ(bool IsAD)
- {
- if (IsAD)//当按下键盘的A 也就是向左移动
- {
- //主角在最左边
- if (transform.position.z == -5f)
- return;
- //主角在中间
- else if (transform.position.z == -10f)
- {
- transform.position = new Vector3(transform.position.x, transform.position.y, -5f);
- }
- //主角在最右边
- else
- {
- transform.position = new Vector3(transform.position.x, transform.position.y, -10f);
- }
- }
- else//当按下键盘的D 也就是向右移动
- {
- //主角在最右边
- if (transform.position.z == -15f)
- return;
- //主角在中间
- else if (transform.position.z == -10f)
- {
- transform.position = new Vector3(transform.position.x, transform.position.y, -15f);
- }
- //主角在最左边
- else
- {
- transform.position = new Vector3(transform.position.x, transform.position.y, -10f);
- }
- }
- }
- }
3
- using UnityEngine;
- using UnityEngine.SceneManagement;
-
- public class Control_Player : MonoBehaviour
- {
- //前进速度
- public float m_ForwardSpeeed = 7.0f;
- //动画组件
- private Animator m_Anim;
- //动画现在状态
- private AnimatorStateInfo m_CurrentBaseState;
-
- //动画状态参照
- static int m_jumpState = Animator.StringToHash("Base Layer.jump");
- static int m_slideState = Animator.StringToHash("Base Layer.slide");
-
- void Start()
- {
- //获得主角身上的Animator组件
- m_Anim = GetComponent<Animator>();
- }
-
- void Update()
- {
- //主角向前跑
- transform.position += Vector3.right * m_ForwardSpeeed * Time.deltaTime;
- //获得现在播放的动画状态
- m_CurrentBaseState = m_Anim.GetCurrentAnimatorStateInfo(0);
- if (Input.GetKeyDown(KeyCode.W))
- {
- m_Anim.SetBool("jump", true);//切换跳状态
- }
- else if (Input.GetKeyDown(KeyCode.S))
- {
- m_Anim.SetBool("slide", true);//切换下滑状态
- }
- else if (Input.GetKeyDown(KeyCode.A))
- {
- Change_PlayerZ(true);//移动主角向左移动
- }
- else if (Input.GetKeyDown(KeyCode.D))
- {
- Change_PlayerZ(false);//移动主角向右移动
- }
- if (m_CurrentBaseState.fullPathHash == m_jumpState)
- {
- m_Anim.SetBool("jump", false);//改变动画状态
- }
- else if (m_CurrentBaseState.fullPathHash == m_slideState)
- {
- m_Anim.SetBool("slide", false);//改变动画状态
- }
- if (m_IsEnd && Input.GetKeyDown(KeyCode.F1))
- {
- //重新开始游戏
- SceneManager.LoadScene(0);
- }
- }
-
- public void Change_PlayerZ(bool IsAD)
- {
- if (IsAD)//当按下键盘的A 也就是向左移动
- {
- //主角在最左边
- if (transform.position.z == -5f)
- return;
- //主角在中间
- else if (transform.position.z == -10f)
- {
- transform.position = new Vector3(transform.position.x, transform.position.y, -5f);
- }
- //主角在最右边
- else
- {
- transform.position = new Vector3(transform.position.x, transform.position.y, -10f);
- }
- }
- else//当按下键盘的D 也就是向右移动
- {
- //主角在最右边
- if (transform.position.z == -15f)
- return;
- //主角在中间
- else if (transform.position.z == -10f)
- {
- transform.position = new Vector3(transform.position.x, transform.position.y, -15f);
- }
- //主角在最左边
- else
- {
- transform.position = new Vector3(transform.position.x, transform.position.y, -10f);
- }
- }
- }
-
- //游戏结束
- bool m_IsEnd = false;
- void OnGUI()
- {
- if (m_IsEnd)
- {
- GUIStyle style = new GUIStyle();
- style.alignment = TextAnchor.MiddleCenter;
- style.fontSize = 40;
- style.normal.textColor = Color.red;
- GUI.Label(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 50, 200, 100), "你输了~点击F1重新开始游戏", style);
- }
- }
- void OnTriggerEnter(Collider other)
- {
- //主角如果碰撞到障碍物
- if (other.gameObject.name == "Vehicle_DumpTruck" || other.gameObject.name == "Vehicle_MixerTruck")
- {
- m_IsEnd = true;
- m_ForwardSpeeed = 0;
- m_Anim.SetBool("idle", true);
- }
- }
- }
创作不易 觉得有帮助请点赞关注收藏~~~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。