テラシュールブログ

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

【Unity】Timelineと移動を連携して、特定のタイミングから"指定の座標"へ移動させる

f:id:tsubaki_t1:20180517183155j:plain

今回はTimelineの機能を使用するが、「目標地点が異なる」場合を対処する方法についてです。
例えば「距離の異なる崖をジャンプで超える」や「位置が毎回異なる敵に攻撃を仕掛ける」といった物をTimelineで制御する場合の話です。

 

 

Timelineアニメーションの「移動」は基本的に固定距離

移動で考えつくのはアニメーションによる移動ですが、これは基本的に固定の距離を移動する物になります。AnimationControllerを動かすキャラクターにセットする事でTimelineで指定された位置ではなく「現在座標からの移動」に設定することが可能ですが、距離が異なる場合にはアニメーションでの実現は難しいです。
それこそAnimationClipを動的に作るとかしない限り。

f:id:tsubaki_t1:20180517211741g:plain

 

Transform Tween Trackで座標を指定して移動する

想定した座標以外でも移動するため、「指定した座標から指定した座標へ移動」する法式を使用します

とは言え初期機能ではこの機能は含まれていないので、Default Playablesに含まれるTransofrm Tween Trackを使用します
上手く使うと、下のように長さの異なる崖を同じTimelineで飛び越える事が出来るようになります。

f:id:tsubaki_t1:20180517212226g:plain

アニメーションは「ジャンプ前」「ジャンプ開始」「ジャンプ中」「着地開始」「着地」「立ち上がる」の5つの動きで構成されていますが、ちゃんとTimelineで調整したので、違和感なく移動が出来ています。

 

実際にTransform Tween Trackを使ってみる

実際にTransform Tween Trackを使用してみます。

まずはキャラクターの移動パスを作成します。単純なもので、スタート地点と終了地点にGameObjectを配置するだけです。
オブジェクトにはアイコンを付けておくと色々と楽です。選択とか

f:id:tsubaki_t1:20180517213507j:plain

f:id:tsubaki_t1:20180517213635g:plain

なお、オブジェクトの向きも影響します。移動方向に向きを変えたい時とかはオブジェクトの向きを気をつけたほうが良いです。


次にDefault Playablesを導入します。

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

https://assetstore.unity.com/packages/essentials/default-playables-95266

 

あとはTimeline側の設定です。

トラックを右クリックすると追加出来るメニューにTransform Tween Trackが増えてるので、コレを追加します
Trackには動かす対象のTransformをセットします。今回の場合はユニティちゃんのルートTransform。

f:id:tsubaki_t1:20180517212910j:plain

f:id:tsubaki_t1:20180517212957j:plain

 

次にクリップ側でAdd Transform Tween Clipを足して、移動タイミングを指定します。最初のタイミングではスタート地点からスタート地点へ、次はスタート地点からゴールまで、最後はゴールからゴールまで。
同じ位置への移動はゲームを再生するとそれ程必要無いかもしれませんが、プレビューだとコレが無いと上手く動きません。

f:id:tsubaki_t1:20180517215841j:plain

f:id:tsubaki_t1:20180517220925j:plain

これで、崖から崖へのジャンプが実現出来ます。

f:id:tsubaki_t1:20180517221106g:plain

 

Timelineの開始地点がStartの位置とズレている場合

ここで一つ悩ましい問題が、TimelineでキャラクターのTween開始地点と実際のキャラクターの位置がズレている場合です。何もしないとTimeline開始時にワープしてしまいます

f:id:tsubaki_t1:20180517221630g:plain

これを解決するには、Ease In Durationをセットします。
これで開始点とTimelineの座標とのブレンドが行われて、いきなりワープする事は無くなります。

f:id:tsubaki_t1:20180517221705j:plain

f:id:tsubaki_t1:20180517221752g:plain

 

カーブを表現したい

カーブを表現したい場合、二つの移動をブレンドします。
例えば下のように二つの移動を持つ場合、この二つをブレンドするとカーブになります。

f:id:tsubaki_t1:20180517223107j:plain

f:id:tsubaki_t1:20180517223142g:plain

パスエディターが欲しい? ・・・それな

 

なんか変更した値が反映されない場合

プレビュー外して、もう一回入れる。
特にTransform Tween TrackはGraph生成時に座標の取得を行っているので、コレがモロに来ます。

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

 

