20200212のUnityに関する記事は11件です。

角丸四角とか円を綺麗に描けるシェーダー作った

BasicShapeSprite

https://github.com/kyubuns/BasicShapeSprite

出来ること

  • キレイな角丸四角とか円が描ける
    • 綺麗なまま拡縮出来る!!!!すごい!!!!
  • どれだけ描いてもSetPass Callが1

  • 左上だけ角丸にする、とか角ごとに指定が出来る
    messageImage_1581500091172.jpg

基本的な使い方

  • SquareComponent, Mesh Filter, Mesh Rendererを貼り付けたGameObjectを作る
  • Mesh Rendererのマテリアルを、BasicShapeSprite/Materials/以下に入っているものにする
  • おしまい

直接シェーダーを呼び出す

  • 以下の情報を渡してメッシュを描画する
  • uv1(float4)
    • [0] : x (0.0f - w)
    • [1] : y (0.0f - h)
    • [2] : w
    • [3] : h
  • uv2(float2)
    • [0] : 角丸のR
    • [1] : 枠の幅
  • uv3(float4)
    • 各角を角丸にするかどうか(1.0f or 0.0f)
    • [0] : 左下
    • [1] : 左上
    • [2] : 右下
    • [3] : 右上
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UnityでROS#のチュートリアルを動かしてみた

はじめに

UnityでROSを動かすためのアセットROS#のチュートリアルをOculusQuest上で動かしてみたところ、
色々躓いたところがありましたので書いておきます。
今回ROSは初めて触ったので、基本的なところがわかっていない状態で進めています。

ROS# wiki
ROS#のページです。ここに記載のある1. Installation and Configuration ~ 2.3 Gazebo Simulation Example
を今回動かしています。

アセットストア
ROS#のアセットストアのページです。
試行中、アセットストアからダウンロードしたものからリポジトリの最新版(更新はいくつか入っているようでした)に切り替えたのですが、自分が遭遇した問題とは関係なかったようです。

VirtualBox上にROSの開発環境を作る
VirtualBoxの環境設定時に参考にさせていただきました。

ROS講座
ROSの環境設定時と、ROSの基礎知識の確認に参考にさせていただきました。ROS入門から各種応用まで非常に幅広い内容を丁寧に解説されています。

開発環境

Unity 2019.3.0f5
ROS# 当初1.6 => リポジトリから2020/2/8にダウンロードに切り替え
Oculus Integration for Unity - 12.0
VirtualBox 6.1.2
ホストOS Windows10 Home バージョン1909
ゲストOS 当初Ubuntu 18.04 LTS => Ubuntu 16.04 LTS
ROS kinetic

躓いたところ

  1. ゲストOS
    最初、UbuntuのLTS最新版でよいかと思い18.04 LTSを入れたのですが、ROSのバージョンkineticを使う場合は16.04 LTSが必要でした。
    ROSのバージョンMelodicであれば18.04 LTSでよいのですが、TurtleBot2をみるとkineticを使っている前提のようにも見えたのでkineticを選択しました。ROS#自体はMelodicで動作するようですので、Melodic+18.04 LTSでもよかったのかもしれません(未確認です)。

  2. VirtualBoxの設定
    当初、ディスプレイ->スクリーン->3Dアクセラレーションを有効化:有効化の設定で使用していたのですが、これが原因で、後でGazeboを起動するときにSegmentation Faultが発生しており、解決に非常に時間がかかりました。設定は後で変更できるので、現象が発生するようであれば無効化に切り替えてもよいと思います。

  3. Guest Additionsのインストール
    画面サイズの追従やクリップボードの共有のために必須の設定なのですが、Ubuntuのインストール直後にそのまま設定すると失敗します。必要なパッケージを設定してから実行する必要があります。VirtualBox Guest Additionsのインストールを参考に設定しました。

  4. ROSで謎のエラーが発生する
    チュートリアルの2.1 Transfer a URDF from ROS to Unityを実行したところ、ROS側で以下のようなエラーが発生しました。
    image.png
    これについては、
    catkin_make
    のあとに
    source ~/.bashrc
    を実行することで解決しました(どうやらcatkin_makeの後は毎回必要なようです)。自分の.bashrcには、ROSのインストールのスクリプトで設定された内容が追加されています。

  5. RVIZ起動でエラーが発生する。
    チュートリアルの2.2 Transfer a URDF from Unity to ROSを実行したところ、ROS側で以下のようなエラーが発生しました。
    image.png
    これについては、catkin_ws/srcフォルダで、
    git clone https://github.com/ros/joint_state_publisher.git
    cd ..
    catkin_make
    source ~/.bashrc
    を実行することで解決しました。

  6. OculusQuestで実行するとエラーが発生する
    チュートリアルの2.3 Gazebo Simulation Exampleを実行したところ、PC(Unityのエディタ)では問題なかったのですが、OculusQuest上で実行すると、大量のNullReferenceExceptionが発生しました。発生していた場所はJoyPublisher.csだったのですが、調査のためにあちこちDebug.Logを入れていたところ、なぜかStartにDebug.Logを追加すると現象が発生しなくなりました。原因は不明なのですが、とりあえずはこれで動かしています。

  7. ROS側で2回目以降の受信ができない。
    前項と同じチュートリアルで、1回目の受信ログは残るのですが、2回目以降の受信ログが残らない現象が発生していました。
    rostopic echo /joy
    で確認してみると、Unity側からのメッセージは送られているように見えました。
    受信のスクリプトjoy_to_twist.pyで、受信処理の最後のrate.sleep()をコメントアウトしたら動くようになりました(メッセージを受信するごとに動かすところなので、ここでウェイトを入れる必要はないはず)。
    image.png

追記1

OculusQuestで実行する部分は、元のチュートリアルから追加した部分になります。OculusQuestでジョイスティックを使用するために、RosConnectorに付加されたコンポーネントJoy Axis Reader(2か所)の設定を以下のように変更しています。
Horizontal => Oculus_CrossPlatform_PrimaryThumbstickHorizontal
Vertical => Oculus_CrossPlatform_PrimaryThumbstickVertical

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

「UnityのARFoundationでAR空間に豆腐を召喚する」をやって、ARFoundationをフレームワークとして使う上で困らないレベルに理解してみた

はじめに

ARFoundationを利用したオリジナルARアプリを作成するにあたり、@shun-shun123さんのQiita記事にあった「UnityのARFoundationでAR空間に豆腐を召喚する」を練習でやってみた。
元記事URL:https://qiita.com/shun-shun123/items/1aa646049474d0e244be

