20200727のUnityに関する記事は9件です。

プログラミング初心者がUnityでゲームをつくってみる その(2)

みなさんこんばんは。お母さんです。
昨日から少しずつUnityの勉強を進めています。

『Unityふりがなプログラミング』というKids向けの本を参考に進めています。

起動中・・・
image.png

起動しました。
画面のレイアウトを変えていきます。

image.png

「Layout」→「2by3」をクリックして、編集用の画面と、カメラから見た画面の2つの視点が分かるレイアウトになります。
image.png

昨日の続きで、オブジェクトを作成していきます。
「Hierarchy」ウィンドウの「3Dオブジェクト」→「cube」を選択すると、四角い小さな箱ができました。

image.png

赤と緑と青の矢印が、それぞれX軸、Y軸、Z軸となっているようです。

次に、このオブジェクトを動かしたり、大きくしたりします。
左上のツールバーの「MoveTool」をクリックすると、矢印をドラックして好きな方向に動かすことができます。

image.png

その二つとなりの「ScaleTool」をクリックして、出ている□の矢印をドラッグして好きな大きさに変えることができます。
image.png

右の「Inspector」ウィンドウの「Transform」で、値を入力して形を作ることもできます。
image.png

形ができたので、このオブジェクトを「Cube」から「Ground」と名前を変えてておきました。

image.png

次に、「Ground」に色を塗ります。
image.png
「Project」ウィンドウから、「create」→「material」とすすみます。
「Project」ウィンドウに、「Newmaterial」が表示されるので、「Gcolor」と名前を変えておきます。
image.png

次に、「Gcolor」をクリックすると、inspectorウィンドウに、「Albed」というところがあるので、
その左側の□をクリック。カラーウィンドウが出てくるので、好きな色を選びます。
すると、「Material」の「Gcolor」の色が選んだ色に変わります。

ここで、「Gcolor」を「Hierarchy」の「Ground」にドラッグ&ドロップすると、「Ground」の色が変わります!しばふの生えたグラウンドって感じ^^
image.png

今日は、これでおしまい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unity 3D入門 #7 [アセット&敵の追加]

前回作った宝探しゲームを豪華にするために、新しいアセットの追加と妨害要素である敵を追加したいと思います。

建物アセット:Sun Temple
Sun Temple参考URL:https://www.asset-sale.net/entry/Sun_Temple

ここで、Sun Templeに入っている家を置こうとすると

'MinAttribute' is an ambiguous reference between 'UnityEngine.PostProcessing.MinAttribute' and 'UnityEngine.MinAttribute'

上のようなエラーが出てしまいました。
これは、MinDrawer.cs内のMinAttributeを3箇所UnityEngine.PostProcessing.MinAttribute に変更すると解決しました。

MinAttributeエラー参考URL:https://qiita.com/ELIXIR/items/140ee125b3c52cc7251d

スクリーンショット 2020-07-22 0.06.33.png

だいたいこんな感じの建物ができました。
現時点では、なぜか壁をすり抜けて家の中に入れることや、家の内部の照明がないこと、扉を開けるスクリプトがないことが問題点としてあげられます。
とりあえず今はただの障害物として配置するにとどめます。

敵(ゴーレム)アセット:Mini Legion Rock Golem PBR HP Polyart
敵の見た目はこのようになります。
スクリーンショット 2020-07-21 16.18.19.png

また、animatorは変更しなければならず、移動についてコードを書く必要があります。

とりあえず、プレイヤーに向かって歩き続けるコードを書きます。

プレイヤーを追いかけ続けるためにNavMeshを使った手法があります。
NavMesh概要参考URL:https://unity.moon-bear.com/3dホラーゲーム「スケアクロウ:廃村の恐怖」/navmeshを使って「追いかけてくる敵キャラ」を作る/

上のURLでは「Window」→「Navigation」とありますが、自分のunityでは違う場所にあったので、メモがわりにスクショを載せます。

スクリーンショット 2020-07-27 19.22.54.png

