Unity3D遊戲開發從零單排(七),unity3d遊戲開發
提要
今天做了一個行動裝置的網路通訊demo,分兩個部分,一個是網路連接,一個是資料通訊。
需要兩台Android裝置A,B。A作用戶端,B作服務端。
最終的效果是玩家控制裝置A中的方塊,B中的方塊也一起動,同時在A的加速度感應器的資訊在B中也即時更新。
網路連接
首先兩台裝置要連網,且IP在同一個網段,比如串連在同一個路由上,或者通過筆記本發出wifi訊號,然後把裝置連在上面。
在Unity3d中建立一個新工程,在情境中建立兩個空物體,一個Client,一個Server。
在client建立一個指令碼client.cs
using UnityEngine;using System.Collections;public class client : MonoBehaviour { private string IP = "10.66.208.191"; private string clientIp; private string clientIpSplite; private Vector3 acceleration; public GameObject cube; private bool cubeInitialed = false; //Connet port private int Port = 10000; void Awake() { clientIp = Network.player.ipAddress; string[] tmpArray = clientIp.Split('.'); clientIpSplite = tmpArray[0] + "." + tmpArray[1] + "." + tmpArray[2] + "."; } void OnGUI() { switch (Network.peerType) { case NetworkPeerType.Disconnected: StartConnect(); break; case NetworkPeerType.Server: break; case NetworkPeerType.Client: OnConnect(); break; case NetworkPeerType.Connecting: break; } } void StartConnect() { if (GUILayout.Button("Connect Server")) { NetworkConnectionError error = Network.Connect(IP, Port); Debug.Log("connect status:" + error); } } void OnConnect() { if(!cubeInitialed) { Network.Instantiate(cube, transform.position, transform.rotation, 0); cubeInitialed = true; } }}
用戶端根據當前當前的狀態來執行相應的動作。StartConnect負責串連,用到了
static NetworkConnectionError Connect(string[] IPs, int remotePort)
第一個參數是Ip,第二個參數是連接埠。
串連上之後調用OnConnect函數初始化一個方塊。注意這個方塊是在用戶端初始化的,屬於這個用戶端,建立成功之後會在其他的一桶串連的裝置上都執行個體化一個cube出來,但是只有在這個client上NetworkView.isMine才為true。
接下來是服務端的代碼。
using UnityEngine;using System.Collections;public class server : MonoBehaviour { private int serverPort; public GUIText status; void Awake() { serverPort = 10000; } //OnGUI方法,所有GUI的繪製都需要在這個方法中實現 void OnGUI() { //Network.peerType是端類型的狀態: //即disconnected, connecting, server 或 client四種 switch (Network.peerType) { //禁止用戶端串連運行, 伺服器未初始化 case NetworkPeerType.Disconnected: StartServer(); break; //運行於伺服器端 case NetworkPeerType.Server: OnServer(); break; //運行於用戶端 case NetworkPeerType.Client: break; //正在嘗試串連到伺服器 case NetworkPeerType.Connecting: break; } GUILayout.Label(Network.player.ipAddress); } void StartServer() { //當使用者點擊按鈕的時候為true if (GUILayout.Button("建立伺服器")) { //初始化本機伺服器連接埠,第一個參數就是本機接收多少串連 NetworkConnectionError error = Network.InitializeServer(12, serverPort, false); Debug.Log("錯誤記錄檔" + error); } } void OnServer() { GUILayout.Label("服務端已經運行,等待用戶端串連"); int length = Network.connections.Length; for(int i = 0; i < length; i++) { GUILayout.Label("用戶端" + i); GUILayout.Label("用戶端ip" + Network.connections[i].ipAddress); GUILayout.Label("用戶端連接埠" + Network.connections[i].port); } } void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info){ // Always send transform (depending on reliability of the network view) if (stream.isWriting) { Vector3 pos = transform.localPosition; Quaternion rot = transform.localRotation; stream.Serialize(ref pos); stream.Serialize(ref rot); } // When receiving, buffer the information else { // Receive latest state information Vector3 pos = Vector3.zero; Quaternion rot = Quaternion.identity; stream.Serialize(ref pos); stream.Serialize(ref rot); }}}
點擊螢幕上的建立伺服器之後就在裝置上建立了一個服務端,監聽對應的連接埠,當有其他裝置串連上來的時間,用戶端的資訊就會列印出來,可以支援多個裝置的串連。
還要建立一個cube的prefab,用於動態建立。
CubeController用於控制方塊的運動,NetWorkView用於資料通訊。
資料通訊
需要進行資料通訊的GameObject都要添加一個NetworkView 組件,資料通訊有兩種方式,狀態同步和RPC(遠端程序呼叫)。在CubeController.cs中,兩種方法都有用到。
using UnityEngine;using System.Collections;public class CubeController : MonoBehaviour { private GUIText accelText; void Start() { accelText = GameObject.FindGameObjectWithTag("AccelTip").GetComponent<GUIText>() as GUIText; accelText.text = ""; } void Update() { if(Network.isClient) { Vector3 acceleration = Input.acceleration; accelText.text = "" + acceleration; networkView.RPC("UpdateAcceleration", RPCMode.Others, acceleration); } Vector3 moveDir = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); Vector3 cubescreenPos = Camera.main.WorldToScreenPoint(transform.position); if (Input.GetMouseButton(0)) { moveDir = new Vector3(Input.mousePosition.x - cubescreenPos.x, Input.mousePosition.y - cubescreenPos.y, 0f).normalized; } Debug.Log("moveDir: " + moveDir); float speed = 5; transform.Translate(speed * moveDir * Time.deltaTime); } void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info) { if (stream.isWriting) { Vector3 pos = transform.position; stream.Serialize(ref pos); } else { Vector3 receivedPosition = Vector3.zero; stream.Serialize(ref receivedPosition); transform.position = receivedPosition; } } [RPC] void UpdateAcceleration(Vector3 acceleration) { accelText.text = "" + acceleration; }}
function OnSerializeNetworkView(stream : BitStream, info : NetworkMessageInfo) {}
這是在Network class中提供的一個func. 主要負責message sent / receive,他會同步被network view所關注的script中的對象,也就是當你寫了一個script內含OnSerializeNetworkView(){},並且丟到observed屬性中,則OnSerializeNetworkView()裡的code就會開始運作。基本上他透過BitStream物件收髮網路上的資訊,使用上不需要瞭解封包的問題,也不需要知道如何切割封包。在這的demo中,服務端只負責接收資訊,所以只執行else後面的代碼,用戶端發送資訊,執行if後面的代碼。
這裡cube的state synchronization選的是Unreliable,對應的通訊協議是UDP,特點是無串連,比較快。
RPC典型的應用情境就是聊天室,使用也非常簡單,首先定義一個rpc函數在(在上面加上[RPC]),然後通過NetWork.RPC來調用就可以了。這裡是把用戶端重力感應器的資料傳了出去,在介面上更新。
參考
unity3D的網路資料傳輸 & 角色控制 - http://ppb440219.blogspot.com/2011/12/unity3d.html
網路視圖 Network View - http://game.ceeger.com/Components/class-NetworkView.html
遠端程序呼叫的細節 RPC Details - http://game.ceeger.com/Components/net-RPCDetails.html
狀態同步的細節 State Synchronization Detailshttp://game.ceeger.com/Components/net-StateSynchronization.html
Unity Networking Tutorial - http://www.palladiumgames.net/tutorials/unity-networking-tutorial/
新手問點遊戲開發順便問點unity3D的問題
如果你真的想做,就要從零開始,從最基礎的開始。現在網上有幾個視頻說學了U3D倆月就做出看上去不錯的,其實都是外掛程式堆出來的,這種方式看似快成,但基本沒什麼用,只是滿足下虛榮心而已,一個只有情境沒有互動的東西能算什麼呢?
反正我是從零開始的,到現在差不多半年了,感覺最難的是編程,因為以前根本就沒接觸過,而對於模型材質什麼的倒是有點基礎。現在的大部分時間都用在了學習編程上,因為這方面是沒法繞開的,雖然現在有款外掛程式playMaker說是可以沒有編程經驗就可以做遊戲,但感覺並不順手,不過如果不想學編程的話可以試試
而對於編程,unity常用的是Javascript和C#,雖然說javascript易學,但Unity的javascript並不是標準的,而是其特有的UnityScript,但現在並沒有系統的UnityScript教材,所以在我看來並不容易學。但我現在還是在啃UnityScript,因為一開始就是學的這個,想學通學精再換C#。如果你想學的話,建議C#,但我不知道unity的c#和標準c#是不是一樣,這方面你可以再做決定
對於untiy是不是適於個人開發,可以看下 康拓耶夫 的視頻,裡面有unity和其他幾個引擎的對比,其中就有大名鼎鼎的虛幻等引擎
你說用兩年做出來,感覺還是靠譜的,但第一年還是啃基礎吧,而即使基礎打好了,也不要急於做大型的遊戲,做些小遊戲試手。
而對於是不是能做出來,我用unity的原因之一是魔獸爭霸的地圖編輯器,雖然我沒編過地圖,但既然編輯器能做出dota那樣經典的東西,unity難道就不行嗎?順道說一句,知道dota但並沒玩過,澄海倒是玩了一段時間,相對於dota,我更喜歡比如浩方平台上的其他魔獸小遊戲,比如前段時間較火的路人三國,還有乏人問津的兔羊之戰等等。而魔獸爭霸戰役也有高水平的,比如血色使命,可稱國內最高,而開放模式的逆流之戰,可以當做網遊來玩
此外,並不是所有的東西都要自己做,比如模型,在Outfit7的開發中,用到的第一個模型是從某網站買的。而如果某個外掛程式很利於遊戲製作,不妨使用,但最開始還是建議從基礎開始,外掛程式是用來提高效率的
現在國內較活躍的論壇是 unity聖典game.ceeger.com/forum/,前幾天把所有資源設為免費下載了,但昨天115下載出了問題,很多東西不能下載了,殘念
其他的比如天地會、cocochina等都是子版塊,活躍度不是很高,unity3d8也不錯,但很多資源需要較進階別才能下載
對於人物是2D還是3D,只是一種變換,所謂2D,是播放渲染好的一系列圖片,這些圖片大多是用3D模型渲染的,但unity並不適於做2D,不過有相關才外掛程式做
因為是自學,也沒什麼系統的東西告訴你,只能說,這是條很艱難的路,做了決定就去做吧!
說的有些亂,呵呵
問幾個對於unity3D開發遊戲的問題
我接觸過virtools和unity,感覺引擎都是各有優點的,只要精通了都一樣,個人感覺unity符合我的風格。不是很華麗,但是所有遊戲功能都可以實現。unity商店上有很多的資源可以下載,做2d遊戲也很方便。
沒事也可以匯出自己做的遊戲到手機上,自己自戀下,有種滿足感。你能把美工和編程結合起來還是很好的,這方面的人才學精的很少的。unity學習起來不是很難,只要多跟著視頻完整的做完幾個遊戲製作的例子就能實現大部分的功能,要想再精通,就要鑽研。
unity破解版網上很多,3.0的就足夠了,破解版還算穩定吧。偶爾出現問題。
感覺現在筆記本5000左右的都能滿足需求,做精模就要用台式機了。