当前位置:   article > 正文

【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细)_unity跑酷游戏源码

unity跑酷游戏源码

需要源码和资源文件请点赞关注收藏后评论区留言私信~~~

下面我们将实现一个3D游戏 跑酷小子 类似于之前大火的神庙逃亡 效果展示和代码在文章末尾 下面为实现步骤

一、前期准备

在项目开始前 需要新建项目 将模型资源导入 模型资源存放在资源文件夹中

新建项目 注意选择3D模板 导入后如下图

ParkourDemoModel.unitypackage是主角模型资源 RoadModel.unitypackage是路段及障碍物模型资源 将这两个资源包依次导入 全部导入后目录结构如下

 

二、路段设置

 在Project视图中的Models->SimpleRoadwoek->Prefabs文件夹中 可以找到需要的各类模型,包括路面 路标 障碍物等等 接下来我们进行路段摆放

将路段拖入Scenes视图后 进行复制摆放到镜像位置,然后复制十次依次摆放形成路面 效果如下

接下来在路面上摆放装饰物,读者可以按照自己的想法摆放 接着做一面特殊的墙,用来检测玩家是否到达路段的中端,如果玩家到达路段中端,就切换路段,切换的逻辑会在后面实现

然后把上述资源全部放在一个对象下然后复制两次,并且设置另外两个对象的开始值,分别是50,0,0和100,0,0 这样总共有三条路段拼接在一起 

三、障碍物设置

只有路段 我们还需要在上面摆放障碍物来增加难度

读者可以自行根据喜好摆放 效果如下图

接着我们将障碍物拖入一个物体下面进行复制 跟上面路段的操作类似 复制到后面的路段上

 

四、主角设置

接下来就是最重要的主角设置,包括对模型的设置 动画切换 主角的移动和摄像机的跟随等等

 将主角模型直接拖入Scenes视图中即可,接着设置主角动画,在Project视图中右击 选择Create-

> Animator Control命令  新建一个动画控制器 把主角的动画控制逻辑弄好 如下图所示

接下来还要设置主角移动 主角死亡判定以及摄像机跟随等等业务逻辑 由于用代码控制 此处不再赘述

五、效果展示

 运行程序 3D游戏效果如下

可以看到场景十分逼真 读者可以根据自己喜好进行修改

 

 六、代码

部分代码如下

1

  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. public class Control_Scenes : MonoBehaviour
  4. {
  5. //是否到达第一段路
  6. bool m_ISFirst;
  7. //所有的路段对象
  8. public GameObject[] m_RoadArray;
  9. //障碍物数组对象
  10. public GameObject[] m_ObstacleArray;
  11. //障碍物的位置
  12. public List<Transform> m_ObstaclePosArray = new List<Transform>();
  13. void Start()
  14. {
  15. //游戏开始自动生成3组障碍物
  16. for (int i = 0; i < 3; i++)
  17. {
  18. Spawn_Obstacle(i);
  19. }
  20. }
  21. //根据传递的参数来决定切换那条路段
  22. public void Change_Road(int index)
  23. {
  24. //到达第一条路段不切换
  25. if (m_ISFirst && index == 0)
  26. {
  27. m_ISFirst = false;
  28. return;
  29. }
  30. else
  31. {
  32. int lastIndex = index - 1;
  33. if (lastIndex < 0)
  34. lastIndex = 2;
  35. //当前到达的路段的上一条路段进行切换,也就是说达到第二条路段,将第一条路段进行切换
  36. m_RoadArray[lastIndex].transform.position = m_RoadArray[lastIndex].transform.position + new Vector3(150, 0, 0);
  37. }
  38. }
  39. public void Spawn_Obstacle(int index)
  40. {
  41. //销毁原来的对象
  42. GameObject[] obsPast = GameObject.FindGameObjectsWithTag("Obstacle" + index);
  43. for (int i = 0; i < obsPast.Length; i++)
  44. {
  45. Destroy(obsPast[i]);
  46. }
  47. //生成障碍物 每个m_ObstaclePosArray对象中都存有三个坐标
  48. foreach (Transform item in m_ObstaclePosArray[index])
  49. {
  50. GameObject prefab = m_ObstacleArray[Random.Range(0, m_ObstacleArray.Length)];
  51. Vector3 eulerAngle = new Vector3(0, Random.Range(0, 360), 0);
  52. GameObject obj = Instantiate(prefab, item.position, Quaternion.Euler(eulerAngle));
  53. obj.tag = "Obstacle" + index;
  54. }
  55. }
  56. }