また、追いかけるプログラムは(https://mono-pro.net/archives/6439 )を参考に以下のようにしました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;  // ここを追加

public class chasePlayer : MonoBehaviour {
    private GameObject player;
    private NavMeshAgent agent;
    void Start() {
        player = GameObject.FindWithTag ("Player");
        agent = GetComponent<NavMeshAgent>();
    }
    void Update() {
        agent.destination = player.transform.position;
    }
}

*プレイヤーを追いかける敵にNav Mesh Agentをアタッチすることを忘れないよう注意

これで、敵がプレイヤーを追いかけてくれるようになりました。
現段階では敵の歩行モーションの設定などをしていないので、スライド移動ですが、いつかやろうと思います。

ezgif-7-7f79660f4cca.gif

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Puppet3D使ってみた

Unity アセット真夏のアドベントカレンダー 2020 Summer! の、6日目担当のニア(ニアルカちゃんねる)です!
よろしくお願いします!✧ヾ(❀╹◡╹)ノ゙

本日ご紹介するのは、Puppet3D - Asset Storeです。リギングやスキニングをUnityの中で行えるアセットです。
f9d38efe-c4f0-46f8-8201-8cd76742a78c.png

こんなシチュエーションでおすすめ!

・Boneの入っていないモデルを、ウェイト調整にあまり拘らず簡易的に揺らしたい
・ツール間の行き来をせずUnity内でリギング・スキニングを完結したい
・モデリングツールが手元に無い、モデラーが居ない

やってみたこと

今回は、VRM形式キャラクターモデルのスカートをUnity ClothからBone制御に変更するというのをやりました。
一部始終をYoutubeにアップしたのでご覧下さい!!(←Clickで動画へ)
Puppet3d.png

動画内容のおおまか手順

〇準備
Boneを入れたいスキンオブジェクトに以下コンポーネントがアタッチされている事を確認します
・Skined Mesh Renderer
・Mesh Filter
・Mesh Collider

※特にMesh Colliderが無いと意図した場所にBoneが生成されません...
私は動画収録時これで失敗しました!

〇Boneを入れる
Puppet3Dウィンドウを出して以下手順を繰り返します
1.スカート選択
2.Create Bone Tool
3.骨を入れたい箇所でマウスクリック
4.Finish Bone

〇バインド
生成したBone全てとメッシュを選択
->Puppet3DウィンドウのSkinningタブで「Skinning」をClosest Pointにする
->「Bind Smooth Skin」を押す

おわりのあいさつ

株式会社スパイス バーチャル支社 研究開発室所属のニアルカちゃんねるの髪が赤い方です!
動画ネタの一つとしてUnityアセット使ってみたをもっとやっていきたいと思ってますイェイL(‘ω’)┘三└(‘ω’)」イェイ

明日は 潮留 さんの「Arbor3をおすすめしたい3つの理由」です!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

スマホアプリ制作未経験者がGooglePlayで配信できるアプリを作るまで~QuizKnockさんに憧れて~

前置き

皆さんはyoutubeを見るだろうか。筆者はよく見る。中でも最近特に注目しているのがQuizKnockという、主にクイズを扱っているチャンネルである。「身の回りのモノ・コトをクイズで理解する」をコンセプトとした東京大学発の知的メディア「QuizKnock」のyoutubeチャンネルといった位置づけだ。
さて、このチャンネルの動画に、「東大生100点は取り飽きたので人生最高得点を取る旅に出ます」という動画がある。
3週間のあいだに、「何か」でより「高得点(※積み重ね不可、1回のチャレンジでの結果。複数回チャレンジは可。)」を取ってきた人が勝ち、という企画だ。
動画は展開が二転三転して面白いのでまず視聴をお薦めする。

以下盛大なネタバレとなるが、

この動画ではふくらPが「1不可説不可説転点」を取り優勝を果たす。
不可説不可説転てなんだよという問題はちょっと後に説明するとして、その方法が「自分でゲームアプリを開発して自分の設定した点数を取る」というものだった。「使う側より作る側が強いの 世の中っていうのはそういうもん」というのは動画内でふくらPが残した名言である。エンジニアとしては心くすぐられる発言ではないか。
しかも後に、「1不可説不可説転点RTA!!(ルイザ・グロス・ホロウィッツ賞クイズアプリ再現RTA)」という動画で実際にエンジニアの方がこのアプリを作るRTA(リアルタイムアタック)までしている(ちなみにこの時の記録は27分36秒)。

こんなのやってみたいじゃん。

というわけで、この記事の目標はPHPエンジニア(スマホアプリ制作未経験)の筆者がGooglePlayで配信できるアプリを作ること、である。
ネタバレになるが結果は成功だ。

要件は以下。
・Androidのみ対応
・本家に倣いUnityで開発
・UI/UXは本家「ルイザ・グロス・ホロウィッツ賞クイズアプリ」を可能な限り再現
・内容は本家と違い、且つ限りなくオマージュ感のあるもの

これだけお薦めされておいて上記の動画を視聴しなかった方のためにアプリの概要を説明しておくと、
①トップ画面
②クイズ(二択)の解答選択画面
③結果表示画面
の3要素のみで構成されているゲームアプリである。

ではいよいよ作っていこう。

作業

①クイズを作る

技術的な点だけ知りたい方は飛ばしていただいて大丈夫だ。
「ルイザ・グロス・ホロウィッツ賞クイズアプリ」はルイザ・グロス・ホロウィッツ賞の唯一の日本人受賞者を当てるクイズゲームなので、理想としては〇〇賞の唯一の○○人受賞者を当てる、というクイズがいい。
また、ルイザ・グロス・ホロウィッツ賞は「生物学、生化学の分野の基礎研究において、顕著な貢献を行った研究者または研究者のグループに与えられる賞(wikipedia参照)」なので、今回は生物学を含むところの自然科学の対義語である社会科学関連の賞にあたりをつける。
それらしいものをwikipediaで漁った結果、ジョン・フォン・ノイマン賞(ライク・ラズロ・カレッジが社会科学の優れた学者に与える賞)をノルウェー人で唯一受賞しているヤン・エルスターという人物を発見。この方を正解とさせていただこう。
不正解の方だが、本家ではルイザ・グロス・ホロウィッツ賞の唯一の日本人受賞者である利根川進(正解)に対して日本人で唯一ダーウィン・メダルを受賞している木村資生(不正解)となっている。これに倣うにはノルウェー人で唯一また何かの社会科学系の賞を受賞している人物を探し出したいところだが、「"ノルウェー人で唯一" "賞"」の検索でhitした人物がノルウェー人で唯一ドイツ十字章金章を授与されたフレドリク・イェンセンしか出てこなかったので、社会科学どころか賞ですらないが妥協することにする。
クリア時の点数は1不可説不可説転点より高い1グーゴルプレックス点にしておく。(参照:https://quizknock.com/large-number)

②Unityでアプリを作る

android版のみの作成でこの画面数ならAndroid Studioでやるのが手っ取り早そうだが(実際RTA動画ではAndroid Studioが利用されている)、本家がUnityなのでなんとしてもUnityを使いたい。オタクとはそういうものだ。

こちらを参考に、まずはUnityでアカウントを作成。
アカウントの作成が完了したら、トップページの「はじめる」から遷移し更に個人向けのタブを選択して、そこにあるPersonalを選択(今回は私の個人的な趣味で収益も発生させないので)。
新規ユーザーを選びたいところだが、参考サイトの指示に従いリピートユーザーを選択。
利用規約に同意してUnityHubをインストール(UnityHubとUnity自体の違いは参考サイト参照)。

無事UnityHubが起動できたら、まず右上のアイコンからサインイン。
サインインできたら、新規ライセンスの認証で先ほどと同様Personal、10万ドル以下で認証。(参考サイトには業務に関連しないライセンスを選択していたが一応会社のメールアドレスで作成したのでこちらにしておいた、そこは各々の裁量で。)
このあたりでお気付きかもしれないが参考サイトと画面が違う。どうやらはじめに環境設定画面が表示されているようだ。左上を押せばトップに移動するので参考サイトに従える。
バージョンに関しては参考サイトとちょっと様子が違うが、説明を読んだ感じ最新の(LTS)でよさそうなのでそれで。
追加モジュールは、今回はandroid版しか作らないが、一応iOSも。ドキュメントはデフォでチェックがあるのでそのまま、言語パックは使う予定ないが一応日本語だけ選択しておく。
規約に2回ほど同意したら実行できるので実行。

Visual Studioのインストーラが出てきて一瞬ビビるがまあ怪しいソフトではないので待機。

更に暇なので背景色をカラーピッカーでピックしておく。
トップ画面:85FEED
クイズ画面:FF7AAA
結果表示画面:FDFC7C

そうこうしている間にインストールが終わった。参考サイトに従い、プロジェクトを新規作成。本家はどう見ても2Dなので2Dで。
プロジェクトが開かれる。
参考サイトによるとシーンというのが場面に相当するそうなので、今回は3ないし4シーン作ればよさそう。

2Dの単純なゲームなのでこの先は先ほどまでのサイトだと高度すぎるため、他の参考サイトを探す。まんまクイズアプリ作ってるところがあったのでここからはこちらを参考にしていく。

しかしまずもって参考サイトはボタンアクションなのに対しこちらは画面タップ遷移だし参考サイトはなぜか画面を縦にする説明がないので他諸々参照した結果Gameウィンドウでアスペクト比を新規作成して9:16にすることで縦画面の編集が可能に。

とりあえずmain Cameraの背景色を先ほどピックした水色に変更すると何となくそれっぽくなる。

次にGUIを使って文字を配置していく。
GUIからテキストを入力する場合、Assetsにfontを格納する必要があるようだ。デフォではArialしか入っていないので適宜用意して入れていく。
GameOcject>UI>textから、文字を入れていく。

参考サイトの「uGUIでの画面遷移:onClickイベント」まで進む。

ボタンアクションだが画面全体にしたいので、無理やりだが
GameOcject>UI>buttonで作成したボタンを全画面サイズにして透過する方法をとる。

ちなみにC#を記述しようとすると先ほど折角ダウンロードしたVisual Studioが起動しようとするが、この程度のコードなので、
Assets>Create>C# Scriptで作成されるファイル(プロジェクトディレクトリのAssetsの中にある)をテキストエディタで開いて記述した。
コードの内容がやや古いようなのでこちらを参考に修正して記述する。

実行により遷移が確認できたら、あとはこれまで使った技術だけで回せそうなので参考サイトの「クイズ画面の作成」~以降は読み飛ばす。

シーンを3つ追加してそれぞれのボタンから遷移(ボタンのデザインはimageを二カ所Noneすればフチなし四角形になります)するように設定。
正誤判定などしない。画面がそうなればよい。今回は。

③Android用にビルド

File>BuildSettingsを開く。
PlatformをAndroidにして、「Build App Bundle(Google Play」にチェックを入れる。(これにより作成されるのがapkファイルでなくaabファイルになる)
Player Settingsを開く。「Company Name」、「Product Name」、「Default Icon」を適宜設定する。
ちょっと参考画像の見た目は違うが、こちらを参考にkeystoreを作成。
更にこちらを参考に64ビット対応させておく。
準備ができたらビルドする。保存場所は適当で良い。

④GooglePlayにアプリケーションを登録する

まずこちらでGoogleアカウントとGoogleディベロッパーアカウントを作成する。$25かかる。
そしてこちらからコンソールに入る。
左メニュー「すべてのアプリ」の「アプリの作成」からアプリを作成する。言語とアプリ名を入力してボタン押下でアプリの設定画面に遷移する。
画面の指示に従い必須事項を記入していく。事前に準備が必要なのは各名称や説明文の他
・アイコン画像
・プレイ画面のスクリーンショット
・フィーチャーグラフィック画像
・メールアドレス
・プライバシーポリシーの記載ホームページURL
だ。一切個人情報など取り扱わないアプリだがプライバシーポリシーのURLが必要なのは手痛い。筆者はこのためだけにFC2に登録しプライバシーポリシーだけのサイトを開設した。
なお最初に表示されるのは「ストアの掲載情報」だが、ここで必須の「コンテンツのレーティング」はまた別の左メニューから入力が必要なので一度未公開で保存した後に左メニューからそれらを順次入力していく。
③でビルドしたaabファイルは左メニュー「アプリのリリース」から製品版の「管理」>「次へ」で選択できる。

左メニューのグレーのチェックがすべて緑になった状態で「アプリのリリース」へ進むと、確認→公開できる。
あとは審査を待つのみだ。

⑤結果

2020/7/14にこの作業を完了し、審査を通過してリリースされたのが2020/7/21だった。
https://play.google.com/store/apps/details?id=com.gluecode.John_von_Neumann_Award
こちらがリリースされたアプリである。
筆者の実機でインストールしたところ、問題なく動作した。
クイズ作成:1.5h
アプリ作成:6h(環境構築含)
アプリリリース:4h(審査待ち除)
程度の作業だった。

まとめ

お遊びとしてやるには大変楽しい作業だった。
実務的に考えると、テスト段階を完全に飛ばしているなど課題が多い。特に、画面サイズがUnityで作成している段階からどうにも小さく思えたのが実機で確認するとやはり小さく、Androidの機種差を考慮してもおそらく違う設定で作成したほうが良かったと思われる。また、今回参考にしたサイトの多くで言及が無かったGooglePlayConsole上での機能(テスト版リリースなど)が全く使えていないので、実際に企業としてアプリをリリースするのであればこのあたりの使用も必要になってくるだろう。今回のようにあれこれhow toサイトをメインに見るよりも本家サイトの手順をしっかり理解して使いこなさなくてはならない。筆者にその日が来るのかは不明だが。

ともあれ楽しい遊びだった。ふくらPをはじめとするQuizKnockの皆さんありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【小ネタ】MacでUnity2019.4LTSがMacごと落ちたりフリーズする場合の解決例

はじめに

今までUnity2018.2を使用していたのですがUnity2019.4LTSに更新したら5分に1回くらいMacごと落ちるようになりました:sob:
さっき解決したので解決方法を残しておきます。

動作環境

  • macOS 10.15.5
  • Unity2019.4.1f1

Unity2019.4で5分に1回くらいMacが落ちる問題

Unity2019.4でなにかボタンを押した際やマウスカーソルを動かした時にMacがストンと落ちました。
再起動の際にクラッシュ内容が表示されるのでこの内容で調査しました。

panic(cpu 0 caller 0xffffff800964aa3a): Kernel trap at 0xffffff7f8bccf24f, type 14=page fault, registers:
CR0: 0x000000008001003b, CR2: 0x0000000000000000, CR3: 0x000000000d9b6000, CR4: 0x00000000003626e0
RAX: 0x000000000c000304, RBX: 0xffffff80265e2800, RCX: 0x0000000000000001, RDX: 0x0000000000000000
RSP: 0xffffff8117a8bdf0, RBP: 0xffffff8117a8bdf0, RSI: 0x0000000000000000, RDI: 0xffffff803c10c600
R8:  0x0000000000000001, R9:  0xffffff8117a8bc34, R10: 0x0000000000002960, R11: 0x0000000000002960
R12: 0xffffff80265e2800, R13: 0x0000000000000004, R14: 0x0000000000000001, R15: 0xffffff7f8bd2a568
RFL: 0x0000000000010246, RIP: 0xffffff7f8bccf24f, CS:  0x0000000000000008, SS:  0x0000000000000010
Fault CR2: 0x0000000000000000, Error code: 0x0000000000000000, Fault CPU: 0x0, PL: 0, VF: 1

Backtrace (CPU 0), Frame : Return Address
:
0xffffff8117a8bfa0 : 0xffffff80094c513e 
      Kernel Extensions in backtrace:
         com.apple.iokit.IOAcceleratorFamily2(438.5.4)[D695D9DA-7C20-35D6-910F-E7A332A0F515]@0xffffff7f8bcab000->0xffffff7f8bd6ffff
            dependency: com.apple.driver.AppleMobileFileIntegrity(1.0.5)[0425E074-601A-3487-A54F-1E675D065186]@0xffffff7f8a1f9000
            dependency: com.apple.iokit.IOPCIFamily(2.9)[3C56BB73-D149-3E84-A2EB-DF806779B96C]@0xffffff7f8a2b3000
            dependency: com.apple.iokit.IOSurface(269.11)[F1E7389D-2807-3C5D-8A7F-5422542E867F]@0xffffff7f8a6a6000
            dependency: com.apple.iokit.IOGraphicsFamily(576.1)[B1C0006F-E1F5-37D9-9548-5F918E92B422]@0xffffff7f8a5bc000
            dependency: com.apple.iokit.IOReportFamily(47)[1FB49168-0280-3F04-A99A-F830C915E994]@0xffffff7f89e9f000
         com.apple.driver.AppleIntelBDWGraphics(14.0.6)[6139D437-2098-316E-967B-4692BAA82C5B]@0xffffff7f8c19f000->0xffffff7f8c238fff
            dependency: com.apple.iokit.IOPCIFamily(2.9)[3C56BB73-D149-3E84-A2EB-DF806779B96C]@0xffffff7f8a2b3000
            dependency: com.apple.iokit.IOSurface(269.11)[F1E7389D-2807-3C5D-8A7F-5422542E867F]@0xffffff7f8a6a6000
            dependency: com.apple.iokit.IOGraphicsFamily(576.1)[B1C0006F-E1F5-37D9-9548-5F918E92B422]@0xffffff7f8a5bc000
            dependency: com.apple.iokit.IOAcceleratorFamily2(438.5.4)[D695D9DA-7C20-35D6-910F-E7A332A0F515]@0xffffff7f8bcab000

BSD process name corresponding to current thread: kernel_task

カーネルがパニックしているようです..。

解決方法: MetalサポートをONにする

以下forumに回答ありました。
https://forum.unity.com/threads/unity-editor-crashes-macos.739535/

スクリーンショット 2020-07-27 8.18.37.png

Project SettingからMetalサポートをONにすると本エラーが防げるとのこと。
古めのMacで発生するそうです。
上記設定後にクラッシュすることはまだありません。

Unity2019.4でPlayボタンを押したときにUnityがフリーズする問題

上の問題が解決され一件落着!..と思ったのですがプロジェクトによってはUnity Editorで再生ボタンを押すとローディングがくるくるまわりそのままフリーズしました。

スクリーンショット 2020-07-27 8.41.16.png

解決方法: 旧Firebase SDKを更新する

この問題は100%発生するプロジェクトと全く発生しないプロジェクトがあったので各ライブラリを確認することにしました。
調査の結果、旧Firebase SDKを使用しているプロジェクトで発生していることがわかりました。

Firebaseのドキュメントにはknown-issuesとして4つの問題が挙げられています。
Unity2020特有のIssueもあるので一読するのが良さそうです。
日本語ドキュメントだと表示されないので言語設定を英語にする必要があります。

https://firebase.google.com/docs/unity/setup#known-issues

  • .NET compatibility when using Unity 2017.x and later
  • Unity 2017.2 networking
  • Missing Firebase Android config file in Unity 2020.
  • Installation Conflict when using Unity Package Manager

Firebase SDK更新後、再生ボタンを押してもフリーズしないようになりました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】TestRunnerを使ったアセットバリデーションツールを最短経路で作ってみる

本記事ではUnityが無料で提供するTestRunnerを使って、アセットバリデーションツールを最短経路で作ってみようと思います。大抵プロジェクトの途中で開発することになるバリデーションツールをTestRunnerでも作れるのではないかという試みです。

準備

  1. Test Frameworkのインストール
  2. バリデーションするアセットの用意

1.Test Frameworkのインストール

TestRunnerを使用するために、PackageManagerからTest Frameworkをインストールしておきます。

コンパイルが成功したらWindow > General > Test Runner > Test RunnerでTest Runnerウィンドウを表示しておきます。

2.バリデーションするアセットの用意

今回は200個のScriptableObject(1001.asset~1200.asset)がバリデーション対象です。
格納先はどこでも良いですが、Assets/AssetBundlesフォルダ配下に追加します。(フォルダ名に制限はありません)

これで準備は完了です。

バリデーション処理の流れ

  1. System.IO.Directory.GetFilesメソッドでアセットパスの配列を取得
  2. AssetDatabase.LoadAssetAtPathメソッドでアセットを1つずつロード
  3. ロードしたアセットをバリデーション処理に通す

バリデーションに引っかかったら(失敗したら)、その理由をAssertの第2引数で出力します。

実際のコード

  • TestRunnerから呼ばれるエントリーポイント
  • バリデーション処理を記述したメソッド

上記の2つの構成になっています。

TestRunnerから呼ばれるエントリーポイント

AssetTest.cs
/// <summary>
/// TestRunnerから呼ばれるエントリーポイント
/// </summary>
[Test]
public void AssetValidate()
{
    // Assertで処理を止めないようにする
    Assert.raiseExceptions = false;

    var assetDirectoryPath = "Assets/AssetBundles/";
    var filePaths = Directory.GetFiles(assetDirectoryPath, "*.asset");

    foreach (var path in filePaths)
    {
        Validate(path);
    }
}

バリデーション処理を記述したメソッド

AssetTest.cs
/// <summary>
/// 各ファイルごとに実行するバリデーション処理
/// </summary>
/// <param name="path">ファイルパス</param>
/// <returns>falseなら失敗 / trueなら成功</returns>
private void Validate(string path)
{
    var fileName = Path.GetFileName(path);
    // アセットをロード
    var asset = AssetDatabase.LoadAssetAtPath<QuestAsset>(path);

    // アセット存在テスト
    Assert.IsNotNull(asset, $"{fileName} => asset is null");

    // ID未記入テスト
    Assert.IsFalse(string.IsNullOrEmpty(asset.id),
        $"{fileName} => ID is null or empty");

    // 命名規則テスト
    Assert.IsFalse(asset.id.IndexOf("A", StringComparison.Ordinal) != 0,
        $"{fileName} => The naming conventions are different. : {asset.id}");
}
  • アセット存在テスト
  • ID未記入テスト
  • 命名規則テスト

3種類のバリデーションを用意しました。
Assertの各メソッドの第2引数は失敗時に出力されます。
失敗時の理由を丁寧に書くことで、その後の修正作業の効率が上がります。

TestRunnerから実行

Run AllまたはRun SelectedをクリックしてTestRunnerを実行します。

validate2.gif
失敗したテストに関しては、事前に書いておいた失敗の理由が出力されます。

TestRunnerを使うメリット

  • [Test]アトリビュートを定義するだけで簡単にTestRunnerウィンドウにテストを追加でき、簡単にテストを実行することが出来る
  • バリデーションをTestRunnerに共通化しておくと後からジョインしたメンバーが把握しやすい
  • TestRunner自体がPackageなので簡単にインストール可
  • テストをコマンドラインから実行できるのでワークフローが組みやすい(GithubActionsなど)

個人的には上記のようなメリットがあると考えています。

Assertを使用するときの注意点

TestRunnerでよく使用されるAssertメソッドをバリデーション処理側に使用すると、デフォルト状態ではテストの失敗時に後続処理が止まります。

これではテスト結果の全貌が見えなくなり開発効率が低下しますので、以下の1行を追加すると良いです。

Assert.raiseExceptions = false;

こうするとテストに失敗しても処理は継続されます。

まとめ

TestRunnerを使って簡単なアセットバリデーションを作ってみましたが、従来のように個別にバリデーションツールを書いても工数はそこまで大きく変わらないです。
しかし成功・失敗(+失敗の理由)をログ出力する程度のバリデーションであれば、記述するコード量を減らす1ことができ、開発の効率化観点でTestRunnerは有用だと思いました。

今回は最短経路で作成したバリデーションでしたが、実践では複雑な実装が想定されます。
いかにバリデーションをし易くするかということを考えて設計・実装することが大事になります。
これはTestRunnerを使用するしないに関わらず必要な視点です。

環境

  • Unity2019.4.4f1
  • Test Framework 1.1.14

今回のサンプル全ソースは以下にアップしています。
https://github.com/baobao/unity-test-runner-asset-test-shortcode


  1. EditorWindowの記述やテスト判定のView処理を書く工数は下げられそうという意味 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unity + PlayFabのタイトルデータを使いモバイルアプリの簡易強制アップデートを作る

使用バージョン

  • Unity 2019.4.3f1
  • PlayFab 2.90.200713

本記事の目的

Unity+PlayFabを使い、PlayFabからモバイルアプリの強制アップデートを促す

本記事で得られないもの

ログイン時以外での厳格な強制アップデート
(通信のたびのバージョンコードのチェック)

はじめに

この記事はUnityやPlayFabのインストールや基本的な使い方には触れていません
なので説明を省く箇所が多々あります

タイトルデータの登録

まず、PlayFabの画面に行き、コンテンツからタイトルデータを登録します
タイトル_データ_·_PlayFab.png
登録するのは
AndroidVersioniOSVersionです
モバイルを両方のOSで出す場合は必ず分けておきましょう。
運営してると共通のバージョンコードではとても管理しきれないためです。

ここではAndroidVersionに1.0.1を設定しておきます。
PlayFabでの操作は以上になります

Unityでログインからバージョンチェックまで

いきなりですがコードはこちらです

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PlayFab;
using PlayFab.ClientModels;

public class PlayFabLogin : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
       var request = new LoginWithCustomIDRequest {CustomId = "MyCustomId", CreateAccount = true};
               PlayFabClientAPI.LoginWithCustomID(request, (result =>
               {
                   GetTitleData();
               }), error =>
               {
                   Debug.LogError(error.GenerateErrorReport());
               });
    }

     void GetTitleData()
     {
         PlayFabClientAPI.GetTitleData(new GetTitleDataRequest(), result =>
         {
#if UNITY_ANDROID
                 if (result.Data.ContainsKey("AndroidVersion"))
                 {
                     // タイトルデータのバージョン
                     string serverVersion = result.Data["AndroidVersion"].ToString();
                     // ローカルのバージョン
                     string lovalVersion = Application.version;
                     // 文字列の大小を比較
                     int compareResult = serverVersion.CompareTo(lovalVersion);
                     // サーバのバージョンの方が大きかったらストアに飛ばす
                     if (compareResult == 1)
                     {
                         Debug.Log("アプリの更新が必要です");
                         Application.OpenURL("アプリのストアページURL");
                     }
                     else
                     {
                         Debug.Log("最新バージョンです");
                     }

                 } 
#else
             Debug.Log("iOSも同じように書く");
#endif
         },
             error => {
                 Debug.Log(error.GenerateErrorReport()); }
         ); }
}

処理の流れとしては

  • ログイン
  • タイトルデータの取得
  • OS 事のバージョンの比較
  • 必要であればストアページに飛ばす

です。ログインとタイトルデータの取得は同時にやってもいいですがここではシンプルにするために分けています。

ここまで書けたらProjectSettingsからAndroidにSwitchPlatformをし、Versionを1.0.0にしてみましょう
VersionCheck.png

この状態で実行すると以下のログが出ます
needUpdate.png
次にVersionを1.0.1にして実行してみると以下のようになると思います
VersionUp.png
LatestVersion.png
これでバージョンチェックの処理ができました。

注意点

今回の実装ではログイン時にしかバージョンをチェックしないため、
プレイ中のユーザーに対してアップデートを促すことができません
なので、必要ならタイトルデータの更新を適宜行うなどの対応が必要になります

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】たまに使うアセットのGUIDを確認するWindow

image.png

なんだかんだ.metaファイルやアセットバンドルやシーンのトラブルシューティングで使うやつ

using UnityEngine;
using UnityEditor;

namespace AssetTool {
    public static class FindGUID  {

        [MenuItem("Tools/Find by GUID")]
        static void Start() {
            FindGUIDWindow.Open();
        }

    }

    public class FindGUIDWindow : EditorWindow {

        private Object asset;
        private string guid;

        public static void Open() {
            var window = (FindGUIDWindow) GetWindow(typeof(FindGUIDWindow));
            window.titleContent = new GUIContent("Find GUID");
            window.Show();                
        }

        private void OnGUI() {
            GUILayout.Label("GUIDを入力するとアセットを検索します。\nまたはアセットをドラッグ&ドロップするとGUIDを表示します。");

            var oldGUID = guid;
            guid = EditorGUILayout.TextField("GUID", guid);
            if (oldGUID != guid) {
                asset = AssetDatabase.LoadAssetAtPath<Object>(AssetDatabase.GUIDToAssetPath(guid));
            }

            var oldAsset = asset;
            asset = EditorGUILayout.ObjectField(asset,typeof(Object),false);
            if (asset != oldAsset) {
                guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(asset));
            }
        }
    }   
}

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity:PackageManager】自作Packageの作成と追加