今回は、上記記事を通じて「ARFoundationをフレームワークとして使う上で困らないレベルに理解してみた」内容を書いていこうと思う。(ほぼ公式サイトを和訳しただけ)
※ARFoundationで提供されるスクリプトのコード理解も後でやりたい
Unity公式サイト ARFoundationページ:https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@3.0/manual/index.html#basic-setup

環境

Unity 2019.3.0f6
ARFoundation 3.0.1
AR Subsystems 3.0.0
ARKit XR Plugin 3.0.1
XR Legacy Input Helpers 1.3.8
Xcode 11.3.1
macOS Catalina 10.15.2
iOS 13.2.3

基本設定

まずはじめにSceneに「AR Session」と「AR Session Origin」をGameObjectとして追加する。
2020-02-12 13.08のイメージ.jpeg
2020-02-12 13.07のイメージ.jpeg
※画像はUnity公式サイトより

この2つのObjectはAR機能を実装する上で必須らしい。
それぞれが果たしている役割が公式サイトに書いてあったので読んでみた。

AR Session

・一連のAR体験をコントロールする(セッション機能)
・ターゲットのプラットフォーム(実機等)でAR機能を利用可能/不能にする

AR Session Origin

・検知したObjectの特徴(位置・向き・大きさ)を確定させる

AR体験においては、「現実世界で検知したものをデジタルなGameObjectとして認識」or「現実世界にデジタルなGameObjectを生成」のように、カメラ越しにリアルとデジタルが重畳表示される。
その際に、例えばカメラが移動してもセッション開始時の原点を覚えておくことで、現実世界で適切にGameObjectの位置・向き・大きさを表示することができる。

このAR Session Originが果たす役割上(現実世界で適切にGameObjectの位置・向き・大きさを表示)、「現実世界を認識するCamera Object」&「現実世界に生成させるGame Object」は、AR Session Originの子Objectでなければならない。

2020-02-12 13.07のイメージ.jpeg
※AR CameraがAR Session Originの子Objectになっている。
※今回「現実世界に生成させるGameObject」である豆腐は、豆腐PrefabのジェネレータスクリプトをAR Session Originのコンポーネントにしている。

AR Camera

初期設定から自分で変更した点があったので、ついでにAR Cameraについても書いておく。
上述の通り、AR Session Originの子Objectに配置されるAR Cameraだが、下記3つのコンポーネントを有している。

① AR Camera Manager
・実機カメラのAuto Focusモードのオン/オフ
・現実世界の光量計算機能のオン/オフ(パフォーマンスに大きく影響するので基本はオフに設定)
2020-02-12 14.36のイメージ.jpeg
※画像はUnity公式サイトより

② AR Camera Background
・実機カメラの映像を背景として表示させる(自分で背景映像をカスタム可能だが、ARアプリなら基本的にはこのまま使う)
2020-02-12 14.37のイメージ.jpeg
※画像はUnity公式サイトより

③Tracked Pose Driver
・実機カメラの位置と向きを認識する(実機から位置・向き情報を読み出す)
2020-02-12 14.50のイメージ.jpeg
※画像はUnity公式サイトより

公式サイトには、「AR Cameraには上記3つのコンポーネントがある」と書いてあったのだが、私がAR Session OriginをSceneに追加したときには、Tracked Pose Driverではなく、AR Pose Driverとなっていた。
2020-02-12 14.56のイメージ.jpeg

後々、不具合が発生してもめんどくさいので、公式サイトに則ることにし、AR Pose DriverをDelete、Tracked Pose DriverをAddしておいた。
※AR Pose DriverとTracked Pose Driverの違いは、後ほどコードを紐解きつつ理解したい。

平面検知 & 検知した平面に豆腐召喚

豆腐を召喚させる方法として、元記事ではまず平面検知をしていた。
平面検知の実装方法としては、AR Plane Managerを、GameObjectのAR Session Originにコンポーネントとして追加するだけで完了。
(厳密には、AR Plane Managerを、ScriptのAR Session Originと同様のGameObjectに追加していればOK)

また「画面タップしてRay(光線)を飛ばし、その光線と検知した平面が衝突した点に豆腐を召喚」という機能を実装するため、AR Raycast ManagerをAR Session Originにコンポーネントとして追加。
最後にPlace On Plane(これは自分で1から書くScript)もAR Session Originにコンポーネントとして追加。
※この辺の実装方法・コードは元記事を見ていただきたい。
※元記事URL:

ちなみにAR Session OriginのInspectorは最終的にこんな感じになった。
2020-02-12 17.03のイメージ.jpeg

これで実装完了なのだが、最後の最後に戸惑った部分があったので共有しておく。
実際に実機(iPhone11 Pro)で動かしてみたときに、検知した平面をタップしても、豆腐が召喚されないという現象が起きた。エラーは何も見当たらないのに。
原因は、召喚した豆腐がデカすぎてカメラが豆腐の内側に入ってしまったため、召喚されていないように見えていただけだった。
TofuPrefabのScaleをX・Y・Zすべて 1→0.1 に変更して解決。

Trackable Manager

AR Plane Managerは、ARFoundationで提供されるTrackable Managersのひとつで、Trackable ManagersはScriptのAR Session Originと同様のGameObjectに追加される必要がある。
理由は、前述した通り、AR Session Originが果たす役割である(現実世界で適切にGameObjectの位置・向き・大きさを表示)。

2020-02-12 17.20のイメージ.jpeg
※画像はUnity公式サイトより
※ちなみにTrackable Managersは上記表の種類がある。
今回、平面検知に使用したAR Plane Manager だけでなく、例えばAR Tracked Image Managerを使用すれば人体検知ができたりする。

Trackable Managersは、各々が検知可能な現実世界の物体が定められており(あるいは自ら定義することも可能っぽい)、その物体検知に基づき、GameObjectの生成・削除を常にupdateしている。

最後に

ARFoundationをフレームワークとして使える状態になるために、この記事を書いてみたが、人に説明できるまで理解するのはやっぱり難しい、、(まだコードの紐解きはできていないし、、、泣)

用語の使い方がおかしかったり、公式サイトの英語をニュアンスで理解してしまっている部分もあるので、間違っている部分があればご指摘いただけると幸いです。

あと、これまで新しいフレームワークを勉強するときは日本語のサイト・記事でどうにかしようとしてばかりいたけど、ARFoundationに関しては公式サイトが一番体系的で分かりやすかった。
英語から逃げてたらダメだ、、!!

Unity公式サイト AR Foundationページ:https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@3.0/manual/index.html

初めて知った用語たち

