テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

【Unity】2D Experimental Preview Release 4のタイルマップ デモが楽しそう

2D Experimental Preview Releaseの4が(だいぶ前に)公開されてました。

https://forum.unity3d.com/threads/2d-experimental-preview-release-4.469914/

f:id:tsubaki_t1:20170615025550j:plain

今回はプレビューリリースの他にデモプロジェクト「RoboDash 」が付いてます。

www.youtube.com

動画には無いですが、光表現とか結構悪くないように見えます。*1

*1:いいから早く出ろ

【Unity】ボタンを押したら音が出る…を、出来る限りコードを書かずに実現する

f:id:tsubaki_t1:20170613224436j:plain

今回は、ボタンを押した際に音を出す方法を聞かれたので、ココにも書いておきます。音の制御というよりは「ボタンを押した時に音を出したい」という要望を叶える為の物です。

ボタンを押したら音が出る

自分が小学生の頃、ボタンを押したら音が出る(あと光る!)玩具で遊んだ事を覚えています。

ボタンを押したら「ジョインジョインドゥ」みたいな音が出る剣とか、ボタンを押したら「パラリパラリラパラリパラリラ(トゥーーーーン)」みたいな音が出るベルトとか。

ゲームでも、大抵のボタンを押すときは何らかの音が出ます。今回はこの動作を、出来るだけコードなしでチャレンジしてみようと思います。

Audio Soureceはスピーカー、Audio Listenerは耳

音は、概ねAudio Source、Audio Listener、Audio Clipの3つの項目から成り立ちます。Audio Sourceが音を発信し、Audio Listenerが音を聞き取ります。Audio Clipは再生する音の種類です。

f:id:tsubaki_t1:20170613225350j:plain

ソースは発信源なので、設定によっては距離や(Listenerとの)相対速度等が表現に影響するかもしれません。

今回は音場の全く関係ない2D設定で話を進めます。

AudioSource.PlayOneShotで音を再生する。…ボタンから

オーディオを流すAPIAudioSource.PlayOneShotです。このAPIでAudio Clipを指定してやれば、音が再生されます。

 

…で、実はこのAPI、ButtonのOnClickで指定出来ます。

ButtonのOn Click(Unityのイベントシステム)では、パブリックかつ戻り値がvoidかつ引数が一つ(シリアライズ可能)なAPIはエディター上で指定する事が出来るので、AudioSourceのPlayOneShotは呼び出すことが出来ます。

その際に引数に出したい音を指定してやれば、ボタンをおした時に指定した音が出ます。

f:id:tsubaki_t1:20170613230001j:plain

実際の手順

まずAudioSourceを用意します。複数の音源があっても一つのAudioSourceで良いです。SE用として使いまわします。

f:id:tsubaki_t1:20170613230437j:plain

 

Buttonを用意して、OnClickの「」を押します。

f:id:tsubaki_t1:20170613230807j:plain

 

None(Object)に先程作成したAudio Sourceを登録、NoFunctionAudioSource.PlayOneShotを設定します。

f:id:tsubaki_t1:20170613230832j:plain

 

あとはNone(AudioClip)の所に再生したいAudioClipを登録すれば完了です。これでボタンを押せば音がなります。

f:id:tsubaki_t1:20170613231050j:plain

 

Gifには音が出ないのでAudio Mixerで音が出てるのを確認します。

f:id:tsubaki_t1:20170613231152g:plain

クリック以外で音を鳴らす場合はEvent Triggerで呼ぶ

上の例だと「クリック時」に音がなります。ソレ以外のケース、例えば「マウスカーソルがボタンの上に乗った」みたいなタイミングで音を出してみます。

クリック以外のタイミングは、Event Triggerで呼び出します。

f:id:tsubaki_t1:20170613231516j:plain

 

例えば「ボタンの範囲内に入ったら音が出る」の場合、Add New EventTypeでボタンをクリック後、Pointer Enterを選択、後は上でやってたようにボタンにイベントを登録するだけです。

f:id:tsubaki_t1:20170613231629j:plain

f:id:tsubaki_t1:20170613231923g:plain

AudioSourceが違うシーンだったり、ボタンを動的に作ってる場合

UIを複数のシーンで跨いで作成していたり、UIをPrefab化して動的に生成してる場合、Cross Scene Reference問題*1で、単純に参照関係を構築出来ない場合があります。

 