自作Packageの作成とプロジェクトへの追加
ドキュメントや記事はあるんだけど古かったりイマイチわからなかったりするので
(多分)わかりやすいようにがんばってまとめてみる

検証:Unity2020.1

GitHub、SourceTree使ってます

自作Package作成

1. GitHubにリポジトリ作成

 適当に新規リポジトリ作る
 https://github.com/username/sample_package.git

 ※結果的にリポジトリはPublic/Privateどちらもパッケージ追加できたが
  Privateは自分自身がSSHkey登録してるからできてるだけかも(普通に落とせたらダメな気がするし)

2. プロジェクト作成

 1のリポジトリをSourceTreeでクローンする
 そこにUnityの新規プロジェクト作る

 例:クローンした「sample_package」に同名の「sample_package」でプロジェクト作成
  sample_package
  ┗ sample_package
   ┣ Assets
   ┣ ...
   ┣ Packages
   ┣ ...

3. Packagesに自作Packageフォルダ追加

 フォルダ階層はなんでもいいんですがPackages配下に入れておくとUnityエディタ上でファイルの設定ができるので多分推奨な気がする

 例:Assetsフォルダと同じ階層にPackagesフォルダがあるので適当に自作パッケージ名のフォルダ追加
 sample_package
  ┗ sample_package
   ┣ Packages
    ┣ sample ←追加
    ┣ manifest.json
    ┣ packages-lock.json