offset
https://wa3.i-3-i.info/word11923.html
→位置を基準点からの距離で表すこと

session
https://it-trend.jp/words/session
→接続を確立してから切断するまでの一連の通信のこと。

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

Unity + Aseprite でドット絵ゲーム開発に快適な環境を目指す

想定環境

Windows10Pro(64bit)

Unity2018.4f

Aseprite v1.2.1

作ったもの

 スプライトシート内のそれぞれのスプライトにそれぞれの Pivot やサイズを保持したままAnimation Importer でインポートできるよう、Animation Importer を改修してみました

https://github.com/john95206/AnimationImporter/tree/add-applying-slice-parameter-option

Unityでドット絵ゲームを作る

 Unityでドット絵ゲームを作るために、まず必要なのは、スプライトシートです。

Sigrud.png

まずはこんなのを用意して、適宜設定をし、スライスし、アニメーションさせるという流れになると思います。

やることが…やることが多い…!!

はい。やってみると意外と大変です。Unity標準の Animation/Animator はそれなりに癖がありますし、アニメーション機能を自作するのもかなり骨が折れます。そこまでするならGameMakerでよくね?

Asepriteの強み

 そこでおすすめなのがAsepriteです。
 https://www.aseprite.org/

 スプライトシートを作るまでならEDGEだろうがフォトショだろうがペイントだろうがなんだっていいのですが、Asepriteは、json出力や、コマンドラインによる操作にも柔軟に対応していて、非常に拡張のしがいがあるという点で強みがあります。(言ってる意味がよくわからなくても大丈夫です)

 上記の機能をうまく活かしてくれた素晴らしいツールの一例としてAnimation Importerがあります。
 https://github.com/john95206/AnimationImporter

 これを Aseprite と組み合わせると、Asepriteの編集ファイル(.ase)をUnityのプロジェクト下に置き、専用のWindowにドラッグアンドドロップするだけで、スプライトシート・Animation・Animatorを自動で生成してくれます。
https://blog.redbluegames.com/unity-tutorial-animate-pixel-art-using-aseprite-and-animation-importer-5c4fe1e06985

最強ですね。

Animation Importer の欠点

 最強の拡張ツール Animation Importer ですが、使ってみるとところどころかゆいところに手が届かなかったりします。(自分のために作られたものではないので当たり前ですが)

 例えば、次のような場合にもんやりします。

  • スプライトシート内の各Sprite のサイズやPivotがまちまちな場合
  • Animation内でスクリプトの呼び出しやコライダーなどのプロパティを変更してる場合

 まず、Animation Importer で絵を更新する場合、スプライトシート・すべてのAnimation・Animatorは一度削除され、新たなアセットとして生成しなおされます。

 そのため、Animation Importerでそれらを生成した後に行った変更(スプライトシートならばSliceのやりなおし・Pivotの手動変更、Animationならばイベントの追加やプロパティの変更)はすべて消えてしまいます。

 そういうことならばそうなっても困らないようにルールを決めて絵を作ればいいじゃんと言えばその通りなのですが、せめて一点目のPivotやサイズに関しては何も気にせず作りたいなと思って頑張ってみました。

Costom Pivot や Sprite のサイズを自由に設定したまま開発したい!

 現行の Animation Importer でも Pivot の設定項目はあるんですが、これはあくまで一律の設定なので、各Sprite毎の設定は今のところできないようです。

スクリーンショット (42).png

 また、Unityの仕様上、前述のようにアセットを削除して新規作成しなおすというフローは致し方ないものがあります。

 ではどうするか。Aseprite1.2beta 以降に実装された、Sliceを使います。

Aseprite の Slice 機能

 Sliceとは、雑に説明すると、UnityのSpriteEditorをAsepiriteでも使えるみたいなものです。
わたしもまだこの機能を把握しきっていないのですが、本稿では上記の機能として扱います。(もしかしたら結構イレギュラーな使い方かも)

 Aseprite上で Shit + C を押すと、Sliceモードになります。この状態で選択した矩形は、Slice Property として登録されます。おあつらえ向きにPivotのプロパティもあるので、SpriteEditorと同じようにPivotも登録します。

スクリーンショット (43).png

 上図だと、矩形の下に小さな1ドットの四角が Pivot になります。

Slice プロパティをAnimation Importerに反映させる

 冒頭でもリンクを貼りましたが、この度、このSliceプロパティをそのままスプライトシートのSliceの設定としてスプライトシートを作れるよう、Animation Importerを拡張しました。(プルリク済み)

https://github.com/john95206/AnimationImporter/tree/add-applying-slice-parameter-option

 使い方は以下の通りになります。

  1. 上記リンクから、改修版 Animation Importer をダウンロードして自分のプロジェクトに適用します。
  2. (Aseprite側)すべてのコマに、Slice設定を一つずつだけ登録する。Sliceを一つ登録したらそのたびにSaveします。この時、直前のコマと同じプロパティの場合、新たなSliceと認識されないので、少しずらしてSave→戻してまたSaveといった手順が必要になります。(もっといい手があるかもです)
  3. (Unity側)Anim Importer のウィンドウを開き、新たな項目 Apply Slice Parameter にチェックを入れます。(この時Pivotの項目が消えますが、仕様です。チェックを外すと戻ります。)

スクリーンショット (44)_LI.jpg

以上です。後は今まで通りAnim Importerで.aseファイルを読み込ませるだけです。

最後に

 ドット絵の新作ゲームはここ数年で、もはや珍しいものではなくなってきています。
わたしも、そして数えきれないほどたくさんの開発者が、ドット絵ゲームを新規開発しています。

 しかし、いざ作るぞ!となった時、ドット絵の描き方や描きやすいツールは調べれば簡単に見つかるのですが、その開発環境についてはあまり語られてきていないと思います。

 今後は、本稿だけでなく、いかにして楽してドット絵ゲームを作っていくか、よりよいドット絵ゲーム開発環境とはどんなものかを議論する機会が増えればいいなあと思っています。

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

Unityでアニメーションさせたらコライダーがずれる解決方法

blender2.8 でダメージを受けたら後ろに飛ばされるアニメーションを作って
unityで使用しようとしたところ

コライダーだけがその場に残ってキャラクターのアニメーションについてこない現象が起こりました。

解決方法

unityでアニメーションを動かして座標が動いているボーンを(数字が動く)探して
その子要素に空のゲームオブジェクトを作成。

コライダーと当たり判定のスクリプトをアタッチする。
あたりのtagづけなどの設定も忘れずにする。

以上。
悩んだ割に簡単でした。
アニメーションにコライダーを.png

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