で、色々と考えましたが、ScriptableObjectを経由して参照関係を構築する方法を思いつきました。Audio Manager(Scriptable Object)にAudio Sourceを登録して、ボタンのイベントで呼び出してもらう方法です。

f:id:tsubaki_t1:20170614000458j:plain

ScriptableObjectの「アセット」を用意

まず、二つのスクリプトを用意します。

AudioManager は、AudioSourceをScriptableObjectに登録して、登録したAudioSourceのPlayOneShotを呼び出すScriptableObject、

MonoBehaviourEventTriggerは、AwakeとDestroyのタイミングで登録したメソッドを呼び出す汎用コンポーネントです。

gist.github.com

まずはScriptableObjectのアセットを用意します。*2。名前は別になんでも良いですが、AudioManagerとしました。

f:id:tsubaki_t1:20170613233833j:plain

 AudioSourceを登録

次に、AudioSourceをAudioManagerに登録する挙動を追加します。

MonobehaviourEventTriggerOnAwakeのタイミングに、AudioManagerを設定、AudioManager.audioSourceAudioSourceコンポーネントを設定します。

AudioManager.audioSourceはプロパティですので、イベントに使用出来ちゃいます。

これで、Audio Sourceオブジェクトがロードされると、AudioManagerにAudio Sourceコンポーネントが自動的に登録されます。

f:id:tsubaki_t1:20170613234006j:plain

 ボタンを押したらScriptableObjectを経由して音が出る

ボタンを押した際に音が出る設定も行います。

AudioSourceは直接参照出来ないので、ButtonにはAudioManagerを登録します。

AudioManagerのPlayOneShotは、AudioSourceと同じように任意の音を登録。

f:id:tsubaki_t1:20170613234441j:plain

 

これでボタンとAudioSouceが揃った時、即座に音が鳴るようになりました。

下の例では、ボタンをシーンに生成すると、ボタンとAudioSourceが繋がって、ボタンを押した際に音が出るようになってます。

f:id:tsubaki_t1:20170613234830g:plain

雑記

もう少し複雑な動作を期待するならスクリプトを書いた方が良いでしょうが、ボタンを押して音を出す演出くらいなら、UIのレベルで運用出来たららくじゃない? という感じで作ってみました。

関連

qiita.com

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

*1:他のシーンにあるオブジェクトや、Prefab(アセット)からシーン内のオブジェクトを参照できない問題

*2:このアセットは個人的には、MonoBehaviourEventTrigger等で登録するシーンのフォルダに配置するのがベータかなと考えてます。つまり今回の場合はAudioSourceがあるシーン。

【Unity】RootMotionを持たないアニメーションをTimelineで動かす

f:id:tsubaki_t1:20170612230633g:plain

今回はTimelineで、RootMotionを持たないキャラクターを動かしてみました。

Timelineと移動

Unity 2017より、やっとこさTimeline(カットシーンエディタ)が追加されました。
この機能は、シーケンスベースでキャラクターにAnimationを流し込める*1という機能です。
またアニメーション間でブレンドも行ってくれるので、割と良い感じにキャラクターのアニメーションを表現出来ます。

f:id:tsubaki_t1:20170612231426j:plain

とまぁ、ココまでは良いのですが、実はこの機能Tweenがありません。まぁ作ること自体はそれ程難しくないのですが、ソレはソレ、これはコレ。

Root Motoinで動く前提?

で、キャラクターの移動をどのように制御するかと言えば

  • Root Motoinを持ったキャラクターを動かす
  • Clip Root Motoin Offsetを設定し、移動した分キャラクターの中心位置を動かす

というふざけた内容。

f:id:tsubaki_t1:20170612232416j:plain

ではRootMotoinが無いアニメーションは? Clip Root Motoinをいい感じに動かしてキャラクターの位置を調整? ハハッ、5000兆歩譲ってもそれはないでしょう。

Animationで動かす

という事で、Animationで動かします。*2

  1. AnimationTrackを右クリックして、Add Override Trackを追加します。
  2. 赤丸を押してレコードモードに切替、後はキャラクターを動かすだけです。

f:id:tsubaki_t1:20170612232956j:plain

f:id:tsubaki_t1:20170612233255j:plain

ちなみに一番下のOverride Animationが移動を制御してるっぽいです。(この振る舞いはバージョンアップで変わる可能性があります)

f:id:tsubaki_t1:20170612233536g:plain

 

なお、Override Animation Trackを「作る」タイミングでHumanoidのRigがOptimized Game Objectしてなかった場合、正常に動作しないという挙動を確認しました。
「Keyframing for humanoid rig is not supported!」とエラーが出て、移動した分を巻き戻されます。

