tanaka's Programming Memo

プログラミングについてのメモ。

Unity2017でのWebGLのビルドエラー Sharing violation on path について

問題

以前、node.exeを古いものにすると直る、というやつは書いたのですが、その後、以下のようなエラーが発生するようになりました。

IOException: Sharing violation on path C:\Users\Public\Documents\Unity17\webglbuildtest\Temp\StagingArea\Data\Output\Build\WebGL.asm.code.unityweb.compressed System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean anonymous, FileOptions options) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.IO/FileStream.cs:320) System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share) (wrapper remoting-invoke-with-check) System.IO.FileStream:.ctor (string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare) System.IO.File.Open (System.String path, FileMode mode) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.IO/File.cs:347) UnityEditor.WebGL.WebGlBuildPostprocessor.SetGzipComment (System.String path, System.String comment) (at /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/BuildPostprocessor.cs:802) UnityEditor.WebGL.WebGlBuildPostprocessor.CompressAndMarkGzip (System.String path) (at /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/BuildPostprocessor.cs:827) UnityEditor.WebGL.WebGlBuildPostprocessor.CompressBuild (BuildPostProcessArgs args) (at /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/BuildPostprocessor.cs:862) UnityEditor.WebGL.WebGlBuildPostprocessor.PostProcess (BuildPostProcessArgs args) (at /Users/builduser/buildslave/unity/build/PlatformDependent/WebGL/Extensions/Unity.WebGL.extensions/BuildPostprocessor.cs:924) UnityEditor.PostprocessBuildPlayer.Postprocess (BuildTargetGroup targetGroup, BuildTarget target, System.String installPath, System.String companyName, System.String productName, Int32 width, Int32 height, BuildOptions options, UnityEditor.RuntimeClassRegistry usedClassRegistry, UnityEditor.BuildReporting.BuildReport report) (at C:/buildslave/unity/build/Editor/Mono/BuildPipeline/PostprocessBuildPlayer.cs:272) UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

Error building Player: 2 errors

Build completed with a result of 'Failed' UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

UnityEditor.BuildPlayerWindow+BuildMethodException: 3 errors at UnityEditor.BuildPlayerWindow+DefaultBuildMethods.BuildPlayer (BuildPlayerOptions options) [0x0020e] in C:\buildslave\unity\build\Editor\Mono\BuildPlayerWindowBuildMethods.cs:181 at UnityEditor.BuildPlayerWindow.CallBuildMethods (Boolean askForBuildLocation, BuildOptions defaultBuildOptions) [0x00065] in C:\buildslave\unity\build\Editor\Mono\BuildPlayerWindowBuildMethods.cs:88 UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)

エラーのタイミングは、以下の圧縮時のようです。

f:id:am1tanaka:20180117145753p:plain

解決策

原因は、GZIP圧縮のようでした。以下の手順で圧縮をしないようにするか、あるいは圧縮方式をBrotliに変更すると、ビルドできるようになりました。

  • Editメニューから、Project Settings -> Playerを選択
  • InspectorビューのPublising Settings欄を開いて、Compression Formatを"Gzip"から"Disabled"に変更する(あるいはBrotli)

f:id:am1tanaka:20180117150217p:plain

まとめ

圧縮しないと容量が大きくなりますし、BrotliChromeFirefox、Edgeには対応していますが、Safariは非対応のようです(Unity - マニュアル: webgl-deploying)。

学校の一部のPCでのみ発生している不具合で、一般的な不具合ではなさそうです。とりあえず応急処置ということで。根本的な原因をつきとめたら追記します。

Unity1週間ゲームジャム Meetup in Tokyo #1 に参加しました!

1/13(土)はこちらのイベントに参加してきました!

connpass.com

2017年度から専門学校のウェイトを増やしたことで、今年度は久々にゲーム開発に復帰しました。学生さんも含めて良い発表の場を探していたところで始まったのがUnity1週間ゲームジャムでした。気づいたのは最初のお題が終わったあとでしたが、すかさず2回目を学生さんにアナウンスして、自分も参加することにしました。こんなもんでいいだろ〜と出したら、恐ろしいレベルの作品がばかすか出てきてビビりましたが、とても良い刺激になりました。マイペースを保って参加を続けていくうちに学生さんも作品を公開するようになり、最高のプラットフォームになっています。

そのUnity1週間ゲームジャムの集会を、毎回素敵なゲームを公開されている青木ととさんが主催され、naichiさんがいらっしゃるということで、これは行かねばと参加を決めました。

雰囲気は、Unity1週間ゲームジャムのゆるさそのまま!お隣にいらっしゃった新ソックスさん、たーぼぉさんはじめ、みなさん気さくにお話しして下さいました。Unity1週間ゲームジャムに参加していれば、安心して参加できると思います。

しかしそこはUnity1週間ゲームジャム。試遊になるとギョッとするハイレベルの作品が並ぶのですけどね。でも、凄い作品の作者さんと和やかにお話できるので、一人で遊ぶのと違ってショックはなく、素直に楽しいと感じられるのではないかと思います。これはどうやって...と感じたところは質問できますし、苦労話も聞けてあっという間の試遊時間でした。

新ソックスさんが、熱くなってクリアした体当たり戦士少年イーサン | 無料ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しようの作者さんだったと知って、作者さんが集まるイベント面白い、と実感しました。

自分の展示の番になり、以下の学生さん作品を展示しました。

遊んで下さり、ご意見・ご感想を頂戴し、本当にありがとうございました。いただいた感想は学生さんに伝えます。

それぞれ遊んでいただいた中で、群を抜いて盛り上がったのがトド君のWhite Walkerでした。何人かが集まって、あれこれ解法を考えられるシステムが、今回の展示にマッチしていたと感じました。トド君は、ドット絵に拘りを持っていて、独特の雰囲気を持っていて、考えるルールも面白いので、作品を完成する力がつけば、これからも良い作品を生み出してくれそうです。とりあえず、Jupmを直して、タイトルに戻れるようにしよう。

ルナ氏はただの重力球君、ぜう君、深田君の作品は、11月のスペースのお題の時に公開されたもので、正月休みの課題として作成されたWhite Walkerより早くに完成した作品でした。3人は、Unity Asset Portalさんの「お題にチレンジ!Vol.4: クリスマスのスクリーンショット」に出展したり、新作も作ったり、精力的に活動しています。他のみんなも、このペースに巻き込まれて盛り上がってくれればと願ってます。そして、次回があれば、学生さんに参加してもらいたいです。

アッキーさん、しもむ〜さん、新ソックスさん、たーぼぉさん、Ryoyaさんの皆さんと一緒に盛り上がっていたらあっという間に展示時間が来てしまい、後半の部の方の作品は、最後の最後にNoSeamsさんのを遊ばせていただいただけで終わってしまいました。

ランキングでお世話になっております、すずきかつーきさんとお話できたり、ころがり勇者にハマり倒した者としてはすしさんとお話できた上にカモのご感想やアイディアまでいただき恐悦至極でした。センスに脱帽し続けている えれのあ さんの新作はやはり光るものがあり、一度見たら忘れない うえすと さんの芝犬で和み、他にもまだまだありましたが書ききれず、ご容赦を。参加者の皆さんのIDは参加者一覧で確認できるので、あとで遊んでコメント残して回る所存です!

次回以降参加する場合...

名刺、作ります...。パネルがあればいいだろうと安易に考えていたのですが、いざイベント中になると名刺の方がぜんぜん楽ですね...。

名刺ですが、Unity1週間ゲームジャム関連であれば、以下のようなことを載せておけば良さそうかなと個人的には感じております。

  • ハンドル名とツイッターのサムネイル
  • 作品のURLや写真、QRコードなど、裏面とかでいいので
  • サムネイルと実物が大幅に違う場合は、不鮮明でいいので、顔写真か全身写真があるとあとで思い出しやすいです

怖い人はいないので、ゆるくてオッケーです。後日、思い出す助けになるものだとありがたいと、人の顔を覚えられない&忘れる能力の持ち主としては希望しております。

最後に

今回のMeetupでは青木ととさんの素晴らしい手配と、スタッフの皆様のご尽力により、素晴らしい時間を過ごすことができました。ありがとうございました。これからも素敵なゲームを楽しみにしております。また、もし学校の方で進展がありましたらお伝えします。

naichiさんにお礼を伝えることが叶いました。年齢的にも、ガチのハッカソンとかは参加すると健康が危ない感じなので、Unity1週間ゲームジャムのゆるさには本当に救われております。学生さんが世の中に出て行くきっかけとしても最適な環境の一つだと感じております。ありがとうございます。

会場を提供してくださった株式会社ORATTAさん、素敵な会社でした。休日にも関わらず会場の手配やお世話をしてくださり、本当にありがとうございました。オリジナル企画で勝負しているのが素晴らしいです。学生さんにゲーム勧めてみます。もう遊んでるかもですが。

Ichijoさんがお持ち下さいましたニフティさんのPAPER PROTOTYPING NOTE、最後のものを学生さんへということで頂戴いたしました。学生さんにしっかりと届けて、糧にいたします。ありがとうございました。

Unityビール、まさか自分も入手できるとは思ってませんでした。バウチャーイベントなどでも大変お世話になりましたUnityの皆さん、ありがとうございました。

最後に、一緒に参加した皆様、良い場を共有できて、色々とお話下さいまして、本当にありがとうございました。あの方にご挨拶してみたかった、とか、お礼をお伝えしたかった、という心残りもありますが、次がありましたらと願っております。素晴らしい会でした!

Projenyを少し使ってみて分かったことメモ

Projenyの概要や使い方は、以下にまとめてあります。

am1tanaka.hatenablog.com

am1tanaka.hatenablog.com

ここには、使ってみて気付いたことを書いていきます。

目次

Unity CollaborateとCloud Build、問題なく動作

表題の通りですが、問題なく使えました。Asset Storeのアセットを共有パッケージに組み込んだものも問題なしでした。

プラットフォームの切り替え時のエラー

WebGLにプラットフォームを切り替えようとしたときにエラーが発生しました。原因はHDDの容量不足でした。こちらの対応をして容量を削減したら、切り替え成功しました。

エラーが一度出ても、切り替えたら問題なく動いたこともありました。少々動作が不安定かも知れません。一度Windowsに切り替えてから、もう一度切り替えなおすなどすることで、直るかも知れません。

シーンが切り替わらない

事前に作成していたプロジェクトで発生しました。原因は、BuildSettingsに登録していたシーンのパスが変わったことでした。Projenyでは必ずパッケージに加える必要があるため、ルートにあるScenesフォルダーなどにシーンをまとめて入れていた場合、パッケージ名をパスの先頭に付加しないとアクセスできなくなるのです。

FileメニューのBuild Settingsを開いて、登録済みのシーンを削除して、設定しなおせば直ります。

Projeny.yamlの優先順位

Projenyの環境変数などの設定ファイルであるProjeny.yamlは、ホームフォルダー直下と、Projenyプロジェクト内にそれぞれ配置することができます。違う内容のファイルを配置することができて、片方に無い設定がもう片方にあれば、その設定を使うことができます。

そこで、デフォルトの設定をホームフォルダー直下のProjeny.yamlに書いておいて、それと別の設定をしたい場合はプロジェクトフォルダー内のProjeny.yamlに上書き設定ができないか試しました。結果、駄目でした。双方に設定があるものは、ホームフォルダー直下のものが優先されてしまいました。残念。。。

大きなAsset Storeのアセットを利用する場合

Projenyの魅力は、別々のプロジェクトで同じAsset Storeのアセットを利用する場合に、展開したリソースを共有できる点にあります。しかし、Unityで利用する際にはリソースを更にプラットフォームごとにリビルドしたテンポラリーファイルを持つことになり、これが元のリソース以上に容量を消費します。そのため、Ultimate VFXUI - Builderといった、多くの画像や音声リソースを持つアセットは扱いを注意する必要があります。

そのような大きなアセットは、共有ではなく、プロジェクトのパッケージに展開して、不要なリソースを削除した方がよいです。例えば以下のようにします。

  • Unityで、ProjenyメニューからPackage Managerを起動
  • 左の三角ボタンをクリックして、"Releases"を表示
  • "Packages"を、"[ProjenyPackagesDir]"などのプロジェクト個別のパッケージにして、そこにアセットをドラッグする
  • 右の三角ボタンを一回クリックして画面を切り替える
  • "Packages"に読み込んだアセットを、"Projects"の"Plugins Folder"にドラッグ&ドロップ
  • "Update Directories"ボタンをクリック