UnityでWheel Colliderを付けた車両が荒ぶるのを落ち着かせる方法

Unityで車両のモデルを動かすとき Wheel Collider を使いますが、何も問題ないように見えてもPlayを押した後に車両が荒ぶることがあります。
こんな風に。
NG

この現象を止めるには、車両のルートとなるGame Objectに適当なサイズのBox Colliderを付けます。
スライド1.PNG

Box Colliderのサイズや位置は地面やほかのColliderに接触しないように、車両のサイズに対してごく小さ目で大丈夫です。例えば下記の画像の直方体のような感じ。
image.png

すべてうまくいくとこの動画のように安定します。
OK

以上になります。

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

Unity 2019.3のHDRP (DXR使用)でLightmapと併用 (Tier1)

Unity 2019.3のHDRP(DXR使用)の説明です。
プロジェクトの設定については「Unity 2019.3のHDRP (DXR使用)のプロジェクトを作成」もご参照くださいませ。

木造の建築物を読み込み、これを使ってフォトリアルなシーンにしていきます。
ここでは「Tier1」を使用し、間接照明はLightmap + Reflection Probe + Light Probeを併用しました。

なお、この木造建築のシーンはGitHubの「Unity2019_3_HDRP_DXR_RoomTest」にプロジェクトを公開していますので、こちらもご確認くださいませ。

ここで行うことは以下になります。

  • Iter1を使用する
  • Ambient Occlusion/Screen Space Reflectionでレイトレーシングを使用
  • Global Illuminationのレイトレーシングは「使用しない」
  • 間接照明(GI計算)部はLightmapのベイク処理に置き換える

DXRの効果として、Ambient Occlusion/Screen Space Reflectionでレイトレーシングする、ということになります。
それ以外は普通のHDRPと変わりません。

Tier2での表現 (参考)

リファレンスとして「Tier2」の「Path Tracing」使用と比較します。
この段階では、まだLightmapのベイクやReflection Probeの配置は行っていません。
「Ambient Occlusion」「Screen Space Reflection」「Global Illimination」をすべてOffにして、
レイトレーシングを使用しないようにすると以下のようになりました。
hdrp_dxr_300.jpg

「Path Tracing」を有効にする (Tier2)

Tier2で「Path Tracing」を有効にし、「Maximum Samples」を512、「Maximum Depth」を5にしました。
hdrp_dxr_302.png

Path Tracing未使用時のままのIBLの場合は明るすぎるため、「Sky and Fog Volume」の「HDRI Sky」の「Exposure」を10から2に変更しました。
以下のようにレンダリングされました。
hdrp_dxr_301.jpg

「Post Process Volume」の「Exposure」の「Fixed Exposure」を8.7から6.0に変更し、全体的に明るくして室内を表示しました。
室外から室内に移動する場合、そのままの露出だと全体が暗いままになるため、露出調整は必要になります。
hdrp_dxr_303.jpg
Tier2の場合は、特にLightmap/Reflection Probeを使用しなくてもフォトリアルな表現になっています。
ただし、Fogは効いていません。

「Path Tracing」を無効にする (Tier2)

「Path Tracing」を無効にし、「Ambient Occlusion」「Screen Space Reflection」「Global Illimination」をOnにします。
hdrp_dxr_304.jpg
「Screen Space Reflection」「Global Illimination」の「Bounce Count」を指定していますが、
「Path Tracing」を使った場合と比較してリアルさは薄れています。

Tier1での表現

速度面と表現面の両方を確保した状態で表現力を上げたいため、Tier1を使用して以下のような手順を取りました。

  • Lightmap用のベイク光源をArea Lightで配置
  • 直接照明の光源は、Realtime光源として配置
  • 間接照明の大部分は、Lightmapに頼る (レイトレーシングのGlobal Illuminationを使わない)
  • 映り込みは Reflection Probeも使用 (レイトレーシングのSSRも併用)
  • Staticでない形状の光源の間接照明の補間として、Light Probeを使用

リファレンスとして、Tier2時の「Path Tracing」の結果を目指す、とします。
直接照明や一次反射でレイトレーシングを使用することでフォトリアルに近づけます。

Tier1に変更

メインメニューの「Edit」-「Project Settings」を選択し、「Graphics」を選択します。
hdrp_dxr_305.png
「Scriptable Render Pipeline Settings」に割り当てられている「HDRenderPipelineAsset」を選択すると、Project上の実ファイルがハイライトされます。
このAssetを選択し、Inspectorで「Raytracine Tier」を「Tier 1」に変更します。
hdrp_dxr_306.png
以下のように、ぬるい感じになりました。
hdrp_dxr_307.jpg
上記は、レイトレーシングとして「Ambient Occlusion」「Screen Space Reflection」「Global Illumination」を使用しています。
「Path Tracing」は無効にしています。

Tier1の場合は、Screen Space ReflectionやGlobal Illuminationで複数回の再帰的な反射は行われないのと、いくつか精度を犠牲にしているようで(Reflectionの解像度など)、Tier2よりは品質が下がります。

これより、パラメータの調整とLightmap/Reflection Probeの使用で補っていきます。

Lightmapの指定

Lightmapを行う手順は、以下の流れになります。
これはHDRPやDXRに限らず、Unityでは共通の作業になります。

  • 建物の形状で「Gegnerate Lightmap UVs」を有効にする
  • シーンの建物を「Static」にする
  • Lightingウィンドウでベイクを実行

Projectウィンドウでインポートした形状を選択し、Inspactorの「Model」の「Gegnerate Lightmap UVs」をOnにしてApplyボタンを押して確定します。
hdrp_dxr_308.jpg
これは形状のすべての面が重ならないようなUVを作成します。Lightmapをベイクする際に利用されます。
この指定がない場合は、一番最後のUVレイヤがLightmap用として参照されます。

Hierarchyウィンドウで、Lightmapのベイク対象の形状を選択します。
ここでは木造の建物と地面に同じ処理を行いました。
対象形状のInspectorで右上の「Static」をOnにします。
hdrp_dxr_309.png
子形状がある場合は、それもStaticにするか聞いてきます。子もStaticにしました。
こうすることで、Lightmapのベイク対象になります。