4. package.json追加

 先ほど作ったsampleフォルダ配下に「package.json」ファイルを作成
 sample_package
  ┗ sample_package
   ┣ Packages
    ┣ sample
     ┣ package.json ←追加

package.json
{
  "name": "com.sample.samplepackage",
  "displayName": "SamplePackage",
  "version": "0.1.0",
  "unity": "2020.1",
  "description": "description.",
  "author": {
    "name": "SamplePackage"
  }
}

色々とパラメータはあるみたいだけどとりあえず最低限必要そうなものだけ記載
Unity上で設定もできます(Packagesフォルダ以下に含まれている必要がある)
package_manager_03.png

5. アセンブリファイル追加

 package.jsonと同じフォルダに
 「Runtime」「Editor」フォルダを追加
 その中にアセンブリファイルと適当にスクリプトを追加
  sample_package
  ┗ sample_package
   ┣ Packages
    ┣ sample
     ┣ package.json
     ┣ Runtime ←追加
      ┣ SampleRuntime.cs ←追加
      ┣ Sample.SamplePackage.asmdef ←追加
     ┣ Editor ←追加
      ┣ SampleEditor.cs ←追加
      ┣ Sample.SamplePackage.Editor.asmdef ←追加

例として「Runtime」「Editor」を追加してますが、ランタイムのみ、エディタのみとかであればそれぞれ不要です
それ以外のアセット(テクスチャとかシーンとか)もpackage.jsonのフォルダ以下に追加すればパッケージに含まれます
ちなみに、アセンブリファイル(.asmdef)があればフォルダ名はなんでもいいです
が、Unity公式のパッケージがそういう命名規則でやってるので揃えるのがわかりやすくて無難