アセットの登録先のパッケージを、プロジェクト個別のものにするところがミソです。"[SharedUnityPackagesDir]"などの共有パッケージにしてしまうと削除した影響が他のプロジェクトにも作用してしまうからです。これだと、他のプロジェクトでリソースを共有するというウマみが無くなりますが、プラットフォームごとに巨大なテンポラリーファイルを作られるのに比べると小さな影響です。

Asset Storeのリソースが組み込まれることになるので、公開リポジトリーなどで管理するのは問題になる恐れがありますので、プライベートリポジトリーが使えないような場合は、.gitignoreに登録するための個別のパッケージをProjeny.yamlProjenyProject.yamlに設定して、Asset Storeのパッケージはそこに登録した方がよいかも知れません。

まとめ

2,3日使ってみた感じではこんなところでした。また新しいものが出てきたら追記していきます。

Projenyチュートリアル:Unityプロジェクトを作成する

f:id:am1tanaka:20171231170411p:plain

Unity用のパッケージマネージャーであるProjenyを使ってUnityのプロジェクトを作ります。

目次

作るプロジェクトの方針

Projenyは複数のUnityのプロジェクトをまとめて扱えます。しかし、Gitなどでバージョン管理することを考えると、1つのProjenyプロジェクトに全てのUnityのプロジェクトを放り込むより、プロジェクトごとにProjenyプロジェクトを作成して、まとめてGitで管理した方が楽そうです。Asset Storeや共有するパッケージは、全てのProjenyプロジェクトから参照できる場所に配置します。

以下のような4階層にします。

f:id:am1tanaka:20180103005530p:plain

どこを共有するのか、プロジェクトとして分けるのか、Gitで管理できるかなどを考えると、こんな感じかなという提案です。赤の部分は、一度作成したら、他のプロジェクトでも共有するものです。それ以外の3つは、プロジェクトごとに作成するのが良さそうだと考えています。

Projenyプロジェクトのフォルダー以下には、Asset Storeのアセットなどは含まないような構成なので、MITライセンスなどのプロジェクトならGitHubに登録して公開してもよいでしょう。

Asset StoreやカスタムのUnityPackageを入れるCustomPackagesフォルダーやGeneralSharedPackagesフォルダーは共有しないか、共有する場合はプライベートリポジトリーにしたり、限定公開設定のクラウドなどで共有するとよいでしょう。

前提条件

  • Windows7 64-bit
  • Projenyはインストール済み。まだの場合はこちらに従ってインストールしてください
  • Unity2017.3 + Visual Studio 2017
  • Gitをインストール済み

共有部分の作成

まずはProjenyの設定ファイルをユーザーフォルダー直下に作成します。

共通のProjeny.yamlの作成

  • コマンドプロンプトを起動します
  • ユーザーフォルダーの場所で開いていることを確認(別の場所だったら、cd %USERPROFILE%などで移動)
  • prj -ccを実行して、設定ファイルを作成します

f:id:am1tanaka:20180102160657p:plain

PathVars:
    # 全てのProjenyプロジェクトが利用する共有パッケージフォルダー
    SharedUnityPackagesDir: 'C:\Users\YourUserName\Documents\UnityProjeny\GeneralSharedPackages'

    # UseDevenv設定がtrueの場合に利用される設定。
    # Visual Studio Solutionの操作で失敗する場合、以下のパスが正しいか設定する。
    VisualStudioCommandLinePath: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\devenv.com'
    # Package Managerの"Open Solution"ボタンや、`prj -ocs`コマンドを実行した時に使われる。
    VisualStudioIdePath: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\devenv.exe'

# 独自のReleaseソースを指定する。
ReleaseSources:
    - LocalFolder:
        Path: 'C:\Users\YourUserName\Documents\UnityProjeny\CustomPackages'

設定されているパスは、ご自身の環境に合わせて変更してください。また、YourUserNameの場所は、ご自身のユーザー名に変更してください。

フォルダーの作成

  • 必要なフォルダーを作成します。Projeny用のプロジェクトフォルダーを作成したいところへ移動します
  • 以下でフォルダーを作成します(変更しても構いません)
mkdir UnityProjeny
mkdir UnityProjeny\CustomPackages
mkdir UnityProjeny\GeneralSharedPackages

以上で共有部分の作成は完了です。ここまでの作業は、最初の1回だけやります。

Projenyプロジェクトの作成

個別のプロジェクトのためのProjenyプロジェクトを作成します。

  • コマンドプロンプトを開きます(開いていたら、そこで作業を継続して構いません)
  • 先に作成したUnityProjenyフォルダーの中にcdで移動します。
  • 以下のコマンドを実行します。taiken03-201703の部分は例のプロジェクト名なので、自由に変更してください
mkdir taiken03-201703
cd taiken03-201703
prj -cc

これで、プロジェクト用のフォルダーを作成して、cdで中に移動して、以下が自動生成されます。

  • プロジェクト用のProjeny.yaml
  • UnityPackagesフォルダー
  • UnityProjectsフォルダー
  • UnityProjectsフォルダー内のデフォルトのProjenyProject.yaml

このフォルダーのProjeny.yamlは以下のようにしました。

PathVars:
    UnityProjectsDir: '[ConfigDir]/UnityProjects'
    ProjenyPackagesDir: '[ConfigDir]/UnityPackages'
    LogPath: '[ConfigDir]/PrjLog.txt'
    # Unityの場所。デフォルト以外の場所にしていたら、以下を設定すること
    # UnityExePath: 'C:\Program Files\Unity20170300\Editor\Unity.exe'

DefaultProject: taiken03-201703

共有パッケージはホームフォルダーで指定したので、ここではProjenyPackagesDirの設定に変更して、このプロジェクト用のパッケージ置き場を指定しました。また、このフォルダーではデフォルトのプロジェクトはtaiken03-201703なので、その設定を加えました。

Unityのバージョンはプロジェクトごとに異なる可能性があるので、UnityExePathの雛形をコメント行に加えてあります。Unityをデフォルトの場所以外にインストールしていたり、複数バージョンのUnityを利用している場合は、UnityExePathのコメントを外して、使いたいUnityのパスを設定してください。

UnityProjects/ProjenyProject.yamlファイルは以下の通りです。恐らく変更は不要だと思いますが、コメントをつけておきました。これで、このProjenyプロジェクト内で共有するパッケージの場所をProjenyPackagesDir、全てのProjenyプロジェクトで共有するパッケージの場所をSharedUnityPackagesDir、Unityプロジェクト内でのみ使うパッケージの場所をUnityのAssetsフォルダー下のPackagesフォルダーに設定しています。

PackageFolders:
    # このProjenyプロジェクト全体で共有するパッケージフォルダーの指定です
    # 特に問題がなければ、このプロジェクトのパッケージはここに作ります
    - '[ProjenyPackagesDir]'
    # 全てのProjenyプロジェクトで共有するパッケージフォルダーの指定
    - '[SharedUnityPackagesDir]'
    # [ProjectRoot] は UnityProjects/YourProjectName を示します
    # Unityプロジェクト専用のパッケージがあれば、この下に配置します
    - '[ProjectRoot]/Packages'

Unityプロジェクトの作成

Projenyのプロジェクトはできたので、次にUnityプロジェクトを作成します。先に作成したC:\Users\YourUserName\Documents\UnityProjeny\taiken03-201703フォルダーで作業します。

Gitでバージョン管理をしたい場合は、Unity用のプロジェクトを作成する前にGitの初期化をしておきます。これを事前にやっておくことで、.gitignoreファイルが自動的に生成されます(バージョン管理をしない場合は飛ばして構いません)。

git init

次に以下で、Projenyプロジェクト内のUnityProjectsフォルダー内にターゲットとなるプロジェクトを作成して、初期化をします。

prj -p taiken03-201703 -cpr
prj -in

以上で、UnityProjectsフォルダー内にtaiken03-201703フォルダーが作成されて、その中のtaiken03-201703-WindowsフォルダーがUnity用のプロジェクトになります。

作成したプロジェクトの使い方

作成したProjenyプロジェクトは以下のような構成になります。

f:id:am1tanaka:20180102175510p:plain

このフォルダー下は、.gitignoreで定義されたフォルダー以外は全てGitで管理することを想定しています。

それでは、Unityでtaiken03-201703-Windowsフォルダーを開きましょう。

新しいシーンやスクリプトを作成する

ここからの作業は、手順としては公式マニュアルには書かれていないので手探りで理解しました。

Projenyでは、全てのリソースは何からのPackageに属している必要があります。そのため、いきなりシーンを保存しようとしたり、新しいスクリプトを作成すると、以下のようなエラーが発生します。

f:id:am1tanaka:20180102223012p:plain

「Projenyが関知しないところにディレクトリーが作成されたので、このデータを失う可能性がある。全てのユーザーデータは、UnityPackagesディレクトリー内になければならない。」ということです。

では、このUnityプロジェクトのパッケージを作ります。

  • UnityのProjenyメニューからPackage Manager...を選択して開きます

f:id:am1tanaka:20180102181427p:plain

  • 左三角をクリックして、Packagesを表示します

f:id:am1tanaka:20180102223816p:plain

  • "Packages"の下のコンボボックスをクリックして開いて、[ProjenyPackagesDir]を選択します。ここがこのProjenyプロジェクトの共有パッケージで、このプロジェクト用に作成するリソースは基本的にこのパッケージに設定します

f:id:am1tanaka:20180102221710p:plain

  • [New]をクリックします

f:id:am1tanaka:20180102221936p:plain

  • パッケージ名を入力して、"Submit"ボタンをクリックします。パッケージ名はここではtaiken03-201703としました

f:id:am1tanaka:20180102222030p:plain

  • これでパッケージができました。これだけだとまだUnityが使えるようになりません。作成したパッケージをドラッグして、"Assets Folder"にドロップします

f:id:am1tanaka:20180102222214p:plain

  • "Update Directories"ボタンをクリックすると、Directory Linkに反映されて、UnityのProjectビューにtaiken03-201703フォルダーが表示されます

以上でパッケージが出来上がります。これ以降、このプロジェクトのリソースはこのtaiken03-201703フォルダーの中に保存していきます。

簡単なシーンを作ってみる

試しに、球を操作できるような簡単なシーンを作ってみます。

  • ProjenyのPackage Managerはとりあえず不要なので、[x]ボタンをクリックして閉じます
  • Projectビューの"taiken03-201703"を右クリックして、Create -> Folderを選択して、フォルダーを作成します

f:id:am1tanaka:20180102232229p:plain

  • フォルダーの名前をScenesにします
  • [Ctrl]+[S]キーを押して、シーンを保存します
  • "Save Scene"ダイアログが表示されたら、taiken03-201703 -> Scenesと開いて、Tameshiなどのファイル名で保存します

これで以下のようにシーンが保存できました。

f:id:am1tanaka:20180102222906p:plain

これでHierarchyの変更はこのシーンに保存されます。では、球を作成します。

  • HierarchyビューのCreateから3D Object -> Sphereを選択します

f:id:am1tanaka:20180102224106p:plain

  • 操作するためのスクリプトを作成します
  • Hierarchyビューに作成したSphereを選択します
  • Inspectorビューの下の"Add Component"ボタンをクリックして、Physics -> Rigidbodyを設定します
  • Inspectorビューの下の"Add Component"ボタンをクリックして、New Scriptを選択します