Lightingウィンドウを開き、Sceneタブを選択します。
hdrp_dxr_310.png
室内シーンなので「Lightmapping Settings」の「Lightmapper」で「Prograssive CPU」が選択されていることを確認します。
「Prograssive GPU」を選択したほうが計算速度が速いのですが、複雑なシーンだとGPU計算の場合に失敗する場合があるため、CPUで計算します。
また、「Bounces」を2から4に変更しました。
こうすることにより、Lightmapのベイク計算の時間はかかりますがより間接照明が回り込むことになります。
「Generate Lighting」ボタンを押すとLightmapのベイク計算が開始されます。
この計算は、シーンの規模が大きくなれば時間がかかります。
数十分から数時間かかる場合もあります。

以下は、Lightmapを使用しない場合+各レイトレーシングの要素を使用したときの結果です。

要素 有効/無効 その他
Lightmap 未使用 -
Reflection Probe 未使用 -
Light Probe 未使用 -
Ambient Occlusion 有効 Ray Tracing On
Screen Space Reflection 有効 Ray Tracing On
Global Illumination 有効 Ray Tracing On

hdrp_dxr_313.jpg

Lightmapのベイクを適用しました。
「Global Illumination」のレイトレーシングを使っている場合は結果はほぼ変わらなかったです。

要素 有効/無効 その他
Lightmap 有効 -
Reflection Probe 未使用 -
Light Probe 未使用 -
Ambient Occlusion 有効 Ray Tracing On
Screen Space Reflection 有効 Ray Tracing On
Global Illumination 有効 Ray Tracing On

hdrp_dxr_312.jpg

Lightmapを使用した場合+「Global Illumination」を無効にした場合は、部屋の奥が暗くなりました。
このほうが結果として正しそうです。

要素 有効/無効 その他
Lightmap 有効 -
Reflection Probe 未使用 -
Light Probe 未使用 -
Ambient Occlusion 有効 Ray Tracing On
Screen Space Reflection 有効 Ray Tracing On
Global Illumination 無効 -

hdrp_dxr_311.jpg

ただし、この場合はStaticではない形状に対してベイクの効果が適用されないため浮いたようになります。

これを解決するには、映り込みについてはReflection Probeを使用、
Staticでない形状での光の当たり具合はLight Probeを使用する必要があります。

Reflection ProbeとLight Probeを使用しない場合は、室内に移動すると以下のようになりました。

要素 有効/無効 その他
Lightmap 有効 -
Reflection Probe 未使用 -
Light Probe 未使用 -
Ambient Occlusion 有効 Ray Tracing On
Screen Space Reflection 有効 Ray Tracing On
Global Illumination 無効 -

hdrp_dxr_315.jpg

机や椅子、奥のタンスなどのライティングが正しくありません。
廊下の映り込みも明るくなっています。

Reflection Probeの配置

部屋の角や光の変化がある部分に、Reflection Probeを配置しました。
hdrp_dxr_318.jpg

この後、再びLightmapのベイクを行いました。

要素 有効/無効 その他
Lightmap 有効 -
Reflection Probe 有効 -
Light Probe 未使用 -
Ambient Occlusion 有効 Ray Tracing On
Screen Space Reflection 有効 Ray Tracing On
Global Illumination 無効 -

hdrp_dxr_317.jpg

床部分の映り込みが変化しています。

Light Probeの配置

壁の境目などの光の変化が激しくなりそうなところに、Light Probeを配置しました。
等間隔にLight Probeを並べるようにしています。
hdrp_dxr_319.jpg
なお、Light ProbeやReflection Probeのアイコン類は、Scene Viewの上の「Gizmos」をOnすることで表示されます。
hdrp_dxr_320.jpg
この後、再びLightmapのベイクを行いました。

要素 有効/無効 その他
Lightmap 有効 -
Reflection Probe 有効 -
Light Probe 有効 -
Ambient Occlusion 有効 Ray Tracing On
Screen Space Reflection 有効 Ray Tracing On
Global Illumination 無効 -

hdrp_dxr_316.jpg

机や椅子、奥のタンスなどのライティングが正しくなりました。

以上で、「Ambient Occlusion」「Screen Space Reflection」でレイトレーシングを使用、
Global Illuminationを未使用とし、Lightmapで置き換えました。
hdrp_dxr_321.jpg

Lightmapを使用しないときよりも明暗のメリハリがつきましたが、廊下と机や椅子との接地感が弱い、全体的なフォトリアル感がない、など気になる点があります。
次にこれらを改善していきます。

Area Lightの配置

間接照明は、Area Lightを使用して間接照明をわずかに補助します。
hdrp_dxr_323.jpg

この光源は、Lightmap用としてBakedを指定しました。
「Baked Shadows」もEnableを指定しました。

「Intensity」は2000 Lumen、「Range」を20として、ほんのわずかに照らすようにしています。
Area Lightを配置後、LightingよりBakeを実行します。

Directional LightをOffにして、背景のIBLとArea Lightだけにすると以下のようになりました。
hdrp_dxr_324.jpg
Directional Light(Realtime)をOnにすると以下のようになりました。
hdrp_dxr_325.jpg

Ambient Occlusionの調整

接地感が弱い箇所を補間するために、Ambient Occlusionを調整します。
「Ray Tracing Settings」を選択してInspectorを開きます。
「Ambient Occlusion」の「Intensity」を0.72から3.5と強くしました。
「Denoise Radius」を0.5から0.2に変更しました。
これは、Denoise時に収集する半径になりますが、これが大きいとAOの効果が飽和したようになって見えにくくなるため、小さくすることでより影響が出るようにしています。
hdrp_dxr_322.png

以下は、AOの編集前です。
hdrp_dxr_326.jpg

以下は、AOの編集後です。
hdrp_dxr_327.jpg
これで、接地感が出ました。

Directional Lightの影の品質を上げる

Directional LightのInspectorを開き、Shadowsの「Resolution」を「Ultra」にすると2048解像度のシャドウマップになります。
また、「Screen Space Shadows」をOnにすると品質が少し上がります。
hdrp_dxr_328.jpg

Screen Space Reflectionの品質を上げる

「Ray Tracing Settings」を選択してInspectorを開きます。
「Screen Space Reflection」の「Minimun Smoothness」の値を下げると、
個々のマテリアルでSmoothness値がそれ以上の場合はレイトレースが行われます(それ以下の値の場合はSSR)。
これにより、GPUリソースを消費しますが1次レイの映り込みの品質が上がることになります。
「Minimun Smoothness」を0.7から0.3に下げました。
hdrp_dxr_329.png

天井や奥の壁の照り返しが少し増しました。
hdrp_dxr_330.jpg
以上で、Lightmap/Reflection Probe/Light Probeとレイトレーシング周りの調整が一通り完了したので、
あとはPost Processingの調整を行います。

Post Processingの調整

Vignetteで「Intensity」を0.3として、少しだけ強めにしました。
hdrp_dxr_331.png

