Unity3D日常開發】(三)實現角色移動行走之跑酷游戲實現

      網友投稿 1244 2022-05-29

      推薦閱讀

      CSDN主頁

      GitHub開源地址

      Unity3D插件分享

      簡書地址

      我的個人博客

      QQ群:1040082875

      一、前言

      最近跑酷游戲比較流行,開發教程也很多,但是大部分都是不太詳細,這篇文章就帶著大家一步一步開發出來一個跑酷類的游戲,教程比較基礎,適合大部分Unity開發的初學者。

      還有就是,此專欄已經開通收費,里面整合的都是小游戲的開發教程,想要學習Unity開發游戲的,都可以訂閱一下。

      如果文章出現什么問題,就及時聯系我

      二、效果圖&下載鏈接

      Github地址:https://github.com/764424567/Game_Parkour

      三、教程

      在教程開始之前,我們分析一下跑酷類游戲制作思路。

      首先是道路和障礙物,我們可以先設置三段道路,然后障礙物隨機生成

      道路中間有抵達點,角色到達抵達點判斷是否將后面的道路移動到前面接起來。

      首先到達第一段的抵達點,肯定是不切換

      到達第二段的抵達點,將1號路段移動到最前面

      到達第三段的抵達點,將2號路段移動到最前面

      循環往復,無窮盡也

      然后是主角的移動腳本,躲避障礙物,移動位置固定三個點,可以跳,可以鏟地

      主角碰到障礙物就掛,游戲結束

      1、新建項目

      博主的Unity版本是Unity5.6.1f1,推薦大家使用我這個版本,或者其他的5.6.x版本,不然可能會出現各種各樣奇奇怪怪的問題。

      文件目錄的話就按照我這個目錄來,比較清晰明了。

      2、導入資源

      資源已經上傳到Github,需要的可以下載

      https://github.com/764424567/Unity-plugin/tree/master/Menu/Unity3D-ParkourDemoAssets

      3、處理動畫資源

      可以看到所有的動畫文件都有。

      接著我們就可以新建一個Animator Controller文件來管理動畫文件。

      命名隨意。

      接著我們將動畫剪輯拖到Animator處理面板中:

      默認狀態是run,然后有jump 、slide、idle

      接著就是“Take Transition”將run和jump 以及 run 、slide、idle連下線。

      設置兩個bool值,來控制動畫的切換:

      接下來我們就可以在場景中看一下動畫效果了:

      4、處理路段模型

      首先我們找到導入的資源SimpleRoadwork,里面有一個Demo場景,點進去可以看一下各類模型:

      在Prefabs文件夾中,可以找到我們需要的各類模型,包括路面、路標、障礙物:

      接下來,我們就設計一下路面:

      接著擺放路標:

      接著擺放障礙物:

      因為障礙物我們要后期自動生成,現在就可以先隱藏起來。

      然后設置到達點(到達點的目的是當角色到達這個位置的時候,自動切換路線):

      隱藏它的Mesh Renderer ,將BoxCollider IsTrigger設置成true:

      路段就完成了:

      整個目錄如下:

      不會擺放也沒有關系,我已經設置好了,用我的也行。

      5、主角模型處理

      明顯是有點大,我們給它同比例縮小一下:

      接著設置一下攝像機的視角:

      6、生成障礙物

      新建腳本Control_Scenes.cs

      我們首先來生成障礙物:

      using UnityEngine; public class Control_Scenes : MonoBehaviour { public GameObject[] m_ObstacleArray; public Transform[] m_ObstaclePosArray; void Start() { //因為要生成3段路段,所以生成的障礙物也是不同的,傳遞不同的下標生成不同的路段障礙物 Spawn_Obstacle(1); } //生成障礙物 public void Spawn_Obstacle(int index) { //銷毀原來的對象 GameObject[] obsPast = GameObject.FindGameObjectsWithTag("Obstacle" + index); for (int i = 0; i < obsPast.Length; i++) { Destroy(obsPast[i]); } //生成障礙物 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; } } }

      將腳本掛在Control_Scenes對象上:

      將Prefab文件夾里面的模型拖入到ObstacleArray對象數組卡槽中

      將隱藏以后的障礙物拖入到ObstaclePosArray對象數組卡槽中

      添加Tag:

      運行看一下:

      7、路段切換

      我們接著打開Control_Scenes.cs

      添加函數:

      bool m_ISFirst; public GameObject[] m_RoadArray; void Start() { //Spawn_Obstacle(1); Change_Road(1); } 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); Spawn_Obstacle(lastIndex); } }

      PS:這里解釋一下代碼,怎么切換的呢

      舉個例子,角色跑到了第二段,那么第一段要移動到第三段后面隔一個路段長度的距離,接下來畫個圖:

      那么為啥x軸減去150。這是因為我發現這三條路段的距離都差了50,坐標軸是負軸,所以就減去了150。

      我們可以測試一下效果:

      但是僅僅這樣是不夠的,我們還需要在角色到達抵達點的時候,切換路線,當然第一段路不用切換,因為再切就沒了。。

      這個在我們寫完角色移動以后再補充。

      8、角色移動

      新建腳本:Control_Player.cs

      說明一下:因為我們設定的三條道,所以角色只能在三條道里面切換。那么只需要改變角色的z值就可以了。如果角色在最左邊,那么只能往右移動,同理在最右邊,只能往左移動,在中間兩邊都可以移動。

      接著我們就可以看一下z軸的值:

      中間:

      左邊:

      右邊:

      代碼:

      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"); // Use this for initialization void Start() { m_Anim = GetComponent(); } // Update is called once per frame void Update() { transform.position += Vector3.left * 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) { if (transform.position.z == -14.7f) return; else if (transform.position.z == -9.69f) { transform.position = new Vector3(transform.position.x, transform.position.y, -14.7f); } else { transform.position = new Vector3(transform.position.x, transform.position.y, -9.69f); } } else { if (transform.position.z == -6.2f) return; else if (transform.position.z == -9.69f) { transform.position = new Vector3(transform.position.x, transform.position.y, -6.2f); } else { transform.position = new Vector3(transform.position.x, transform.position.y, -9.69f); } } } }

      鍵盤WSAD控制上跳,下滑,左右移動等操作。現在就可以去試試啦。

      【Unity3D日常開發】(三)實現角色移動行走之跑酷游戲實現

      但是,有一點哈,角色怎么越跑越遠離開了我們呢,因為,還沒有寫攝像機跟隨腳本,接下來繼續吧。

      9、攝像機跟隨

      新建腳本Control_Camera.cs

      using UnityEngine; public class Control_Camera : MonoBehaviour { //間隔距離 public float m_DistanceAway = 5f; //間隔高度 public float m_DistanceHeight = 10f; //平滑值 public float smooth = 2f; //目標點 private Vector3 m_TargetPosition; //參照點 Transform m_Follow; void Start() { m_Follow = GameObject.Find("Player").transform; } void LateUpdate() { m_TargetPosition = m_Follow.position + Vector3.up * m_DistanceHeight - m_Follow.forward * m_DistanceAway; transform.position = Vector3.Lerp(transform.position, m_TargetPosition, Time.deltaTime * smooth); } }

      OK 攝像機跟著Player跑起來了

      10、碰撞檢測

      我們需要不停的躲避障礙物,一旦碰撞到障礙物就dead了

      我們首先修改障礙物的碰撞器屬性:

      Mesh Collider : Is Trigger=true

      我們給Player加上剛體和碰撞體:

      注意要勾上Is Trigger

      打開Control_Player.cs腳本:

      //游戲結束 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), "你輸了~", 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); } }

      11、切換道路

      在第七章的時候就已經寫好了道路切換,但是一直沒有講到碰撞檢測,那么現在我們就結合碰撞檢測,檢測到抵達點然后切換道路吧

      我們首先找到三個抵達點:MonitorPos

      然后改名叫做MonitorPos0 MonitorPos1 MonitorPos2

      修改一下BoxCollider的Is Trigger屬性:

      修改Control_Player.cs的代碼:

      //場景控制對象 Control_Scenes m_ControlScenes; void Start() { m_Anim = GetComponent(); m_ControlScenes = GameObject.Find("Control_Scenes").GetComponent(); } 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); } if (other.gameObject.name == "MonitorPos0") { m_ControlScenes.Change_Road(0); } else if (other.gameObject.name == "MonitorPos1") { m_ControlScenes.Change_Road(1); } else if (other.gameObject.name == "MonitorPos2") { m_ControlScenes.Change_Road(2); } }

      5G游戲 unity

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:canvas炒雞簡單的貪吃蛇效果?υ? html+css+js
      下一篇:Java并發編程基礎之線程應用實戰-基于線程池的簡單web服務器
      相關文章
      亚洲精品美女在线观看播放| 亚洲一级黄色视频| 亚洲熟伦熟女新五十路熟妇| 亚洲精品国产av成拍色拍| 国产成人精品日本亚洲网址| 亚洲成人免费网站| 亚洲最大在线观看| 亚洲国产日韩在线成人蜜芽| 久久精品国产亚洲av高清漫画 | 国产亚洲欧洲精品| 伊人久久综在合线亚洲91| 久久久久国产成人精品亚洲午夜 | 亚洲国产aⅴ综合网| 在线观看亚洲精品专区| 国产亚洲综合久久| 亚洲国产午夜福利在线播放| 亚洲国产激情一区二区三区| 亚洲国产成人VA在线观看| 亚洲欧洲中文日韩av乱码| 中文字幕亚洲天堂| 国产精品亚洲一区二区三区在线 | 国产精品国产亚洲精品看不卡| 亚洲色中文字幕无码AV| 国产av无码专区亚洲av桃花庵| 亚洲VA中文字幕不卡无码| 亚洲激情在线视频| 亚洲视频在线观看视频| 亚洲av永久无码精品三区在线4| 亚洲综合色7777情网站777| 亚洲日韩av无码中文| 亚洲AV成人精品一区二区三区| 国产天堂亚洲国产碰碰| 亚洲国产一级在线观看| 国产亚洲视频在线播放| 久久精品国产亚洲av四虎| 亚洲精品456在线播放| 涩涩色中文综合亚洲| 精品国产亚洲一区二区三区在线观看 | 一本色道久久88亚洲精品综合 | 亚洲AV无码一区二区一二区| 亚洲国产成人精品久久久国产成人一区二区三区综|