f:id:am1tanaka:20180102224331p:plain

  • スクリプト名は適当にSousaなどにしておきます
  • この場所はPackage外ですのでProjenyに怒られます。taiken03-201703パッケージに新しい‘Scripts`という名前のフォルダーを作成して、その中に移動しましょう

f:id:am1tanaka:20180102224548p:plain

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof (Rigidbody))]
public class Sousa : MonoBehaviour {

    [TooltipAttribute("移動速度")]
    public float SPEED = 10f;
    private Rigidbody rb;

    // Use this for initialization
    void Start () {
        rb = GetComponent<Rigidbody>();
        rb.useGravity = false;
    }
    
    // Update is called once per frame
    void Update () {
        Vector3 ctrl = new Vector3(
            Input.GetAxisRaw("Horizontal"),
            Input.GetAxisRaw("Vertical"),
            0f
            );
        Vector3 vel = ctrl.normalized * SPEED;
        rb.velocity = vel;
    }
}

できたら、上書き保存をしてUnityを実行してください。矢印キーや、[W][A][S][D]キーで球が操作できます。

f:id:am1tanaka:20180102225248p:plain

ここまでの作業で、追加されたり変更があったフォルダーやファイルは以下の通りです。

f:id:am1tanaka:20180102225608p:plain

スクリプトやシーンが、"UnityPackages"フォルダーに追加されていることが分かります。本来、Unityのリソースは、Unityプロジェクトフォルダー内の"Assets"フォルダーにあるのですが、Projenyを使うとその構造が変わる、ということが見てとれます。これが、後のAsset Storeや共有パッケージの利用時に役立つのです。

Asset Storeのアセットの利用

Asset Storeのアセットの組み込み方です。これがProjenyを使ってみようと思いたった機能です。

アセットを利用するには、以下の手順を踏みます。

  • Asset Storeからアセットをダウンロード(これまでにダウンロードしたことがあるアセットでは不要です)
  • "Releases"から、共有パッケージにドラッグ&ドロップして加えます
  • パッケージからPluginフォルダーに加えます
  • Directory Linkを更新します

最初のステップは省略できる場合が多いので、まずは"Releases"から共有パッケージに加える作業から試みましょう。

アセットを共有パッケージに加える

Asset Storeのアセットは、共有パッケージフォルダーに展開します。この作業は一度やれば、2回目以降は最初から共有Packagesに列挙されるので飛ばすことができます。

  • UnityのProjenyメニューからPackage Manager...を選択して開きます
  • 赤枠で囲んだ辺りにある左三角ボタンを、"Releases"欄が表示されるまでクリックします

f:id:am1tanaka:20180102181611p:plain

Asset StoreのパッケージはGitで管理したくないので、"SharedUnityPackagesDir"に加えます。

  • ウィンドウ右上の"Packages"の下のコンボボックスをクリックして、[SharedUnityPackagesDir]に変更します。

f:id:am1tanaka:20180103191941p:plain

"SharedUnityPackagesDir"は、ホームフォルダー直下のProjeny.yamlに加えた設定で、Gitで管理しない位置の共有用フォルダーを指しています。使いたいアセットを"Releases"からドラッグして、"Packages"欄の下にドロップして加えていくと、"SharedUnityPackagesDir"で指定したフォルダーにAsset Storeのアセットが展開されていきます。

以下、"Allosaurus"と"Post Processing Stack", "Unity Particle Pack", "Japanese Otaku City"を加えた例です。

f:id:am1tanaka:20180103192127p:plain

足りないアセットをAsset Storeからダウンロードする

必要なアセットが全て揃っていたら、次へ進んでください。使いたいアセットが無かった場合の手順です。

  • UnityのWindowメニューからAsset Storeを開きます
  • Sign in してなかったらします
  • 欲しいアセットを検索して、必要なら購入します
  • "ダウンロード"ボタンをクリックして、ダウンロードします。以下は、Standard Assetsを例にしています

f:id:am1tanaka:20180102233210p:plain

  • ダウンロードが完了したら自動的に展開されて、インポートするかを聞かれますが、インポートはしないでください!

f:id:am1tanaka:20180102233809p:plain

直にインポートしてしまうと、新しいフォルダーを作った時と同様、Projenyが管理するべきフォルダーを無視して読み込んでしまいます。読み込みもProjenyのPackage Mangerで行う必要があります。

必要なアセットを全て上記の流れでダウンロードだけしてください。完了したら、アセットを共有パッケージに加えるの手順で、共有Packageに加えてください。

間違えてインポートしてしまったら

簡単に取り消す方法はないので、一つ一つ削除するしかありません。まずはエラーを確認して、問題のフォルダーを見つけます。

以下のように、"The directories in question are following:"という行と、"UnityEngine.Debug:LogError(Object)"という行の間に、問題のフォルダーが表示されています。

f:id:am1tanaka:20180102235116p:plain

これをProjectビューなどで見つけて削除してください。

f:id:am1tanaka:20180102235406p:plain

削除後、エラーが表示されなくなったらOKです。

PackagesのアセットをPlugins Folderに追加する

ここまでだと、パッケージを展開しただけで、Unityプロジェクトには組み込まれていません。Plugins Folderに読み込む必要があります。

  • Package Managerを開いていなかったら、UnityのProjenyメニューからPackages Manager...を選んで開きます
  • 左右どちらかの三角をクリックして以下の"Packages"と"Project"が表示される画面にします

f:id:am1tanaka:20180103000247p:plain

  • "Packages"の下のコンボボックスが"[SharedUnityPackagesDir]"になっていなかったら、クリックして開いて選択します
  • "Packages"のリストから、使いたいアセットを選択して、"Plugins Folder"にドラッグ&ドロップします。

f:id:am1tanaka:20180103192438p:plain

  • "Update Directories"ボタンをクリックします

以上で、追加したアセットへのDirectory Linkが生成されて、Unityのプロジェクトにアセットが組み込まれます。最初の一回は、リソースの再構築が必要なので、作業が完了するまでしばらく待ってください。以下のウィンドウが表示されたら"I Made a Backup, Go Ahead!"をクリックしてください。

f:id:am1tanaka:20180102184334p:plain

Pluginsフォルダーに追加したので、以下のようにProjectビューのPluginsフォルダー下に配置されます。

f:id:am1tanaka:20180103001157p:plain

一度登録したアセットは、"SharedUnityPackagesDir"を同じ場所に指定すれば、他のProjenyプロジェクトでもすぐにPackages欄から使えるようになります。2回目以降はインポート時間や容量を減らすことができます。

組み込んだアセットの削除方法

先にインストールしたアセットのうち、"Post Processing Stack"は、"Unity Particle Pack"に含まれているので、スクリプトでエラーが発生してしまいました。このような時のアセットの削除方法です。

  • UnityのProjenyメニューからPackage Manager...を選択して開きます
  • Plugins Folderから不要なパッケージを選択します
  • [Delete]キーなどでリストから削除します
  • "Update Directories"ボタンをクリックします

f:id:am1tanaka:20180102185231p:plain

実ファイルを削除しなくても、これでDirectory Linkが削除されて、Unityプロジェクトから削除することができます。

GitHubなどで公開にする時の設定

ここまでの説明では、非公開の共有Packagesと、公開の自分のPackagesの主に2箇所での設定でした。しかし、GitHubで公開を前提とした場合、パスワードや重要な情報はダミーにして、テスト用のものは非公開のPackageを用意した方がよさそうです。

例えば、Projenyプロジェクト直下のProjeny.yamlに、以下のようにIgnorePackagesDirという設定を追加します。

PathVars:
    UnityProjectsDir: '[ConfigDir]/UnityProjects'
    ProjenyPackagesDir: '[ConfigDir]/UnityPackages'
    IgnorePackagesDir: '[ConfigDir]/IgnorePackages'
    LogPath: '[ConfigDir]/PrjLog.txt'
    # Unityの場所。デフォルト以外の場所にしていたら、以下を設定すること
    # UnityExePath: 'C:\Program Files\Unity20170300\Editor\Unity.exe'

DefaultProject: taiken03-201703

次に、同じフォルダーの.gitignoreに以下の設定を追加します(なければファイルを作成します)。

**/IgnorePackages/**
**/IgnorePackages.meta

UnityからProjenyメニューのPackage Manager...を選択して開いて、Projectの"Edit"ボタンをクリックします。

f:id:am1tanaka:20180104002827p:plain

しばらく待つと、Visual Studioなどで、ProjenyProject.yamlファイルが開きますので、以下のように[IgnorePackagesDir]を加えます。

PackageFolders:
    # このProjenyプロジェクト全体で共有するパッケージフォルダーの指定です
    # 特に問題がなければ、このプロジェクトのパッケージはここに作ります
    - '[ProjenyPackagesDir]'
    # 全てのProjenyプロジェクトで共有するパッケージフォルダーの指定
    - '[SharedUnityPackagesDir]'
    # [ProjectRoot] は UnityProjects/YourProjectName を示します
    # Unityプロジェクト専用のパッケージがあれば、この下に配置します
    - '[ProjectRoot]/Packages'

    # GitHubで管理しないパッケージ
    - '[IgnorePackagesDir]`

あとは以下の通り、Unityで設定します。

  • Package Managerで"Packages"を開きます
  • コンボボックスを[IgnorePackagesDir]にします
  • [New]ボタンをクリックして、IgnorePackagesという名前のパッケージを作成します
  • それを"Project"のAssets Folder欄にドラッグ&ドロップして、"Update Directories"をクリックします

以上で、UnityにIgnorePackagesというフォルダーが表示されます。この中に入れたリソースは、GitHubにはアップされません。

まとめ

Projenyでプロジェクトを構築して、リソースの新規作成や組み込み、Asset Storeのアセットの組み込みができるようになりました。

Projenyでは、全てのリソースは何れかのPackageに属さなければいけない、ということを念頭に入れておく必要があります。Packageフォルダー内であれば、削除や追加は普通の操作でできますが、Packageを削除する場合は、Package Managerを使う必要があることも注意です。また、フォルダー構造を変えたら、"Update Directories"をクリックすることも忘れてはいけません。

Asset Storeのアセットのうち、個別のフォルダーやファイルの読み込みをキャンセルしたり、あるプロジェクト向けの改変をしたい時などは、予めプロジェクトを分けるなどの運用上の工夫も必要になりそうです。

学習コストがやや必要で、まだ手放しで利用を推奨できる完成度には至っていないと思います。しかし、一度理解して環境を作ってしまえば、Asset Storeのアセットを使い回す時の手間が減るのと、容量が膨らまないという点だけでも、個人的には大きなメリットだと感じます。また、プロジェクトをPackageごとに簡単にフォルダーに分割できるので、Gitで管理するか楽になりました。

しばらくは使い続けてみようと思います。

参考URL

TextMesh Proのスプライトアセットを入れておくフォルダー

Sprites, TextMesh Pro Documentationを読むと、Resources/Spritesフォルダーにスプライトアセットを放り込んで、<sprite="スプライト名" index=?>で表示できる」とある。しかし、うまく行かない。

で、TextMesh Proのデフォルトのスプライトの設定方法 - tanaka's Programming Memoとかで誤魔化したのですが、冷静に考えてみれば指定できない訳ないだろう、ということで調べたら分かりました。

答えはこちら → Settings, TextMesh Pro Documentation

セッティングにフォルダーの指定が追加されていて、デフォルト値がどうやらSprite Assetsに変わっている模様・・・。自分のTMP Settingsを確認したら、確かにResources/Sprite Assetsになっている。

f:id:am1tanaka:20180103233503p:plain

ということで、numbersというスプライトアセットを以下の場所に配置しました。

f:id:am1tanaka:20180103233211p:plain

そして、<sprite="numbers" index=0>でちゃんと表示できました。

Projeny - Unity用のプロジェクトとパッケージマネージャー

f:id:am1tanaka:20171231170411p:plain

Zenjectと同じ開発元からGitHubで公開されているUnity用のプロジェクトとパッケージマネージャーです。ざっくりと、以下のような機能を提供するものです。

  • Assetフォルダーをリンクで構成することで、プロジェクトと、スクリプトやプレハブなどを分離します
  • 分離したスクリプトやプレハブは、他のパッケージやプロジェクトからリンクで参照できます
  • これにより、容量を削減したり、複数のプラットフォーム間での移動を簡易化することができます
  • ダウンロード済みのAsset Storeのデータを管理する機能もあります。

2017/12/31時点では、Unity5.3+Visual Studio 2013向けに開発されたものが提供されています。それが原因か、うちの環境が悪いのか分かりませんが、とりあえずUnity2017.3+Visual Studio 2017だと、Visual Studio Solutionに関連する一部の機能が動作しませんでした。リポジトリーの最終の更新は、1月前ぐらいなので開発が止まっている訳ではないようですが、Zenjectに比べるとIssuesへの対応も鈍く、プロダクトで使うのは不安かも知れません。MITライセンスなのでバリバリ手を入れて使う覚悟があればいいかも知れません。