Exposureで「Mode」を「Automatic」として、自動露出にしました。
こうすることで、室内と室外に移動してもその都度Exposureを調整する必要がなくなります。

また、「Limit Max」を8としました。
hdrp_dxr_332.png

White Balanceで「Temperature」を10としました。
少しだけ暖色になるようにしています。
hdrp_dxr_333.png

Chromatic Aberrationで「Intensity」を0.095としました。
hdrp_dxr_334.png
Tonemappingで「Mode」をNeuralとしました。
hdrp_dxr_335.png

Bloomで「Intensity」を0.13としました。
hdrp_dxr_336.png

Color Adjustmentsで「Post Exposure」を0.7にしました。
これにより、少しだけ明るくします。
「Saturation」を-10にしました。
これにより、少しだけグレイスケールの要素を入れて全体を落ち着かせています。
hdrp_dxr_337.png

Depth Of Fieldで「Focus Mode」を「Manual」とし、Near Blur/Far Blurの値を指定してボカシを与えました。
なお、DOF効果はGame Viewで表現されます。Scene Viewでは表示されません。
hdrp_dxr_338.png

Post Processingの調整の結果、以下のようになりました。
hdrp_dxr_339.jpg

光沢用の光源を配置

上記画像では床の映り込みの光沢が薄いです。
光沢に関しては、Point LightをRealtime光源として配置するとしました。
Point Lightの影(Shadow Map)は無効にしています。
hdrp_dxr_340.jpg

以下のようになりました。
床の光沢感が増しました。
hdrp_dxr_341.jpg
これは本来はないニセ光源ではあるのですが、光沢を出す場合は特に有効です。

HDRIとフォグの確認

HDRIとフォグについては確認のみです。
「Sky and Fog Volume」では以下のように指定しています。
hdrp_dxr_342.png
背景を暗くする場合は「Exposure」の値を下げるようにします。

フォグはわずかにかけるようにしていますが、もし、強めに与える場合は距離値を調整します。
「Fog Attenuation Distance」を20000から100に変更、「Maximum Height」を5000から1000に変更、「Max Fog Distance」を5000から1000に変更してみました。
hdrp_dxr_343.png
以下のようになります。
hdrp_dxr_344.jpg

光が入りにくくなったため、「Directional Light」のEmissionの「Intensity」を10000(Lux)から100000に変更しました。
hdrp_dxr_345.jpg

Spot Lightで強めの光を設けた場合など、フォグがある空間ではボリュームライト表現が行えます。
以下は、Spot LightのEmissionで「Intensity」を5000000(Lumen)と極端に大きな値を与えてます。
hdrp_dxr_346.jpg

以上で、Tier2のパストレーシングを使用しなくても、Tier1でそれなりに詰めることができるのを確認できました。
フォグ効果や速度面を考えると、Tier1を使い、間接照明は従来のLightmapを使う、というのは今のところ有効かもしれません。

以上のプロジェクトは、
GitHubの「Unity2019_3_HDRP_DXR_RoomTest」に公開しています。

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

【VSCode】ちゃんと拡張機能を入れたのに、MonoBehaviourだけ怒られる(動作には支障がない)

Code Spell Checker へホワイトリストとして登録すれば解決します。
(ちなみにVSCodeは2020/01にバージョンアップしているので、拡張機能含め諸々のアップデートの時間を考慮しましょー)
b01.png

この子が原因
b02.png


やり方

ホワイトリストに入れたい、MonoBehaviourをマウスクリック
b03.png

shift + cmd + P を押下

下図赤枠に
Add Word to User Dictionary と入力してエンター
b04.png

おしまい

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

【Unity】イメージエフェクトを使用しない簡易GlowShader

なるべく軽量にするため、イメージエフェクトを使用せずに光の玉を表現させる一例です。

gif_animation_005_m.gif
一枚の板で、円をぼかし拡大縮小して
光っている風に見せかけてます。

vertex

どこから見ても同じように見せるようにビルボードにします。

Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" }

・・・

struct appdata
{
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;
};

struct v2f
{
     float2 uv : TEXCOORD0;
     float4 vertex : SV_POSITION;
};

・・・

v2f vert (appdata v)
{
  v2f o;

  o.vertex = mul(UNITY_MATRIX_P,
      mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0)) 
      + float4(v.vertex.x, v.vertex.y, 0.0, 0.0)
      * float4(0.5, 0.5, 1.0, 1.0)); // XYのスケーリング
}

ビルボードについての詳細はこちらの記事が詳しいです。
常にカメラを向くオブジェクトをGPUで実装

fragment

四角形からはみ出ない程度に円を描いて良い感じにぼかし、アニメーションさせています。
形状によってはテクスチャのほうがきれいに表現できるかと思います。

fixed4 frag (v2f i) : SV_Target
{
    float4 col = _Color;

    float dist= length(i.uv - 0.5) * 2;
    // 外に行くほど薄くなるようぼかす
    col *= saturate(1 - dist);
    // 中心の光具合を強調・拡縮アニメーション
    col *= (1 - dist) * lerp(1, 3, sin(_Time.z) * 0.5 + 0.5);

    col = saturate(col);

    clip(col.a - 0.0001);
    return col;
}

アルファブレンド

背景と馴染むようこれもよい感じに調整。
サンプルの場合は

Blend SrcAlpha DstAlpha

ちなみに確認時は以下のようにしておくとmaterialで調整ができるので便利です。

Properties
{
    [Enum(UnityEngine.Rendering.BlendMode)]_BlendSrc("Blend Src", Float) = 0
    [Enum(UnityEngine.Rendering.BlendMode)]_BlendDst("Blend Dst", Float) = 0
}
・・・

Blend [_BlendSrc][_BlendDst]

利用できる場面

結局板なので、角度によって他のオブジェクトに板が遮られたりすると
切れ目が不自然に見えたりしまいます。
近距離のオブジェクトとの兼ね合いでどのくらい許容できるか次第かと思います。

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

VRで飛行移動の開発で調べた酔い対策

はじめに

Unityで一人称視点のVRアプリに飛行移動の機能を開発するに当たって、
主に移動・旋回機能での酔いに関して調べたことと、個人的な感想となります。

確認したデバイスは
Oculus Rift s/Oculus Quest/HTC VIVE

また基本的な対策に関しては以下を参考にさせていただいたので、
詳細は参照ください。

移動方法

元々アプリの移動方式は地上移動のみでテレポート型だったが
飛行移動に関してはスティックの前後操作で前進/後退する仕組み。(空間移動型)
ただやはりこの方式になると酔いに強い/弱い人で結構差が出てくる。