動的に移動先を動かしたい場合

Transform Tween TrackはExpose Propertyで実現しているので、登録が面倒です。なのでstartとendをTimelineの子プレハブ的な感じで生成しておいて、startとendを動かすのが良いです。
もしくはScriptableObjectに格納したVector3に準じて動く感じに改造するとか。

関連

移動系トラブル

tsubakit1.hateblo.jp普通にキャラを動かす場合

tsubakit1.hateblo.jp

【Unity】Unity 2018.1でunsafeなコードを使う

今回はunityでunsafeなコードを使う方法についてです。

 

以前はUnityは公式的にはUnsafeはサポートしていませんでしたが(unsafeを使う手順は存在して、IL2CPPもunsafe向けコードを出力していた)、Unity 2018.1辺り?からオプションとしてunsafeに対応したみたいです。

 

 

Unsafeなコード

まず検証用に適当なunsafeを使用したコードを用意してみました。
構造体の配列を持っているコードで、各要素に対して直接内容の書き換えを行っています。
元々のコードはこちら

gist.github.com

f:id:tsubaki_t1:20180516065032j:plain

実行結果を確認すると、ちゃんとyの中身をxに再設定出来ています。
また3つ目の要素に12を直接代入出来ている事も確認出来ます。

 

なおコードにはIl2CppSetOptionを使用しています。これはIL2CPPでC# からC++に変換する際のオプションで、unsafeでも効果があります。
特に[Il2CppSetOption(Option.NullChecks, false)]はポインタのアクセス時のコストを回避出来ます。ArrayBoundsChecksはポインタ上では要らんですが、まぁ。

