まきゼミ技事録!

とあるゼミのプログラマー達が送る技術ブログのようなもの

Unity初心者がUIを実装した話 マップ編

どうも、ぴょんさんです。

わけあって久しぶりの更新になります。あれです、夏休みの宿題を夏の終わりに慌ててやる学生みたいになっていました。

 

そんなこんなで今回は、前回の続きとして「マップ編」です。

ちなみに前回はこれ↓

makizemi.hatenablog.com

 

環境

  • Unity2017.4.0f1

 

マップ系UIを実装する

経験者からするとわざわざシェーダを書いてマテリアルで実装するよりかは、uGUIとスクリプトで実装するほうが楽かもしれません。(私は勉強をしたくなかったのです。)

 

実装する上で大事なのが、移動・回転・拡大縮小です。(ゲーム によってはいらないものもあるかもしれませんが)

シェーダでも移動・回転・拡大縮小はできちゃいます。そのコードがこちらになります。

↑こんな感じで行列計算を行い、移動、回転、拡大縮小を組み合わせることで、自由な動きを作成することができます。

 

実装したものは、こんな感じ↓になります。赤い三角形のアイコンの座標等が変わっていることがわかると思います。

f:id:MakiZemi:20180906205036g:plain

マップのテクスチャとアイコンのテクスチャはlerpという関数で重ねています。

lerpは線形補間値を返してくれる関数ですが、シェーダだと↑こんな感じでテクスチャを重ねることにも使えます。

 

まとめ

以上、Unity初心者がUIを実装した話 マップ編でした。がんばればシェーダで色々できちゃうので、使える場面では是非使ってみてください。もちろんデメリットもあると思うので、その辺はケースバイケースで...。

 

参考にしたところ

thebookofshaders.com

 

