FreelyApps

個人によるアプリ開発の日記です。アプリの収入だけで生活できるようになるのが目標です。UnityでAndroid向けのゲームアプリを作成しています。


    アプリ『トランプ・7並べ』を公開しました。
    Android/iOS https://goo.gl/zsFces

    カテゴリ: Unity

      このエントリーをはてなブックマークに追加 Clip to Evernote
    UIの位置を調整する場合はスクリーン座標を基準に考えるのが最も良いです。スクリーン座標とは表示するディスプレイ上でのピクセル単位の座標です。
    Unityでは左下が(0,0)、右上が(幅,高さ)となるように座標を定めています。カメラのところにちょろっと説明が載っています。
    こういったゲームビューなら右上の座標は画面のサイズになります。
    gameview

    なぜスクリーン座標で考えると良いのかというと、画面上でどこに表示されているかを直接表しているためです。画面上の位置が表示にそのまま関係するため最もわかりやすいのです。

    3DとUIを連携したい場合
    わかりやすい例で言うと3D空間上にいる物体の近くにUIを常に出したいといったことがあるでしょう。これはキャラクターにHPのバーを表示し続けるといったことが該当します。
    キャラクターが3Dだとすると、キャラクターの位置は3D空間上での位置を表しています。(モデルの中心位置に一致することでしょう。)x,y,zの3成分があるベクトルで表されますが、この数字はワールド座標であるはずです。空間上の位置から画面上のどこ(スクリーン座標)に表示されるのかを求める必要があるわけです。これはキャラクターを移しているカメラから変換行列をかけてもらい求めます。Unityではこの行列計算は、カメラコンポーネントを取得してWorldToScreenPointを位置に適用するだけなので簡単です。
    キャラクターのスクリーン座標がわかったら、UIの位置を補正するなどしてUIのスクリーン座標を決めます。頭上にHPを出したければ、キャラクターのスクリーン座標に適当な量yを増やせばいいです。このスクリーン座標をUIの座標にして、それをUIにセットすれば目的が達成されます。RectTransformUtility.ScreenPointToLocalPointInRectangle(RectTransform rect, Vector2 screenPoint, Camera cam, out Vector2 localPoint)を使えば、あるRectTransform内でのローカル座標を求めることができます。rectは設定したいUIの親になることがほとんどになるでしょう。camはCanvasに使っているカメラを渡します。オーバーレイモードならnullにします。localPointには結果を取得するための変数を渡します。これで得られたlocalPointを設定したいUIのRectTransform.localPositionに設定すると完成です。

    UI同士を連携したい場合
    UIのCanvasが異なるなど単純には位置を求められない場合もスクリーン座標を介することで位置を連携することができます。
    あるUIの位置がスクリーン座標でどこになるかが分かれば良いことになります。これはRectTransformUtility.WorldToScreenPoint(Camera cam, Vector3 worldPoint)を使うと可能です。なぜかこれについてはドキュメントに載っていないようです。使い方は引数からわかるようにUIを表示しているカメラとRectTransform.position(ワールド座標)を渡します。
    スクリーン座標からUIの座標を求めることは既に述べたので、これでどちらにも変換ができます。


    UIのもつ座標→スクリーン座標とその逆であるスクリーン座標→UIのもつ座標の変換方法があれば自由に位置を調整できるということになります。
    • UIのもつ座標→スクリーン座標はRectTransformUtility.WorldToScreenPoint
    • スクリーン座標→UIのもつ座標はRectTransformUtility.ScreenPointToLocalPointInRectangle
    を使うことで可能です。
    注意点はピボットの位置がRectTransformの位置である(localPositionとかはピボットの位置を表しているということ)ということです。変換を行うときに微妙に位置がずれるときはピボットの位置がセンターだったり、トップだったりと統一がされていない可能性があります。

    意外とありそうなミスとしてはアクティブでないUIの座標を取得してしまうことです。このときの座標は正しくないようなので、起こりやすい間違いです。 これは消していたいUIの座標を取りたいという時に困るのですが、どうしようもないようです。

    以上のような変換はスクリプトで制御したい場合に必要になることが多いでしょう。Canvasの異なるUI同士の座標をそろえたりする機能が今のところなさそうなので、こういった方法が要ると思っています。
    もっと簡単な方法があると良いのですが…… 

      このエントリーをはてなブックマークに追加 Clip to Evernote
    以前、同じ内容で記事を書いたのですが、より良い方法がUnity5.3では行えるようです。

    rn-custom_coroutine
    Unity5.3で新しく使えるようになったカスタムコルーチンというものを使います。 公式の説明を見るとCustomYieldInstructionクラスを継承して、keepWaitingプロパティのgetをオーバーライドすれば新しいyieldオペレーションが作れます。
    yieldオペレーションとは、yield return ~とするときの~の処理のことを言っているのだと思います。(この記事ではそうだと思って書くことにします。)
    keepWaitingがtrueであればyieldオペレーションが処理を返さず継続し、falseになると処理を抜けます。このプロパティにDebug.Logを仕込んだところ毎フレーム呼ばれていたので、コルーチンで無限ループ内にyield return 0;というような書き方で行うのと同じと考えて良いでしょう。

    以前の方法のあまり良くない点は、処理をクラス内に書いていなければいけなかったため、あるクラスのstaticメソッドにするかクラス内での利用しかできないようになっていたことです。色々なところから自由に呼び出すということを考えると、その処理は独立した1つのクラスになっている方が見通しが良いのでそうすべきだと思っていました。
    メソッドに処理がある場合は、呼び出し方がStartCoroutineを介するというのもいまいちだと思います。StartCoroutineを使うと、渡すパラメータの個数の制約があること、わずかにコードが増えること、文字列での呼び出しだとエディター上で編集しにくいことが良くないです。
    新たな方法では導入が手間ですが、その後の作業を減らしてくれるため良い方法だと思います。WaitUntilやWaitWhileを使っても同じことができますが、よくある同じ処理をいちいち書くのは無意味なので、以下のようにカスタムコルーチンを作りました。

    上のソースは、ある時間処理を待たせるがスキップも可能であるというyieldオペレーションになります。使い方は
    yield return new SkippableWaitForSeconds(10, () => Input.GetMouseButtonUp(0));
    のようにします。この例だと10秒待つ処理であり、もしその間にマウスの左ボタンが上げられたらスキップするということになります。
    スキップするかの判定を外から渡せるため、色々と使えるようになっています。

      このエントリーをはてなブックマークに追加 Clip to Evernote
    ヒエラルキーにスクリプトをドラッグアンドドロップしたら、そのスクリプトがアタッチされたゲームオブジェクトがヒエラルキーにできると思っていたことがありました。それはプレハブをドラッグアンドドロップするとそのコピーができることからそんな勘違いをしていたのです。
    そうなっていてほしいことがそうなっていないので、Unityを使っていて長い間不満でした。それでどうにかできないかと思っていたので、今回なんとかしてみました。スクリプトはC#のみ対象です。BooやJavaScriptの方は型の情報が取れなかったので、やめました。といってもC#がメインでしょうからあまり関係ありません。


    以上のようにMonoBehaviourを継承していようが、継承していなくても関係なくスクリプトをヒエラルキーにドラッグアンドドロップしても何も起こりません。これはUnityの通常の挙動です。
    MonoBehaviourを継承したクラスはゲームオブジェクトにアタッチできますから、MonoBehaviourを継承したクラスのスクリプトをヒエラルキーにドラッグアンドドロップしたら、新しいゲームオブジェクトをヒエラルキーに作成しそのスクリプトをアタッチするというように変更したいと思います。


    できたものの動作は以下のようになりました。
    MonoBehaviourを継承したスクリプトのみ反応して、ゲームオブジェクトが作られています。(partialを使った場合は、クラス名と一致するスクリプトのときだけ反応します。)



    これをどうやって作ったかは結構難しい話になると思います。まず参考にしたサイトがいくつかあるのでそれを挙げておきます。
    Unity5 HierarchyにC#スクリプトをドラッグ&ドロップできるようにするエディター拡張
    Create GameObjects/Components by Dragging Assets to Hierarchy/Inspector
    の2つです。特に前者の方の目的はやりたかったことそのままと言ってもいいです。じゃあわざわざ作る必要があったのかとなりますが、うまく動かなかったので自分で作ることにしました。

    以下に作ったコードを載せておきます。現在、私が使っているUnityのバージョンは5.3.1f1 Personalです。これで動くことは確認しています。使い方は、UnityのプロジェクトにEditorフォルダを作りそこにこのスクリプトDropScript.csを置けば使えます。
    ログに”DropScript AutoStart”と出れば読み込みが完了しています。

    #if~#endifの部分は手動でこの拡張機能をON/OFFするためのものです。使いたい場合は適当なdefineを入れてください。
    重要なのはリフレクションを使って型の情報を取っている部分です。(Unity4だったら、名前でAddComponentできるので、それにclassNameを渡すだけで良いです。)Types.GetTypeという部分がドキュメントには載っていないので、使い方が正しいか微妙です。
    ドラッグのイベントは何度も呼ばれてしまうので、boolフラグで一度だけ呼び出されるように対処しています。

    完成したものは十分に要件を満たしていますが、いくつかの欠点があります。もう少し改善すると注意せずに誰でも使えるものになりますが、ちょっと無理そうなのでそれはしません。
    • ヒエラルキーにゲームオブジェクトがひとつもないと反応しない
    • スクリプトをドラッグしたままヒエラルキーを横切るとゲームオブジェクトができてしまう
    • スクリプトをドラッグしてゲームオブジェクトにアタッチすると、ついでにゲームオブジェクトができてしまう
    1つ目はEditorApplication.hierarchyWindowItemOnGUIがヒエラルキーにあるゲームオブジェクトから呼ばれているようなので、他の判定方法がないと改善できません。よって、これはどうしようもないと……
    2つ目はドラッグ中にヒエラルキーのウィンドウ外に出ることをドロップと判定されているようなので、おそらくどうよもないです。
    3つ目は個人的に結構大きな問題と考えています。ドラッグでのアタッチをやめてボタンからコンポーネントをつければ競合しないですが、気をつけないと知らずに不要なものができてしまうので問題です。
    まあ何らかの方法で対応できるかもしれませんが、これを使うとこんな感じのこともできるのでこのままの方が使えると思っています。ヒエラルキーをまたぐように行ったり来たりして大量のゲームオブジェクトを作っています。


    これすごく便利だと思うので、Unityの公式の機能としていずれ追加してほしいです。

    • カテゴリ:
      このエントリーをはてなブックマークに追加 Clip to Evernote
    Unity UIにはOutlineというコンポーネントがあります。
    実は影をつけるエフェクトもそうなのですが、単にコピーを下に描いているだけのものです。コピーの数は上下左右で4つです。そのため描画する文字は5倍になります。
    outline
    OutlineコンポーネントのEffect Distanceを大きな値にすると4つのコピーがあることがわかります。

    outline-edge
    「あ」の右下のはらいの部分で縁がいびつにになっているのがわかります。大きな文字だと意外と気になることもあります。
    4つコピーを配置することでも十分なこともあるのですが、もっと多くのコピーが存在している方が文字の縁が綺麗になります。ある文字から等距離にコピーを配置していけばうまくいきます。つまりコピーはオリジナルの文字列から一定距離の円周状に配置します。
    Unite2015 uGUIの拡張と応用」を参考に拡張したOutlineコンポーネントを作ってみました。拡張したOutlineコンポーネントCircleOutlineのソースコードはこの記事の一番下に置いておきます。(Unity 5.2.3では動いていますが、Unity 5.3以降でBaseMeshEffectの使い方が変わっている可能性があります。実際5.2で何回か変わっていて、そのたびに少しずつ変えています。)

    CircleOutlineで縁をつけたものが以下のようになります。10個のコピーを使った例が下の文字になります。縁が丸みを帯びて滑らかになっているのがわかります。
    circleoutline

    これはアウトラインが単なるコピーによってできていることを示す動画です。
    かなり離れたところに出るように設定してあるので、増えていくと円形の模様になっています。
    ol
     
    コピーしているという性質上オリジナルのアルファを下げていくと、コピーが重なっているところが目立ってきてしまいます。不透明にして使うとコピーがオリジナルに隠れて最も見やすいです。
    アウトラインをつけられるのはUIの要素のText以外にもImageも可能だったりします。

    ソースコードを以下に載せておきます。 

      このエントリーをはてなブックマークに追加 Clip to Evernote
    この記事を書いているときのアップデートは5.2.2f1から5.2.3f1です。

    アップデートの方法は、Unityの起動時に通知が来て自動的にウィンドウが開きます。 そのウィンドウでアップデートがあるから更新するかと聞いてきます。
    updateunity

    たぶんデフォルトだとCheck for Updatesにチェックが入っているので、更新が通知されます。Download new versionを押すと、最新のUnityのダウンロードサイトに飛ばされます。
    ダウンロードサイトからインストーラーを落とし、実行すればアップデートが可能です。ウィザードに従っていけばアップデートを自動で行ってくれます。

    更新通知が開かない場合でもアップデートがあるかチェックすることができます。Helpメニューにアップデートがあるか確認するメニューあるのでそれを押せば確認することができます。
    menuupdate


    ウィザードの表示を撮ったので載せておきます。バージョンによっては変わる可能性がありますが、そんなに大きくは変わらないと思います。

    1ページ目
    da-1

    2ページ目
    左下のチェックマークを入れないと同意したことにならず次のページに進めません。
    da-2

    3ページ目
    ダウンロードするものを選ぶ画面ですが、デフォルトのままで良いと思います。
    da-3

    4ページ目
    一時フォルダにファイルをダウンロードすれば良いので、そのまま進んで問題ありません。
    da-4

    5ページ目
    da-5

    6ページ目
    インストールが終わると個の画面になります。これが出ればインストールは成功しているでしょう。試しに起動してみてUnityのバージョンがどうなっているか確認すれば万全です。
    da-6

    インストールが終わるとWindowsのプログラムの一覧に新しいバージョンの項目が追加されます。画像のように古いバージョンのものも残ったままです。
    インストール先を変更していない場合はUnityを上書きしてバージョンアップしているので(古いバージョンは残っていない)古い方の項目は消しても構いません。
    startmenu

      このエントリーをはてなブックマークに追加 Clip to Evernote
    Unity MultiplayerはUnity 5.1から追加されたオンラインマルチプレイヤーなゲームを簡単に作るための仕組みです。これによって楽になったことは間違いないのですが、まだまだ発展途上という感じで実際に使われていることは多くない気がします。
    その原因の一つとしては、日本語ドキュメントの準備に時間がかかったことがあると思います。はじめはUnityの公式ドキュメント上で英語版しかなくそれを読むしかないという状況だったのです。今は「マルチプレーヤーとネットワーキング」という日本語の公式ドキュメントが公開されています。


    いくつかのブログでUnity Multiplayerについて解説されているのでリンクを載せておこうと思います。

    テラシュールブログより
    【Unit 5】Unityでマルチプレイヤーなゲームを作る入門(1)」 
    Unityについて解説している超有名なブログです。キャラクターの移動を同期するサンプルを説明されています。ちょっと試してみたい人向けの解説です。

    凹みTipsより
    Unity 5.1 から導入された新しいネットワーク機能の UNET について詳しく調べてみた」 
    公式ドキュメントの内容を日本語でわかりやすくまとめられています。Unity Multiplayerを使って作られた3D空間を歩き回れるチャットのアプリケーションを公開されていて、Unity Multiplayerを使ったデモをすぐに体験することができます。このデモのような使われ方が最もUnity Multiplayerに向いていると思います。(リアルタイムに同期して、プレイヤーは自由に出たり入ったりする)
    日本語ですが公式マニュアルの説明が元で少しレベルは高めです。

    ひよこのたまごより
    【Unity9】UNETでマルチプレイヤーなオンラインゲーム開発【UNET1】」 
    こちらの解説動画を日本語で記事に起こしたもののようです。1つの記事だけでなく色々なトピックを上げられています。位置の同期のやり方から始まり、ゲームオブジェクトの生成・破棄の同期、マッチメイクといった内容が解説されています。
    動画が英語なのが最大の障害ですが、それ以外は丁寧に段階を追って進んでいくため習得しやすいと思います。手を動かしつつゆっくりと習っていく感じです。


    上記の記事の気にいったものでもUnity Multiplayerのさわりを試すことができますが、ここでも説明しようと思います。
    キャラクター(Cube)の移動を同期するというサンプルを作ってみました。キャラクターを動かすスクリプトも作りましたが、これはなくても試すことが可能です。

    必要なものは
    • Network Manager
    • Network Manager HUD
    • Network Transform
    • Network Identity
    の4つです。これだけあればキャラクターの移動を異なる端末間で同期することができます。
    実際に異なる端末間で通信を行うためには相手を見つけなければなりません。IPアドレスがわかればできますが、IPアドレスは一定でなかったりして特定は結構難しい問題だったりします。ここらへんの話はマッチングやマッチメイクといった内容になるので今回は省きます。
    同じPC上で複数のプログラムを動かして通信を行うことにします。ひとつのPCしかなくてもPC内で通信ができるのでテストが簡単です。

    まず最も重要なNetwork Managerを用意します。Network ManagerコンポーネントとNetwork Manager HUDコンポーネントを同じゲームオブジェクトにアタッチするだけです。
    Add ComponentのNetworkというカテゴリーにまとまっているようです。
    networkcomp

    アタッチするところはどこでも良いのですが、今回はMain Cameraにくっつけました。特に設定は行わずアタッチだけしてください。
    networkmanager

    Network Managerの設定はプレイヤーをセットするところが残っていますが、まずはプレイヤーを作ります。ドキュメントではプレイヤーオブジェクトと呼ばれているもので重要なものです。
    今のところは通信が確立するたびに作られるゲームを遊ぶ人を表すものと考えて良いと思います。自分で制御できない他人のゲームオブジェクトがシーン上に現れます。

    プレイヤーの制作はプレハブを作るだけです。目に見える方がわかりやすいのでCubeを使います。Cubeをプレハブ化して、Network IdentityとNetwork Transformコンポーネントをアタッチします。
    Network IdentityにあるプロパティにLocal Player Authorityというものがあるのでそれをtrue(下の画像のようにチェックを入れる)にします。Network Transformコンポーネントがこの値を見て同期を行うべきか決めているのでチェックしないと位置の同期がされなくなります。
    他の設定は変更しないでそのままにしてください。
    networkplayer
     
    プレイヤーのプレハブができたら、 Network Managerに設定を行います。
    Spawn Infoを開いて、Player Prefabという項目があるのでさっき作ったプレイヤープレハブ(ここではCubeという名前)をセットします。これによりプレイヤーがNetwork Managerに認識されます。
    nmplayer
     
    以上で手順は完了です。これで通信してCubeの位置が同期されることを試してみます。Editor上での実行とexeを作ってそれを実行して通信を行っています。

    左側の2画面の上がシーンビューで下がゲームビューです。右側のウィンドウがexeの実行画面です。
    どちらも起動してからウィンドウにGUIでボタンが表示されています。 
    まず片方でLAN Hostを押し、その後にLAN Clientを押します。こうするとPC上で通信が行えます。左の
    Editor上では自分のプレイヤーをシーンビュー上で動かしています。ゲームビューでも動くのは当然ですが、右のexeの方でも位置の変化が反映されているのがわかります。これは通信をして位置の同期を行われていることを表しています。
    networkdemo

    最後にキャラクター(Cube)を動かすスクリプトを載せておきます。このスクリプトをキャラクターにアタッチすれば方向キーで移動させることができます。
    isLocalPlayerというプロパティで自分のものかどうか判定しているので、全部が動くのではなく自分のプレイヤーだけが動きます。

    using UnityEngine;
    using UnityEngine.Networking;
    using System.Collections;

    public class Move : NetworkBehaviour
    {
        public float fSpeed = 0.1f;

        void Update()
        {
            if (isLocalPlayer)
            {
                float vert = Input.GetAxis("Vertical");
                float hori = Input.GetAxis("Horizontal");

                transform.Translate(new Vector3(hori, 0, vert) * fSpeed);
            }
        }
    }
     

      このエントリーをはてなブックマークに追加 Clip to Evernote
    Unityのビルドを行いAPKファイルを作ります。できたファイルのサイズが大きかった場合どうすればよいでしょうか?
    50MBを超えないようにするだけでなく、より小さいファイルになっている方がダウンロードが早く終わり好ましいです。APKに含まれるアセット(テクスチャ、サウンド、スクリプトなど)を小さくするということがAPKファイルを小さくすることにつながります。
    効果的なのは大きなアセットを削減することです。例えば1MBのテクスチャと1KBのサウンドがAPKに含まれている場合、前者を減らす方が効果があります。容量が1000倍違うので当たり前なんですが、PC上で見れるファイルサイズがAPK内でのファイルサイズと異なるためどのファイル(アセット)を削減すべきなのか調べるのはそれほど簡単ではありません。
    もちろん元々大きなファイルはAPK上でも大きいはずですが、どれくらいの割合を占めているかを知ることはできません。あくまでも元のファイルサイズは目安です。APK上でアセットがどの程度のファイルサイズなのかを知る方法は以下の通りです。(公式に発表されている方法ではなく、私が調べてみて実際に推測通りだと思われる方法になります。) 

    test.apkというようにAPKファイルができているとします。
    拡張子をzipに変えて、解凍します。解凍したら以下のようなフォルダ構成になっているかと思います。(Unityのバージョンによっては多少変わるかも知れません。)
    apkunzip

    assets以外のフォルダは削減することができないので、assets以下にあるリソースのうち容量の大きいものを探します。assets/bin/DataにRESOURCEファイルというものがあります。これはプロジェクトのResourcesフォルダ以下にあるアセットのバイナリだと思われます。
    この中の大きなものを削減すると効率的です。ファイル名がGUIDと一致するため、プロジェクトフォルダ内をgrepすることで元のファイル名を調べることができます。
    シーンに置いているゲームオブジェクト等はシーンの方にまとめられてしまうようで個別にサイズの大小を測ることができません。
    apkres
     
    上の画像で言うと、3番目の1f2c3a...とかいうファイル名がGUIDです。

    かなり手間がかかる方法なのですが、極端に大きなファイルがResourcesにあり、それがアプリを圧迫している場合には有効です。それ以外の場合だとResourcesを使っているときが有効だと思います。

      このエントリーをはてなブックマークに追加 Clip to Evernote
    Unity5では2つの種類があります。無料のPersonal Edition有料のProfessional Editionです。
    機能的な差はほぼありません。ゲームを作る上では差がないのですが、ゲーム起動時のスプラッシュスクリーンがUnityのロゴから変更できなかったり、Pro向けのサービスが使えないといった制限がPersonal版にはあります。といってもProfessional版がUnityから受けられるサービスで優遇されるというだけでPersonal版だと全く使えないというわけではないです。後から使えるようになったり、使える範囲が狭かったりするということです。

    pvsp
    どういう差があるか詳しい情報はこちらの公式サイトで説明されています。
    Asset Store Level 11というサービスは良いな~と思いますが、Personalで十分使えるというのが大多数の意見になるのではないでしょうか。

    ゲームを作るのに機能的に変わらないならProfessional版を買うなんてプロを気取った人だけだとお思いかもしれません。
    しかし、そうではなくてPersonal Editionを使うには条件を満たす必要があります。条件を満たさなければ自動的にProfessional Editionを選ぶことになります。(そうなってなかったらUnity作っている会社は儲かりませんし……)
    条件の詳細は「Unity Pro および Unity Personal ソフトウェアライセンス契約 バージョン 5.x」のユーザーが使用可能なバージョン-Unity Personal の収入制限に使用条件が書いてあります。詳細情報は上に載っていますが、FAQにも簡単に書いてあります。
    売り上げと使用者がどういった立場なのかによって条件が決まっています。
    個人または個人事業主なら、Unityを使って得た収入が1年で$10万(約1200万円)を超えた場合はPersonal Editionは使えません。趣味でゲームを作っている人なんかは大抵Personalを使えます。Unityを使って稼いだ額が10万ドルを超えるというのは使い始めではあり得ないし、相当すごいものを作らない限り超えることはないでしょう。
    企業などの法人の場合も額は$10万ですが、資金や予算が$10万を超えたらということなので大抵はProfessional Editionを使うということになります。Unityの使用による利益かどうかは関係ないので、始めからProfessional Editionになるでしょう。
    Personal Editionの使用条件を満たしていてもProfessional Editionを買って使うことは可能です。(どうしてもスプラッシュスクリーンを変えたい人やPro向けのサービスを使ってみたい人は買うことができます。)

    大雑把にいえば、Unity5の使用料は
    個人なら、無料
    それ以外なら、一人当たり$1500以上
    となります。

    Professional Editionの値段は$1500(今だと18万円)で永続ライセンスを買うか月$75(今だと9000円)の料金を払い続ける2通りになります。20カ月以上使うなら永続ライセンスの方が安くなるので、そちらを買うのが良いでしょう。
    iOSやAndroidにアプリを作る場合は$1500では足りません。追加でPro用のアドオンを買わなければなりません。ちなみに値段はProfessional Editionと同額です。つまりiOS/AndroidともにProfessional Editionでアプリを作るには$4500が必要です。

    10万ドルを超える利益を何年にもわたって得たとしてもUnity5の料金としてかかるのは一人当たり$1500です。利益に比例して料金を要求されるのではないため、非常に良心的と言えるでしょう。

    個人開発者としてはProfessional Editionを使わなくてはならないようになりたいものです。 

      このエントリーをはてなブックマークに追加 Clip to Evernote
    Unity Multiplayerを使ってオンラインゲームを作るといったときにはUnityを同時にいくつも起動するということがあるでしょう。複数のUnityを起動することでそれぞれが1つの端末としてデバッグすることが楽になるためです。
    作っているプロジェクトを丸ごとコピーするなどしてプロジェクトを増やすと、Unityとしてはそれらが別のプロジェクトとして認識し、同時に起動することができるようになります。
    別プロジェクトだけれども内容は一緒というのは管理しにくいので、それについてはバージョン管理ソフトを使って、複数の作業フォルダを作るというのがお勧めです。

    何度もやると、Unityを複数起動するのが面倒になってきます。
    色々な所にプロジェクトがあったりすると、いちいちウィザードから選んだり、フォルダのところに行ったりでわずらわしいです。
    ……なので、これを簡単に行う方法を私なりに実践しています。

    やり方はバッチファイルからUnityのプロジェクトを指定して同時に起動するという方法です。
    Unityはコマンドプロンプトからも起動できるので、バッチファイルで起動することができます。同時に起動するためにはstartコマンドを使う必要があります。使わないとコマンドが終わるまで次のコマンドが実行できないからです。startコマンドにより、本来終了してから次へという処理が同時に行えるようになります。

    以下のような内容のバッチファイルを作れば5つのプロジェクトが同時に開けます。プロジェクトのパスは全て異なるものにしてください。
    バッチファイルの作り方はテキストエディタに以下のコマンドをコピーして、ファイルを"ファイル名.bat"と名付ければバッチファイルになります。

    ここから
    set UNITY="C:\Program Files\Unity\Editor\Unity.exe"

    start "" %UNITY% -projectPath プロジェクトのパス1
    start "" %UNITY% -projectPath プロジェクトのパス2
    start "" %UNITY% -projectPath プロジェクトのパス3
    start "" %UNITY% -projectPath プロジェクトのパス4
    start "" %UNITY% -projectPath プロジェクトのパス5
    ここまでをコピペしてください。

    プロジェクトのパス1~5にはプロジェクトのあるパスで全て異なるように指定してください。 プロジェクトのあるパスとは、AssetsとかLibraryフォルダを含んでいるフォルダへのパスのことです。絶対パスで指定する方が問題が起こらないので、そうしてください。

    最後に起動してみたデモを載せておきます。 
    pre-nosou

    バッチファイルのアイコンが画面中央に表示されています。それをダブルクリックするとバッチファイルの内容が実行されます。ウィンドウがいくつも表示されているのでちょっとわかりづらいですが、複数のUnity起動されています。

      このエントリーをはてなブックマークに追加 Clip to Evernote
    『トランプ・ナポレオン』で通信対戦を作成したときに必要だったことを書いておきます。オンラインマルチプレイヤーのゲームに必要なことは大抵同じであるので、他のものを作るときにも参考になると思います。

    大きく分けて3つに分類できるでしょう。
    通信を開始するところ、つなげてから切断するまでと切断時で分けています。一般的にオンラインゲームを作るといった場合はつなげてから切断するまでに注目されていると思います。オンラインゲームというのは通信しているときだけなので当然ですが、接続をするところと切断するところはゲームの面白さとかには関係ないですが重要です。この部分はどのように作るかが作成者の考えによって大きく変わるようなので、正解がなく難しいです。
    以下の1と3が接続をするところと切断するところであり、2が通信中のところです。
    1. マッチメイキング 
    2. 同期
    3. 切断
    マッチメイキングはオンラインで一緒に遊ぶプレイヤーを見つけるための処理です。通信を確立する段階です。他のユーザーが知り合いの場合は別として、基本的には知らない人と遊びます。
    ユーザー同士が一緒に遊ぶにはまず相手を探さなければなりません。インターネットの仕組みではIPアドレスがわかると通信ができるようになります。このIPアドレスを相手に伝えれば良いのですが、どうやって伝えるかが問題になります。

    マッチメイキングでは特定の場所(固定されている)に自分の情報を登録し相手に見つけてもらうか、その逆を行います。自分と相手が同じところにアクセスして仲介してもらうことでIPアドレスを教えあうことになるわけです。
    固定されている場所というのはサーバーになるわけですが、自前で用意しなくてもUnity Multiplayerではサービスとして提供されます。(今後有料になるかもしれませんが、まだわかりません。) 


    2つ目に同期ということを行いました。 これは複数の端末間でのゲームの進行状況の足並みをそろえるための処理です。通信自体は確立してからの話になります。
    すべての状況を一致させるということは不可能ですが、大事な情報は一致させるということで同期が必要になります。リアルタイムで刻一刻と一致させる必要な場合もあれば、特定のタイミングで全員をそろえるという場合もあります。

    『トランプ・ナポレオン』 のようなトランプゲームでは特定のタイミングで同期すれば良いです。誰が何のカードを出したかというのをカードが出されるたびに情報の共有を行い、進行させていけばうまく行きます。ランダム要素がないなら、カードの情報だけ揃えればゲームの状況は一致します。(このようなときはゲームの処理は誰が行っても同じ結果になるので、端末ごとに処理を行う分散型の設計が可能です。)
    全員の進行状況をそろえる方法は単純です。先に処理が終わったユーザーは他のユーザーが終わるのを待っていて、全員の状況が同じであると判定されたら次に進むというようにしました。


    最後に切断です。おそらく一番面倒なことです。どういったやり方が良いのかというのは自分で決めなければいけません。
    切断が起こるタイミングはわからないので、起こる可能性のある箇所には対処を入れていく必要があります。変なタイミングで切断すると、アプリが動かなくなったりすることが結構起こります。頑張ってデバッグしましょう。

    『トランプ・ナポレオン』 の対処については以前に記事にしました。切断されてもゲームが続くというように設計されています。このようなことを行うにはゲームを途中から行えるような再現機能かオンラインとオフラインの処理が融合しているような作りが必要です。
    規模が大きい場合は切断時に一旦ゲームを終了して、その後同じ状況に復帰させるという作りが安全だと思います。(切り替えに時間がかかりますが、オンラインとオフラインの処理が完全に切り離せるので問題が置きにくいはずです。) 
    オンラインとオフラインの処理が融合しているというのは同期の部分をif文で分岐しているというだけです。 各ユーザーが処理すべきところもコンピュータで処理するように置き換えるようになっていれば問題ありません。コードがわかりにくくなるデメリットが大きいですが、即座に切り替わるというのはメリットです。 

    このページのトップヘ