2

  1. using UnityEngine;
  2. public class Control_Player : MonoBehaviour
  3. {
  4. //前进速度
  5. public float m_ForwardSpeeed = 7.0f;
  6. //动画组件
  7. private Animator m_Anim;
  8. //动画现在状态
  9. private AnimatorStateInfo m_CurrentBaseState;
  10. //动画状态参照
  11. static int m_jumpState = Animator.StringToHash("Base Layer.jump");
  12. static int m_slideState = Animator.StringToHash("Base Layer.slide");
  13. void Start()
  14. {
  15. //获得主角身上的Animator组件
  16. m_Anim = GetComponent<Animator>();
  17. }
  18. void Update()
  19. {
  20. //主角向前跑
  21. transform.position += Vector3.right * m_ForwardSpeeed * Time.deltaTime;
  22. //获得现在播放的动画状态
  23. m_CurrentBaseState = m_Anim.GetCurrentAnimatorStateInfo(0);
  24. if (Input.GetKeyDown(KeyCode.W))
  25. {
  26. m_Anim.SetBool("jump", true);//切换跳状态
  27. }
  28. else if (Input.GetKeyDown(KeyCode.S))
  29. {
  30. m_Anim.SetBool("slide", true);//切换下滑状态
  31. }
  32. else if (Input.GetKeyDown(KeyCode.A))
  33. {
  34. Change_PlayerZ(true);//移动主角向左移动
  35. }
  36. else if (Input.GetKeyDown(KeyCode.D))
  37. {
  38. Change_PlayerZ(false);//移动主角向右移动
  39. }
  40. if (m_CurrentBaseState.fullPathHash == m_jumpState)
  41. {
  42. m_Anim.SetBool("jump", false);//改变动画状态
  43. }
  44. else if (m_CurrentBaseState.fullPathHash == m_slideState)
  45. {
  46. m_Anim.SetBool("slide", false);//改变动画状态
  47. }
  48. }
  49. public void Change_PlayerZ(bool IsAD)
  50. {
  51. if (IsAD)//当按下键盘的A 也就是向左移动
  52. {
  53. //主角在最左边
  54. if (transform.position.z == -5f)
  55. return;
  56. //主角在中间
  57. else if (transform.position.z == -10f)
  58. {
  59. transform.position = new Vector3(transform.position.x, transform.position.y, -5f);
  60. }
  61. //主角在最右边
  62. else
  63. {
  64. transform.position = new Vector3(transform.position.x, transform.position.y, -10f);
  65. }
  66. }
  67. else//当按下键盘的D 也就是向右移动
  68. {
  69. //主角在最右边
  70. if (transform.position.z == -15f)
  71. return;
  72. //主角在中间
  73. else if (transform.position.z == -10f)
  74. {
  75. transform.position = new Vector3(transform.position.x, transform.position.y, -15f);
  76. }
  77. //主角在最左边
  78. else
  79. {
  80. transform.position = new Vector3(transform.position.x, transform.position.y, -10f);
  81. }
  82. }
  83. }
  84. }