以下、公式のGitHubページのドキュメントを読んだメモです。2017/12/31現在、使えるのはWindowsのみです。

目次

公式のREADMEをざっと意訳

GitHub - modesttree/Projeny: A project and package manager for Unityのドキュメントのざっとした意訳です。訳の精度は怪しいので、おおよその機能を把握するなどのお役に立てば幸いです。

Introduction

ProjenyはUnity3Dのプロジェクトの肥大化を抑えて開発時間を節約することを目的にしたものです。Projenyは以下のような機能を提供します。

  • コード、シーン、プレハブといったUnityの様々なアセットを、コピー&ペーストなしに複数のプロジェクトで共有
  • プラットフォームを簡単に切り替える
  • インストール済みのAsset Storeのパッケージのアップグレードやダウングレードを簡単に行う
  • 変更されたファイルのみを再コンパイルすることでコンパイル時間を減らす
  • 巨大な一つのUnityプロジェクト内でファイルの関係性を管理するのではなく、プロジェクトをパッケージに分割してそれらの依存関係を管理する
  • パッケージ間の依存関係を記述できるので、ライブラリーやリンク切れの心配なく、パッケージを使える
  • パッケージの依存関係をcsprojに生成して利用することで、Unityが出力するものよりも良質なSolutionファイルを生成できる

ProjenyはUnity 5.3.1以降で動作します。(注:Visual Studioは2013向けです)

インストール

Pythonからソースファイルを直に利用するか、Windows版の64-bitのバイナリーを利用します。2017/12/31現在はWindowsのみ対応で、将来的にOS Xに対応予定となっています。

バイナリーからの利用

ソースからの利用

概要

Projenyは、ジャンクションやシンボリックリンクと呼ばれるディレクトリーのリンクを使って、Unityのプロジェクトを構築します。

サンプルを使って説明します。ここからProjenySamples-vX.X.X.zipをダウンロードして、新しいフォルダーを作成してその中に展開してください。

UnityProjectsフォルダー内に3つのUnityのプロジェクトフォルダーが入っています。それぞれにProjectSettingsフォルダーはありますが、Assetsフォルダーはありません。まだProjenyで初期化をしていないからです。サンプルのルートにProjeny.yamlというテキストファイルがあります。このファイルがProjenyの設定で利用されます。

これらのプロジェクトを初期化するために、コマンドラインを起動して、サンプルのルートフォルダーに移動します。Projeny.yamlがあるフォルダーです。以下を実行すると、初期化されます。

prj --init

f:id:am1tanaka:20171221182357p:plain

f:id:am1tanaka:20171221182542p:plain

インストール後、CubeMoverプロジェクトのフォルダーを見ると、以下のような構成になっています。

  • UnityProjects
    • CubeMover
      • ProjectSettings
      • CubeMover-Windows
        • Assets
          • CubeMover
          • Plugins
            • CommonShapeMover
            • Projeny
        • ProjectSettings

CubeMover-Windows以下が新しく追加されたフォルダーで、お馴染みのAssetsフォルダーが作られています。このフォルダー内に更にCommonShapeMoverCubeMoverといったフォルダーが作られています。

CubeMover-WindowsフォルダーがUnityのプロジェクトフォルダーで、これをUnityで開きます。CubeMoverフォルダー内のCubeMainシーンを開くと、立方体が色を変えながら左右に動くサンプルが確認できます。

f:id:am1tanaka:20171230225534p:plain

新しく作成されたフォルダー内のファイルやフォルダーはリンク形式のもので、実体は他の場所にあります。

Gitなどでバージョン管理をしている場合は、.gitignoreなどを使ってCubeMover-WindowsフォルダーなどのUnityのプラットフォームごとのプロジェクトフォルダーは管理しないようにします。GitかSubversionを利用している場合は、Projenyを初期化した時に自動的にignoreファイルが作られます。以下、.gitignoreに追加される内容です。