Il2CppSetOption.NullChecksやArrayBoundsChecksはNativeArray使う分には要らんかな?どうだろう(未検証

docs.unity3d.com

Unsafeなコードを利用する

Unsafeなコードを利用したい場合、PlayerSettings > Other SettingsのAllow 'unsafe' Codeを有効にします。

f:id:tsubaki_t1:20180516062924j:plain

 

少し注意すべきなのが、Assembly Definition FileにもAllow Unsafe Codeのオプションがあります。これはAssembly Definition File毎にunsafeを許容するかの設定になっています。

f:id:tsubaki_t1:20180516063125j:plain

 

少しややこしいですが、PlayerSettingsのallow unsafe codeはプロジェクト全体の設定(ADFが設定されていないコード全て)ですが、Assembly Definition Fileで更に個別に設定できるという感じみたいです。

f:id:tsubaki_t1:20180516064315j:plain

 

もしIl2CppSetOptionが必要な場合(速度が欲しくてunsafeを使用してる)場合には、Il2CppSetOptionAttribute.csも必要です。
Il2CppSetOptionAttributeは{インストールしたフォルダ}/Editor/Data/il2cpp以下にあるのでプロジェクトに突っ込んでおきます。

もしAssembly Definition Fileを使用してる場合は、依存関係の構築も忘れずに。

f:id:tsubaki_t1:20180516064744j:plain

関連

お馴染みJacksonDunstan.comのIL2CPPでunsafeを使用した時にどのようなコードが生成されるのかの解説記事

jacksondunstan.com

C# 7.2の機能を使用したい場合はincrementalcompilerを導入します。

baba-s.hatenablog.com

unsafeはコチラが分かりやすいです

ufcpp.net

さり気なくunsafeとか使ってたりします。

tsubakit1.hateblo.jp

【Unity】ProBuilderがなんか重い対処

ProBuilderでステージを作るときに何か重い…というものの対処についてです。

 

 

ProBuilderで作成…あれ重い?

ProBuilderでモデルを作って色々する訳ですが、何かやたらレスポンスが悪かったりSceneViewの視点を動かすのに時間がかかるという事があります。

ライトを焼いてるせい

これは大抵、ライトを焼いてるせいです。
ProBuilderは初期設定でLightmapStaticにチェックが入っているので、最初からライトを焼き付ける設定になっています。
またProgressive LightmapperがとてもCPUを専有するので、エディターのレスポンスが非常に悪くなります。このベイクがオブジェクトを動かす度に発生するので、そりゃあ重いかもしれません。

f:id:tsubaki_t1:20180515010600g:plain

対策1:自動的にベイクするのを止める

一番手っ取り早いのが、自動的にベイクするのを止める事です。
「まだ編集中なので今はライトが必要ない」というニュアンスで使えます。

LightingSettingsのAuto Generateのチェックを外せばOKです。

f:id:tsubaki_t1:20180515011830j:plain

勿論、ライトマップを焼かない事で間接光表現が無くなり、遠距離の影が表示されなくなったり、本来明るくなる場所が暗いまま、ビルドしたらなにか違う結果になる…といった問題は残ります。
作業が終わったら一旦GenerateLightmapを実行するのが良いです。

 

対策2:ライトマップを最初から諦める

対策その2では、ライトマップを最初から完全に諦めます。そのために、ProBuilderの生成するオブジェクトからLightmap Staticのチェックを外す設定を行います。

f:id:tsubaki_t1:20180515012104j:plain

ProBuilderのStatic Flagsで、生成時のStaticフラグを設定できます。ここでNothingを設定しておけばOKです。
なお、自分の初期設定ではNothing(実際にはEverything)という中々にロックな設定でした。一旦手動でNothingに変更することで明確にNothingになります。

 

対策3:Enlightenを使用する

Progressive Lightmapperは非常に高いCPU負荷を要求してきますが、Enlightenはそこまでエディターをロックせずベイク出来ます。

ので、設定をEnlightenに変更することで、物凄い負荷を計上してくるのを回避します。

f:id:tsubaki_t1:20180515012404j:plain

対策4:ライトのベイク負荷を下げる

Progressive Lightmapperを使い続けたい場合、ライトのベイク負荷を下げます。
LightmapResolutionは初期設定では40という、屋内向けの超解像度が設定されています。これを12とか10に設定すると、ライトのベイクは直ぐ終わるしライトのベイクで重い部分は直ぐ流れます。
他にもDirectSamplesやIndirectSamples等を調整することで、10分のベイク時間が3秒になります。

間接光などの表現を維持しつつ、結果を得たいという場合です。

f:id:tsubaki_t1:20180515012516j:plain

【Unity】知らないと苦労するかもしれない、Timelineと座標の話

f:id:tsubaki_t1:20180514224133g:plain

 

 

Unity 2018.3以降の場合

この記事の内容の幾つかは当てはまりません。

tsubakit1.hateblo.jp

 

Unity 2018.2までのTimelineの座標系の話

今回はTimelineで知らないと多分死ぬ思いをする、Timelineの座標系の話です。
この部分を気にせず使用すると、「Timeline再生時にキャラクターが変な所に出現する」「Timeline操作を止めるとキャラクターの位置がおかしい」といった事が発生するかもしれません。 

 

AnimationControllerがAnimatorにセットされていれば現在位置から移動、無ければ絶対座標からアニメーションを開始する

Timelineで知っておくべき最初の事は、Timelineの移動モードはAnimationControllerの有無で変わるという点です。
TimelineのAnimationTrackから操作するキャラクターにAnimationControllerがセットされている場合には、キャラクターはTimelineを再生開始した位置から移動を始めます
逆にAnimationControllerが無い場合は、Timeline上で指定した位置を移動します

f:id:tsubaki_t1:20180514232541j:plain

例えば下のアニメです。

ユーコにはAnimationControllerがセットされず、逆にユニティちゃんにはAnimationControllerをセットしました。

Timelineで指定した動きは、ユーコの移動するパス(つまりオレンジから青に移動し、90度回転する)です。
ユーコはAnimationControllerがセットされていないため、どの座標に居たとしてもTimeline開始時には開始点であるオレンジに戻ります
一方ユニティちゃんはAnimationControllerがセットされている為、現在位置から移動を開始します

f:id:tsubaki_t1:20180514230903g:plain

 

ApplyTrackOffsetはAnimationControllerの有無で用途が異なる

今ひとつ用途のわからないApplyTrackOffsets。

AnimationTrackの説明文には以下のように書かれています。

Apply Track Offsets を有効にすると、選択したアニメーショントラック上のすべてのアニメーションクリップに同じ位置と回転のオフセットを適用できます。トラックオフセットの適用には シーンビューでギズモを使用して位置と回転のオフセットを設定する方法と、正確な位置と回転のトラックオフセットを指定する 2 つの方法があります。

f:id:tsubaki_t1:20180515013210j:plain

ではコレが何の役に立つのかというと、AnimationControllerの有無により動作が異なり、それにより用途が異なります。

 

まずAnimationControllerが無い場合…座標を調整したり同じ動きを行うキャラクターを量産する用途に使えます。
例えば下のように、同じようにダッシュするが位置が微妙に違う…みたいな場合には、トラック毎にApplyTrackOffsetの位置を少しずつズラせば、複数体を配置出来ます。

f:id:tsubaki_t1:20180514233153g:plain

ではAnimationControllerがセットされている対象を動かす場合は?
この場合はゲーム再生時にApplyTrackOffsetが無視されます

AnimationControllerがセットされている対象のApplyTrackOffsetは、キャラクターのアニメーション開始位置を調整した状態でのプレビューに役立ちます。
上に書いたとおりAnimationControllerはTimeline開始時から移動であるため、ステージの何処かで呼ばれる事になります。その時に、実際に動かしてみて確認ではなく、キャラクターの開始点をOffsetで動かしてプレビューする事が出来る訳です。

f:id:tsubaki_t1:20180514234637g:plain

なおRecorded OffsetやClipRootMotoinOffsetは微妙に似ている機能ですが、こちらはAnimationClipの開始点を0にするための設定です。こちらもAnimationControllerがある場合は無視されます。

 

AnimationControllerがセットされている場合、移動にはApplyRootMotoinが必要

Timelineでキャラクターをアニメーションしながら動かす等をする訳ですが、AnimationControllerの有無により動かし方が異なるみたいです。

 

AnimationControllerがセットされているキャラクターは、ApplyRootMotoinにチェックを入れていない場合、キャラクターはその場でバタ足をします。

逆にAnimationControllerが無い場合にはApplyRootMotionにチェックを入れなくとも動くみたいです。

f:id:tsubaki_t1:20180515002352g:plain

ApplyRootMotoinを使用してないがAnimationControllerを使用している(多分95%の)人々は、親のオブジェクトに乗せて動かすとか、Tween系のTrackを用意して動かすとかでも良いかもです。
Tween系のTrackはDefaultPlayablesに参考になるものが入ってます。

tsubakit1.hateblo.jp

Timelineを編集後、キャラの位置がズレるのはPreview中にキャラの位置を編集しているため

Timelineを使用していてよくあるのは、Timeline編集後にキャラクターが変な位置に移動する…というものです。これはTimelineのPreview中に編集していたりするとよく起こります。

TimelineのAnimationでの移動や座標指定は、TransformコンポーネントではなくAnimationで指定するかApplyTrackOffsetによるものです。そのためGizmoで何時ものように動かすと、再生時に変な所に移動したり、Preview停止時に全て元に戻ったりします。特に親子関係の構築は絶対に止めましょう。

 

その他Timelineで「何か設定が反映されてない」とか「プレビューが予想と違う」みたいな場合には、Previewボタンを押して一旦TimelineのON/OFFを切り替えると、大抵治ります。(TimelineのGraph生成(Preview)時に色々集めたり設定を揃えてる事が多いのでこうなる)

f:id:tsubaki_t1:20180515002835j:plain

 

それがAnimationControllerが無い場合はプレビュー後にキャラがどこか変な所に飛んでいくだけですが、AnimationControllerを持つキャラクターの場合は、何処か飛んでいった先から移動を開始するので、これは注意が必要です。
逆を言えば、プレビュー中でも特定の位置に動かせるって事でもありますが、それを嬉しいかと言えば、うーん

f:id:tsubaki_t1:20180515111013g:plain

 

要するに

AnimationControllerがあればゲームキャラクターのイベント用

AnimationControllerが無ければカットシーン用

 困ったことがアレばPreview連打

 

宣伝

Timeline使ったこと無い人向けに実況やります。

軽めで雑談しながら色々とやったりします(主にntny氏が)

 

関連

TImelineで物理演算の動きを再現するの面倒だよねという話

tsubakit1.hateblo.jp

ExposedProprtyTableは大体Preview時に色々と集めるので。

tsubakit1.hateblo.jp

座標系を理解してないと、妙な挙動になる代表

tsubakit1.hateblo.jpRootMotoinの無いキャラクターを動かすには

tsubakit1.hateblo.jp