【Unity9】UNETでマルチプレイヤーなオンラインゲーム開発【UNET1】
Unity5.1.1f1 Personal(2015年7月)
マルチプレイヤーネットワーキングシステムであるUNETが、Unity5.1から標準搭載されました!
そして、少し前からUNETのチュートリアルがあがっていたので、今回から記事にまとめていきたいと思います〜
今後ブログ記事をアップしていく中でよく分からないけど動いたというパターンや、誤った説明等拙い点が多々あるかと思います〜
間違いなどお気付きの点がありましたら、コメント等で教えて下さると助かります〜
UNET Part 1 - Setup and Movement Syncing - YouTube
【目標】ホストプレイヤーとクライアントプレイヤーに別々の動きをさせる
①下準備
まずは「Main」と「Menu」という名前で、Sceneを2つ作ります〜
今から編集するのはMainシーンですので、Mainシーンを開いておいて下さい〜
次にPlaneを作成し、SizeをX:100,Z:100に変更し、灰色のMaterialを作成し取り付けて下さい〜
続いてCubeを作成し、PositionをY:0.5に変更して下さい〜
また作成したCubeをコピーしてもうひとつCubeを作り、適当な場所へ配置して下さい〜
コピーしたCubeのScaleはX,Y,Z全て2に変更しておきましょう〜
Mainシーンに床1つとCube2つを配置
最後にEnvironmentという名前で空のゲームオブジェクトを作成し、PlaneとCube2つを子オブジェクトして下さい〜
フィールドはEnvironmentオブジェクトの子オブジェクトとする
②Player作成
続いてPlayerを作成します〜AssetsからImport Package>Charactersを選択し、Standard Assetを用意します〜
Character選択
続いてStandard Asset>Characters>FirstPersonCharacter>PrefabにFPSControllerというプレハブがあるので、Hierarchy上へドラッグ&ドロップして下さい〜
名前は「Player」に変更します〜
ドラッグ&ドロップ!
次にPrefabsフォルダを作成し、Playerオブジェクトをドラッグ&ドロップしてプレハブ化しましょう〜
ドラッグ&ドロップ!
Playerの子オブジェクトとしてCapsuleオブジェクトを作成します〜
Capsuleオブジェクトに最初から付いているCapsule ColliderはRemove Componentで消して下さい〜
Capsuleオブジェクトを子オブジェクトにする
今のままだと地面に埋まってしまうので、PlayerのPositionをX:0, Y: 1, Z: 0に変更します〜
とりあえず一人称視点でフィールドを動くPlayerが完成しました〜ゲームを実行すると、矢印キーで移動、スペースキーでジャンプ、マウスを動かすことで視点が変わります〜
ここまではネットワークと全く関係ない部分ですので、混乱せずにこられたかと思います〜
③NetworkManagerを作成する
いよいよここからネットワークと関係してきます!
まずは「NetworkManager」という名前で空のゲームオブジェクトを作成して下さい〜
次にInspectorビューからAddComponent>Network>NetworkManagerを取り付けて下さい〜
NetworkManagerコンポーネント
動画ではOffLineの時にMenuシーンを、Onlineの時にMainシーンを指定したかったようですがうまくいっていないようなので、Offline SceneとOnline Sceneの設定は今回はまだしません〜
今回はインターネット越しではなく自分のパソコン内(ローカル環境)でUNETを使うので、Network InfoのNetworkAddressはlocalhost(127.0.0.1と入力しても同じ意味)のままにしておいて下さい〜
ポートは外部からデータを受け取る時の入り口で、今回はローカル環境で完結させるので、Network Portについても今回は設定する必要はありません〜
Spawn Infoでは、ネットワークに接続した時に作成する、自分が操作するプレイヤーを設定することができます〜早速Player Prefabに、先ほど作成したPlayerプレファブを設定しましょう〜
ドラッグ&ドロップすると・・・
NetworkIdentityが無いですよというエラーが発生する
というわけで、PlayerプレハブにNetworkIdentityコンポーネントを付けて回避しましょう〜
Hierarchy上にあるPlayerプレハブにAdd Component>Network>NetworkIdentityで取り付け、Local Player Authorityにチェックを入れて下さい〜
Local Player Authorityにチェックを入れることで、他のプレイヤーと自分が操作するプレイヤーが区別されるようになります〜
ここまでできたらApplyボタンを押して下さい〜Projectビュー上のPlayerプレハブに変更が反映されます〜
Network Identityを取り付けApplyボタンを押すことで変更を反映
NetworkManagerのSpawn Info>Player Prefabに、Playerプレハブを設定できるようになった
続いてNetworkManagerHUD(ヘッドアップディスプレイ)コンポーネントを取り付けます〜GUIでネットワークに接続したりを指示できるようになります〜
NetworkManagerのInspectorビューからAdd Component>Network>NetworkManagerHUDを選択して下さい〜取り付けるだけで、特に設定することなく使えます〜
ゲームを実行するとGUIが出てくる
④Playerの動きをインスタンスごとに分ける
今の状態で既に自キャラと相手キャラの2オブジェクトを作成して動かすことはできますが、片方のオブジェクトを動かした時、もう片方のオブジェクトも全く同じ動きをしてしまう状態にあります〜
対策として、まずはHierarchyにあるPlayerオブジェクトにNetwork Transformコンポーネントを付けます〜これを付けることで、位置情報を同期させることができるそうです〜
さて、まずはNetworkTransformのTramsform Sync ModeをSync Rigidbody 3DからSync Transformに変更しましょう〜Character ControllerとFirst PersonController(Script)を使って移動している場合は、Sync Transformに変更するそうです〜
続いてPlayerが方向を変更した時に変更したことが分かりやすいように、鉄砲のようなものを取り付けます〜Playerの子オブジェクトにCubeを取り付け、Transformを以下のような設定にして下さい〜また、Box Colliderは取り除いておいて下さい〜
次にPlayerオブジェクトをApplyして変更を反映し、Hierarchy上にあるPlayerオブジェクトは削除します〜
ここまで準備ができたら、Buildして実際に動かしてみましょう〜File>Build Settingsを選択し、Add CurrentでMainシーンをビルドの対象にし、Build And Runを実行します〜
Buildして実行
これで2人のプレイヤーが1つのゲーム空間で同時に存在できるようになりました〜
左側がビルドして作ったゲーム画面、右側が開発環境のゲーム画面です〜
それでは開発環境のほうをホスト、ビルド環境のほうをクライアントで遊んでみましょう〜まずは開発環境で「LAN Host(H)」と書かれたボタンをクリックして適当に動かして下さい〜
次にビルド環境のほうで「LAN Client(C)」と書かれたボタンをクリックして下さい〜
すると、相手プレイヤーを確認することができます〜
相手プレイヤーがいる
しかし今の状態だと先ほど説明したように、2オブジェクトが全く同じ動きをしてしまいます〜
この状態を回避するために、Playerプレハブに付いているコンポーネントを非アクティブ状態にしておき、Playerプレハブを生成した時に各コンポーネントをアクティブ化する必要があります〜
まずはPlayerに付いているCharacter ControllerとFirst Person Controllerを非アクティブ化します〜
チェックを外して非アクティブ化
次にPlayerの子オブジェクトであるFirstPersonCharacterのCameraとAudio Listenerも非アクティブ化します〜
チェックを外して非アクティブ化
最後にMain Cameraの名前を「Scene Camera」に変更して下さい〜
それでは、コンポーネントを比アクティブからアクティブへ変更する「Player_NetworkSetup」スクリプトを作成していきます〜以下ソースです〜
using UnityEngine; using System.Collections; using UnityEngine.Networking; //ネットワーク関連で必要なライブラリー //継承はMonoBegaviourではなくNetworkBehaviour public class Player_NetworkSetup : NetworkBehaviour { //SerializeField: publicでなくてもInspector上で変数内容を指定できる [SerializeField]Camera FPSCharacterCam; //FirstPersonCharacterのCamera [SerializeField]AudioListener audioListener; //FirstPersonCharacterのAudio Listener void Start () { //自分が操作するオブジェクトに限定する if (isLocalPlayer) { //FPSCharacterCamを使うため、Scene Cameraを非アクティブ化 GameObject.Find("Scene Camera").SetActive(false); GetComponent<CharacterController>().enabled = true; //Character Controllerをアクティブ化 //FirstPersonControllerをアクティブ化 GetComponent<UnityStandardAssets.Characters.FirstPerson.FirstPersonController>().enabled = true; //FirstPersonCharacterの各コンポーネントをアクティブ化 FPSCharacterCam.enabled = true; audioListener.enabled = true; } } }
Player_NetworkSetup.cs
まずはSerialize Fieldに、CameraとAudio Listenerを設定してあげましょう〜Playerの子オブジェクトであるFIrstPersonCharacterをそれぞれドラッグ&ドロップしてあげれば指定できます〜
ドラッグ&ドロップ!
それではスクリプトに入ります〜
isLocalPlayerがtrueの時のみStartメソッドを実行するようになっています〜
isLocalPlayerは自分が操作するPlayerに対してのみtrueになりますので、画面上にPlayerが2人いても自分が操作するPlayerのコンポーネントのみをアクティブ化することができます〜
isLocalPlayer変数を使うためにはNetworkBehaviourを継承する必要があります〜そして、NetworkBehaviourを継承するためには「using UnityEngine.Networking」とスクリプトの頭に書いておく必要があります!
再度Buildを行い動作を確認してみると、今度は自プレイヤーと相手プレイヤーが別々の動きをします!
動画がpart1の途中ですが長くなってしまったので、今回はここまでです〜
ありがとうございました〜
【Unity9】UNETでマルチプレイヤーなオンラインゲーム開発【UNET1】
【Unity9】UNETでプレイヤーの動きを補間し、なめらかな動きを実現する【UNET1-2】
【Unity9】UNETでネットワーク越しに傾き(Rotation)を同期させる【UNET2】
【Unity9】UNETでオンライン開始時のプレイヤー生成位置を変更する【UNET2-2】
【Unity9】UNETのネットワークトラフィックを軽減し、効率化する【UNET3】
【Unity9】UNETのlatency(遅延時間)を改善する【UNET4】
【Unity9】UNETのlatency(遅延時間)を表示して、ちょっとだけ改善する【UNET4-2】
【Unity9】UNETのSyncVarのhookの使用例と、前時代の同期方法【UNET5】
【Unity9】UNETを使ってRotationを同期させる【UNET6】
【Unity9】UNETで各プレイヤーにPlayerIDを設定する【UNET7】
【Unity9】UNETで敵プレイヤーにダメージを与える!【UNET8】
【Unity9】UNETでHPを画面に表示し、Playerへダメージを与える【UNET9】
【Unity9】UNETでHPが0以下になった時、Playerを破壊する!【UNET10】
【Unity9】UNETで死んだPlayerを生き返らせる!【UNET11】
【Unity9】UNETでゾンビAIを出現させる!【UNET12】
【Unity9】UNETでゾンビ生成時にユニークなIDを付ける!【UNET13】
【Unity9】UNETでゾンビを撃つ!【UNET14】
【Unity9】UNETでゾンビに攻撃させる!【UNET15】
【Unity9】UNETでゾンビの動きをスムーズにシンクロさせる!【UNET16】
【Unity9】UNETでゾンビ発生地点を増やす【UNET17】
【Unity9】UNETで発生したバグを取り除く【UNET18】
【Unity9】Unity MultiPlayerを使ってネットワーク越しにマッチメイキング!【UNET19】
【Unity9】GUIを改善して、Network Managerを見やすくする!【UNET20】
【Unity9】表示したGUI(Network Manager)を機能させる!【UNET20-2】
【Unity9】UNETでAnimationを同期させる!【UNET21】