/*-Android
/*-Webplayer
/*-WebGL
/*-Linux
/*-OSX
/*-iOS
/*-Windows
/*-UWP
/*.sln
/ProjenyProjectCustom.yaml

該当フォルダーはリンクかUnityが自動生成するファイルのみなので、バージョン管理をする必要はありません。リンク先の実体ファイルは、UnityProjectsフォルダーと同じ階層にあるUnityPackagesフォルダーに入っています。

各プロジェクトフォルダーごとに入っているProjenyProject.yamlというテキストファイルに、Projenyが各プロジェクトとパッケージを結びつける情報が記載されています。このファイルは手作りもできますが、Projenyの組み込みプラグインを使って管理することができます。サンプルのCubeMoverプロジェクトをUnityで開いたら、Projenyメニューから Package Manager...を選ぶと管理ウィンドウを開くことができます。

f:id:am1tanaka:20171221190240p:plain

f:id:am1tanaka:20171221190259p:plain

Projenyを利用するメリット

設定ファイルや沢山のフォルダー、リンクといった複雑な構造を持ち込んでも、Projenyが有利な点を確認していきます。

1 - プロジェクト間でのファイルの共有

リンクを使うことで、コピー&ペーストをせずに、同じパッケージのフォルダーを複数のプロジェクトで共有することができます。DLLを作成して、必要なプロジェクトにコピーする方法はありますが面倒です。

2 - パッケージの組織化とアセットストアの統合

Projenyは、作成したプロジェクトの管理も可能ですが、Asset Storeでインストールしたようなパッケージの管理にも有効です。

Asset Storeで入手したり購入したアセットを、UnityPackagesフォルダーに追加することで、Projectごとに必要なパッケージの組み込みや解除を簡単に行えるようになります。また、Projenyのインターフェースを使うことで、アセットのアップグレードやダウングレードも簡単に行えます。

3 - プラットフォームの切り替え

プロジェクトフォルダー名に-Wiindowsとついていたり、複数のProjectSettingsが用意されているのは、プラットフォームごとに別々のプロジェクトフォルダーをProjenyで作成できるからです。これにより、ビルドターゲットを変更する際のアセットの再構築をせずに済みます。

サンプルにはWindows用の-Windowsプロジェクトしかありませんが、-iOS-Androidといった様々なプラットフォーム用のプロジェクトを作ることが可能です。

ProjenyでメインのProjectSettingsディレクトリーへのリンクを作れば、異なるプラットフォーム間で、同じプロジェクト設定を共有できます。

サンプルのCubeMoverプロジェクトで、ProjenyメニューからChange Platform -> iOSと選べば、動作を確認することができます。

f:id:am1tanaka:20171221193745p:plain

最初の一回はUnityがファイル処理をするために完了に時間がかかりますが、二回目以降はすぐに切り替わるようになります。

バージョン違いのUnityが複数インストールされていた場合、以下のようなエラーが発生する場合があります。

f:id:am1tanaka:20171221193831p:plain

設定ファイルにUnityの実行ファイルへのパスを設定すると直すことができます。補足に方法を記しました。

4 - コンパイル時間の改善

Unityでは、まずPluginsフォルダー内のC#ファイルをコンパイルして、次に他のC#ファイルをコンパイルします。Pluginsフォルダーが変更されていなかった場合、最初のステップは不要になります(実際にはもう少し複雑です。詳細は こちら )。

この性質を利用して、アセットストアなどで入手した更新が不要なパッケージはPluginsフォルダーに配置して、変更する対象のものをAssetsフォルダーに配置することで、コンパイルを効率的にできます。

*-Windowsフォルダーはバージョン管理の対象ではないので、このようなフォルダーの構成の変更が与える影響は少ないです。これらの変更はProjenyのPackage Managerウィンドウで簡単に行えます。

AllMovers-Windowsプロジェクトで例示します。デフォルトのフォルダーは以下のようになっています。

  • AllMovers
  • CommonShapeMover
  • CubeMover
  • Plugins
    • Projeny
  • SphereMover

作業する対象がAllMoversプロジェクトのみであれば、その他のCommonShapeMover, CubeMover, そしてSphereMoverプロジェクトはスクリプトを変更するたびに再コンパイルする必要はありません。そこで、それらのプロジェクトはPluginsフォルダー下に移動します。

ProjenyメニューからPackage Manager...を選択して、管理ウィンドウを開きます。

f:id:am1tanaka:20171221200128p:plain

Editボタンをクリックすると、ProjenyProject.yamlがコードエディターで開かれます。これを手作業で変更することもできますし、GUIで操作することも可能です。ProjenyProject.yamlは以下のような内容です。

AssetsFolder:
- AllMovers
- CommonShapeMover
- CubeMover
- SphereMover
ProjectSettingsPath: '[ProjectRoot]/ProjectSettings'
TargetPlatforms:
- Windows
- UWP

GUIで操作する場合は、CommonShapeMover, CubeMover, そしてSphereMoverプロジェクトをドラッグして、"Plugins Folder"欄にドロップします。

f:id:am1tanaka:20171221200450p:plain

それから"Update Directories"ボタンをクリックすると、ProjenyProject.yamlファイルが更新されて、プロジェクト内のリンクが変更されます。Unityで更新が反映されると、プロジェクトは以下のように変更されます。

f:id:am1tanaka:20171221200654p:plain

(注:変換時にエラーが発生しましたが、実行したら問題なく動作しました。)

これで、AllMoversプロジェクトを更新した時のコンパイル時間の短縮が見込めます。

5 - プラットフォームごとのパッケージフォルダー

Unity5で、プラットフォーム上のDLLの有効無効が設定できるようになりました。DLLをインポートして、Inspectorビューのチェックボタンで切り替えることができますが、Projenyでは同様のことを全てのアセットやフォルダーに対してできます。これは、Projenyがプラットフォームごとに別のフォルダーを生成して、それぞれ異なるパッケージを設定できるからです。

例えば特定のプラットフォーム向けの大量のデータを持つ巨大なリソースフォルダーがあった場合でも、Projenyを使えばプラットフォームごとに別々にリソースフォルダーを持たせることができるので、プラットフォームを切り替える度に発生していた再構築の処理をせずに済みます。

これによりコードも簡単にできます。プラットフォームごとにパッケージフォルダーを持たせるので、#ifdefによるパッケージごとの切り替えコードが不要になり、他のプラットフォームの設定が引き起こすエラーを無くすことができます。

Projeny.yamlリファレンスのところで具体的な使い方などを説明します。

6 - パッケージの依存関係管理

UnityPackagesフォルダーにパッケージを追加する時に、そのパッケージの依存情報も指定することができます。ProjenyがUnityプロジェクトフォルダーを生成するときに、自動的に必要なパッケージが示されます。

この動作は、AllMovers-Windowsプロジェクトで確認できます。ProjenyのPackage Managerをメニューから開いて、プロジェクトセクション内のCommonShapeMover, CubeMover, そしてSphereMoverプロジェクトをDeleteキーや右クリックから"Remove"で削除してみてください。

"Update Directiories"をクリックして処理が完了すると、ProjectビューのPluginsフォルダーに、削除したはずのプロジェクトが残っています。ProjenyProject.yamlファイルからは以下のように設定は消えています。

AssetsFolder:
- AllMovers
ProjectSettingsPath: '[ProjectRoot]/ProjectSettings'
TargetPlatforms:
- Windows
- UWP

しかし、AllMoversパッケージがプロジェクト内にそれらのパッケージの依存情報を持っているのです。Package Managerウィンドウの左端の左三角ボタンをクリックします。

f:id:am1tanaka:20171221224404p:plain

画面が以下のように切り替わって、削除したパッケージがリストに載っているのが確認できます。

f:id:am1tanaka:20171221224515p:plain

先のProjenyProject.yamlの情報に、このプロジェクトで利用できる全てのパッケージ一覧が追加して表示されました。

パッケージリストからAllMoversを右クリックして、Edit ProjenyPackage.yamlを選択すると、UnityPackages/AllMovers/ProjenyPackage.yamlがコードエディターで開きます。

f:id:am1tanaka:20171221225007p:plain

以下のようなファイルです。

Dependencies:
    - CubeMover
    - SphereMover

これにより、AllMoversパッケージは、CubeMoverSphereMoverパッケージに依存していることが分かるので、それらが自動的に追加されたのです。ProjenyPackage.yamlファイルをプロジェクトに追加したら、それ以降は自動的に依存先のプロジェクトが組み込まれます。そして組み込んだプロジェクトの依存関係も確認していくので、CubeMoverSphereMoverが依存しているCommonShapeMoverプロジェクトも組み込まれたのです。

7 - Visual Studio Solutionのカスタマイズ

パッケージ間の依存関係を設定することで、Visual StudioのSolutionファイルを最適化できます。AllMovers-Windowsプロジェクトで動きを確認します。

プロジェクトを開いたら、ProjenyメニューからPackage Manager...を選択して、管理ウィンドウを開いたら、右にある右三角のボタンを以下の画面になるまでクリックします。

f:id:am1tanaka:20171231160837p:plain

"Open Solution"ボタンをクリックすると、Unityで設定したコードエディターが起動します。起動するエディターは、Projeny.yamlファイルのVisualStudioIdePathで以下のように明示的に指定することもできます(注:Visual Studio 2017の場合はパスがC:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\devenv.exeなどに変わります。エラーが出ないなら、指定する必要はありません)。

PathVars:
    UnityPackagesDir: '[ConfigDir]/UnityPackages'
    UnityProjectsDir: '[ConfigDir]/UnityProjects'
    LogPath: '[ConfigDir]/PrjLog.txt'
    VisualStudioIdePath: 'C:/Program Files (x86)/Microsoft Visual Studio 12.0/Common7/IDE/devenv.exe'```

Solutionを開くと、"AssetsFolder"と"PluginsFoler"の2つのプロジェクトが確認できます。

f:id:am1tanaka:20171226180934p:plain

"AssetsFolder"には、UnityのAssetsフォルダー内の全てのC#ファイルが含まれます。"PluginsFolder"の方には、Pluginsフォルダー内にあるC#ファイルが含まれます。これがデフォルトの状態です。

Projenyのパッケージマネージャーで、AllMovers, CubeMover, SphereMoverの3つを、"Visual Studio Solution"欄にドラッグ&ドロップして、"Update Solution"ボタンをクリックします。

f:id:am1tanaka:20171226181427p:plain

Visual Studioに切り替えると、再読み込みをするかのウィンドウが表示されるので、再読み込みをします。そうすると、以下のようにプロジェクトが増えました。

f:id:am1tanaka:20171226181537p:plain

移動させたプロジェクトが、別のプロジェクトとして管理されるようになりました。また、先ほどまであった"AssetsFolder"プロジェクトが消えています。"PluginsFolder"は残っていますが、これは"CommonShapeMover"を移動しなかったからです。

このようにするとコードを組み立てるのが便利になる上、モジュール単位での依存関係が設定できるようになり、それが重要な点です。通常のUnityプロジェクトでは、あらゆるコードがプロジェクト内に組み込まれます。小さいプロジェクトならそれでも問題ありませんが、大きなプロジェクトではモジュールごとにコードを分けることができることで、Big Ball Of Mud(大きな泥だんご)にならないで済みます。

算術系のライブラリ集など、一緒に再利用することを前提にしたような場合に、複数のUnityプロジェクトに分けて開発することができます。そのような場合、ライブラリ内の特定のゲームコードを無視できることが重要です。作成している算術ライブラリとゲームのコードを密接に関連させてしまうと、他のプロジェクトで使えなくなってしまうからです。Projenyで生成したSolutionファイルを使ってコンパイルすれば、ゲームコードと算術ライブラリの間に密接な依存関係があって、Unity自身がそれに依存しているとしても、この問題は起きません。

(注:以下、うちのUnity2017.3+Visual Studio 2017の環境では動作しませんでした)

Unityに以下の設定をすることで、Projenyが生成したVisual Studio Solutionファイルをメインで利用しているエディターのデフォルト設定として利用することができます。

  • Unityを開いて、EditメニューからPreferences -> External Toolsを開く
  • "External Script Editor"欄の次にあるドロップダウンをクリック
  • "Browse"をクリック
  • Projenyのインストールフォルダー(デフォルトでは、C:\Program Files (x86)\Projeny)を開いて、ファイルタイプをAll Filesにして、Bin/PrjOpenInVisualStudio.batを設定します

f:id:am1tanaka:20171226215214p:plain

  • "External Script Editor Args"欄に、"$(File)" "$(Line)"を入力します

f:id:am1tanaka:20171226215251p:plain

あとは、Projeny.yamlVisualStudioIdePathの設定をすることで、UnityでC#のファイルをダブルクリックするとProjenyで作成したSolutionで開くようになります。

(注:うちで動かなかったのはここまで)

以下、注意事項です。

  • Package Manager内のVisual Studio Solutionのリストは、ProjenyProject.yamlファイルに保存されます。ここまでの作業をした後に、Package Mangaerの"Edit"ボタンをクリックすると、設定内容を確認することができます
  • C#プロジェクトの依存関係は、先のセクションで説明したProjenyPackage.yamlファイルで定義される依存関係を元に生成されます。Visual Studioで、References(参照) -> Add Reference(参照の追加)をクリックして、Solution -> Projectsで確認することができます
  • Solutionファイルは、UnityProjects/AllMovers-Windows.slnに生成されて保存されます。Unityが生成するSolutionファイルは、UnityProjects/AllMovers-WIndows/AllMovers-Windows.slnに保存されるので、それぞれ別々に存在することになります
  • Solutionファイルとcsprojファイルは自動的に生成されます。プリプロセッサーの定義や出力パスなどを手動で設定する必要はありません。Update Solutionを実行すると、手で加えた変更は上書きされます。また、バージョン管理ツールを利用している場合、csprojファイルやslnファイルは、Assetsフォルダーがignore設定されているので、管理対象外になります。Projenyで更新すれば自動的に再生成されるので、これが問題になることはありません
  • このカスタム設定で生成されたDLLはそのまま使われるのではなく、Unityで再コンパイルされます
  • Solutionファイルはプラットフォームごとに生成されて、それらには対象のプラットフォーム向けのプリプロセッサーの定義が含まれます。これにより、プラットフォームを変更する際に、Visual Studioを一旦閉じて、別のSolutionを開きなおす必要がなくなるので、手間が省けます
  • ProjectリストにはPython正規表現(7.2. re — Regular expression operations — Python 2.7.14 documentation)が使えます。Package ManagerのVisual Studio Solutionリストの何もないところを右クリックして、"Add As Regex..."を選択します。例えば、全てのパッケージのVisual Studioプロジェクトを生成するには、.*正規表現で加えます。Python正規表現が使えます

Asset StoreのアセットとReleasesリストの管理

ProjenyメニューからPackage Managerを開いて、ウィンドウ左にある矢印ボタンを2回押すと、以下のような画面になります。

f:id:am1tanaka:20171221225816p:plain

"Releases"リストは、外部のアセットとそのバージョン番号の一覧です。多くの場合はAsset Storeからダウンロードしたものですが、ローカルPCやリモートファイルサーバーから検索されたその他の情報も列挙されます。デフォルトでは、ProjenyはAsset Storeキャッシュからリストを生成します。

"Releases"から何か一つアセットをドラッグして、右側の"Packages"欄にドロップすると、そのアセットが登録されます(複数バージョンのUnityをインストールしていると、エラーが発生する場合があります。補足に対応方法を書きましたので、エラーが出たら参照してください)。以下、TextMesh Proを追加した時の例です。

f:id:am1tanaka:20171228214420p:plain

"Releases"に表示される名前と"Packages"に表示される名前が一致している必要はありません。Projenyはフォルダー名をデフォルトのPackageの名前として使います。アセットによっては、特定のフォルダー名でなければならない場合があり、そのための仕様です。デフォルトの名前を変更したい場合は、"Packages"に追加したあとに、右クリックメニューから"Rename"をしてください。

"Releases"の方の名前は緑色で表示されます。releaseをインストールするたびに、ProjenyはProjenyInstall.yamlというファイルに新しいパッケージフォルダーを追加します。このファイルには、そのパッケージがどこから得られたかや、バージョンといった情報が含まれます。このファイルによって、Projenyはパッケージがどのreleaseに対応しているかを把握します。サンプルのAllMoversCubeMoverといった独自に作成した簡単なパッケージの場合は、これらはnoneになっている場合が多いです。

このファイルはパッケージのアップグレードやダウングレードが発生するかの確認にも使われます。バージョンの違うアセットを、"Releases"から"Packages"に移動しようとすると、ポップアップが表示されます。アップグレードによって不具合が発生したら、"Releases"一覧に古いバージョンが残っていれば、それに戻せばよいということになります。

"Releases"から"Packages"に追加したら、それを"Project"の"Asset Folder"か"Plugins Folder"に追加して、"Update Directories"ボタンをクリックするのを忘れないでください。その作業をすることでUnityのプロジェクトに反映されます。

"Releases"一覧に新しいアセットを追加したい場合は、まずはAsset Storeで欲しいアセットを必要なら購入した後にダウンロードします。ダウンロード後にインポートするかのダイアログが表示されたらキャンセルします。ProjenyのPackage Managerを開いて、"Refresh"ボタンをクリックすると、新しく入手したアセットが"Releases"に追加されます。

自作アセットを"Releases"に登録する方法や、Asset Storeのキャッシュの応用についてはこちらを参照してください。

複数のパッケージフォルダーを管理する

ここまでは、プロジェクトの全てのパッケージは、定義済みの一つのフォルダーに入っていることを前提にしてきましたが、必要に応じて、パッケージがどこにあるかを示すことで、複数の場所にあるパッケージを定義することができます。この機能は、プロジェクト専用のパッケージを、共有パッケージのUnityPackagesフォルダーと別のフォルダーで管理したい場合に有用です。

All-MoversプロジェクトのAllMovers-Windowsプロジェクトで説明します。UnityからサンプルのAll-Moversフォルダー内のUnityProjects/AllMovers/AllMovers-Windowsフォルダーを開くか、あるいは、コマンドラインから以下を実行することでプロジェクトを開きます。

prj --project AllMovers --openUnity
prj -p am -ou

UnityのProjenyメニューからPackage Manager...を選択してパッケージマネージャーを開きます。左三角のボタンを一回クリックして"Packages"を表示します。枠で囲んだドロップダウンリストをクリックすると、パッケージを読み込む場所を指定できます。

f:id:am1tanaka:20171224193950p:plain

ドロップダウンから"[ProjectRoot]\Packages"を選択します。Packagesのリストが空欄になるので、何もないところを右クリックして、"New Package"を選択します。

f:id:am1tanaka:20171224194305p:plain

Testという名前を入力して[Enter]キーで確定すると、以下のスクリーンショットのようになります。

f:id:am1tanaka:20171224194420p:plain

再び、Packagesの空いているところを右クリックして、今度は"Show Root Folder In Explorer"を選択します。

f:id:am1tanaka:20171224194606p:plain

そうすると、サンプルフォルダー内のUnityProjectsの中のPackagesフォルダー内にTestフォルダーができていることが確認できます。

f:id:am1tanaka:20171224194733p:plain

このPackagesフォルダーの場所を示すリストは、プロジェクトごとにProjenyProject.yamlファイルで管理されます。これで、共有するUnityPackagesフォルダーと、プロジェクトごとのフォルダー内の2ヶ所にパッケージを持てることになります。

UnityProjects/ProjenyProject.yamlを開くと、以下のような設定が確認できます。

PackageFolders:
    - '[SharedUnityPackagesDir]'
    - '[ProjectRoot]/Packages'

このリストがパッケージマネージャーのGUIのドロップダウンに表示されます。

プロジェクト設定の共有

Unityのプロジェクト間でパッケージを共有するのと同様に、プロジェクトの設定も共有することができます。プロジェクトの設定は、UnityのEditメニューのProject Settingsに含まれる全てのメニューの値を含めることができます。この機能は、あるパッケージを少し設定を変更するだけで再利用したい場合などに有用です。

All-Moversプロジェクトで動作を確認します。AllMovers-WindowsフォルダーをUnityで開いたら、ProjenyメニューからChange Project -> Newを選択します。以下のようなポップアップが表示されます。

f:id:am1tanaka:20171228223426p:plain

"Share Project Settings with 'AllMovers'"というチェックボックスがデフォルトではチェックされていないので、チェックします。名前をTestにしたら"Submit"ボタンをクリックします。

これで新しい"Test"というUnityプロジェクトが作成されて、Unityが開きます。このプロジェクトでEditメニューからProject Settingsを選択して設定を変更すると、"AllMovers"と"Test"のどちらのプロジェクトのプロジェクト設定にも反映します。

このプロジェクトの設定は、ProjenyProcest.yamlファイル内で定義されます。パッケージマネージャーの"Edit"ボタンをクリックして開くか、テキストエディターなどでUnityProjects/Test/ProjenyProject.yamlを開くと、以下のような設定が確認できます。

ProjectSettingsPath: '[ProjectRoot]/ProjectSettings'
TargetPlatforms:
- AllMovers
- Windows

このプロジェクトにはまだ何もパッケージを追加していないので、AssetsFolderPluginsFolderの定義はまだありません。

Directory Linkの注意点

  • Unityフォルダー内でのパッケージフォルダーの移動
    • UnityのProjectビュー内のファイルやフォルダーは自由に移動できます。しかし、パッケージフォルダー自身は動かさないようにしてください。そうしないと、Projenyで"Update Directories"を押してDirectory Linksを更新した時に、ファイルが複製されてしまいます。
  • プロジェクトのコピー&ペーストは機能しません
    • フォルダー全体をハードディスクの他の場所にコピー&ペーストすると、ペーストした先の空のDirectory Linksは空になります。この問題を解決するには、コピー&ペーストをした後で、コピー先のフォルダーで prj -cla --init を実行します。これにより、生成されたファイルを全て削除(-cla)してから、全てのプロジェクトのためにDirectory Linksを初期化し直します(--init)。
  • gitなどを利用している場合、git cleanの利用に気をつける必要があります
    • git clean -dfは問題なく動作しますが、git clean -xdf(.gitignoreに指定されているファイルやフォルダーも削除対象にするオプション)ではいくつかのデータを失います。何故なら、git cleanがDirectory Linksを辿った先を削除するからです。UnityProjectsフォルダー内に生成されたファイルだけを削除するつもりが、UnityPackagesディレクトリー内のいくつかのファイルも削除されてしまいます。git clean -dfは、.gitignoreで指定されているファイルやフォルダーを削除対象から除外するので、UnityProjectsフォルダーは対象外なので問題は起きません。-xオプションを指定していた場合、管理対象外のファイルやフォルダーを削除してしいまいます。-xオプションを使いたい場合は、先にprj -claを実行してDirectory Linkを削除してから実行することを推奨します
  • git cleanと異なり、WindowsのExplorerによる削除は安全です
    • Windowsエクスプローラーで、UnityProjectsフォルダー内の異なるプロジェクトを削除した場合は、git cleanとは異なり、UnityPackagesフォルダー内のファイルは一切削除されません。エクスプローラーは、Directory Linksを削除する際に、リンク先を削除するのではなく、参照だけを削除するからです
  • 最初にプロジェクトを開いたあと(あるいは、新しいパッケージを追加したあと)、Unityは以下の警告を表示しますが、無視して構いません
[Asset] is a symbolic link. Using symlinks in Unity projects may cause your project to become corrupted if you create multiple references to the same asset, use recursive symlinks or use symlinks to share assets between projects used with different versions of Unity. Make sure you know what you are doing.

よくある質問

どうやって新しいパッケージを作るのですか?

方法1 - Package Managerを使う

  • UnityのProjenyメニューからPackage Managerを選択
  • 左の三角のボタンをクリックして、Packagesセクションを表示
  • "New"ボタンをクリックするか、右クリックして、"New Package"を選択
  • 新しいパッケージの名前を入力
  • Assets FolderPlugins Folder欄に、作成したパッケージをドラッグ&ドロップ
  • (必要なら)ProjenyPackage.yamlに新しいパッケージを追加する。詳しくは ProjenyPackage.yaml reference を参照

方法2 - 手動

  • UnityPackagesフォルダーを開く
  • 新しく作るパッケージの名前のフォルダーを作成する
  • このパッケージを、ProjenyPackage.yamlProjenyProject.yamlにフォルダー名を追加して加えることができます。
  • (必要なら)ProjenyPackage.yamlに新しいパッケージを追加する。詳しくは ProjenyPackage.yaml reference を参照

新しいプロジェクトの作り方は?

方法1 - Unityで行う

  • ProjenyメニューからCreate Projeny -> New... を選択
  • 新しいプロジェクトの名前を入力して、Project Settingsを共有するかどうかを、チェックボックスのチェックによって設定
  • 新しいプロジェクトをUnityが開き直したら、Package Managerメニューを再び開いて、必要なパッケージの追加などを行う
  • (必要なら)ProjenyProject.yamlに新しいプロジェクトを追加する。詳しくは ProjenyProject.yaml reference を参照

方法2 - コマンドライン

  • コマンドプロンプトPowerShellを開いて、Projeny.yamlファイルがあるフォルダーに移動
  • prj --project MyNewProject --createProjectを実行(あるいは、prj -p MyNewProject -cpr)
  • 以上で完了。Unityで、MyNewProject-Windowsフォルダーを開くことができます
  • (必要なら)ProjenyProject.yamlに新しいプロジェクトを追加する。詳しくは ProjenyProject.yaml reference を参照

Projenyを使ったPackageやProjectを自前で作る方法は?

方法1 - コマンドライン

  • コマンドプロンプトかパワーシェルを開いて、新しくプロジェクトやパッケージを作りたいフォルダーへ移動
  • prj --createConfig(あるいは、prj -cc)を実行
  • Projeny.yamlという名前のファイルが作成されて、基本的な設定が記入されます。詳細は Projeny.yaml リファレンスを参照
    • Projectsの保存場所にUnityProjectsフォルダーを使います
    • Packagesの保存場所にUnityPackagesフォルダーを使います
    • 全てのプロジェクトはUnityProjects/PROJECT_NAME/Packagesフォルダー内にそれぞれ個別のオプションを持ちます
  • 以上が完了したら、新しいプロジェクトを作成するとよいでしょう

方法2 - 手動で行う

  • プロジェクトのルートになるフォルダーを作成します
  • Projeny.yamlという名前のファイルを作成したフォルダー内に作って、以下の内容を記載します
PathVars:
  UnityProjectsDir: '[ConfigDir]/UnityProjects'
  LogPath: '[ConfigDir]/PrjLog.txt'
  • UnityProjectsという名前の新しいフォルダーを作成します
  • 以上が完了したら、新しいプロジェクトを作成するとよいでしょう

UnityのStandard Assetsをインポートする方法は?

Unity5.3.4用の全てのStandard Assetsを、Projenyのパッケージにまとめて、それぞれの依存設定をProjenyPackage.yamlファイルに記載しました。それらは、Release PageStandardAssets-Unity5.3.4.zipをダウンロードすると使えます。ダウンロードしたZIPファイルを、UnityPackagesフォルダーに展開したら、ProjenyのPackage Managerで、必要なアセットをプロジェクトにドラッグ&ドロップしましょう。

Projeny.yaml リファレンス

Projeny.yamlには、Unityなどのツールへのパスや、ログファイルを出力する先などのProjenyの一般的な設定が入っています。

prjコマンドを使って、Projenyをコマンドラインから呼び出すと、以下のパスから設定を読み込もうとします。

  • [Current directory]/Projeny.yaml
  • [User Home Directory]/Projeny.yaml (Johnというユーザー名だった場合、C:/Users/John/Projeny.yaml)

上記の両方に設定ファイルを配置しておくのが一般的です。ホームディレクトリーに設定を置いておくと、Visual StudioやUnityなどのツール用にパスを定義するのが楽になります。

先に記した手順に従って新しいプロジェクトを作成した場合は、Projeny.yamlは以下のようなデフォルト設定の内容になっているでしょう。

PathVars:
    UnityProjectsDir: '[ConfigDir]/UnityProjects'
    LogPath: '[ConfigDir]/PrjLog.txt'

これは、Projenyが要求する最低限の設定です(LogPathは必須ではありませんが、エラーの詳細を知るために設定しておくべきです。Projenyを実行するたびに、指定のパスのPrjLog.txtファイルに、実行結果の情報が書き込まれます。

以下、設定の全リストです。使いやすいようにデフォルト値が設定されているので、必要がなければ設定する必要はありません。#から始まる行はコメントです。

# コマンドラインをよく利用する場合のために、プロジェクトに
# エイリアスを設定することができる。以下、デモプロジェクトの
# 設定例で、`prj -p am`で、`prj -p AllMovers`を実行したのと同等になる。
ProjectAliases:
    am: AllMovers
    cm: CubeMover
    sm: SphereMover

# `-p`オプションなしでコマンドラインから`prj`を実行した場合に
# 実行されるデフォルトのプロジェクト設定
DefaultProject: AllMovers

# Projenyが利用するパスの一覧。
# 設定ファイルで利用する独自のパスを追加してもよい。
# また、`[SOME_ENVIRONMENT_VARIABLE]`などとして、同様にその他の環境設定を追加することもできる。
PathVars:
    # 必須設定。Projenyが利用するプロジェクトの場所を指定。
    UnityProjectsDir: '[ConfigDir]/UnityProjects'

    # ProjenyがUnityを実行する時に呼び出すパス。
    # Unityを以下と異なる場所にインストールしていたら、設定する必要がある。
    UnityExePath: 'C:/Program Files/Unity/Editor/Unity.exe'

    # `-b`や`bf`、`bcs`オプションを利用する際に使われる設定。
    # Visual Studio Solutionファイルの生成に使われる。
    # 以下がデフォルトの設定。Visual Studio Solutionファイル関連の
    # 操作が失敗する場合は、以下の設定の場所を確認して、該当するファイルが
    # なければ、正しい場所を設定すること。
    MsBuildExePath: 'C:/Windows/Microsoft.NET/Framework/v4.0.30319/msbuild.exe'

    # UseDevenv設定がtrueの場合に利用される設定。
    # Visual Studio Solutionの操作で失敗する場合、以下のパスが正しいか設定する。
    # Visual Studio 2017の場合、"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\devenv.com"などに変更。
    VisualStudioCommandLinePath: 'C:/Program Files (x86)/Microsoft Visual Studio 12.0/Common7/IDE/devenv.com'

    # Package Managerの"Open Solution"ボタンや、`prj -ocs`コマンドを実行した時に使われる。
    # Visual Studio 2017の場合、"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\devenv.exe"などに変更。
    VisualStudioIdePath: 'C:/Program Files (x86)/Microsoft Visual Studio 12.0/Common7/IDE/devenv.exe'

    # `prj`コマンドが出力するログファイルを出力する先を設定。
    LogPath: '[ConfigDir]/PrjLog.txt'

Console:
    # 利用するコンソールが多色対応の場合、trueにすることで
    # 警告を黄色、エラーを赤などで表示するようになる。
    UseColors: False

# 独自のReleaseソースを指定する。
# Asset Store以外の自分のパッケージをReleasesに表示したい場合、以下に追加する。
ReleaseSources:
    - LocalFolder:
        Path: 'C:/MyUnityPackages'

    # 複数のローカルフォルダーを指定することもできる。
    - LocalFolder:
        Path: 'G:/NetworkSharedUnityPackages'

    # 複数のファイルサーバーを指定することもできる。
    - FileServer:
        ManifestUrl: 'http://localhost:8092/ProjenyReleaseManifest.txt'

Compilation:
    # この値は、`-b`、`bf`、`bcs`のコマンドラインオプションで利用される。
    # デフォルトでは、Projenyは"MsBuildExePath"で定義されたMsBuildを
    # 使ってSolutionをビルドする。しかし、Visual StudioのGUIを
    # 使ってビルドするために、devenv.exeを使いたい場合もあるかも知れない。
    # その場合、この値を`true`にして、"PathVars"セクションの'VisualStudioCommandLinePath'を
    # 正しく設定する。
    UseDevenv: False

SolutionGeneration:
    # Visual Studioプロジェクトを作成する際に、"DefaultNamespace"内で利用される設定。
    # 外部に出す場合は、設定しておいた方がよさそう。
    RootNamespace: MyCompanyName

Unity:
    # デフォルトで64bit Windows用にビルドさせたい場合は、このオプションを含める。
    Win64IsDefault: True

ProjenyProject.yaml リファレンス

通常はProjenyProject.yamlはUnityのPackage Managerから編集しますが、Package ManagerのGUIには全ての操作が含まれていません(例えば、SolutionフォルダーはPackage Managerからは設定できません)。

ProjenyProject.yamlファイルは複数作成することができるので、プロジェクトごとに設定が可能です。Project名がFooだった場合、Projenyは以下の4箇所を確認します。

  1. UnityProjects/Foo/ProjenyProject.yaml
  2. UnityProjects/Foo/ProjenyProjectCustom.yaml
  3. UnityProjects/ProjenyProject.yaml
  4. UnityProjects/ProjenyProjectCustom.yaml

これらは全て同じ書式で記述します。(3)と(4)は、自動的に全てのプロジェクトから利用されます。そのため、色々なところから利用したいPackageはここに定義するのがよいでしょう。

(2)と(4)は、gitなどのバージョン管理ソフトの対象外にしましょう。それにより、特定のパッケージを開発者ごとに自由に設定できるようになります。例えば、異なる開発者が同じプロジェクトで作業しつつ、別々のプラグインを開発していたり、個別にシーンを持たせたい場合などに、ProjenyProjectCustom.yamlファイルにパッケージを登録します。

ProjenyProject.yamlのフォーマットは以下の通りです。

AssetsFolder:
    - {PackageName}
    - {PackageName}

PluginsFolder:
    - {PackageName}
    - {PackageName}
    - {PackageName}

SolutionProjects:
    - {PackageName}
    - /{PackageNamePattern}
    - /{PackageNamePattern}
    - {PackageName}

SolutionFolders:
    {FolderName}: /{PackageNamePattern}
    {FolderName}: /{PackageNamePattern}

PackageFolders:
    - {DirectoryPath}
    - {DirectoryPath}

TargetPlatforms:
    - Windows
    - WebPlayer
    - Android
    - WebGL
    - OSX
    - Linux
    - iOS
    - UWP

パッケージの指定方法は以下の通りです。

  • {PackageName}は、PackageFoldersフォルダーに含まれる一つのディレクトリー名です
  • {PackageNamePattern}は、Python正規表現を使って、UnityPackagesフォルダー内の一つ以上のパッケージを指定するのに使われます

注記事項です。

  • AssetsFolderカテゴリー以下に並べるパッケージは、Unityのプロジェクト内のAssetsフォルダー内に配置する必要があります
  • PluginsFolderカテゴリー以下に並べるパッケージは、Unityのプロジェクト内のAssets/Pluginsフォルダー内にある必要があります
  • SolutionProjectsカテゴリー以下に並べる全てのパッケージは、それぞれの.csprojファイルが生成されます。ProjenyメニューからUpdate C# Projectや、Update SolutionボタンをPackage Manager内から押した際に、実行されます
    • パッケージ名をそのまま書くのではなく、正規表現を使うことができます。例えば、C#プロジェクトをプロジェクト内の全てのパッケージに対して生成したい場合は、/.*を追加すれば、全てのパッケージに適用されます
  • 生成されるSolutionのフォルダーを作成して、プロジェクト間を関連付けることができます。フォルダーごとに一つの正規表現パターンを持ち、プロジェクトの全リストのフィルターとして使われます。最初に/のプレフィックスが必要です
  • パッケージファイル内で使われる正規表現は、Python正規表現ルールが適用されます

ProjenyPackage.yaml リファレンス

Projectの設定と違い、Packageの設定にはGUIがありません。そのため、設定をするにはProjenyPackage.yamlファイルを直接編集する必要があります。

ProjenyPackage.yamlファイルの最も良く使われるケースは、このパッケージが依存している他のパッケージのリストを以下のように列挙することです。

Dependencies:
    - CubeMover
    - SphereMover

上記は、デモプロジェクトのUnityPackages/AllMovers/ProjenyPackage.yamlの設定です。

このファイルは作らなくても構いません。ない場合は、このパッケージは他のパッケージを自動的に組み込むことはしません。

ProjenyPackage.yamlが取り得る全てのオプションの例を以下に挙げます。

Dependencies:
    - {PackageName}
    - {PackageName}
    - {PackageName}

Extras:
    - {PackageName}
    - {PackageName}

FolderType: {FolderType}

Platforms:
    - {PlatformName}
    - {PlatformName}
    - {PlatformName}

ForcePluginsDirectory: {True/False}
ForceAssetsDirectory: {True/False}
  • {PackageName}は、UnityPackagesフォルダーの名前で指定します
  • DependenciesExtras以下に列挙された全てのPackageは、このパッケージを利用するプロジェクトに自動的に加えられます
    • DependenciesExtrasの唯一の違いは、Dependenciesに定義したパッケージのフォルダー下にはProjenyが自動的にcsprojの依存設定を生成し、Extrasの方はそれをしないという点です。殆どの場合はDependenciesでよいですが、ごく稀にExtrasが必要になる場合があります。例えば、作成しているパッケージをテストする一連の単体テストコードを個別のパッケージとして作成して、それを常に作成しているパッケージと一緒に運用したい場合、Extrasリストが追加場所として適しています。これらをDependenciesに含めると、循環依存になってProjenyがエラーを出力することになります。
  • デフォルトでは、Projenyはパッケージを全てのプラットフォームに対応していると見なします。Platformsリストを追加すると、リストで指定した以外のプラットフォームにはパッケージのリンクが作成されなくなります。リスト中の{PlatformName}として使える文字列は以下の通りです
  • ForcePluginsDirectoryを設定すると、指定のパッケージはAssets/Plugins/PackageNameに配置されます
    • 指定の場所にパッケージを配置することを前提にハードコーディングされている場合があるので、そのための設定です
  • ForceAssetsDirectoryも同様で、Assets/PackageNameに配置されます
  • FolderTypeで以下のようなことが設定できます

カスタムのReleaseのソース

Asset StoreのアセットとReleasesリストの管理のところで触れましたが、Releasesのリストは通常はAsset Storeで入手したアセットのリストですが、その他のソースを加えることもできます。

Asset Storeのキャッシュも含めて、全てのソースは、Unity Packageを集めたものです。

ローカルフォルダーのソースをReleasesに含めたい場合は、Projeny.yamlを開いて、以下のような行を追加して、指定の行に追加したいUnityパッケージを入れます。

ReleaseSources:
    - LocalFolder:
        Path: 'C:/MyLocalFolderSource'

システム全体で共有できるProjenyの設定場所として最適なのは、ユーザーのホームフォルダー直下にProjeny.yamlを配置することです(C:/Users/[Your User Name]/Projeny.yaml)。この場所は、そのユーザーがPC上に作成した全てのProjenyプロジェクトから参照されます。

指定したフォルダーに、.unitypackageファイルをコピー&ペーストして、Package Managerの"Refresh"ボタンをクリックすれば、追加したUnityパッケージがReleasesのリストに表示されるようになります。

複数のローカルフォルダーやネットワーク上のフォルダーをソースとして設定に追加することもできます。

また、MyCustomPackage@1.2.unitypackageなどのようにUnityパッケージ名をつけておけば、バージョンが有効になります。この例の場合、MyCustomPackageのバージョン1.2であることを示しています。この手法はカスタムパッケージのみ必要です。Asset Storeからダウンロードしたアセットのバージョン情報は組み込み済みになっています。

ReleaseソースをLAN上で共有すれば、オフィスなどでの開発ではとても便利になるでしょう。会社などで巨大な一つの"Releases"のコレクションを構築して、それを共有してアクセスすることができます。

ネットワーク共有を利用したくない場合は、File Serverを使ってURLで共有する方法があります。URLを設定したら、ネットワーク上でUnityパッケージにアクセスできる静的なWebサイトを動かします。まずは公開したい.unitypackageファイルを並べたリストを静的なWebサイトに持たせる必要があります。.unitypackageファイルを配置したフォルダーを、PrjUpdateReleaseManifest [directory](Projeny/Binフォルダーにあるバッチファイル)を実行してスキャンします。.unitypackageファイルがあるフォルダーから実行する場合は、単純にPrjUpdateReleaseManifest .でも構いません。そうすると、対象のフォルダーにProjenyReleaseManifest.txtというファイルが作られます。PrjUpdateReleaseManifestを、'watch'オプションを指定して実行すると、指定のフォルダーに.unitypackageをアップロードすると自動的にPrjUpdateReleaseManifest.txtの更新が行われるようになります。

設定が完了したら、以下のような設定をProjeny.yamlに追加することで、File ServerのReleaseソースへの参照が可能になります。

ReleaseSources:
    - FileServer:
        ManifestUrl: 'http://mysharedserver/ProjenyReleaseManifest.txt'

コマンドラインリファレンス

殆どのProjenyのコマンドは、UnityのPackage Managerから実行できます。しかし、Visual Studio Solutkonのビルドなど、一部のことは実行できません。また、サーバーを継続的に更新したり、チームで共有するビルドパイプラインがある場合などは、コマンドラインの方が便利な場合があります。

以下に、prjコマンドに設定できる全てのパラメーターを示します。これらのオプションは自由に組み合わせが可能です。prjは合理的な順位でそれらを実行します。

  • --openDocumentation / -d
  • --project / -p
    • 他のパラメーターにより行う動作の対象プロジェクトを指定します
    • プロジェクトが1つなら、このオプションは省略できます
    • prj -p AllMovers -ulを実行した場合、AllMoversプロジェクトの全てのDirectory Linkを更新します(デフォルトのプラットフォームはWindowsです)
    • 与えられる値は、UnityProjectsフォルダー内にあるフォルダー名です
      • 全てのプロジェクトリストは、-lpコマンドで確認できます
      • ProjenyProject.yamlファイルで定義したプロジェクト名のエイリアスを渡すこともできます
  • --platform / -pl
    • 他のパラメーターによって指定されるコマンドの対象プラットフォームを指定します
    • 省略するとWindowsを対象にします
    • 有効な値は以下の通りです
    • 例えば、prj -p AllMovers -pl ios -ulを実行すると、AllMovers-iOSフォルダー内のDirectory Linkが全て更新されます
  • --updateLinks / -ul
    • 指定のProjectとPlatformのDirectory Linkを全て更新します
    • Projenyは与えられたプロジェクトに関連するProject.yamlファイルを読み込んで、必要な全てのパッケージを割り出して、パッケージごとにAssetsAssets/Pluginsフォルダーへの全てのDirectory Linkを作成します
    • このコマンドを実行する時には、必ずプロジェクトを指定するか、Projeny.yamlファイルにデフォルトのプロジェクトを設定しておく必要があります。また、プラットフォームをオプションで指定できます
  • --listProjects / -lp
    • UnityProjectsフォルダー下にある全てのプロジェクト名や、定義されていたらエイリアスも一覧表示します
  • --updateCustomSolution / -ucs
    • 指定されたプロジェクトとプラットフォームのProjeny.yamlの設定に従って、.csproj.slnファイルを生成します
    • この動作の詳細はVisual Studio Solutionのカスタマイズを参照
    • プロジェクトにDLLを追加したり、Player Settingsの追加や削除をした場合は、このコマンドと一緒に-ussを指定するか、このコマンドを実行する前に実行する必要があります
    • このコマンドを実行する時には、必ずプロジェクトを指定するか、Projeny.yamlファイルにデフォルトのプロジェクトを設定しておく必要があります。また、プラットフォームをオプションで指定できます
  • --updateUnitySolution / -uus
    • スタンドアロンMonoDevelop Solutionを作成するために、Unity.exeを実行します。-ucsコマンドと一緒に使うことができます。この操作は、Unityを起動して、AssetsメニューからOpen C# Projectを実行することと同じです(Visual StudioMonoDevelopのどちらが開くかは関係ありません)。
  • --verbose / -v--veryVerbose / -vv
    • これらのパラメーターは、コンソール出力にどの程度詳細に出力するかのスイッチです。-vを指定するといくらかの詳細が追加出力されて、-vvだとUnityエディターログやVisual Studioなどのログも含めたあらゆる情報が出力されます
  • --buildCustomSolution / -b
    • カスタムのSolutionをビルドします
    • ビルドの際には、UseDevenvの設定に応じて、Projeny.yamlVisualStudioCommandLinePathか、MsBuildExePathの設定を使います
    • -ucsコマンドを使ってカスタムSolutionファイルを生成していない場合、このコマンドは失敗します
    • このコマンドを実行する時には、必ずプロジェクトを指定するか、Projeny.yamlファイルにデフォルトのプロジェクトを設定しておく必要があります。また、プラットフォームをオプションで指定できます
  • --buildFull / -bf
    • このコマンドは、prj -ul -uus -ucs -bを実行することと同じです
      • 与えられたプロジェクトとプラットフォームのリンクと、カスタムSolutioを更新してから、カスタムSolutionでビルドします
    • このコマンドを実行する時には、必ずプロジェクトを指定するか、Projeny.yamlファイルにデフォルトのプロジェクトを設定しておく必要があります。また、プラットフォームをオプションで指定できます
  • --openUnity / -ou
    • 指定のプロジェクト/プラットフォームをUnityで開きます
    • このコマンドを実行する時には、必ずプロジェクトを指定するか、Projeny.yamlファイルにデフォルトのプロジェクトを設定しておく必要があります。また、プラットフォームをオプションで指定できます
  • --openCustomSolution / -ocs
    • 指定のプロジェクト/プラットフォームのカスタムSolutionをVisual Studioで開きます
    • このオプションを実行するには、Projeny.yamlVisualStudioIdePathを設定しておく必要があります
    • -ucsコマンドを使ってカスタムSolutionファイルを生成していない場合、このコマンドは失敗します
    • このコマンドを実行する時には、必ずプロジェクトを指定するか、Projeny.yamlファイルにデフォルトのプロジェクトを設定しておく必要があります。また、プラットフォームをオプションで指定できます
  • --clearProjectGeneratedFiles / -clp
    • 指定のプロジェクトのために生成されたファイルやフォルダーを全て削除します。このコマンドは、実際のファイルやフォルダーは削除しません。このコマンドで削除するのは、指定したDirectory Linkと、Unityが生成したテンポラリーファイルです
    • このコマンドは、プロジェクトをリセットしたい時に便利です。prj -clp -bfとすると、まずはプロジェクトのために生成済みだったファイルを全て削除してから、再生成して、Visual Studio Solutionをビルドします
    • このコマンドを実行する時には、必ずプロジェクトを指定するか、Projeny.yamlファイルにデフォルトのプロジェクトを設定しておく必要があります
  • --clearAllProjectGeneratedFiles / -cla
    • 全てのプロジェクトを対象とした-clpコマンドです
  • --deleteAllLinks / -dal
    • 全てのプロジェクトのDirectory Linkを全て削除します。このコマンドは-inコマンドの逆のものです
  • --init / -in
    • このコマンドは、UnityProjectsフォルダー下の全てのプロジェクトに対して、-ulコマンドを実行することと同じです
  • --deleteProject / -dpr
    • UnityProjectsフォルダーから指定のプロジェクトを削除します
  • --suppressPrompts / -sp
    • 確認プロンプトの省略コマンドです。これを指定しなかった場合、重要な操作の前に確認のプロンプトが表示されます
  • --createProject / -cpr
    • UnityProjectsフォルダー内に新しいプロジェクトを作成します。そして、デフォルト設定がされているProjenyProject.yamlファイルが追加されて、Directory Linkが作成されます
  • --configPath / -cfg
    • メインとなるProjenyProject.yaml設定ファイルのパスを指定します
    • 省略した場合、[CurrentDirectory]/ProjenyProject.yamlを参照します
  • --listPackages / -lpa
    • UnityPackagesフォルダー内にある全てのパッケージを一覧表示します
  • --deletePackage / -dpa
    • UnityPackagesフォルダーから指定のパッケージを削除します
  • --installRelease / -ins
    • 指定のリリースやバージョンのソースをReleaseソースから検索します
  • --listReleases / -lr
    • 全てのReleaseソースにある全てのReleaseを一覧表示します
  • --editProjectYaml / -epy
    • 指定のプロジェクトのProjenyProject.yamlファイルを開きます
  • --createPackage / -cpa
    • 指定の名前のパッケージ用のフォルダーを、UnityPackagesフォルダーの下に作成します

付録

外部リソースを使うことについて

  • DLL内では、UNITY_WEBPLAYERUNITY_5_3といったプリプロセッサーを利用することができないので、プラットフォームごとにDLLを作成することになります。Unity5.3以降であれば、プラットフォームごとにどのDLLを含めるかを指定することができるので、このような使い方が楽になります
  • 外部リソースからコードを利用するには、いくつかの制限があります。特に、カスタムのベースクラスを持ったMonoBehaviourは、GameObjectに追加することができません
  • Unityは、MonoBehaviourがどこにあるかを把握しません。そのため、MonoBehaviourをダブルクリックしても、ソースファイルを開くことができません

補足

以下、マニュアルに載っていないことの補足です。

プラットフォーム切り替えやアセットの管理がうまくいかない時の対処

Unityを複数利用しているなどでインストール先がデフォルトのパス以外だった場合、プラットフォームの切り替えや、アセットの管理をしようとした時にエラーが発生する場合があります。

Can't move assetstore package from Releases section to Packages · Issue #65 · modesttree/Projeny · GitHubに以下のような書き込みがありました。

I managed to fix this by setting the UnityExePath PathVar in the Projeny.yaml to the new Unity.exe path. I had installed more than 1 version of unity.

プロジェクトフォルダー直下にあるProjeny.yamlファイルのPathVar:の要素にUnityExePathを追加することで直せました。自分はOドライブにインストール先を変更していたので、以下のように最後の行を追加しました。

ProjectAliases:
    am: AllMovers
    cm: CubeMover
    sm: SphereMover

PathVars:
    UnityProjectsDir: '[ConfigDir]/UnityProjects'
    SharedUnityPackagesDir: '[ConfigDir]/UnityPackages'
    LogPath: '[ConfigDir]/PrjLog.txt'
    UnityExePath: 'O:\Program Files\Unity20170300\Editor\Unity.exe'

指定するパスは、ご自身の環境に合わせて変更してください。これでプラットフォームの切り替えも、アセットの読み込みもどちらも正常に動くようになりました。エラーが発生した場合はお試しください。

Visual Studio Solutionが開けない場合の対処

サンプルのAllMovesプロジェクトのカスタムのVisual Studio Solutionを開こうとした時に、以下のようなエラーが出て開けませんでした。

f:id:am1tanaka:20171230215408p:plain

Unity Projectsフォルダーの間に改行が入っているのが問題だったようで、別のフォルダーに移動させたところ開けるようになりました。ただ、問題なく開けていたような記憶もあり、本当にこれが原因かは分かりません。とりあえず、エラーが発生してからは、フォルダーを変更してプロジェクトを生成し直したらうまくいきました。因みに、フォルダーの移動後は、コマンドラインProjeny.yamlがある場所から以下を実行して、環境の再構築をしました。

prj -cla -dal -in
prj -ucs -uus -p AllMovers

まとめ

Visual Studio Solutionの辺りで不具合が出ていたり、Unity Collaborateで使えるかや、バージョン管理とどう組み合わせるかなど、確認したいことが残っておりますが、概ね良さそうな感じのツールです。うまくいけば、HDDの容量の削減や、違う場所での作業の効率化ができそうです。あとは使ってみてのお楽しみです。

訳が怪しい部分があれこれあると思いますので、何かあればお知らせいただければ幸いです。

参考URL

フライング・カモ!制作記

正月休み課題に、「1日ぐらいで作れる小さいゲームを一本完成させて公開する!」というのを発令しました。いつもの如く、課題を発したら自分も参加するスタイルなので、自分でも作って公開しました。以下から遊べます。

フライング・カモ!

目次

企画

作戦

少ない要素でも遊べるものにするための作戦として、以下のようなことを考えました。

  • フィールドを歩ける系のやつはまとめにくいので避ける
  • ランキングに対応させて、単純操作を競うようにする

これまでのUnity1週間ゲームジャムで、一つの要素で楽しめるシンプルな作品に憧れてたので、とにかく今回は余計なものをそぎ落とそうと考えました。

ゲームの要素

作戦を元に、以下のような要素を考えました。

  • 一発操作ものだと、タイミングよくパワーを止めるやつが好き、ということで、マウス操作で飛ばす方向を決めて、パワーゲージをタイミングよくクリックして飛ぶものにする
  • 主人公は、SURIYUNさんCute Petのカモに決定!
  • 背景は、同じくアセットストアで購入したばかりのPBR Desert Landscapeを少しいじるかそのままでいけそう
  • UI - Builderで円形のパワーゲージを作る
  • 開始点から着地点の距離がスコア

ゲーム内容はこれで決定。飛んだあとに姿勢を変えて、飛ぶコースや速度を調整することも考えていましたが、今回はとにかくシンプルがテーマなので削りました。

開発方針

開発に入る前に、大雑把に全体像を箇条書きにしました。

全体的なこと

  • フォントは太いカタカナのインパクトのあるやつ
  • 1シーンで、タイトル、ゲーム中、結果表示、ランキングを実装

ゲームの流れ

  • 方向を決めてクリックしたら次へ
  • ゲージを動かして、クリックを検出して次へ
  • 飛ばして、停止するのを待つ
  • 距離表示
  • タイトルへ

効果音

  • 決定音
  • パワーゲージの音
  • 飛ぶ音
  • 飛んでいる間のbgm
  • バウンド音
  • 結果音
  • ハイスコアファンファーレ

こんなことを日野へ向かう電車の中でスマホにメモりました。行きだけでほぼ書き終わっていたので、1時間ぐらいでまとめました。

開発

PBR Desert Landscapeの高速化は、事前に研究してました。まとめ記事はこちら → PBR Desert Landscapeを高速化する - tanaka's Programming Memo

進捗としては以下のような感じでした。

  • 1日目:ゲームのルールは全て実装
  • 2日目:バグや的の範囲の制限、画面エフェクトの調整、BGMとSEの実装など
  • 3日目:ランキング、ツイート、アニメーションの実装
  • 4日目:操作説明の実装、当たり判定の調整など仕上げして完成

まとめ

今回、久々にプレイヤーのキャラクターを登場させられました。また、ステージをアセットでさくっとまとめられて、画面も綺麗にまとまりました。

内部的には、1シーンということで各フェーズの処理を1つのファイルにまとめてしまいました。同じオブジェクト上なら簡単にGetComponentでお互いのインスタンスを取得できるので、フェーズごとにスクリプトファイルを分けることを少し検討しましたが、考えているうちに完成してしまったのでそのままになりました。いずれ、UniRxやZenjectの練習台にしてもいいかと考えています。

前回から使いまくり始めたAnimationとAnimatorを今回もあちこちで使いました。文字のアニメーションは勿論、パワーゲージもAnimationで動かしています。スクリプトを書かずに色々できて楽です。Timelineはタイトルの表示ぐらいでしか使ってません。シンプルな構造ならステートマシーンをマウスでぽちぽちできるAnimatorもまだ捨てたものじゃないと感じていますが、ちゃんと勉強したらTimelineの方が楽なのかな?今後の研究課題です。

以上、正月明けにどのような作品が揃うか楽しみにしています。

利用アセット

以下のアセットやリソースにお世話になりました。作者の皆様、ありがとうございました。

アセット

  • SURIYUNさんのかわいいペットアセットから、主人公のカモのモデルとアニメーションに登場してもらいました

  • PBR Desert Landscape
    • 背景の地形のアセットです。すでに公開が終っています。お買い得です。そのまま使うと遅かったので、高速化のためにやったことをここにまとめてあります

  • Post Processing Stack用のプロファイルセットです。このプロファイルをちょこっとだけ調整するだけで綺麗な画面になりました

  • ツイートやランキングボタンや、照準、ゲージをこれで作りました。色見本もゲージの色作りに参考にしました

Package Managerのもの

  • Cinemachine
    • 定番カメラ制御アセットです
  • Post Processing Stack
    • 画面のクオリティアップには無くてはならないアセットです
  • TextMesh Pro
    • 文字が滑らかになって、グラデーションなどの効果を簡単に設定できるこれまた定番アセットです

フォント

オーディオ

    • タイトルとゲーム中のBGMは、今回は音楽の卵さんのものを使いました
  • 効果音ラボ
    • ゲージの上昇音以外の効果音は全て効果音ラボさんで探しました
  • PEKO STEP. 効果音メーカー
    • パワーゲージの音を作りました

オンラインランキング