1. 程式人生 > >Unity3D獨立遊戲開發日記(二):擺放建築物

Unity3D獨立遊戲開發日記(二):擺放建築物

在沙盒遊戲裡,能自由建造是很重要的特點,比如說風靡全球的《我的世界》,用一個個方塊就能搭建出規模巨集大的世界。甚至有偏激的人說,沒有自由建造,就不是一個真正的沙盒遊戲。的確,沙盒遊戲的魅力有很大一部分是能自由構建一個遊戲世界。看著自己一磚一瓦搭建起一個城堡世界會很有成就感的。

現如今的手遊,大多數就是一個爭鬥和炫耀的世界。不管是傳奇類的狂霸拽酷,還是連連看,消消樂等好友排名,就是消費國人的虛榮心。其實,遊戲是第九藝術,要上升到藝術的角度。在遊戲裡,玩家需要一種情感的宣洩和寄託以及體驗。

說了這麼多,還是回到正題。我是如何在自己編寫的獨立遊戲《中世紀之路》裡實現建築物的擺放呢?

在實現這個功能的時候,我首先考慮的不是程式碼。而是考慮其他遊戲是如何實現這樣功能的,有那些可以借鑑的地方。我首先想到了《魔獸爭霸》裡建築物的擺放,可以自由的拖放。然後想到了《部落衝突》(簡稱COC)裡的建築放置方式,在COC裡建築是按格子擺放的,在一個平面上。

在我的遊戲《中世紀之路》裡,我既不想讓玩家一磚一瓦的搭建建築,又想讓玩家一下就把建築整體放置到地上了。我覺得像搭積木那樣,既可以節省玩家時間,又有建造的樂趣。選定了這種方式後,我就要考慮建築模組的資料儲存方式了:我需要儲存單個模組的三維空間裡的座標值(x,y,z的值),同時為了讓模型選擇,我還需要儲存模型的旋轉角度數。

然後,我還需要考慮如何用滑鼠去執行這個操作。我構想的方案是:點選揹包裡的物品後,一個模型就動態產生,然後跟隨滑鼠在地面移動。然後按"E"鍵就放置到地面上滑鼠所指的位置(E鍵放置,是我學《獸人必須死》得來的)。而元件的旋轉呢?我考慮的是讓滑鼠滾輪(也就是中鍵)滾動時,就繞著Y軸旋轉。當然如果更近一步,可以做到繞三個軸都能自由旋轉。具體操作見下圖:

建築擺放動畫

使用滑鼠放置篝火

通過上面的操作,我們可以看到程式碼的實現效果很好,完美達到了我們的需求。不過想通了上面的操作原理後,還需要我們動腦筋來構思,如何用程式碼來實現這些操作功能。這對新手來說可能過難了點,但對於有經驗的開發者就能比較快的找到近似的解決方案,然後加以改進。

我首先想到的是我曾經在手機上做過2D積木的搭建功能。把我們的操作動作拆解開來,無非就是三個步驟:

1.第一次按下手指或者滑鼠,找到初始座標,讓物體動態出現在座標位置上。

2.然後判斷移動情況,讓物體跟隨滑鼠或者手指的移動。

3.最後擡起手指或者滑鼠,讓物體固定在最後的座標位置,把座標資料寫入到文字或者資料庫裡。

想清楚了這三個步驟,我們就心裡底了,我們只要實現了這三步操作程式碼,基本上物體擺放功能就可以實現了。

在我實現第一個步驟的時候,我就遇到了個問題。我之前在寫搭積木遊戲的時候是2D的,座標很好獲取。但是在《中世紀之路》裡,我可是要獲取的是滑鼠在地面上的座標點啊。我開始用的是兩行程式碼:

Vector3 mousePosition= Input.mousePosition;    //獲取滑鼠所在的座標

Vector3 mouseWorldPosition =Camera.main.ScreenToWorldPoint(mousePosition) ; //把滑鼠的座標變成3D遊戲世界裡的空間座標

我以為我的思路是沒問題的,結果執行程式碼一看。哈哈,建築物完全不是擺在地面上的啊,是在空中的啊。後來查了相關文件才知道,這個滑鼠位置是滑鼠在螢幕這個立體面上的位置(你可以想象螢幕是一個透明的立體牆,這個牆是樹立在地面上的)。再說得專業點,是從主攝像機為起點,滑鼠所指為終點的一個射線,與螢幕所在立體面相交的點。對於這個立體面的直觀感覺,大家可以看看在3D空間裡2D UI介面所在的那個面。