対策

脳と体の同期ズレの軽減。見ているものと身体の動きが違うと感じると酔う。

速度は遅く等速直線運動であるほうが酔いにくいとのことだが、移動範囲もあるのでそこそこの速度が必要。
ということで加速度を加えて、後退速度は前進時より低速で移動するように調整。
この辺りは特に日本列島VRを参考にさせていただいた。

次の動きを「予測」させて酔いを軽減

進行方向については、HMDで向いてる方向に移動という手法もあるが、
今回は既存の仕組みでVRレーザーポインターを装備していたため、上下前後ポインタの向きに合わせて進むようにした。
向きの指針として認識もしやすいため、進む方向の「予測」の役割を果たせているかと思う。

旋回

スティック左右操作での自分の向きを回転

対策

これに関しては常にスナップターン方式(スティックの左右操作一回ごとに30度ずつ回転)
停止・低速状態でスムーズ回転はかなりきつい。
速度がでている状態であればかなり軽減される。(ただ本当にそこそこな速度が出てる状態でないときつめ。)
機能としては旋回できた方が楽しい体験になるが、今回一番酔い影響が強いと感じたところでもあった。

その他の対策等

今回は基本的に上記のような対策を行ったが、
さらに酔いを軽減させる方法としては

  • 手前に固定のパネル・UIなどを表示。(効果高そう)
  • 向きをさらに意識しやすいよう矢印を表示。
  • 移動中は速度に応じて視野を狭める類のエフェクトを追加。
  • 移動停止時の減速。(未検証)

など。
また当アプリは特にアクション性も低く、周りの動きも激しくないため、
アプリの特性にもよるのかとも思います。

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

[Unity]ML-Agents「Hide / Escape - Avoidance of Pursuing Enemies」を動かす

かくれんぼのやつが動かない

Unityの機械学習「ML-Agents」を使ったサンプル「Hide」これがエラーするわ動かないわで大変だった
image.png

これが動くようになったので、そこまでの記録を残します

ダウンロード

データセット

このサイトの下の方にあるGitHub
Hide
image.png
この「いいね!」マークの上にあるリンクからダウンロードします↑

このページに飛びます↓
image.png
んでダウウンロード↓
「Clone or download」
image.png

zipでお好みの場所に保存(どこでも)
image.png

このセットの中に色々入ってますので
image.png
ドキュメントなり普段unityプロジェクトを保存している場所なりに解凍してください

Json.net

JSON.net
Newtonsoft.json(JSON使うためのもの)をダウンロードしていない人はこちらも後で必要になるので
↓一番上の「Json120r3.zip」だけで大丈夫です
image.png
適当にダウンロードして適当に解凍してください
後で必要になります

Unity

UnityHubを起動し、「リストに追加」
image.png
先ほど解凍した
hide-escape-master の中の unity-environment を選択
これで↓「フォルダの選択」
image.png

こうなる
asdfjkdalfj.png
噂によるとバージョンは2018.4以上がいいそうなので
image.png2018.4.16をインストール

こんな感じで↓バージョン変更して開く
asdfjkdalfj.png
ウィンドウ出ますが「確認」押してGO
image.png

例のブツをみてみよう

image.png
↑の「Hide」というシーンを開く
image.png
これですよこれ 見たかったのは

~ライティングをOFFにしておく~

本編に特別関係ないけど、何かあるたび光の当たり方を計算されるのはストレスなので、機能をオフにする
image.png
開いたウィンドウ↓の一番下にある「Auto Generate」のチェックを外し
image.png
「Genaerate Lighting」ボタンを押す
image.png

とりあえずエラー

image.png
下2つはBlenderインストールしてれば何か違うのかもしれませんが、入ってないのでパス
左上の「Clear」押しても消えないエラーに対処していきます
image.png

Json.netをプラグインに入れる

ダウンロードした「Json120r3」の
Json120r3 → Bin → net20 → Newtonsoft.Json.dll を以下の場所にコピペ
image.png
参考文献

するとエラーは3つ
image.png

Unityでセットアップ

参考文献
image.pngProject Settingの
image.pngPlayerの
image.pngother Settingを開き
image.pngちょっと下の方

この
「ENABLE_TENSORFLOW;UNITY_POST_PROCESSING_STACK_V1」

「ENABLE_TENSORFLOW」
に変更↓
image.png

image.png
しかしエラーは減らない
んんんんんんんんんんんん
まあ必要な項目ではあったはずなので、エラーが消えるための設定ではなかっただけでしょう

パッケージを入れませう

なんか言ってた
image.png
適当なところにダウンロードし、「Import package」でダウンロードしたファイルを指定する
image.png
そしたらウインドウでるから、右下の「Import」ボタンをクリック
image.png
image.png
驚きの白さ

なんだか様子が変です

「HideBrain」を選択すると
image.pngimage.png
なんか言ってる ファイルがねぇ と

なのでこの「Hide3-3M」を指定してあげます
image.png
image.png

これで動くぜ ヒャッハー!

ダウンロード.gif
赤おっっっっせぇぇぇぇ
なんじゃあの移動速度はぁぁぁ一生追いつけんわぁぁぁ

赤を早くさせる

「Academy」を選択
image.pngimage.png
「Value」の値を「3」とかにします(お好みで)
ダウンロード.gifこんだけ早ければいいだr…

いまUターンしなかった?

これで盲目の追跡者が完成しましたね✨(コナン君の映画のタイトルにありそう)
次は赤に視界を設けます
※Blenderが入っていないために、視界のモデル(扇形↓)が生成できなかったと思われ
image.png

プログラム的には、
視線上にいる
→扇の当たり判定作動
→青を追いかける
ってなってるので、
扇の代わりを作ればおk

つまり、シーンにいる各9人に視界を設けるだけ!!
こんな時のためのプレハブ機能!!

image.png※尚、プレハブではない
ど う し て

視界を作る

仕方ないので方法は2通り
・先を見越して「Chaser」をプレハブに置き換える
・9人の「Chaser」に当たり判定を設ける

選ばれたのは後者でした

やり方は簡単
1. 全ての「fov-shape」を同時選択
2. 位置調整
3. メッシュとコライダーを設定

1.全ての「fov-shape」を同時選択

「Ctrl」を押しながら、各fov-shapeをクリック
image.png

2. 位置調整

以下のように値を調整
image.pngimage.png

3. メッシュとコライダーを設定

Mesh Filter の「Mesh」に「Cube」を選択
image.png
Mesh Collider の「Mesh」に「Cube」を選択
image.png