おわり(。-`ω-)

Unity初心者がUIを実装した話 ゲージ編

どうも ぴょんさんです。

訳あってPythonとC系言語がごっちゃになって、大量の構文エラーと戦う日々が続いております。(もはやプログラミング初心者...)

 

さて今日はUnity初心者の私が、UIを実装した話になります。といってもUnityでのUI実装方法を調べるのが面倒だったので、シェーダでよくね?って感じでマテリアルを作成して実装しました。

ちょこっと長くなりそうなので、「ゲージ編」と「マップ編」の2つに分けます。今回はゲージ編です。(マップ編はそのうち)

 

環境

  • Unity2017.4.0f1

 

シェーダで実装するメリット・デメリット

UnityのUIの機能ではテキストや画像を表示するくらいしかやったことがないので、正直に言いますとよくわかりません...。

しかし、マテリアルを作成することになるので、様々なメッシュに適用させられることはメリットの一つかと思います。デメリットはシェーダを全く分からないと訳が分からないことですかね...。それと、単純な形状で複雑な表現もないUIでしたら、おそらくシェーダで実装するほうが面倒かもしれません。

 

ゲージ系UIを実装する

実装すると以下のようになります。マテリアルのThresholdというパラメータが変化すると、UIのHPバーのようなものが空になっていくのがわかると思います。

f:id:MakiZemi:20180816193054p:plain

f:id:MakiZemi:20180816193058p:plain

f:id:MakiZemi:20180816193103p:plain

 実はこちら、先日行われたUniteTokyo2018であった講演を聞いて実装したものになります。仕組みを理解するなら↓こちらを見ていただいたほうが良いと思います。

www.youtube.com

UIの話は27分くらいからですが、とてもためになる面白い話だったので時間があるときに全部見ることをオススメします!

 

「あれ、これShaderGraphの話じゃん??????」

そう、その通りです。そして今回の環境はUnity2017であるため、ShaderGraphは使っていません。(使おうと思えば使えるのかな???)

そのため、コードに書き直す必要がありました。

そのコードがこちらになります。

ShaderGraphの例ではRemapノードが使われていました。しかし、コードを書く場合、Remapという関数はUnityのシェーダにはないため、自作する必要があります。

そこでMathFunctions.cgincを作成し、そこにRemap関数を作成しました。

 

 ShaderGraphのノードの中身は公開されているので、今回みたいに訳あってコードに書き直す場合は、こちらを参考にして実装することができます。

github.com

 

画面に表示する

さて完成したら描画します。適当なQuadにアタッチし、シーンに配置すると...

f:id:MakiZemi:20180816201333p:plain

あれ???

これは極端な例ですが、ポストエフェクトをかけていると場合によっては大惨事になります。

そんなときはImageオブジェクトを作成し、それにマテリアルをアタッチします。

f:id:MakiZemi:20180816201720p:plain

これでいい感じに表示されました!

 

まとめ

以上、Unity初心者がUIを実装した話 ゲージ編でした。この方法なら複雑な形をしたゲージでも簡単に実装できるのではないかと思います。必ずしもシェーダで実装する必要はないかもしれませんが、興味がありましたら是非やってみてください。

Stateパターン

皆さんこんにちは。ひろたか('Д')です。

今回はデザインパターンの一つのStateパターンについてご紹介します。

 

目次

 

 Stateパターンとは

Stateパターンとは、振る舞いに関するデザインパターンの一つでオブジェクトの「状態(State)」をクラスで表現するパターンです。

 

状態・動作の変化に応じて振る舞いが変わるようなときに使えます。

 

キャラクターの移動と待機状態をステートパターンで分けたもののサンプルです。

なお、環境はUnity2017.4.0f1です。

悪い例

 

良い例

 

各種ステートクラスの状態がそのままのならばnullが返るためstateは変わりません。

状態が変わった際にはcurrentStateがnullではなくなり14行目のif文に入りstateが変わります。

 

 

まとめ

Stateパターンを使うとif文やswitch文で処理を切り替えずにすみコードが見やすくなります。また、新しい状態が必要になったときも追加が簡単にできます。

 是非皆さんも使ってみて下さい。

 

Behavior Designerについて②

さんかくです。(/・ω・)/

今回はUnityのAIを簡単に実装できるアセット
「Behavior Designer」(有料)の機能から
初心者は知っといたほうがいい事を紹介します。

②とありますが最初を見ても繋がってはいないので大丈夫です笑

assetstore.unity.com

機能紹介

f:id:MakiZemi:20180807164542j:plain
1. ヘルプ
?の青いアイコンを押すと公式のヘルプへ飛ぶことができます。
もちろん英語です、、。
全てのタスクにあるわけでは無さそうです。

2.色変更
○アイコンを押すと8色から選択することができます。
色は画像の通りです。

3.スクリプト編集
歯車マークを押すと[Edit Script]というのがあるので押すと、タスクのスクリプトに移動することができます。
これにより、標準では足りない機能などを付け足すことができます。

4.プロパティ取得
Tasks>Action>Reflection>GetPropertyValueではその名のとおりプロパティを取得することができます。
TargetGameObject:取得したいプロパティを含むスクリプトをつけているオブジェクト
ComponentName:取得したいプロパティを持っているコンポーネント
PropertyName:取得したいプロパティ名
PropertyValue:取得したプロパティを保存する変数

画像の例だとTestObjectというオブジェクトにHogeプロパティーを持たせたTestスクリプトを持たせているので、
TargetGameObjectにTestObject、ComponentNameにTest、PropertyNameにHogeとなっています。
本来ならVariablesで変数を作りPropertyValueに選択し、値を保存して使用します。

5.メソッド実行
Tasks>Action>Reflection>InvokeMethodではメソッドを実行することができます。
4のプロパティを取得するGetPropertyValueと同じようにオブジェクト、コンポーネント選択をしてメソッドを選択することができます。

Tasks>Action>Reflection>には他にも値を代入するタスクもあるのでかなり重要です。

終わり

私自身InvokeMethodを知らず、教えてもらうまであれこれ悩んでいたので、
アセットをどれだけ理解して使いこなせるかが大事だと思いました。
またいい機能などあったら書きたいです。ヽ(・∀・)ノ

Mayaでコリジョン設定してUnityで使う話

こんにちは。ぴょんさんです。

暑いですね。水、飲みましょう。

 

今日はUnityとMayaの話です。

ウソです。ほとんどUnityの話でMayaの話はちょこっとなので、期待してこの記事を開いた方はごめんなさい(/ω\)

f:id:MakiZemi:20180726114924p:plain

Maya上でモデルにコリジョンを設定できるスクリプトと、自動でコリジョン情報からColliderコンポーネントを追加してPrefab化するUnityエディタ拡張を作成したので、それについてまとめます。

 

環境

  • Unity2017.4.0f1
  • Maya2018(2017でも動きます)

 

なぜ作ってしまったか

理由は2つあります。1つは、デザイナーが使い慣れているツールでコリジョンを設定できるからです。もう1つは、コリジョン情報とモデルデータを1つのファイルとして扱うことができるからです。

 

Unityでやったこと

↓図で表すとこんな感じです。ここでいうColliderオブジェクトはCollider設定用のオブジェクトのことです。

f:id:MakiZemi:20180726154727p:plain

まず、モデルをPrefabにしています。

そして出来たPrefabに、Collider Componentを追加します。追加するCollider Componentの種類は、あらかじめモデルデータに設定してあるColliderオブジェクトの名前から決定するようにしています。

f:id:MakiZemi:20180726150950p:plain
↑この図の例だとFUC_BoxがColliderオブジェクトにあたります。BoxなのでCone PrefabにBox Collider Componentを追加します。

その後、Colliderオブジェクトからpositionなどを取得し、追加したCollider ComponentのCenterなどのパラメータに値を設定します。

最後に、ColliderオブジェクトをPrefabに残す必要はないので削除します。

 

この一連の流れをエディタ拡張スクリプトで自動化しているので、そのソースも載せておきます。

Prefabを作成する処理は↓こちらを参考にしました。

Unity - Scripting API: PrefabUtility.CreatePrefab

本当はモデルを読み込んだときに処理を走らせるようにしたかったのですがうまくいかず、メニューから選択もしくはショートカットで処理を走らせるようにしています。

 

ここまで出来てしまえば、モデル作成時に手作業でColliderオブジェクトを作成すればよいのですが、ヒューマンエラー等の問題が起こることを防ぐために、Mayaのスクリプトも作成しました。

 

Mayaでコリジョンを設定するために作ったもの

github.com

ソースは↑こちらです。

ほぼ初めてのPythonだったのでよくわかんないコードになってますが、お許しください(>_<)

いつかmel.evalに頼らなくてもコードをかけるようになりたいです。

f:id:MakiZemi:20180726164733p:plain

実行するとこんな感じのウィンドウが表示されます。BoxもしくはSphereを選択すると、「FUC_XXX(XXXはBoxもしくはSphere)」という名前のオブジェクトが作られ、Colliderオブジェクトとなります。Colliderオブジェクトのみ表示方法を切り替える機能も実装しています。

 

まとめ

いかがでしたでしょうか。これでプログラマが手作業でColliderを設定する必要がなくなりました。また、デザイナーが、使い慣れたツールで思い通りのコリジョンを設定することも可能になり、効率よく開発できるようになったかと思います。
(ちなみにちょこちょこ出てきた「FUC」は「For Unity Collider」の略で、私が勝手につけた名前です。)

 

参考にしたところ

l-s-d.sakura.ne.jp

lo25131.hatenablog.com

qiita.com

 

Mayaのスクリプトは本や公式リファレンスを参考にしました。

 

おわりー(*‘∀‘)

VRでのUIの種類について

皆さんこんにちは。ひろたか('Д')です。

今回はVRでのUIの種類について紹介したいと思います。

 

環境

  • Unity2017.4.0f1
  • ovr_unity_utilities_1.26

ovr_unity_utilitiesは最新版の1.27が下記のリンクでダウンロードできます。

Oculus Utilities for Unity | Developer Center | Oculus

 

UIの種類

  • Spatial UI(空間UI)
  • Diegetic UI
  • Non-diegetic(HUD)

大きく分けてこの3つがあります。上から順に紹介します。

Spatial UI(空間UI)

これは、3D空間上にUIを表示する手法です。多くのVRゲームで採用されています。

f:id:MakiZemi:20180723150521p:plainやり方はCanvasのRender Modeを World Space Canvasに変えるだけです。

Diegetic UI

Spatial UIの代替案としてDiegetic UIがあります。これはオブジェクト自体に情報を表示するというものです。例えば、壁掛け時計やテレビ、コンピューターの画面、携帯電話、近未来の銃に搭載されたホログラム画面があります。

f:id:MakiZemi:20180723160925p:plain

やり方はSpatial UIと同じようにCanvasのRender Modeを World Space Canvasに設定したのちに表示したいオブジェクトの子に設定すれば大丈夫なはずです。

 Non-diegetic(HUD)

常に画面の最前面に表示するというものです。VRではなく一般的なゲームでよく使われます。VRの特性上、目に近すぎると焦点が合わなくなるためこれは向いていません。また、HUDのUI 設定(CanvasのRender ModのScreen Space - Overlay)に VRが対応していません(Unity上では表示されますがVR上だと表示されません)。

それでも前面に表示したい人のために疑似的に再現しました。

やり方は

  1. CanvasのRender Modeを World Space Canvasに設定します。
  2. VRのカメラとは別にUI用のカメラを用意して、CameraのCrearFlagsをDepthOnryにします。
  3. UI用のカメラのCulliMaskをUIのLayerのみにチェックを入れ、VRのカメラ(オキュラスならCenterEyeAnchor)のCulliMaskをUIのLayerのみに以外にチェックを入れます。

これで、UIを常に最前面に表示させることができます。しかし、前述したとおり、目に悪いのであまりお勧めはしません。f:id:MakiZemi:20180723170343p:plain

 

まとめ

VRでUIを表示するならやはり、Spatial UIかDiegetic UIどちらかを使用したほうがいいです。また、Spatial UIに限らず、VR空間でUIを置く際はカメラとの位置が重要になるので皆さん気を付けましょう。

 

参考サイト

 

unity3d.com

code.hildsoft.com

Unity5.3のVR機能(ユーザーインターフェース) | TaoVisor

Behavior Designerについて

さんかくです。(/・ω・)/

今回はUnityのAIを簡単に実装できるアセット
「Behavior Designer」(有料)を紹介したいと思います。

assetstore.unity.com

お品書き
  • Behavior Designerとは
  • タスク紹介
  • 簡単な使い方の例

Behavior Designerとは

このアセットではビヘイビアツリーというAIの思考・行動などを決める手法をUnity上で簡単に実装することができます。
ビヘイビアツリーは思考・行動をツリー(木)構造にし、状況に合わせて分岐させ、行動を決めることができます。

例えば、
敵が近くにいたら 攻撃
敵が遠くにいたら 近づく
などをすることができます。
f:id:MakiZemi:20180719003505p:plain:w200
また視覚的にも見やすく、すでに用意されているタスクを組み合わせるだけで簡単にAIが作成できます。
下の画像の左側のようにタスクが様々用意されてます。
これをポチポチして画像右側に配置、後は線をくっつけるだけでできます。

また、すでに用意されているタスクだけでなく、もちろん自分でタスクを作ることもできます。
f:id:MakiZemi:20180719004132p:plain

ドキュメント(英語)や動画(英語)もあるので勉強しやすいですね!(動画、ドキュメントもちろんグーグル翻訳して見ました(;'∀'))

タスク紹介

ドキュメントを見れば大体わかるは思うので簡単に説明します。
f:id:MakiZemi:20180719005613p:plain

  • Sequence:

子タスクを左から順番に実行、
trueが出た場合次の子タスクへ、全てtrueの場合trueが返される。
falseの場合、即終了しfalseを返す。

  • Selector:

子タスクを左から順番に実行、
trueが出た場合即終了、trueを返す。
falseの場合、次の子タスクへ移る、全てfalseでfalseが返される。

  • Parallel:

全ての子タスクを同時に実行、falseが出たら全て終了される、trueが出た場合は他のタスクは継続される。

  • ParallelSelector;

(Parallelの逆)全ての子タスクを同時に実行、trueが出たら全て終了される、falseが出た場合は他のタスクは継続される。

  • ParallelComplete:

子のどれかが結果を返したら終了、false・trueは関係ない。

簡単な使い方の例

先ほど図にした
敵が近ければ攻撃、敵が遠ければ近づく というのをやりたいと思います。
またついでに敵が近い場合は、敵の方向を向いて攻撃させたいので、敵のほうへ向かせる処理も加えます。
本当はアニメーションなども必要ですが、今回は省略します。

敵との距離の比較は
「Float Comparison」という用意されているタスクを使います。
Conditionals/Basic/Mathにあります。
・↓FloatComparisonのInspector
f:id:MakiZemi:20180719012053p:plain
これのOperationでどのように値を比較するか設定できます。
今回は敵との距離が攻撃の当たる距離よりも小さくなって欲しいのでLessThanでFloat1がFloat2よりも小さかったらtrueにするようにします。
EnemyDistanceは敵との距離、HitSordDistanceは攻撃の届く範囲となっています。
数字を入力することもできますが、このように変数を使うにはVariablesタブで変数を作ることができます。
f:id:MakiZemi:20180719012621p:plain
作成した後FloatComparisonのInspectorでFloat1などの右にある丸を押して適用することができます。

攻撃が当たる距離なら相手のほうを向かせます。
それにはLookAtを使用します。こちらもInspecto上でTargetGameObjectに実際に向かせるもの、つまりAI自身を指定、TargetLookAtに向かせたい位置を設定します。この場合はプレイヤーを攻撃するということにして、プレイヤーの座標を指定します。

向き終わった後は攻撃アクションをさせますがこれは個々で違うと思うので省略させてもらいます。

もし、敵に遠い場合は近づくにはSet Destinationを使います。
この場合、ナビメッシュなどを使いますがいいサイトさんがあるので説明は省略します。
www.asset-sale.net


そしてこちらの部品を組み合わせることによって完成するのが下の画像の通りです。
f:id:MakiZemi:20180719011231p:plain
動きとしては、Selector,Sequenceともに一番左側にあるFloatComparisonを判定します。これがもし成功でない場合はSequenceは即終了となります、ここでSelectorにfalseを返しますが、Sequenceはtrueが出るまで続けるので、無事に敵に近づくを実行することができます。
もし敵に当たる距離だった場合は次の相手に方向を向き、攻撃を行いことができSelectorにtrueを返すことができ、ここで終了します。

また普通に実装してしまうと、敵と遠くて近づくを実行した場合、武器が当たる距離になっても近づくを優先してしまいます。その場合はSelector,Sequenceについている記号、「AbortType」を設定することによって近づいてる最中でも武器が届く距離か再判定してくれます。それについてはこちらのサイトさんが説明してくれています。
kurihara-n.hatenablog.com

終わりに

そこまでこのアセットについて書いてある技術ブログがなかったので、しょうがなく公式サイトで勉強しました(笑)
様々な公式サイトの堅苦しい感じが苦手なのですが頑張って慣れていきたいです(/ω\)