所以,上面兩行程式碼是不能夠解決問題的。不過這麼一分析,我就接觸到了射線的概念。我轉念一想,如果我找到這個射線和地面相交的焦點不就行了嘛!我們的思路就變成了以下的虛擬碼:

1.建立一個從主攝像機為起點,滑鼠所指為終點的一個射線Ray。

2.找到Ray和地面Terrain的交點position。

3.把物體的座標動態創建於position。

核心程式碼如下:

if (Input.GetMouseButton(0))
 {
     Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

       RaycastHit hit;

       if(Physics.Raycast(ray, out hit))
       {

               if(hit.transform.name=="Terrain")
               {
                           position = hit.point;//得到與地面碰撞點的座標
               } 
        }
}

解決這個核心難題後,移動的程式碼就很好寫了。只要在手指或者滑鼠移動的時候,動態更新物體的座標為新的position就可以了。旋轉物體的程式碼也可以寫到一起,動態更新物體的旋轉度就可以了。這段程式碼很容易寫了,我就不貼出來了,新手可以鍛鍊自我動手能力。老手早就不用看在眼裡了。當然需要提醒的是這段程式碼是需要在update函式裡去執行的。

最後的固定物體座標的程式碼,也就演變成了把最後的position記錄於文字或者寫入資料庫了。這些程式碼都不是有多難寫的。

最後回顧下,我們整個解決問題的思路:

構思操作步驟和方式->分解操作步驟->用程式碼實現分解後的操作步驟->完善和修正程式碼

如果大家問我要整個程式碼,坦白的說:我覺得"授人於魚,不如授於漁"。大家能獲取正確解決問題的思路就夠了,然後記住核心程式碼就可以了。做程式設計師到一個“手中無劍,心中有劍”的境界就夠了。當然新手還是多練練劍,比劃比劃下招式。

PS:遊戲DEMO試玩群:198035671  Unity3d技術交流群:308185833  鬥魚遊戲開發直播地址:www.douyutv.com/unity3d

相關推薦

Unity3D獨立遊戲開發日記擺放建築物

在沙盒遊戲裡,能自由建造是很重要的特點,比如說風靡全球的《我的世界》,用一個個方塊就能搭建出規模巨集大的世界。甚至有偏激的人說,沒有自由建造,就不是一個真正的沙盒遊戲。的確,沙盒遊戲的魅力有很大一部分是能自由構建一個遊戲世界。看著自己一磚一瓦搭建起一個城堡世界會很有成就感的。 現如今的手遊,大多數就是一個爭

遊戲開發經驗談對戰類全球服遊戲的設計與實現

bbr tro 機房 產品 sql 服務器 通過 簡單 自己實現 上篇文章《遊戲開發經驗談(一):遊戲架構裏隱藏的五個坑及其應對方案》,我們主要講解了遊戲架構設計當中隱藏的一些坑及其應對方案,錯過的小夥伴可以點擊鏈接回溯之前的內容。本期內容,將會重點介紹對戰類全球服遊戲的設

塔防遊戲學習日記之朝敵人發射子彈

one for component targe instant .cn times code 至少   檢測到炮塔內敵人進入以後,當然下一步就是要向他們發射子彈。   接下來我們來做朝敵人發射子彈的相關操作。   分析一下,要向敵人發射子彈,需要有攻擊速度,簡單的計時器,子

LayIM.AspNetCore Middleware 開發日記預備知識介紹

Locator route ppk 我只 netcore blank req rop read 前言   開發一個AspNetCore的中間件需要理解RequestDelegate。另外,還需要理解.NET Core中的依賴註入。還有一個就是內嵌資源的訪問。例如:Embed

我的遊戲開發筆記Animator的運用

