- 投稿日:2019-05-02T21:58:54+09:00
[VRChat]DynamicBoneスカートの私も優雅に裾をつまんでご挨拶(カーテシー)したいですわ
今回のアバター
先日、また新しいアバターを購入しました。
クローシアさんのシルヴィーヌちゃんです。
昨日シルヴィーヌちゃんをお迎えして、私のパーソナルカラー(?)の紫ベースに変えたりした。
— ほけ (@hoke946) 2019年4月28日
もともといい感じのSitモーション入ってるけど、DynamicBone吊りでさらに仰け反っても安定!
シルヴィーヌ | CaTrusty https://t.co/6ysMFxiqHe #booth_pm pic.twitter.com/bApssoIF2h
もともとは以前のDynamicBone吊りスカートを長い丈のスカートで検証するためにと思って買ったのですが、純粋にかわいいです。すぐに使い込みたくなりました。長い丈のスカートはつまみたくなる
ほぼ時を同じくして、妻がメイドさんになりました。
「こんなメイド欲しいわ~」と思いながら坊ちゃまとメイドを一人二役でやって来た。※BGMはありますが声は入って無いです。
— 三十個(みそこ)BLラウンジ店長 (@0ne_chan) 2019年4月28日
二人ともホバー移動。
VRCワールド名:Twin Spire Village
BGM:MusMus
VRC向けアバター 「Amelia」 Ver.1.0 | SakuSakuのモデリング工房 https://t.co/qEkd8GkvqO #booth_pm pic.twitter.com/P0r3cHEMOx
このメイドさんモデルのAmeliaさんですが、スカートの裾をつまんでご挨拶、いわゆるカーテシーができるようになっています。
その仕組みはどうやら、Clothの網の目のようなコライダーに、ハンドサインで手に出現させたコライダーを引っかけてスカートを持ち上げるというもののようです。
いいですねぇ。
シルヴィーヌちゃんも長い丈のスカート、つまんでご挨拶したくなります。スカートは大抵DynamicBoneですね
ところが、アバターのスカートの揺れはClothではなくDynamicBoneで表現されることが多く、シルヴィーヌちゃんもその1人です。
Clothのような網の目のコライダーはなく、スカートのボーンの粒をどうにかしてつまみ上げるしかありません。それが目標になります。
スカートのボーンをコライダーで引っかける
こんな形のDynamicBoneColliderを左右の手の先に用意します。
この3つのコライダーの窪みでスカートのボーンを引っかけるという寸法です。
右手の例ですが、手のボーン(hand.R)の下に空GameObjectを加えて、その下にさらに3つの空GamgeObjectを加え、それぞれDynamicBoneColliderをアタッチして位置調整をします。
今、わかりやすくコライダーに沿ってCylinderモデルも一緒につけていますが、こちらは実際には不要です。
コライダーが出来上がったら、スカートを揺らしているDynamicBoneに設定してください。特定のハンドサインで出るようにアニメーション設定
しかし、常時コライダーが飛び出していては邪魔になるし、スカートの中に手を入れることもできなくなってしまうので、
普段はコライダーの幹である「holdhand.R」(左手は「holdhand.L」)のscaleを0.001などに縮小しておき、
それを特定のハンドサインで1に戻すようにします。私はRockNRollに設定しました。ハンドサインの設定方法についてはこちらを参照してください。
AnimationClipにはTransform値も設定することができます。
あと折角なので、つまんだときの指の形を作っておくのもオススメです。スカートをつまむことができました
これで一応、VRChatでスカートをつまみ上げることができるようになりました。
スカートの裾つまむの見てたら私もやりたくなったから仕込んでみたよ pic.twitter.com/tf0VtJdOqr
— ほけ (@hoke946) 2019年4月30日
「たぐり寄せアニメーション」で掴み判定を拡大
ただ、このボーンの1点をコライダーの隙間に挟み込むのは結構難しく、
瞬間でさっとつまんで優雅にご挨拶、とするのはかなりの修練が必要です。そこで、ハンドサインでつまむとき、コライダーを下からたぐり寄せるようにアニメーション設定しました。
1コマ目。z軸のマイナス方向に少し動いたところから始まります。
Position.zを選択してCurves画面を開き、図のように0:00での傾きをゼロを超えてしまわない程度に右肩上がりにします。
スカートをつまんでいる間はこのハンドサイン(RockNRoll)から同じハンドサイン(RockNRoll)へのアニメーション遷移が断続的に発生し、このアニメーションの先頭へループすることが避けられないのですが、
できるだけ素早く0に近づけることによって、コライダーの動きを目立たなくする意図です。
最初の一瞬はまだ遷移割合が低いので、コライダーは殆ど動きません。
この傾きをつけないと、コライダーの動きが目立ってスカートがプルプルします。あと、忘れそうになりますが、
AnimationClipのLoopTimeのチェックを外しておいてください。
これにチェックがついていると、否応なくコライダーがブルブルします。しっかりスカートをつかめました
よしできた。すすっとご挨拶。
— ほけ (@hoke946) 2019年5月2日
結局はアニメーションの時間を調整するしかないかな。 pic.twitter.com/A5jNLgjNntちゃんと動きの中でスカートをつまめていますね。
たまに失敗しますが、成功率は格段に上がりました。【アーカイブ】当初のアニメーション設定
以上ですが、初稿からアニメーションの設定が改善されています。
最初に記載していた内容を参考までにアーカイブとして残しておきます。:
:
:
0:00~0:01の間で移動して、0:01~0:03はキープしています。
これは、必ずしもベストかどうかはわかりません。VRChatの悩ましい仕様の私なりの妥協点です。VRChatのハンドサインアニメーションには
- 設定されているアニメーションの長さの4倍の時間で次のアニメーションに遷移する
- その遷移中は、さらに他のアニメーションに遷移することができない
という特徴があります。
要するに、設定するアニメーションが長いほど、その後の動作が鈍くなります。
通常は動きなどつけず、0:01で固定しておくべきです。今回も0:01で留めておくべきなのですが、
一方でこのハンドサイン(RockNRoll)から同じハンドサイン(RockNRoll)への遷移も当然発生していて、
このアニメーションの先頭へループ、すなわちコライダーが動いてスカートが小刻みにプルプル動くことになります。
もちろん、この設定でも同じことが言えますが、0:03までアニメーション設定していることでその周期を下げているんですね。
- アニメーションを長くするとその後の遷移が鈍くなる
- アニメーションを短くするとスカートのプルプルが小刻みになる
この2つの問題に挟まれた中で、比較的どちらも不自然にならないバランスだと考えた長さが0:03です。
:
:
:とまぁ、そんな話でしたが、
カーブの傾きをつけることによって、0:01のアニメーションでもプルプルが目立たなくなったという次第です。
- 投稿日:2019-05-02T20:27:25+09:00
Live2DでVRコンテンツを作りたい
はじめに
Live2DでVTuberをやっている方も多いと思いますのでLive2D × VRでコンテンツが作れないかと思い調べてみました。
Live2D SDKのダウンロード
https://live2d.github.io/
こちらのページからLive2DSDKをダウンロードできます。SDKにはサンプルモデルがいくつか入っていますが、自分のオリジナルのモデルを使用するのも非常に簡単です。
Unityにインポート
ダウンロードしたunitypackageを実行しunityに導入します。
Roomのアセットは下記を使用させて頂きました。
https://assetstore.unity.com/packages/3d/environments/free-medieval-room-131004
モデルにはLive2DSDKのSampleに入っているkohakuちゃんを使用させて頂きました。ヒエラルキーにモデル等を配置してHMDにBuildすれば360度見渡すことができます。
ライブ配信
facebookの360-Capture-SDKを使用すればそのままライブ配信もできそうです。
https://github.com/facebook/360-Capture-SDK/releases終わりに
Live2DとFaceRigで手軽にVTuberを始めることができますが3Dと比べて自由度に限界があるのでVRと組み合わせてなにか面白いことできないかな~と思って調べてみました。
- 投稿日:2019-05-02T18:44:32+09:00
UnityのAnimation Eventで関数定義と関数選択が分かりにくかった
はじめに
アニメーションイベントの使用 - Unity マニュアルと[Unity] Animation Eventを使いこなそう!を参考に自作アニメーションにAnimation Eventをつけようとしたのですがインスペクターの挙動が分かりにくいのでまとめました。
Animation Eventの関数定義
- プロジェクトタブでAnimationファイルを選択します。
- アニメーションタブでAnimation Eventを選択します。
- インスペクターに関数定義が出てきます。
Animation Eventの関数選択
- ヒエラルキーで上記Animationを含むAnimation Controllerを関連付けたゲームオブジェクトを選択します。
- アニメーションタブでAnimation Eventを選択します。
- インスペクターに関数選択が出てきます。
まとめ
何でこんな挙動なのか考えてみると分かったのですが、関数定義はAnimation Eventの定義はAnimation自体にあるのでファイルを選択してから、関数選択は同じゲームオブジェクトにアタッチしたスクリプトから選ぶのでヒエラルキーのゲームオブジェクトを選択してからなので納得できます。とは言え直前に選択したもので挙動が変わるのは分かりづらい…
参考リンク
- 投稿日:2019-05-02T18:06:45+09:00
【GooglePlay】AdMob広告を入れた場合の設定「コンテンツの不適切なレーティング」
AdMob側の設定で、「デリケートなカテゴリ」で広告の種類が設定できる。
Google Playの「コンテンツのレーディング」とAdMobの「デリケートなカテゴリ」を、矛盾なく設定する必要がある。コンテンツのレーディングを「3歳以上」の場合は、AdMobの「デリケートなカテゴリ」を
許可→ブロック
に設定する。
↓↓Google Play 無料Free
CherryCocktailGlassチェリーカクテルグラス〜無料簡単ミニゲームFree games
⭐️Androidアプリ⭐️リリース
— non (@nonnonkapibara) April 26, 2019
?CherryCocktailGlass?
Blenderで絵を描いてUnityで作成したミニゲームリリースしました?
?カクテル?グラス?に
?チェリー?をのせるシンプルなゲームです。
✨(●^o^●)✨
【Android】
Google Play 無料Freehttps://t.co/I70R9QEDuq#CherryCocktailGlass pic.twitter.com/g8kCM9QVhL
- 投稿日:2019-05-02T17:49:24+09:00
Azure Spatial Anchors v1.1.0 Unity iOS版をビルドしてみる
はじめに
Azure Spatial Anchors v1.1.0 Unity Android版をビルドしてみる の次にiOS版もビルドしてみる。公式ドキュメントはこちら
やってみる
Azure Portalでの設定と、azure-spatial-anchors-samplesをcloneして
Unity
フォルダを開くところまではAndroid版と同じUnity ARKit Plugin version 2.0.0 をダウンロードしておく
ファイル -> ビルド設定 を選択する
ビルドに含まれるシーン はデフォルトのまま全選択。プラットフォーム で
iOS
を選択しSwitch Platformボタンをクリックする設定が完了したらビルド設定 を閉じる
先ほどダウンロードしておいたUnity ARKit Plugin version 2.0.0を展開し、展開したフォルダの
Assets
フォルダの中身をUnityのAssets
フォルダにコピーするプロジェクトからAssets -> AzureSpatialAnchorsPlugin -> Examples -> Resources とフォルダを選択して、
AzureSpatialAnchorsDemoConfig
アセットを選択するインスペクターで控えておいたSpatial Anchor AccountのAccount IDとPrimary Keyを入力してプロジェクトを保存する
ビルド前にアセットの再インポートをやっておいたほうがいいのはAndroid版と同じ。アセット -> すべてを再インポートを選択してアセットを再構成する
ファイル -> ビルド設定 を選択する
ビルド ボタンをクリックしてプロジェクト名を入力しSaveボタンをクリックする。ここではプロジェクト名を
SpatialAnchorsDemo-iOS
とするエクスポートされたプロジェクトに移動して、依存パッケージをインストールする
cd SpatialAnchorsDemo-iOS pod install --repo-updateXCodeで
Unity-iPhone.xcworkspace
を開く。.xcodeproj
でないことに注意open ./Unity-iPhone.xcworkspaceBundle Identifierを適当な名称に変更して、Teamに有効なアカウントを設定する
iPhoneをMacに接続して、ビルドボタンをクリックし、iPhoneにアプリケーションをインストーする
アプリがインストールされるのでデモを実行する。デモの操作方法はAndroid版と同じ
まとめ
Android版との違いは
Unity ARKit Plugin version 2.0.0
のインポートくらいであとは普通にiOS用にビルドすればできる。次はAndroid版とこのiOS版のデモを使ってシェアリングをやってみたいと思う
- 投稿日:2019-05-02T17:40:16+09:00
UnityでiPhoneX系による表情取得について
自己紹介
こんにちはゆずです。@Yuzu_Unity
自分はUnityエンジニア・3DCGデザイナーの学生です。(軸はエンジニア 4年ほど…)
※自分は現在どこの企業にも所属していませんので技術周りなら色々言っちゃおうかと
インターンとか行きたいです…(切実(3回目))オリジナルのVtuberですのでチャンネル登録お願いします…
藤田りあ@Ria_fujita 自己紹介動画
上記のリンクの映像を作るための技術紹介記事です。はじめに
これを使います…これで記事は終わりです。
https://github.com/Unity-Technologies/facial-ar-remote
キズナアイが使ってるらしい?ZIPで紹介されていたみたいです(自分は見ていないので…)
にじさんじの3Dはこれを使っていのかな?準備物
iPhoneX/XR/XS
Mac(iOSビルドを行うため)
最終的にiPhoneの表情データを取得させたい!
Windows/Mac使い方
https://github.com/Unity-Technologies/facial-ar-remote/releases
releasesから使いたいところですが
iPhoneXS/XRで使える記述がver1.1ではないみたいです。
なので最新版をクローンします!!
zipでダウンロードするといろんなデータが死んでしまうみたいなので
LFSが使えるGit等でクローンしましょう。Githubに使い方等が書いています。
iOS Build Setup
Editor Animation Setup
の欄です。iOSビルドを行った後
Win/MacのローカルLan内での接続です。
ファイアーウォールの設定を行わないと接続できないので注意インストールTips
ARKit pluginの場所 BitBucket
7.Enable "ARKit Uses Facetracking" on UnityARKitPlugin > Resources > UnityARKitPlugIn > ARKitSettingsの場所
自分のキャラクターを動かしたい…
このアセットに含まれている自分のメッシュへの適用なのですがセットアップがめんどくさい…
なのでそこは触れず自分は
tmp[i]=Mathf.Clamp(skin.GetBlendShapeWeight(i),0,100);
を用い
狸?のブレンドシェイプをそのままコピーすることにしました。
あとは自分の使いたいキャラクターにSetBlendShapeWeightを行うだけです。//目線制御 こちらもブレンドシェイプから取得しボーンに回転値を割り当てします。 void Update() { debugRotL = EyeRot(tmp[1], tmp[4], tmp[3], tmp[2]); debugRotR = EyeRot(tmp[8], tmp[11], tmp[9], tmp[10]); eyeL.localRotation = Quaternion.Euler(debugRotL); eyeR.localRotation = Quaternion.Euler(debugRotR); } Vector3 EyeRot(float valueL,float valueR,float valueUp,float valueDown) { float left = (valueL - valueR) * 45/100/4; float up = (valueDown - valueUp) * 45/100/4; return new Vector3(left, up, 0); }Unityの地味な便利機能Constraintでコード書かずボーンに割り当て…
Mayaとの連帯機能ですが便利です。
首や頭の傾き等もこれを用い設定します。
【Unity】複数のオブジェクトの位置を元にオブジェクトを動かす、○○○Constraint系というオモシロ機能表情レコード機能
このアセットにはレコード機能など含まれていますが
自分はこちらを使うため使わないことにします。
https://qiita.com/Yuzu_Unity/items/d891ecee64a164149167結果
リップシンクはOVRLipSyncを用いたので今回は瞬きのみ適用しました。
iPhoneで取得するとリアル差がかなり上がります。
人間の瞬きは奥が深いものですね…
OpenCV×Dlibで行うより簡単で高精度なのでおすすめかと…
- 投稿日:2019-05-02T13:28:10+09:00
UnityでAdMobやFirebaseを入れた時のgradleファイルを晒す
はじめに
UnityのAndroidビルド時に巻き起こる謎のビルドエラー
だいたいはライブラリの不足や競合だったりするのですが、エラーメッセージが分かりにくい為に解決するのに時間がかかるんですよねー。
ので、自分がビルド通った時のgradleファイルを晒して少しでも参考になればと...
(自分自身Androidやgradleについてあまり詳しくないので、ちょっとずつ加筆修正していくと思います)実装環境
- Unity 2019.1.0f2
- gradle 3.2.0
使用ライブラリ
- Firebase Analytics
- Firebase Remote Config
- AdMob
- nend(AdMob Mediation)
- AppLovin(AdMob Mediation)
gradleファイル
mainTemplate.gradle// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN buildscript { repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.2.0' **BUILD_SCRIPT_DEPS**} } allprojects { repositories { google() jcenter() flatDir { dirs 'libs' } } } apply plugin: 'com.android.application' **APPLY_PLUGINS** dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) // AndroidSupport compile group: 'com.android.support', name: 'customtabs', version: '26.1.0' compile group: 'com.android.support', name: 'support-annotations', version: '26.1.0' compile group: 'com.android.support', name: 'support-compat', version: '26.1.0' compile group: 'com.android.support', name: 'support-core-ui', version: '26.1.0' compile group: 'com.android.support', name: 'support-core-utils', version: '26.1.0' compile group: 'com.android.support', name: 'support-fragment', version: '26.1.0' compile group: 'com.android.support', name: 'support-media-compat', version: '26.1.0' compile group: 'com.android.support', name: 'support-v4', version: '26.1.0' compile group: 'com.android.support', name: 'recyclerview-v7', version: '26.1.0' compile group: 'com.android.support', name: 'appcompat-v7', version: '26.1.0' compile group: 'com.android.support', name: 'cardview-v7', version: '26.1.0' compile group: 'com.android.support.constraint', name: 'constraint-layout-solver', version: '1.1.3' compile group: 'com.android.support.constraint', name: 'constraint-layout', version: '1.1.3' // gms compile group: 'com.google.android.gms', name: 'play-services-ads', version: '17.2.0' compile group: 'com.google.android.gms', name: 'play-services-ads-base', version: '17.2.0' compile group: 'com.google.android.gms', name: 'play-services-ads-identifier', version: '16.0.0' compile group: 'com.google.android.gms', name: 'play-services-ads-lite', version: '17.2.0' compile group: 'com.google.android.gms', name: 'play-services-base', version: '16.0.1' compile group: 'com.google.android.gms', name: 'play-services-basement', version: '16.2.0' compile group: 'com.google.android.gms', name: 'play-services-gass', version: '17.2.0' compile group: 'com.google.android.gms', name: 'play-services-measurement', version: '16.4.0' compile group: 'com.google.android.gms', name: 'play-services-measurement-api', version: '16.4.0' compile group: 'com.google.android.gms', name: 'play-services-measurement-base', version: '16.4.0' compile group: 'com.google.android.gms', name: 'play-services-measurement-impl', version: '16.4.0' compile group: 'com.google.android.gms', name: 'play-services-measurement-sdk', version: '16.4.0' compile group: 'com.google.android.gms', name: 'play-services-measurement-sdk-api', version: '16.4.0' compile group: 'com.google.android.gms', name: 'play-services-stats', version: '16.0.1' compile group: 'com.google.android.gms', name: 'play-services-tasks', version: '16.0.1' // Firebase compile group: 'com.google.firebase', name: 'firebase-abt', version: '17.1.0' compile group: 'com.google.firebase', name: 'firebase-analytics', version: '16.4.0' compile group: 'com.google.firebase', name: 'firebase-common', version: '16.1.0' compile group: 'com.google.firebase', name: 'firebase-config', version: '16.4.1' compile group: 'com.google.firebase', name: 'firebase-core', version: '16.0.8' compile group: 'com.google.firebase', name: 'firebase-iid', version: '17.1.0' compile group: 'com.google.firebase', name: 'firebase-iid-interop', version: '16.0.1' compile group: 'com.google.firebase', name: 'firebase-measurement-connector', version: '17.0.1' // Other compile 'com.google.ads.mediation:nend:5.1.0.1' compile 'com.applovin:applovin-sdk:+' compile group: 'com.google.auto.value', name: 'auto-value-annotations', version: '1.6.3' // internal compile(name: 'com.google.firebase.firebase-app-unity-5.6.0', ext: 'aar') compile(name: 'com.google.firebase.firebase-config-unity-5.6.0', ext: 'aar') **DEPS** } android { compileSdkVersion **APIVERSION** buildToolsVersion '**BUILDTOOLS**' compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } defaultConfig { minSdkVersion **MINSDKVERSION** targetSdkVersion **TARGETSDKVERSION** applicationId '**APPLICATIONID**' ndk { abiFilters **ABIFILTERS** } versionCode **VERSIONCODE** versionName '**VERSIONNAME**' } lintOptions { abortOnError false } aaptOptions { noCompress = ['.unity3d', '.ress', '.resource', '.obb'**STREAMING_ASSETS**] }**SIGN** buildTypes { debug { minifyEnabled **MINIFY_DEBUG** useProguard **PROGUARD_DEBUG** proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'**USER_PROGUARD** jniDebuggable true } release { minifyEnabled **MINIFY_RELEASE** useProguard **PROGUARD_RELEASE** proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'**USER_PROGUARD****SIGNCONFIG** } }**PACKAGING_OPTIONS****SPLITS** **BUILT_APK_LOCATION** bundle { language { enableSplit = false } density { enableSplit = false } abi { enableSplit = true } } }**SPLITS_VERSION_CODE****REPOSITORIES****SOURCE_BUILD_SETUP**補足
- gradleへ記載するライブラリ名は https://mvnrepository.com/ で調べました
- 現在のSDKのバージョンに合わせる必要があります(新しければいいという訳ではないので注意を)
// internal
の項目のライブラリはファイルをダウンロードしておく必要があります。それ以外はライブラリ競合を起こすので削除 or Androidのビルド対象から外してください- AdMobやFirebaseのUnitySDKインポート時に
Play Services Resolver
がインストールされ、ライブラリが自動的にインポートされます。これはgradleのライブラリと競合を起こすので、以下の手順で自動インポートを解除する必要があります
- 投稿日:2019-05-02T11:43:55+09:00
UnityのスマホネイティブプラグインをKotlin/Nativeで共通化する
Unityのスマホネイティブプラグインを言語統一できないか?
昨今のスマホネイティブプラグインの言語の選択肢としてはJava, Kotlin, Objective-c, Swiftがあげられるかと思います。
たまに自分も趣味などでプラグインを使うことがあるのですが同じような処理を別で書かないといけないのが手間だと思っていました。
そこで昨年くらいからスマホのネイティブ界隈で話題になっていたKotlin/Nativeに目をつけてUnityで実行させてみたという記事です。そもそもKotlin/Nativeとは…?
まとめている記事もありましたので参照させて頂きます。基本的にはスマホネイティブの共通化できるロジックをKotlinで書いて共通化させようぜ!ってことなのですがAndroidでは.jarとしても吐き出せますし、iOSは.frameworkとして吐き出せるのでネイティブにとって扱いやすいものになっています。
さて、今回検証に使用したリポジトリです。動かして見たい人は是非ご活用ください。
実行した結果
Android iOS 文字列をOS毎に変えるという処理ですが呼び出すメソッドは1つにしてあります。
準備
Kotlin/Native自体の作成方法は既にわかりやすい記事がありますのでそちらを参照させていただきます。
Kotlin/Nativeチュートリアル Android, iOS編
自分はここを参考にさせて頂きました。そのため今回上記の記事をベースに進めます。Androidのネイティブが自分はよくわからなかったので、最初は基本的にコピペで作って必要な箇所を変えていきました。
今回、上記記事の「Common moduleの解説」の章まで出来たら一旦は大丈夫です。
上記の記事ほぼそのままですがソースコードを載せておきます。共通
common.ktpackage com.sample.mizotake.kotlinnativeforunity expect fun platformName(): String public class common { public fun createApplicationScreenMessage(): String { return "Call Kotlin Native on ${platformName()}" } }Android
actual.ktpackage com.sample.mizotake.kotlinnativeforunity actual fun platformName(): String { return "Android" }iOS
actual.ktpackage com.sample.mizotake.kotlinnativeforunity import platform.UIKit.UIDevice actual fun platformName(): String { return UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion }共通処理にUnityで呼び出すクラスとメソッドを定義します。OS毎に変える処理はexpect actual処理でinterfaceのように切り出して呼べるようです。
Unityへの導入
Android
自分もよく把握できていませんがGradle Syncをするとbuildというディレクトリができて
プロジェクト名 + android.jar
ができていました。
もし出来ていない場合は
右端にGradleというタブがあるのでそこからbuildの項目を見るとbuildの詳細一覧があるのでandroidJarをダブルクリックすれば走り出してjarができるかと思います。吐き出されたjarをUnityのPlugin/Androidに放り入れるだけです。
これでUnityへの導入は完了です。iOS
こちらは先ほどのKotlin/Nativeチュートリアル Android, iOS編の「iOSアプリ」の章にあるbuild.gradleの追記だけ行いましょう。
/common/build.gradle... task packForXCode(type: Sync) { final File frameworkDir = new File(buildDir, "xcode-frameworks") final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG' inputs.property "mode", mode dependsOn kotlin.targets.iOS.compilations.main.linkTaskName("FRAMEWORK", mode) from { kotlin.targets.iOS.compilations.main.getBinary("FRAMEWORK", mode).parentFile } into frameworkDir doLast { new File(frameworkDir, 'gradlew').with { text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n" setExecutable(true) } } } tasks.build.dependsOn packForXCodeここの部分ですね。これを追記して
./gradlew build
することで
main.frameworkができます。これをUnityのPlugin/iOSに放り込めばframeworkの導入は大丈夫ですが、iOSの場合もう一手間必要です。
externの実装がないとC#では呼び出せませんそのためPlugin/iOSフォルダにcommon.mm#import <main/main.h> extern "C" { const char* createApplicationScreenMessage() { NSString *message = [[Maincommon alloc] init].createApplicationScreenMessage; return strdup([message UTF8String]); } }を追加しましょう。これを追加することで先ほど作ったKotlinで書いたコードのframeworkを参照できます。
ここでcommonというkotlinファイルを作ったがMaincommonって何だろう?ってなると思います。どうやらframeworkに吐き出す時に変換されているようです。
それを確認するにはAndroidStudioでframeworkのHeaderを見ると一番下の行に自分で実装した処理が追記されていると思います。
これを参考にしてObjective-c++でインターフェースを定義する必要があります。
ちなみにSwiftだとMaincommonという変換名ではなくcommonで呼び出せそうですがSwiftを使うために手間をかけるよりObjective-c++を書いた方が早いと自分は思うのでこのまま進めます。C#で呼び出す
事前準備は終わりました。
UnityではuGUIのTextにネイティブで呼び出した文字列を表示させます。CallKotlinNative.csusing System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using System.Runtime.InteropServices; public class CallKotlinNative : MonoBehaviour { #if UNITY_IOS [DllImport("__Internal")] private static extern string createApplicationScreenMessage(); #endif private Text viewableText; void Start() { var pluginMessage = ""; #if UNITY_ANDROID using (var plugin = new AndroidJavaObject("com.sample.mizotake.kotlinnativeforunity.common")) { pluginMessage = plugin.Call<string>("createApplicationScreenMessage"); Debug.Log(pluginMessage); } #elif UNITY_IOS pluginMessage = createApplicationScreenMessage(); #endif viewableText = GetComponent<Text>(); viewableText.text = pluginMessage; } }C#側は普通にネイティブプラグインを呼び出すだけですね。
これを実機ビルドまたはシミュレータービルドすることで動作の確認ができると思います。終わりに
Kotlin/NativeのUnityProjectへの導入は手間が必要かと思っていましたが思った以上に簡単でした。ただ、iOSの導入のexternだけどうにかならなかいとAndroidProject内に.mm入れてみて.frameworkだけ吐き出して更新させるなどをしようと思いましたがうまく行きませんでした…Androidネイティブのディレクトリ構成やtaskのカスタムに詳しければどうにかできるのかな?と思っています。
Kotlin/Nativeを使えば基本的に言語はKotlinひとつに統一できますし、共通処理やOS依存処理も問題ないのではない気がしています。個人的にKotlinでUIKitなどもimportして使えることに驚きました。
何にせよ扱う言語は少ないに限ると思っていますのでKotlin/Nativeは良いものだと思います。ただ現在betaなので書き方や吐き出し方が変わる可能性は高いです。
- 投稿日:2019-05-02T02:13:22+09:00
UnityでのVSCodeの導入手順とおすすめ設定、拡張機能(Mac)
はじめに
Unityを使う際、デフォルトではスクリプトエディタとしてVisual Studioが設定されていますが、「VSCode便利だよ」と先輩エンジニアの方に勧めて頂いたので導入してみました。結果、色々カスタマイズできて便利だったので、備忘録として導入手順とおすすめ設定をまとめてみました。
VSCodeのインストール
下のリンクからダウンロードし、インストールする。
Download Visual Studio CodeUnityの設定
デフォルトのスクリプトエディタをVSCodeに変更する
[Unity] → [Preferences] → [External Tools] → [External Script Editor] → [Browse]
finderが開くので「Visual Studio Code.app」を探してきて選択する。[External Script Editor]に「Code」と表示されていればOK。
VSCodeのおすすめ設定と拡張機能
設定
自動保存
[File] → [Auto Save]にチェックをつける。
自動整形
[Code] → [Prefarences] → [Settings]
で設定画面を開く
下記3つの項目にチェックをつける。・Format On Paste
→ペースト時に自動でフォーマット
・Format On Save
→ファイル保存時に自動でフォーマット(自動保存では整形してくれないので、手動で「cmd+S」する必要あり)
・Format On Type
→入力した行を自動でフォーマットまた、後述の拡張機能「C# FixFormat」をインストールする。
これを入れて置かないと自動整形が働かないので注意。ミニマップを非表示
横に出てくるやつです。個人的にいらなかったので非表示にしました。
[Code] → [Prefarences] → [Settings]
で設定画面を開く。
以下の項目のチェックを外す
・Editor › Minimap: Enabled.metaファイルを非表示
デフォルトだと.metaファイルが表示されて邪魔なので非表示にします。
[Code] → [Prefarences] → [Settings]
で設定画面を開く。・Files:Exclude
の項目に以下を追加してOKを押す。
**/*.meta
拡張機能
C#
必須。C#が使えるようになる。
C# FixFormat
C#の自動整形ができるようになる。
Japanese Language Pack for Visual Studio Code
VSCodeの日本語化。
vscode-icons
Bracket Pair Colorizer
zenkaku
Debugger for Unity
C# XML Documentation Comments
MonoBehaviour Snippets
Classy Naming
C# Extensions
Rainbow CSV
参考
今日からUnity + Visual Studio Codeを用いた快適な開発生活(随時更新中)
VSCodeのオススメ拡張機能 24 選 (とTipsをいくつか)
VS CodeでUnityプログラミングしてる僕が入れてる拡張機能
- 投稿日:2019-05-02T01:07:08+09:00
ml-agents 0.8.0 で自分のプロジェクトで機械学習させる (Windows)(Tensorflow-GPU導入編)
前段
Macでのml-agents導入はこちらを参照してほしい。
今回はWindows用、それもtensorflow-gpu を使ってやりたい。基本的に以下の本家のページの通りだが
https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Installation-Windows.md
ハマリポイントがいくつかあったので、それには注意を促したい、というのがこの記事の趣旨だ。
あと1年後は100%忘れる自信がある私自身のためのものでもある。環境設定
1、 ml-agents をダウンロード
https://github.com/Unity-Technologies/ml-agents/tags/0.8.0
をダウンロードして、適当なところに配置2、 anaconda をインストール
ターミナルで「conda」と打って反応があれば既にインストール済み
3、 仮想環境を作る
conda info -eで[ml-agents]があれば良い。なければ↓でつくる。
conda create -n ml-agents python=3.6で仮想環境を作る(なんか聞かれたら「y」と入力)
conda activate ml-agentsで仮想環境切り替え。
4、 CUDA toolkit のインストール
Unity ML-agentsドキュメントによると、CUDA toolkitのバージョンは「9.0.176」限定であるらしいので、それをダウンロードする。ダウンロードサイト直リンク
5、cuDNN library のインストール
- NVIDIAサイトでcuDNNのサイトに行って、ダウンロードの手続きをする。ディベロッパー登録やらアンケートやらをやる必要がある。(こちらもCUDA toolkit 同様、バージョンが限定されているので要注意。「7.0.5」らしい。ダウンロードサイト直リンク )
- ダウンロードしたzipを展開すると「bin」「include」「lib」フォルダができるので、それをCUDA toolkitのインストール先である
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0
に配置する。6、環境変数の設定
CUDA_HOME
という環境変数を新規に作り、C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0を設定する。
次に、Path
環境変数に、以下の二つを追加する。C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\lib\x64 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\extras\CUPTI\libx64(Unity ML-agentsドキュメントには「関連するパスを置き換えろ」と書いてあるが、CUDA toolkit インストール時に書き加えられたパスを消してはいけないので注意が必要)
以下の感じにパスが張っていればOK。
7、tensorflow-gpu のインストール
3で作った仮想環境で
pip install tensorflow-gpu==1.7.1とやって tensorflow-gpu を仮想環境にインストール。
確認のために、pythonとやって、pythonを起動後、
import tensorflow as tf sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))で、tensorflow-gpu が起動するのを試してみる。
Found device 0 with properties ...とかなんとか出れば成功。出てなければ、tensorflow-gpu がインストールできていない可能性がある。
8、ML-Agents が使うライブラリをインストール
★★★ここで注意★★★
このままML-Agents の使うライブラリをインストールしようとすると、せっかくいれたtensorflow-gpu に 通常のCPUを使う tensorflow が上書きインストールされてしまう。
なので、ml-agents/setup.py を以下のように編集する必要がある。setup.py: packages=['mlagents.trainers'], # Required zip_safe=False, install_requires=[ 'mlagents_envs==0.8.0', # 'tensorflow>=1.7,<1.8', # ←ここをコメントをしておく 'Pillow>=4.2.1', 'matplotlib', 'numpy>=1.13.3,<=1.14.5', 'jupyter', :そして、改めて以下を実行して ml-agents のライブラリをインストールする。
cd ml-agents-envs pip install -e . cd .. cd ml-agents pip install -e . cd ..確認のために
mlagents-learnとやってみてちゃんとUnityロゴのアスキーアートが出ていれば成功。
念の為、先ほどのPythonを動かしてみて
import tensorflow as tf sess = tf.Session(config=tf.ConfigProto(log_device_placement=True))で、tensorflow-gpu が正常に動いていることを確認する。(たまにCPUに切り替わってたりするので要注意)
- 投稿日:2019-05-02T00:58:34+09:00
Substance Painter で読み込んだNormal mapの上下が逆転している際の対処法
Substance Painter のNormal map読み込みについて
Substance Painterでは外部で作成したNormal mapをインポートして使う事ができます。しかし、しばしば読み込んだNormal mapのY方向が逆転していることがあったので、この対処方法を共有します。
Normal mapの上下が逆転する原因
Normal mapにはOpenGL方式とDirectX方式があり、Y方向を示すGチャンネルの表現が逆となっています。なおUnityのNormal mapはOpenGL方式です。
Substance Painterでは外部から読み込んだNormal mapをレイヤーにアサインした場合にこの方式を自動で判別しますが、これが間違っている場合に上下が逆に表示されてしまうようです。
Substance Painter での修正方法
Substance Painterでの修正は簡単ですが、設定場所が少しわかりにくいかもしれません。
1.Normal mapイメージを適用したレイヤーのPROPERTIESを開きます
2.Normal欄の右下にある小さな▽をクリックします
3.開いた小ウインドウの二段目右をクリックします(これ以外の設定項目はありません)
4.開いたリストからOpenGL normalかDirect3D Normalの正しく表示される方を選択します
Photoshopでの修正方法
Substance Painterを使わずに単にNormal mapの上下を反転させたい場合は、PhotoshopでNormal map画像のGチャンネルを選択し、イメージ>色調補正>階調の反転とする事で修正できます。Photoshopの場合は画像の上書きが必要ですが、Substance Painterは非破壊で修正できるところが利点です。
まとめ
Normal方向の反転はSubstance Painterのごく基本機能ですが、少しわかりにくい場所にあると感じたので記事にしました。