Unityでオフラインでの協力プレイや対戦プレイを出来るようにするには
の記事でやり方を記載しました。
今回の記事では↑の記事のようにプレイヤー毎にキャラクターを操作出来るようになっている必要があります。
カメラが動かず1画面でプレイヤー全てを見る事が出来ればゲームとして問題はありませんが、キャラクターが広い世界を動き回りプレイヤー毎に専用のカメラがある場合はそれぞれの動かすキャラクターが見えないと困ります。
そこで今回はプレイヤー毎のカメラを作成し2プレイヤーなら画面を2つに分割し、それぞれのキャラクターを写すようにしたいと思います。
プレイヤー数分のカメラの作成
今回はカメラを2プレイヤー用の縦・横の分割、4プレイヤー用の4分割が出来るようにしていきます。
プレイヤー数分のカメラ分割が出来ますが大型ディスプレイとかでないと全然見えなくなるかもしれません・・・・。
キャラクターを4プレイヤー作成するのは設定が大変なのでキャラクターは2プレイヤーだけ作り、4プレイヤー分のカメラを作成します。
カメラにはFollow Targetスクリプトを取りつけます。
Add Component→Scripts→StandardAssets.Utility→Follow Targetを選択します。
Targetにはカメラが追っていくキャラクターをドラッグ&ドロップし設定します。
Offsetはカメラの位置調整ですね。
カメラが出来たら名前をPlayer1Cameraとします。
カメラを選択している状態でCtrl+Dでコピーし名前をPlayer2Camera、Player3Camera、Player4Cameraとします。
2~4のカメラに付いているAudio Listenerがあるとコンソールに重複があると表示されるので右クリック→Remove Componentを選択し削除します。
さらにFollow TargetのTargetにはPlayer2を設定します。
今回のサンプルでは2プレイヤーしかいないので2~4のカメラはPlayer2を追いかけることにします。
カメラがそれぞれ分かれていると見づらいので、空のゲームオブジェクトを作成し名前をCameraとしその子要素にカメラをまとめてしまいます。
↑のようにします。
カメラを作成するとデフォルトでAudio Listenerという音声を聞くためのコンポーネントが付いてきますので、1つのカメラについているAudio Listenerだけ残し、後は削除しておきます。
これでカメラの作成が終了しました。
カメラ分割スクリプト
カメラの作成が終了したので次はカメラの分割をするスクリプトを作成します。
実際には分割しているわけではなくウインドウ内のどこからどこまでがカメラ1の描画範囲、どこからどこまでがカメラ2の描画範囲と設定を変えるだけです。
通常であればカメラ分割をするにはタイトル画面のシーンで協力プレイや対戦プレイを選択した時に設定を変更しその設定にしたがってカメラを分割させますが、
今回はタイトルシーンとゲームシーンを分けて作りません。
本来であればシーン移動時にゲームの設定等を引き継ぎその設定にしたがってカメラの分割を行う必要があります。
今回は空のゲームオブジェクトを作成し名前をCameraScriptとし、それに新しくSplitCameraSettingスクリプトを作成し取りつけます。
SplitCameraSettingスクリプトのインスペクタでカメラの分割設定を出来るようにし確認する事にします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | using UnityEngine; using System.Collections; public class SplitCameraSetting : MonoBehaviour { // カメラの分割方法 public enum SplitCameraMode { horizontal, vertical, square }; public SplitCameraMode mode; // カメラの分割方法 // プレイヤーを写すそれぞれのカメラ public Camera player1Camera; public Camera player2Camera; public Camera player3Camera; public Camera player4Camera; // Use this for initialization void Start () { // 2プレイヤー用の横分割 if (mode == SplitCameraMode.horizontal) { // カメラ3、4は非表示 player3Camera.gameObject.SetActive (false); player4Camera.gameObject.SetActive (false); // カメラのViewPortRectの変更 player1Camera.rect = new Rect (0f, 0f, 0.5f, 1f); player2Camera.rect = new Rect (0.5f, 0f, 0.5f, 1f); // 2プレイヤー用の縦分割 } else if (mode == SplitCameraMode.vertical) { // カメラ3、4は非表示 player3Camera.gameObject.SetActive (false); player4Camera.gameObject.SetActive (false); // カメラのViewPortRectの変更 player1Camera.rect = new Rect (0f, 0.5f, 1f, 0.5f); player2Camera.rect = new Rect (0f, 0f, 1f, 0.5f); // 4プレイヤー用の4分割 } else if (mode == SplitCameraMode.square) { // カメラのViewPortRectの変更 player1Camera.rect = new Rect (0f, 0.5f, 0.5f, 0.5f); player2Camera.rect = new Rect (0.5f, 0.5f, 0.5f, 0.5f); player3Camera.rect = new Rect (0f, 0f, 0.5f, 0.5f); player4Camera.rect = new Rect (0.5f, 0f, 0.5f, 0.5f); } } } |
インスペクタで4プレイヤー用のカメラを設定出来るようにし、カメラの分割モードによってカメラのViewPortRectを変更します。
Rectは第1引数がXの位置、第2引数がYの位置、第3引数が幅、第4引数が高さとなります。
Xの0はウインドウの左、Yの0はウインドウの下、Xの1はウインドウの右、Yの1はウインドウの上をあらわしています。
4プレイヤーモードの場合はPlayer1が左上、Player2が右上、Player3が左下、Player4のカメラが右下に表示されるようになります。
SplitCameraSettingのインスペクタでmodeをsquareにしてUnityを実行すると
↑のようにプレイヤー毎のカメラが4分割されて表示されました。
カメラの枠を付ける
カメラの分割は出来ましたがカメラの仕切りがないので少し見づらい部分があります。
そこでカメラに枠を付けそれぞれのカメラをわかりやすくしたいと思います。
まずはカメラ枠用の画像を作成します。
Windowsのペイントで作成した10×10サイズの画像です。
枠画像を作るのが面倒な方は↑の画像を右クリック→名前を付けて保存でローカルに保存してご自由に使ってください。
UnityのAssetsフォルダ内で右クリック→Import New Asset…でさきほど作成した画像を選択します。
Unityに取り込んだら画像を選択しTexture TypeをSprite(2D and UI)に変更します。
次にヒエラルキー上で右クリック→UI→Canvasを選択し名前をPlayer1Wakuとします。
CanvasのRender ModeをScreen Space – Cameraにし、Render CameraにはPlayer1Cameraを設定します。
こうすることでこのCanvasはPlayer1Cameraの枠に合わせて表示されるようになります。
次にPlayer1Wakuの子要素に右クリック→UI→Imageを4つ作成し名前をLeft、Right、Top、Bottomという名前に変更します。
それぞれが枠の部品になります。
一つの大きい枠を作成し設定する事も出来ますがウインドウサイズによって画像が引き延ばされるので個別に作ることにしました。
一つの枠でも出来るような気がしますが・・・とりあえず今回はパスで・・・・(;一_一)
Imageには先ほど取り込んだ10×10の画像を設定します。
枠それぞれでAnchorsの位置を設定し、幅や高さを変更します。
Leftは
Rightは
Topは
Bottomは
のように設定します。
Left、RightはWidth、Top、BottomはHeightのサイズを変更します。
これでPlayer1Wakuが出来たのでCtrl+DでコピーしPlayer2Waku~Player4Wakuを作ります。
2~4のCanvasのRender Cameraはそれぞれのカメラを設定するようにします。
これで枠の設定が終わりました。
接している部分の枠の幅を変更する
このままでも枠が表示されますが、カメラそれぞれが接している部分は枠が重なるので太さが2倍になります。
接している部分を強調する場合はこのままでいいですが、枠の幅を同じにしたい場合は調整が必要になります。
そこでSplitCameraSettingスクリプトに枠の幅を変更する処理を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | using UnityEngine; using System.Collections; public class SplitCameraSetting : MonoBehaviour { // カメラの分割方法 public enum SplitCameraMode { horizontal, vertical, square }; public SplitCameraMode mode; // カメラの分割方法 // プレイヤーを写すそれぞれのカメラ public Camera player1Camera; public Camera player2Camera; public Camera player3Camera; public Camera player4Camera; // カメラ用の枠 public Transform waku1; public Transform waku2; public Transform waku3; public Transform waku4; // Use this for initialization void Start () { // 2プレイヤー用の横分割 if (mode == SplitCameraMode.horizontal) { // カメラ3、4は非表示 player3Camera.gameObject.SetActive (false); player4Camera.gameObject.SetActive (false); // カメラのViewPortRectの変更 player1Camera.rect = new Rect (0f, 0f, 0.5f, 1f); player2Camera.rect = new Rect (0.5f, 0f, 0.5f, 1f); // 枠の幅を変更する var waku1Rect = waku1.Find("Right").GetComponent <RectTransform> (); waku1Rect.localScale = new Vector3 (waku1Rect.localScale.x / 2f, waku1Rect.localScale.y, waku1Rect.localScale.z); var waku2Rect = waku2.Find ("Left").GetComponent <RectTransform> (); waku2Rect.localScale = new Vector3 (waku2Rect.localScale.x / 2f, waku2Rect.localScale.y, waku2Rect.localScale.z); // 2プレイヤー用の縦分割 } else if (mode == SplitCameraMode.vertical) { // カメラ3、4は非表示 player3Camera.gameObject.SetActive (false); player4Camera.gameObject.SetActive (false); // カメラのViewPortRectの変更 player1Camera.rect = new Rect (0f, 0.5f, 1f, 0.5f); player2Camera.rect = new Rect (0f, 0f, 1f, 0.5f); // 枠の幅を変更する var waku1Rect = waku1.Find("Bottom").GetComponent <RectTransform> (); waku1Rect.localScale = new Vector3 (waku1Rect.localScale.x, waku1Rect.localScale.y / 2f, waku1Rect.localScale.z); var waku2Rect = waku2.Find ("Top").GetComponent <RectTransform> (); waku2Rect.localScale = new Vector3 (waku2Rect.localScale.x, waku2Rect.localScale.y / 2f, waku2Rect.localScale.z); // 4プレイヤー用の4分割 } else if (mode == SplitCameraMode.square) { // カメラのViewPortRectの変更 player1Camera.rect = new Rect (0f, 0.5f, 0.5f, 0.5f); player2Camera.rect = new Rect (0.5f, 0.5f, 0.5f, 0.5f); player3Camera.rect = new Rect (0f, 0f, 0.5f, 0.5f); player4Camera.rect = new Rect (0.5f, 0f, 0.5f, 0.5f); // 枠の幅を変更する var waku1Rect = waku1.Find("Bottom").GetComponent <RectTransform> (); waku1Rect.localScale = new Vector3 (waku1Rect.localScale.x, waku1Rect.localScale.y / 2f, waku1Rect.localScale.z); waku1Rect = waku1.Find ("Right").GetComponent <RectTransform> (); waku1Rect.localScale = new Vector3 (waku1Rect.localScale.x / 2f, waku1Rect.localScale.y, waku1Rect.localScale.z); var waku2Rect = waku2.Find ("Bottom").GetComponent <RectTransform> (); waku2Rect.localScale = new Vector3 (waku2Rect.localScale.x, waku2Rect.localScale.y / 2f, waku2Rect.localScale.z); waku2Rect = waku2.Find ("Left").GetComponent <RectTransform> (); waku2Rect.localScale = new Vector3 (waku2Rect.localScale.x / 2f, waku2Rect.localScale.y, waku2Rect.localScale.z); var waku3Rect = waku3.Find ("Top").GetComponent <RectTransform> (); waku3Rect.localScale = new Vector3 (waku3Rect.localScale.x, waku3Rect.localScale.y / 2f, waku3Rect.localScale.z); waku3Rect = waku3.Find ("Right").GetComponent <RectTransform> (); waku3Rect.localScale = new Vector3 (waku3Rect.localScale.x / 2f, waku3Rect.localScale.y, waku3Rect.localScale.z); var waku4Rect = waku4.Find ("Top").GetComponent <RectTransform> (); waku4Rect.localScale = new Vector3 (waku4Rect.localScale.x, waku4Rect.localScale.y / 2f, waku4Rect.localScale.z); waku4Rect = waku4.Find ("Left").GetComponent <RectTransform> (); waku4Rect.localScale = new Vector3 (waku4Rect.localScale.x / 2f, waku4Rect.localScale.y, waku4Rect.localScale.z); } } } |
RectTransformのWidthやHeightを直接変更する事が出来なかったのでScaleを変更するようにしました。
枠の子要素から名前で検索し、そのカメラの枠が接している部分のScaleを半分にしています。
SplitCameraSettingの設定は
↑のように設定します。
これで全ての機能が完成しました。
カメラ分割機能を確認する
カメラ分割機能と枠の表示機能が完成したのでゲームパッドを2つ繋いで機能を確認してみます。
↑のようになりました。
これで協力プレイ時も他のユーザーがどこにいるかわかるので便利ですね。