するとこうなる
image.png

できた

AIi.gif

仁王立ちの追跡者

赤の横を青がスルッと通りすぎると以下のように、到達点で停止するバグが判明
image.png

プログラムに工夫が必要
「HideChaser」を開き
グローバル変数を宣言

HideChaser.cs
    float timer = 0;
    Vector3 pos;

Update()の中に以下を追加

HideChaser.cs
        if(transform.position == pos)
        {
            timer += Time.deltaTime;
            if(timer > 5)
            {
                timer = 0;
                Debug.LogWarning("Stopped");
                agentInFOV = false;
                agentInLOS = false;
                chasingAgent = false;
                PickNextRoom();
            }
        }
        else
        {
            timer = 0;
        }
        pos = transform.position;

応急処置ですがこれでなんとかなります
一応全文載せておきます↓

HideChaser.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class HideChaser : MonoBehaviour {

    public GameObject myAgent;
    public GameObject chaserHead;
    [HideInInspector]
    public HideAgent hideAgent;

    public GameObject[] seekLocations;
    private float positionDoneThreshold = 0.15f;

    public GameObject[] chaserInitialPositions;

    [HideInInspector]
    public NavMeshAgent navAgent;

    [HideInInspector]
    public GameObject currentTarget;
    public GameObject targetLocationIndicator;

    [HideInInspector]
    public bool agentInLOS = false;
    [HideInInspector]
    public bool agentInFOV = false;
    [HideInInspector]
    public bool chasingAgent = false;
    public bool showDebug = false;

    [HideInInspector]
    public Vector3 lastKnownAgentLocation;

    private Rigidbody chaserRigidbody;

    public HideAcademy hideAcademy;

    public GameObject winZone;

    float timer = 0;
    Vector3 pos;
    void Start ()
    {
        this.navAgent = this.GetComponent<NavMeshAgent>();
        this.chaserRigidbody = this.GetComponent<Rigidbody>();

        this.hideAgent = myAgent.GetComponent<HideAgent>();

        currentTarget = seekLocations[Random.Range(0, seekLocations.Length)];
        navAgent.SetDestination(currentTarget.transform.position);

        this.targetLocationIndicator.transform.parent = null;
        lastKnownAgentLocation = Vector3.zero;
        pos = transform.position;
    }

    void Update ()
    {
        PlaceTargetIndicator();
        MoveChaser();

        if(transform.position == pos)
        {
            timer += Time.deltaTime;
            if(timer > 5)
            {
                timer = 0;
                Debug.LogWarning("Stopped");
                agentInFOV = false;
                agentInLOS = false;
                chasingAgent = false;
                PickNextRoom();
            }
        }
        else
        {
            timer = 0;
        }
        pos = transform.position;
    }

    void MoveChaser()
    {
        // If Agent Has Not Been Seen
        // Pick next room upon reaching destination
        if (Mathf.Abs((currentTarget.transform.position - this.transform.position).magnitude) < positionDoneThreshold && (chasingAgent == false))
        {
            //Debug.Log("Chaser Arrived At Location: " + currentTarget);
            PickNextRoom();
        }

        // If Agent Has Been Seen
        // Pick next room upon reaching last known location
        if ((Mathf.Abs((lastKnownAgentLocation - this.transform.position).magnitude) < positionDoneThreshold) && (chasingAgent == true) && (agentInLOS == false))
        {
            //Debug.Log("Chaser Arrived At LastKnownAgentLocation");
            chasingAgent = false;
            PickNextRoom();
        }

        // If Agent is currently seen, chase
        if (chasingAgent == true)
        {
            //Debug.Log("Chase Agent");
            ChaseAgent();
        }
    }

    public void InLOS()
    {
        if (agentInFOV)
        {
            agentInLOS = true;
            chasingAgent = true;
            lastKnownAgentLocation = myAgent.transform.position;
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject == myAgent.transform.gameObject)
        {
            HideAgent agent = myAgent.GetComponent<HideAgent>();
            agent.done = true;
            agent.reward -= 10f;
            agent.losses += 1;
        }
    }

    void PlaceTargetIndicator()
    {
        if (chasingAgent == false)
        {
            targetLocationIndicator.transform.position = currentTarget.transform.position;
        }
        else
        {
            targetLocationIndicator.transform.position = lastKnownAgentLocation;
        }
    }

    public void PickNextRoom()
    {
        GameObject tempCurrentTarget = seekLocations[Random.Range(0, seekLocations.Length)];
        while(tempCurrentTarget == currentTarget)
        {
            tempCurrentTarget = seekLocations[Random.Range(0, seekLocations.Length)];
        }
        if(tempCurrentTarget != currentTarget)
        {
            //Debug.Log("New target chosen: " + tempCurrentTarget + " Old target was: " + currentTarget);
            currentTarget = tempCurrentTarget;
            navAgent.SetDestination(currentTarget.transform.position);
            targetLocationIndicator.transform.position = currentTarget.transform.position;
        }
    }

    public void ChaseAgent()
    {
        currentTarget = myAgent;
        navAgent.SetDestination(lastKnownAgentLocation);
    }

    public void Reset()
    {
        // Get curriculum variables from academy
        float chaserSpeed = hideAcademy.GetComponent<HideAcademy>().chaserSpeed;

        // Set curriculum variables
        navAgent.speed = chaserSpeed;

        this.chaserRigidbody.isKinematic = true;

        GameObject chaserInitialPosition = chaserInitialPositions[Random.Range(0, chaserInitialPositions.Length)];

        this.transform.position = new Vector3(chaserInitialPosition.transform.position.x, this.transform.position.y, chaserInitialPosition.transform.position.z);
        this.transform.rotation = chaserInitialPosition.transform.rotation;

        if (hideAcademy.mode == HideAcademy.Mode.Escape)
        {
            if (winZone != null)
            {
                winZone.transform.position = new Vector3(chaserInitialPosition.transform.position.x, winZone.transform.position.y, chaserInitialPosition.transform.position.z);
            }
        }

        agentInLOS = false;
        chasingAgent = false;
        currentTarget = null;
        //lastKnownAgentLocation = Vector3.zero;
        this.chaserRigidbody.isKinematic = false;
        PickNextRoom();
    }
}

モード変更

「Academy」オブジェクトの「Mode」を「Escape」にすると脱出口が現れるようになります
image.png
image.png黄色の四角いやつ

あとはがんばって

動いたはいいけど、果たして機械学習しているのか まだわかってない

それでは皆さん よき機械学習を
ダウンロード.gif

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