Sample.SamplePackage.asmdef
{
    "name": "Sample.SamplePackage",
    "references": [],
    "includePlatforms": [],
    "excludePlatforms": []
}
Sample.SamplePackage.Editor.asmdef
{
    "name": "Sample.SamplePackage.Editor",
    "references": [
        "Sample.SamplePackage"
    ],
    "optionalUnityReferences": [],
    "includePlatforms": [
        "Editor"
    ],
    "excludePlatforms": [],
    "allowUnsafeCode": false,
    "overrideReferences": false,
    "precompiledReferences": [],
    "autoReferenced": true,
    "defineConstraints": [],
    "versionDefines": []
}

「references」がそこそこ重要で
他のパッケージに依存してる場合はここに追記しないといけない
あえてエディタのアセンブリに「Sample.SamplePackage」が追加してますが、これで自作のランタイムスクリプトに依存してることになります
Unity公式のパッケージの依存がある場合はこんな感じ

Sample.SamplePackage.asmdef
{
    ...
    "references": [
        "Unity.InputSystem", InputSystem使用してる場合
        "Unity.RenderPipelines.Universal.Runtime" URP使用してる場合
    ],
    ...
}

というか依存してるのに記載がない場合はエラー出るので気づくと思います

記載するのはアセンブリファイル名です
プロジェクトの「Library/PackageCache」に使用してるパッケージが含まれているので
エラーになってるパッケージの「○○.asmdef」を探して○○をreferencesに記載すればOKです