3

  1. using UnityEngine;
  2. using UnityEngine.SceneManagement;
  3. public class Control_Player : MonoBehaviour
  4. {
  5. //前进速度
  6. public float m_ForwardSpeeed = 7.0f;
  7. //动画组件
  8. private Animator m_Anim;
  9. //动画现在状态
  10. private AnimatorStateInfo m_CurrentBaseState;
  11. //动画状态参照
  12. static int m_jumpState = Animator.StringToHash("Base Layer.jump");
  13. static int m_slideState = Animator.StringToHash("Base Layer.slide");
  14. void Start()
  15. {
  16. //获得主角身上的Animator组件
  17. m_Anim = GetComponent<Animator>();
  18. }
  19. void Update()
  20. {
  21. //主角向前跑
  22. transform.position += Vector3.right * m_ForwardSpeeed * Time.deltaTime;
  23. //获得现在播放的动画状态
  24. m_CurrentBaseState = m_Anim.GetCurrentAnimatorStateInfo(0);
  25. if (Input.GetKeyDown(KeyCode.W))
  26. {
  27. m_Anim.SetBool("jump", true);//切换跳状态
  28. }
  29. else if (Input.GetKeyDown(KeyCode.S))
  30. {
  31. m_Anim.SetBool("slide", true);//切换下滑状态
  32. }
  33. else if (Input.GetKeyDown(KeyCode.A))
  34. {
  35. Change_PlayerZ(true);//移动主角向左移动
  36. }
  37. else if (Input.GetKeyDown(KeyCode.D))
  38. {
  39. Change_PlayerZ(false);//移动主角向右移动
  40. }
  41. if (m_CurrentBaseState.fullPathHash == m_jumpState)
  42. {
  43. m_Anim.SetBool("jump", false);//改变动画状态
  44. }
  45. else if (m_CurrentBaseState.fullPathHash == m_slideState)
  46. {
  47. m_Anim.SetBool("slide", false);//改变动画状态
  48. }
  49. if (m_IsEnd && Input.GetKeyDown(KeyCode.F1))
  50. {
  51. //重新开始游戏
  52. SceneManager.LoadScene(0);
  53. }
  54. }
  55. public void Change_PlayerZ(bool IsAD)
  56. {
  57. if (IsAD)//当按下键盘的A 也就是向左移动
  58. {
  59. //主角在最左边
  60. if (transform.position.z == -5f)
  61. return;
  62. //主角在中间
  63. else if (transform.position.z == -10f)
  64. {
  65. transform.position = new Vector3(transform.position.x, transform.position.y, -5f);
  66. }
  67. //主角在最右边
  68. else
  69. {
  70. transform.position = new Vector3(transform.position.x, transform.position.y, -10f);
  71. }
  72. }
  73. else//当按下键盘的D 也就是向右移动
  74. {
  75. //主角在最右边
  76. if (transform.position.z == -15f)
  77. return;
  78. //主角在中间
  79. else if (transform.position.z == -10f)
  80. {
  81. transform.position = new Vector3(transform.position.x, transform.position.y, -15f);
  82. }
  83. //主角在最左边
  84. else
  85. {
  86. transform.position = new Vector3(transform.position.x, transform.position.y, -10f);
  87. }
  88. }
  89. }
  90. //游戏结束
  91. bool m_IsEnd = false;
  92. void OnGUI()
  93. {
  94. if (m_IsEnd)
  95. {
  96. GUIStyle style = new GUIStyle();
  97. style.alignment = TextAnchor.MiddleCenter;
  98. style.fontSize = 40;
  99. style.normal.textColor = Color.red;
  100. GUI.Label(new Rect(Screen.width / 2 - 100, Screen.height / 2 - 50, 200, 100), "你输了~点击F1重新开始游戏", style);
  101. }
  102. }
  103. void OnTriggerEnter(Collider other)
  104. {
  105. //主角如果碰撞到障碍物
  106. if (other.gameObject.name == "Vehicle_DumpTruck" || other.gameObject.name == "Vehicle_MixerTruck")
  107. {
  108. m_IsEnd = true;
  109. m_ForwardSpeeed = 0;
  110. m_Anim.SetBool("idle", true);
  111. }
  112. }
  113. }

创作不易 觉得有帮助请点赞关注收藏~~~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/110791
推荐阅读
相关标签
  

闽ICP备14008679号