RigにGenericを使用するか、Override Animation Trackを「作る」タイミングでOptimized Game Objectを設定しとけば回避出来ます(終わったらもとに戻してもOKっぽい)

 

カーブエディタを使いたい

Timelineでカーブを追加出来ますが、本丸のカーブエディタと比較して使い勝手は悪いです。また、繰り返し等をする際に不便です。…なのでカーブエディタを使用します。

Convert to Clip TrackでカーブはAnimationClipに変換されます。

f:id:tsubaki_t1:20170612233747j:plain

f:id:tsubaki_t1:20170612233757j:plain

その状態で生成されたクリップをダブルクリックすると、何時ものカーブエディタが使えます。Timelineとも同期しているので、割と楽に編集出来ます。

f:id:tsubaki_t1:20170612233954g:plain

なお、AnimationClipはPlayableAssetの子として生成されるので、フォルダ周りもスッキリです。名前はAnimation PlayableのAnimation Clip Nameで指定します。
Project Saveしないと反映されない点に注意です。

f:id:tsubaki_t1:20170612234218j:plain

関連

 

tsubakit1.hateblo.jp

tsubakit1.hateblo.jp

 
 

*1:Animatorに指定のAnimationClipが含まれていない場合でも、アニメーションを再生出来る

*2:ちなみに、この動作は少し古いバージョン(Unity 2017 b6とか)だとまともに動きません。動作があまりにも酷いのでClip Root Motoinで動かすのが正しい動作かと勘違いしたレベルで動きませんでした。

【Unity】Textureの「Wrap(繰り返し)」でMirrorが出来るようになった

https://cdn-ak.f.st-hatena.com/images/fotolife/t/tsubaki_t1/20170412/20170412232539.jpg

Unity2017より、TextureのWrap表現でMirrorが使用出来るようになりました。

TextureのWrap

Wrapモードを指定すると、TextureのTilingが設定されていた時に「繰り返し」表現を行ってくれます。
例えば下のように、QUADは13,9のサイズでTilingが13,9の場合、横に13、縦に9の矢印マークを表示してくれます。

f:id:tsubaki_t1:20170611231826j:plain

また、この「繰り返し」が不要な場合、Clampに設定すれば繰り返しは行われません。その場合、一つだけ表示されます。

f:id:tsubaki_t1:20170611232108j:plain

Mirror

2017よりWrapモードでMirrorが表現出来るようになりました。これは下のように、繰り返す際に反転という動画です。

f:id:tsubaki_t1:20170611233131j:plain

UVスクロール時、始点と終点を合わせなくても繋げやすい

上手く使用すると、地形のリピートのようなケースで、終点と始点の画像がキッチリ合うように設定する…といった面倒臭さを回避出来ます。

これが特に活用されるのはUVスクロール時でしょう。勿論、画像が反転してしまう点は注意が必要ですが、良い言い方をすれば、2回に1回は反転した画像が流れるため、UVスクロール時に2種類の画像を使用していると言えなくもないです。

f:id:tsubaki_t1:20170611233238j:plain

パーティクルに活用

多分この機能で性能面で活用出来るのはパーティクルかもしれません。

パーティクルで「円」や「左右対称」な絵を使用する事は多いと思います。この際に、片面もしくは1/4面のテクスチャを用意すれば、ミラーする事で残りの面も表示する事が期待出来ます。

例えば魔法陣のような左右対称の円形の物を使用する場合、同一サイズでより高画質な、もしくは同画質でより小さな物を使用できるかもしれません。

f:id:tsubaki_t1:20170611233850j:plain

上下左右対象である点がミソです。

また、SpriteParticleには使用できなさそうです。

TextureImporterから設定

設定方法は、TextureのImporter設定にあるWrapModeをMirrorに設定するだけです。

f:id:tsubaki_t1:20170611234318j:plain

Pre-axisではX軸とY軸で各々設定することが出来ます。例えばX軸はMirrorだがY軸はClampとしたい場合、この設定が活用出来ます。

f:id:tsubaki_t1:20170611234644j:plain

Spriteでは使えない

残念ながら(?)ImageやSprite RendererといったUVありきの設定では使用する事は出来ませんでした。Raw ImageやQUAD(With Material)、Particle等では使用できるので、その辺りで使い分ける事になるかなと思われます。

日記

やっと書く時間が取れた感

関連

tsubakit1.hateblo.jp