とか説明しておいてUnity上で設定もできるので依存関係はこっちで設定した方が楽です(Packagesフォルダ以下に含まれている必要がある)
package_manager_04.png

6. プッシュ

 これでPackage側の準備は完了
 作成したファイル等をGitにプッシュしておいてください
 各ファイルの.metaファイルもプッシュ必須です
 無いと以下Package追加時にエラー出ます

自作Package追加

1. PackageManagerから追加

 新規でも既存でもいいんですが適当にUnityプロジェクト開いてPackageManager開いて下さい
 左上に+ボタンがあるので画像の「git URL...」を選択
 package_manager_add.png
 URL入力して「Add」で追加できます
 
 URLは最初に作成したリポジトリ(※下記は例で実際は自身で作成したURLです)
 https://github.com/username/sample_package.git
 なんですが、これだとリポジトリ直下にpackage.jsonを配置した場合なので
 
 今回のように独自のフォルダ階層の場合は
 sample_package
  ┗ sample_package
   ┣ Packages
    ┣ sample
     ┣ package.json ←ここ

 https://github.com/username/sample_package.git?path=/sample_package/Packages/sample
 のようにpathで階層指定する必要があります

2.完了

 ここまで問題なくできればPackageManagerに自作パッケージが追加されているかと思います
 package_manager_01.png
 package_manager_02.png

 とりあえず追加までに最低限必要な作業だけやったんですが
 他にも「LICENSE.md」とか「CHANGELOG.md」とかちゃんとパッケージとして配布するならあった方がいい作業もあるんですが、あとは細かいファイルや定義追加なので公式のドキュメント見てもらえればと
 https://docs.unity3d.com/Manual/CustomPackages.html

 ちなみに…
 Previewパッケージは2020以降デフォルトで表示されないのでProjectSettingsから表示してあげてください
 依存関係の表示設定もできます
 pakagemanager.png

まとめ

以前に比べ2020で大分便利になったと思うんですが
今後まだ改良されていくとは思います
サンプルフォルダの追加とか…
色々調べつつではあるのでそのうち追記や別記事書くかもです

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む