好了好了,上篇說到如何用程式碼來控制Animator裡的條件引數,話不多說,直接開始。 Animator m_Animator;m_Animator = GetComponent<Animator>(); m_Animator.SetBool("OnGround

ArcGIS Engine 系統開發設計開啟地圖文件、鷹眼圖的製作

首先是製作一個按鈕來負責開啟地圖文件: 在toolbox中選擇Button控制元件拖入我們的Form中,接下來在該button的Cilck事件中呼叫 OpenFileDialog類獲取檔案路徑後,  將檔案路徑呼叫到axMapControl1.LoadMxFil

網頁開發學習表格

一、表格 表格所涉及的標籤有“表格標籤”,“行標籤”和“單元格標籤”。 < table >…< /table >:表格標籤,表示一個表格的開始和結束。 < tr >…< /tr >:行標籤,成對出現,包含在表格標籤之間,有

Cris 學習Python日記條件判斷語句

1、if 語句和input 函式 # 條件判斷語句(if 語句) # 語法:if 條件表示式: # 程式碼塊 # 預設情況下,if 語句只會控制僅僅跟在後面的那條語句,如

JRtplib開發筆記JRtplib庫編譯、示例演示

原博主部落格地址:https://blog.csdn.net/qq21497936 本文章部落格地址:https://blog.csdn.net/qq21497936/article/details/84785593 《JRtplib開發筆記(一):JRtplib簡介、JThread庫編譯》

Java專案開發心得使用EhCache+SSM實現資料快取

在專案的開發過程中,經常會考慮到提高使用者訪問效率,降低伺服器的壓力,這個時候會用到資料快取。當前實現快取的技術有很多, 例如: jCache、Ehcache以及快取伺服器redis,redis作為分散式系統重要的組成部分,該技術的使用以及相關的一些問題會在後面的文章當中詳細介紹。

Cocos2D遊戲之旅主角血條的實現

血槽血量的變化是有兩個元素構成的: 1.血槽圖 2.紅色的進度條 當進度條的進度值不斷減少的時候,就產生血量減少的效果。 UI的佈局我採用了CocoStudio的UI編輯器,感覺不錯,挺容易上手的,如果需要相關資料的給我留言。繼續上圖~ 二、再說實現 bool HelloWorld::init()

Java企業級開發框架涉及的技術

基於:   JDK:1.8 Maven:3.3.9 Spring Boot 1.5.10.RELEASE spring-boot-starter-web 1.5.10.RELEASE (inherited from spring-boot-

【實戰】Unity3d實戰之Unity3d網路遊戲實戰篇6服務端框架的搭建

Unity3d實戰之Unity3d網路遊戲實戰篇(6):服務端框架的搭建 學習書籍《Unity3d網路遊戲實戰》 羅培羽著 機械工業出版社 本文是作者在學習過程中遇到的認為值得記錄的點,

FFmpeg開發實戰FFmpeg 文件操作

打開 重命名 har ffmpeg else 刪除 ext %d 操作 FFmpeg 提供了豐富的API供我們使用,下面我們來講述一下文件操作相關的API: FFmpeg 刪除文件:avpriv_io_delete() FFmpeg 重命名文件:avpriv_io_mov

快速開發框架SpringBoot-學習日記

第2章 Spring Boot重要用法 自定義異常頁面 在resources目錄中新建***public/error***目錄 在resources/public/error目錄新建自定義異常頁面,要求檔名稱必須為對應的狀態碼,副檔名為html

小米VR一體機遊戲開發日記第二天

unity裝了一個晚上終於裝完了,不知道為啥要裝個VS 2017,搞得我完全不知道入口在哪?在“程式”裡面找半天沒找到在哪裡開啟,後來在安裝資料夾裡找到了unity.exe,執行居然報錯,什麼“應用程式****報錯 ”之類的。百度了一下,缺了一些dll,在這個地方找到了,ht

Go遊戲伺服器開發的一些思考綜合考察

對Go做體檢 Go語言在遊戲伺服器方向的開發,起步比較晚。有必要考察下使用Go來實現,該怎麼去做,會遇到什麼問題,以及怎麼克服。這裡把使用Go語言開發MMO RPG遊戲作為考察物件,對Go做一次體檢。 MMO RPG最小功能清單 首先,羅列下開發一個M

網路遊戲《叢林戰爭》開發與學習之粘包分包現象以及服務端解析資料

1. 粘包和分包 粘包和分包是利用Socket在TCP協議下內部的優化機制。粘包指的是傳送資料比較頻繁,但資料量較少,此時客戶端不會直接將資料包傳送給伺服器,而是會與其它的資料包進行一個結合,例如遊戲中的位置資訊就是屬於頻繁傳送但資料量小的資訊,此時如果每條資料都S

Python遊戲伺服器開發日記skynet_messagequeue和skynet_timer

        最近,skynet群裡有同好與我一起討論skynet底層一些比較難理解的實現細節,乘此機會仔細看了一下原始碼,我最關心的是skynet_mq和skynet_timer兩個我會用到的部分。         本文不想討論太細節的問題,具體的實現思路我並沒有理的非

Unity3D開發NGUI之UIButton"禁用"狀態時置灰

NGUI中的Button幾乎是最常用到的控制元件之一,並且可以組合各種元件(比如UIButtonColor,UIButtonOffset,UITweenxx),方便設定Button的各種狀態下的屬性,幾乎可以滿足我們的所有需求。 但是對於當Button的isEnabled屬