Unity項目 - 坦克大戰3D TankBattle


目錄


游戲原型

- 游戲玩法:在有界的戰場上,玩家將駕駛坦克,代表綠色陣營,與你的隊友一起擊潰紅藍陣營的敵人,在這場三方大戰中奪得勝利! - 操作指南: - 移動:WASD - 開火:Space - 第一/第三人稱視角轉換:PgDn - 第三人稱下的視角轉動:← →

項目演示

![](https://img2018.cnblogs.com/blog/1688704/201907/1688704-20190727160643934-6854301.png)

Github項目地址:3D坦克大戰 TankBattle


繪圖資源

主要素材來源於官方[Tanks教程](https://learn.unity.com/project/tanks-tutorial)中的[Tanks!Tutorial素材包](https://assetstore.unity.com/packages/essentials/tutorial-projects/tanks-tutorial-46209)
  • 戰場搭建:直接使用素材包內的LevelArt即可,當然也可在此基礎上修改、擴展
  • 玩家
    • 物體:選用素材包內綠色坦克模型作為Player,除了模型外還包含子物體:發射點ShootPoint,第一人稱攝像機FirstCamera,血條畫布HealthCanvas
    • 組件/腳本掛載:AudioSource,Tank.cs,TankWeapon.cs
  • 敵人/隊友
    • 物體:除了模型外還包含子物體血條畫布HealthCanvas
    • 組件/腳本掛載:AudioSource,NavMeshAgent,AITank.cs,TankWeapon.cs
  • 相機:默認開局為第三人稱視角
    • ThirdCamera:采用Orthographic模式,作為TankCamera的子物體,在TankCamera掛載TankCamera.cs腳本進行控制
    • FirstCamera:采用Perspective模式,作為玩家坦克Player的子物體,調整適當位置及角度
  • 陣營
    • 創建Layer:Ground、Players、Blue、Green、Red,並對應設置
    • 將創建多個敵人歸並於各自陣營的空物體下,本例為BlueEnemy,RedEnemy,GreenEnemy
  • UI
    • 全局UI:建立Canvas,用於顯示屏幕左下角玩家血量,及左側操作指導,此外還包括死亡、勝利等UI
    • 坦克外圍血條UI:新建HealthCanvas,包含血量背景條Health Background及實時血條HealthSlider(素材均來自官方包內)。后將HealthCanvas設於各方坦克預制體下,調整合適大小、高度及顯示方式
  • 其他
    • 背景音樂:另設空物體BackGroundMusic添加AudioSource,開始時即循環播放
    • GameManager空物體:掛載GameManager.cs及全局UI的腳本UI.cs
    • 導航網絡烘培:Window->AI->navigation內設置
    • 坦克殘骸:另取坦克模型保留基本的物件,修改為灰暗色,修改BoxCollider保持間隔不相互碰撞,添加素材包內TankExplosion爆炸特效。死亡后實現爆沖力將各部件被沖散


代碼實現

腳本名 掛載於 功能
shell.cs 炮彈Shell預制體 實現發射的炮彈的爆炸(特效,沖擊力,銷毀炮彈)
TankWeapon.cs 所有坦克的預制體 實現坦克發射炮彈的過程(實例化炮彈,賦予初速度,開火聲,炮彈冷卻)
Tank.cs 玩家Player 實現玩家與坦克的交互(前后左右移動,空格開火)
TankCamera.cs TankCamera 實現第三人視角跟隨玩家坦克移動,且還進行第一/第三人稱視角的切換控制
Unit.cs 作為Tank.cs和AItank.cs的父類 實現所有坦克的基本屬性(陣營,血量,死亡爆炸特效,傷害計算)
AITank.cs 除玩家外的所有坦克預制體 實現npc坦克的功能(設置陣營、搜索敵人、自動導航、攻擊、自身血條UI)
UI.cs GameManager 實現主界面下玩家的血條UI及玩家坦克外圍的血條UI,勝利及失敗UI,此外還有勝利判定
LayerManager.cs 設置靜態方法供其他腳本調用 實現設置陣營(設置Layer)的函數
GameManager.cs GameManager 判定玩家是否死亡,若死亡則重置游戲

技術探討

**1.炮彈實現射出的方法**: - 賦予炮彈初速度:`ShellRigidbody.velocity = shootPoint.forward * shootPower;`,(本例方案) - 施加力:`ShellRigidbody.AddForce(shootPoint.forward * shootPower * 50f);`

2.開火時炮彈的實例化位置

  • 產生問題:運動中開火時,實例化的炮彈與自身碰撞
  • 問題分析:炮彈發射機理就是炮彈shell在炮口前一定位置實例化並賦予初速度,但是坦克也存在移動,因此假若距離較近,坦克移動速度較快時,容易造成實例化的炮彈立即與自身碰撞
  • 解決方案:需要留意位置調整、角度及坦克運動速度,本例實例化炮彈位置即為shootPoint的position

3.AI坦克對敵判定

  • 產生問題:原思路想采用射線檢測來判定前面一定范圍是否存在敵人,即if (hit.collider.gameObject.layer == enemy.layer),但現象是:敵人/隊友是否開火呈隨機發生,無規律
  • 問題分析:射線檢測到的一直是tank上的部件,而那些部件物體不是enemy,if不滿足無法進行射擊
  • 解決方案:在AITank.cs腳本內另設SearchEnemy()函數,功能是搜索返回距離自己最近的敵人;在Update內首先導航跟蹤這個敵人,然后判斷當這個搜索到的敵人在開火范圍內即可開火,否則重新SearchEnemy(),詳細描述見腳本內注釋

4.AI坦克導航

  • 產生問題:敵人及隊友坦克的NavMeshAgent導航混亂
  • 問題分析:很大原因在於導航網絡的烘培,及NavMeshAgent的參數設置
  • 解決方案:方法就是合理設置Navigation內的各項參數及NavMashAgent上的參數,也可直接采用官方教程視頻內的參數

5.第一人稱視角

  • 產生問題:玩家在第一人稱視角下被銷毀是報錯,第一人稱視角消失,再無法切換視角
  • 問題分析:FirstCamera掛載於Player,當玩家死亡時Player銷毀,造成FirstCamera的銷毀
  • 解決方案:在TankCamera.cs內添加判定,若玩家不存在則啟用第三人稱視角相機
  • 理想方案:兩個視角的相機都掛載在物體TankCamera上,統一由本腳本使用;FirstCamera不僅跟隨Player正常移動、旋轉,且不會在玩家死亡時銷毀;該方案暫未較好實現

參考來源

- [Unity3D坦克大戰項目實例 - TRULYSPINACH](https://www.bilibili.com/video/av7097738) - [Unity設置物體旋轉角度誤區 - feng](https://gameinstitute.qq.com/community/detail/121547) - [Unity3D中的Layers和LayerMask解析 - AaronBlogs](https://www.cnblogs.com/AaronBlogs/p/8260361.html) - [Unity3D射線碰撞檢測+LayerMask的使用 - 丁小未](https://blog.csdn.net/dingxiaowei2013/article/details/27107209) - [Tanks - unityLearn](https://learn.unity.com/project/tanks-tutorial) - [Tanks!Tutorial - unityAssetStore](https://assetstore.unity.com/packages/essentials/tutorial-projects/tanks-tutorial-46209)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM