- 投稿日:2019-05-22T23:34:58+09:00
�UnityでUIをレスポンシブに対応する方針について
こんにちは、ブログ「学生ブロックチェーンエンジニアのブログ」を運営しているアカネヤ(@ToshioAkaneya)です。
UnityでUIをレスポンシブに対応する方針について
UnityのCanvasにはVertical LayoutやHorizontal LayoutといったLayout Groupの機能があります。
Webフロントを経験していた自分はこれをたくさん使ってレスポンシブ対応をするのかと思いましたが、勉強していくと違うことに気がつきました。
Vertical LayoutやHorizontal Layoutは分かりにくいですし、細かい調整が面倒です。
また、デザイナーの方に調整してもらうことも難しくなります。そこで、アンカーやピボットを正しく設定する方針が良いことに気がつきました。
例えば公式にもこのようなドキュメントがあります。
https://docs.unity3d.com/Manual/HOWTO-UIMultiResolution.htmlVertical LayoutやHorizontal Layoutは必要な箇所だけに限るようにした方が良さそうです。
はてなブックマーク・Pocketはこちらから
- 投稿日:2019-05-22T20:52:55+09:00
【Unity】カウントダウンの作り方
概要
このようなよくあるカウントダウンをDOTweenを使って実装した方法を書きました。
環境
Unity 2019.1.3f1
DOTween 1.2.235
コード
using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using TMPro; public class CountDownPlayer : MonoBehaviour { private TextMeshProUGUI textMeshPro; private CanvasGroup canvasGroup; private void Start() { textMeshPro = this.GetComponent<TextMeshProUGUI>(); canvasGroup = this.GetComponentInParent<CanvasGroup>(); PlayCountDown(); } private void PlayCountDown() { var sequence = DOTween.Sequence(); sequence .OnStart(() => UpdateText("3")) .Append(FadeOutText()) .AppendCallback(() => UpdateText("2")) .Append(FadeOutText()) .AppendCallback(() => UpdateText("1")) .Append(FadeOutText()) .AppendCallback(() => UpdateText("START")) .Append(FadeOutText()) .OnComplete(() => Debug.Log("Do something")); } //テキストの更新 private void UpdateText(string text) { InitializeAlpha(); textMeshPro.text = text; } //フェードアウトさせる private Tween FadeOutText() { return canvasGroup.DOFade(0, 1.0f); } //アルファ値の初期化 private void InitializeAlpha() { canvasGroup.alpha = 1.0f; } }補足
ここでは、とある別々のGameObjectが2つあることを想定しています。
1つは空のオブジェクトに
CanvasGroupコンポーネントがアタッチされているだけのGameObjectです。(ここではStartUIという名前を付けます)もう1つは
TextMeshProUGIコンポーネントがアタッチされており、カウントダウンの数字を表示するためのGameObjectです。(ここではCountDownTextと名前を付けます)この2つのGameObjectの関係は親子です。
StartUIが親でCountDownTextが子です。参考
- 投稿日:2019-05-22T16:22:01+09:00
AdMob for Unity の更新でハマったこと
前提
- unity 2018.4.0f1 LTS
- Mobile Ads SDK(Unity)
- Assets/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml
- 旧
<androidPackage spec="com.google.android.gms:play-services-ads:15.0.1">- 新
<androidPackage spec="com.google.android.gms:play-services-ads:17.2.0">現象
Android実機で起動したとたんにクラッシュしました。
見た感じ「起動したハズなのに何も起きない」という体です。
端末側で起動すると、OSが「さっきからクラッシュしてるんだけど?」と言ってきます。必要だったこと
導入案内に「AdMob アプリ ID を設定する」と書かれている通りにする必要がありました。
ご丁寧に「設定しないと17.xではクラッシュする」と書かれています。Assets/Plugins/Android/GoogleMobileAdsPlugin/AndroidManifest.xml<manifest> <application> <!-- Your AdMob app ID will look similar to this sample ID: ca-app-pub-3940256099942544~3347511713 --> <meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="[YOUR_ADMOB_APP_ID]"/> </application> </manifest>
- テスト広告を使う分には、
[YOUR_ADMOB_APP_ID]の部分を直上のsample IDに置き換えて、android:value="ca-app-pub-3940256099942544~3347511713"/>とすればOKです。- 本番広告では、AdMobコンソールで生成された実際のアプリIDにする必要があります。
- 投稿日:2019-05-22T16:00:18+09:00
VRMモデルの視線制御(目の可動範囲)の設定方法
はじめましておぐらです。
今回はVRMモデルの設定で忘れられがちな、目の可動範囲の設定方法をまとめます。目の可動範囲がデフォルト設定のままだと、VRM対応アプリでこんな風に目が動く現象が起こり得ます。
目が動きすぎてちょっと気持ち悪いですね。
これではせっかくのアバターが台無しなので、VRMLookAtBoneApplyerの設定を変えて、目の可動範囲を適切に設定してあげましょう。
公式のドキュメントにもこのコンポーネントについては記載されていますが、こちらは動作確認の仕方などの説明がありません。
https://vrm.dev/univrm/components/univrm_lookat/1. VRMを読み込む
まずはUnity2017か2018で空のプロジェクトを用意し、最新のUniVRMをインポートします。もちろん、VRMを書き出した過去のプロジェクトを開いても構いません。
Unity2019もリリースされていますが、Shaderの仕様がやや変わっているらしく、表示が崩れることがあるので今回はUnity2018.2.21f1を使います。VRMモデルをProjectにドラッグ&ドロップで配置します。
書き出されたPrefabをシーン上に配置しましょう。
同時にCameraやLightもいい感じに設定しておきます。
Cameraはモデルの前に移動、180度回転させてFieldOfViewを小さくしました。
LightはColorを白にし、回転させて前から光がさすようにしています。2. VRMLookAtBoneApplyerを確認する
シーンに置いたモデルを選択して、Inspectorを確認します。
下の方までスクロールしていくと…
ありました。コレです。
Degree Mappingの下にある4つの▶を開きましょう。
この設定値がそれぞれ90と10なら、それは初期設定のまま、という事です。
では、目線の様子を確認しながらいじっていきましょう。3. 目の動きを確認しながらパラメータを編集する
VRMLookAtBoneApplyerの数値をそのまま編集してもいいですが、実際にどう目が動くかはよく分かりません。
実際に目の動きを確認しながら設定しましょう。3-1 VRMモデルが「見る」オブジェクトを配置する
Hierarchyに適当にCubeを生成します。
(※Hierarchyで「何も選択していない状態」でCubeを生成してください。何かが選択されていると選択されたオブジェクトの子に配置されてしまいます。)
適当な位置にCubeが置かれるので、InspectorからTransformを操作してPositionをすべて0、Scaleをすべて0.1にします。すると、Scene上ではモデルの足元にCubeが配置されます。
次に、このCubeをモデルの目の前まで移動させましょう。
3-2 VRMLookAtHeadにCubeを設定する
シーン上のVRMモデルを選択して、Inspentorで
VRMLookAtHeadを探します。
ありました。ここの
Targetに、先程配置したCubeをドラッグ&ドロップで設定します。
3-3 目の動きを確認しながらパラメータを編集する
実行中にCubeの位置を動かすと、モデルの視線がCubeを追うはずです。
Cubeを向かって左端に移動させると、こんな感じになります。
デフォルトでは左目がやや内側に行き過ぎている気がするので、モデルのVRMLookAtBoneApplyerを編集します。
(まだUnityを停止させないでください)内側に向きすぎている、という事は、
Horizontal InnerのCurve Y Range Degreeの値を操作してやればOKです。
10→3にしたら左目がいい感じになりました。
右目もちょっと外に向き過ぎですね。
では次は、
Horizontal OuterのCurve Y Range Degreeを操作します。
10→7にしたらいい感じになりました。
かわいい。OK!今は左右の設定をしました。次は上下の設定です。
Cubeを中央の高い位置に移動させます。
ちょっと上を向きすぎですね。目のハイライトが隠れるとアレなので、もう少し小さい値にしてあげます。
操作するのはVertical UpのCurve Y Range Degree。
10→5にするといい感じになりました。
では最後に、Cubeを移動させて下の方に配置します。
う~ん、カワイクない!
ので、これも調整。残ったVertical DownのCurve Y Range Degree値を操作します。
これも10→5くらいでいい感じになりました。
4. 最終確認をして値を適用する
まだUnityを停止しないでくださいね!
最後に、Cubeをぐるぐる動かして目の動きを確認しましょう。
お疲れ様でした。
最後に、VRMLookAtBoneApplyerに編集した値を適用します。
Unityに慣れた方は分かるかと思いますが、実行中に編集したパラメータは一時的なもので、停止すると編集した値はすべて実行前の状態にリセットされてしまいます。なので、まずは
VRMLookAtBoneApplyerの右上にある歯車アイコンからCopy Componentをクリックして値を保持しておきます。
では、シーンを停止します。
VRMLookAtBoneApplyerを見ると、値がすべて10になっていますね。
でも大丈夫。右上の歯車アイコンからPaste Component Valuesをすることで、値が復活します。
5. VRMファイルを書き出す
これで設定は完了です!
あとはVRMをExportしてお楽しみください!…そういえば、
Curve Y Range DegreeばかりでCurve X Range Degreeの設定は触りませんでしたね。あの90になっていた方のスライダーです。
こちらの値は、見る対象物に視線を向ける速さみたいなものです。値を小さくするほど速くなったかと…(曖昧)
可動域には影響しないので、説明を省きました。スミマセン!Ex. VRoid Studioでの目の可動範囲設定
- 投稿日:2019-05-22T14:25:26+09:00
【Unity】モデルとHMDの位置をキャリブレーションする方法
概要
モデルの頭部とHMDの位置を同じ座標に合わせます。
FinalIKなどを使わない時に,モデルの視点とHMDの視点を合わせたい時に使いました。※注意 CameraRigの位置を動かします。
環境
- Unity 2018.3.14
- SteamVR 2.2
- Unity-Chan
- HTC Vive
大まかな流れ
- Calibrator用のGameObjectの作成
- Caribrator.csの作成
- 1.のGameObjectに,2.のスクリプトをアタッチ
- Caribrator.csにCameraRig, Camera, モデルの頭部を設定
- オフセット値を設定(任意)
- SteamVR_Play_AreaのBorder Thicknessを設定(任意)
Caribratorの作成(1-2)
Hierarchyで右クリックして,CreateEmptyを選択。Calibrator用のGameObjectの作成する。
Projectで右クリックして,C# Scriptの作成。スクリプトは下記にあります。Caribratorの作成(3-4)
Caribrator.csにCameraRig, Camera, モデルの頭部を設定。
CameraRigは,SteamVRの[CameraRig]を設定
HMDEyePosは,[CameraRig]ないのCameraを設定
ModelHeadPosは,モデルの頭部のオブジェクトを設定スクリプトの流れ・仕組み
- CameraRig, Camera, モデルの頭部の座標を取得。
- cキーの入力を待機。
- モデルの頭部の座標からCameraの座標を引いてズレを計算。
- CameraRigの座標に3で計算したズレを加算し,モデル頭部とCameraの座標を一致させる。
コード
Caribrator.csusing System.Collections; using System.Collections.Generic; using UnityEngine; public class Caribrator : MonoBehaviour { /** * CameraRigの位置 */ [SerializeField] Transform cameraRig; /** * HMDの目の位置 */ [SerializeField] Transform hmdEyePos; /** * モデルの頭の位置 */ [SerializeField] Transform modelHeadPos; /** * 微調整パラメータ */ [SerializeField, Range(-0.5f, 0.5f)] float x_offset; //0.01 Unity-ChanのCharacter1_Headを選択したとき [SerializeField, Range(-0.5f, 0.5f)] float y_offset; //0.03 [SerializeField, Range(-0.5f, 0.5f)] float z_offset; //0.11 void Update(){ if(Input.GetKey("c")){ Calibrate(); } } /** * キャリブレーション */ public void Calibrate () { float x = modelHeadPos.transform.position.x - hmdEyePos.transform.position.x + x_offset; float y = modelHeadPos.transform.position.y - hmdEyePos.transform.position.y + y_offset; float z = modelHeadPos.transform.position.z - hmdEyePos.transform.position.z + z_offset; cameraRig.position = new Vector3(cameraRig.position.x + x, cameraRig.position.y + y, cameraRig.position.z + z); // Debug.Log("y: " + y); } }実行結果
カメラの位置
視点
- 投稿日:2019-05-22T13:58:46+09:00
【Unity個人的メモ】Androidプロジェクトをビルド時に出力する。
Gradleで躓いたのでどこに原因があるのか調べたく、
--infoとか--debugとか--stackなどのオプションをつけて検証したかった。Export Project
BuildSettingsのExportProjectにチェックを入れるとAndroidのプロジェクトを出力してくれるらしい
既に他の方の記事もあった
リンク
- 投稿日:2019-05-22T09:05:36+09:00
【Unity】Unity-Chan!(ユニティちゃん)でCS0234エラーが発生したときの調査結果と解決方法
開発環境
- Windows 10
- Unity 2018.3.1f1
事象
Asset Storeから、下記の「Unity-Chan! Model」をすべてImportしました。
「Assets」→「unity-chan!」→「Unity-chan! Model」→「Prefabs」の「unitychan.prefab」を配置したとき、下記のエラーが発生しました。
Assets\unity-chan!\Unity-chan! Model\Scripts\AutoBlink.cs(8,23): error CS0234: The type or namespace name 'Policy' does not exist in the namespace 'System.Security' (are you missing an assembly reference?)該当するソースコードを確認すると、
型または名前空間の名前 'Policy' が名前空間 'System.Security' に存在しません (アセンブリ参照があることを確認してください)。 (CS0234)
メッセージの通りですが、System.SecurityにPolicyが存在しないため、エラーになっています。解決方法
多くの場合、System.Security.Policyのクラスを利用していないため、using節からSystem.Security.Policyを削除することで対処できるとのこと。
調査してみた&解決方法その2
Unity公式?キャラクターのアセットがエラーしているのは、自分の設定などの問題では?というモヤモヤが消えなかったので、頑張って調べてみました。
とりあえず、Import漏れ、欠落などを疑いましたがそんなことはなさそうでした。
(そもそもスクリプトの問題の時点で、関係なさそうですが…)「C# System.Security」でググったところ、MS公式のドキュメントが出てきました。
System.Security Namespace
ここで、そもそもUnityで.NETのバージョンを意識したことがないことに気が付きました。「Edit」→「Project Settings」→「Player」の
Other Settings、ConfigurationsのApi Compatibillity Levelが.NET Standard 2.0になっていました。
これを.NET 4.xに変更しました。これでも、エラーが出なくなりました。
おわりに
自分が調査して見つけた解決方法が正しいのか分かりません。
解決方法が間違っていたら、教えてください…参考文献
Unityちゃんのインポート
"error CS0234: The type or namespace name 'Policy' does not exist in the namespace 'System.Security'" エラーが発生する (Unityプログラミング)
- 投稿日:2019-05-22T06:41:17+09:00
【Unity】 AudioManagerの作り方
解説
https://youtu.be/0cms8lI8XEAAudioManager.csusing System.Collections; using System.Collections.Generic; using UnityEngine; public class AudioManager : MonoBehaviour { [SerializeField] AudioClip[] seList; AudioSource audioSource; static AudioManager Instance = null; // staticをつけると別のファイルからでもアクセスできる public static AudioManager GetInstance() { if (Instance == null) { Instance = FindObjectOfType<AudioManager>(); // AudioManager.csのついたオブジェクトを探して代入する } return Instance; } private void Awake() { if (this != GetInstance()) { // 探してきたオブジェクトが自分自身じゃなければ破壊する(AudioManager.csのついたオブジェクトは1つのみになる) Destroy(this.gameObject); return; } audioSource = GetComponent<AudioSource>(); DontDestroyOnLoad(this.gameObject); } public void PlaySound(int index) { audioSource.PlayOneShot(seList[index]); } }利用方法
・
seListに音源を設定
・音を鳴らしたい場所でAudioManager.GetInstance()PlaySound(0)のコードを書く
- 投稿日:2019-05-22T00:37:12+09:00
UnityでSQLiteをAndroid(64bit対応)向けに導入する
概略の手順
- 公式サイトから最新版を取ってきます。
- パッケージ内のプラグイン名に合わせてDllImportの引数を書き換えるか、逆にAARパッケージ内のプラグイン名を変更します。
- AARパッケージのままで、"Assets\Plugins\sqlite3\Android"とかに配置します。
留意点
- AARパッケージはZIPファイルなので、ファイル名を「sqlite-android-xxxxxxx.aar.zip」などと変更することで内部にアクセスできます。
- パッケージからフォルダ構造ごとファイルを取り出してAssetフォルダに配置することも可能ですが、そのままのファイル名だとビルドの際にUnityの同名チェックに引っかかります。
- 投稿日:2019-05-22T00:10:15+09:00
"Screen Space - Overlay"なCanvasのuGUI要素が、Orthographicなカメラで3Dオブジェクトの背後に隠れてしまう
前提
- unity: 2017.4.27f1、2018.4.0f1
- unity Asset Store: Alpha Mask
状況
- "Screen Space - Overlay"なCanvasに配置したAlpha Maskを施したImageが、Orthographicなカメラで3Dオブジェクトの背後に隠れてしまいます。
- カメラがPerspectiveだと正しく表示されます。
- Android向けにビルドして実機で実行したときに発症し、PC向けビルドでは発症しません。
- エディタでは起きたり起きなかったりしますが、条件は特定できていません。
課題
- カメラのOrthographic/Perspectiveに拠らず、マスクされたuGUIの画像が、3Dの前面に表示されるようにしたいです。
結論
- Alpha Maskに含まれる2D用シェーダ(Sprites-Alpha-Mask-WorldCoords.shader)中の、"ZWrite Off"と書かれている辺りに1行追加して、"ZTest [unity_GUIZTestMode]"を加えることで解決可能です。
"unity_GUIZTestMode"は、マニュアルに記述が見つけられなかったのですが、この辺りに拠れば「Canvasのタイプに応じて適切な値になる(Screen Space - OverlayならAlways)」もののようです。
解決までに試したこと
- unityのバージョンを変えて試しました。
- unityのプロジェクト設定(品質やグラフィック)を色々試しました。
- Alpha Maskの開発元に問い合わせました。
- (解決したことも報告しましたが、現時点までには何も返信ありません。)
- Alpha Maskのシェーダを標準のUI用シェーダ(UI-Default.shader)と比較して、相違点をひとつずつ変更して試しました。
- 投稿日:2019-05-22T00:10:15+09:00
"Screen Space - Overlay"なCanvasのuGUI要素が、Orthographoicなカメラで3Dオブジェクトの背後に隠れてしまう
前提
- unity: 2017.4.27f1、2018.4.0f1
- unity Asset Store: Alpha Mask
状況
- "Screen Space - Overlay"なCanvasに配置したAlpha Maskを施したImageが、Orthographoicなカメラで3Dオブジェクトの背後に隠れてしまいます。
- カメラがPerspectiveだと正しく表示されます。
- Android向けにビルドして実機で実行したときに発症し、PC向けビルドでは発症しません。
- エディタでは起きたり起きなかったりしますが、条件は特定できていません。
課題
- カメラのOrthographic/Perspectiveに拠らず、マスクされたuGUIの画像が、3Dの前面に表示されるようにしたいです。
結論
- Alpha Maskに含まれる2D用シェーダ(Sprites-Alpha-Mask-WorldCoords.shader)中の、"ZWrite Off"と書かれている辺りに1行追加して、"ZTest [unity_GUIZTestMode]"を加えることで解決可能です。
"unity_GUIZTestMode"は、マニュアルに記述が見つけられなかったのですが、この辺りに拠れば「Canvasのタイプに応じて適切な値になる(Screen Space - OverlayならAlways)」もののようです。
解決までに試したこと
- unityのバージョンを変えて試しました。
- unityのプロジェクト設定(品質やグラフィック)を色々試しました。
- Alpha Maskの開発元に問い合わせました。
- (解決したことも報告しましたが、現時点までには何も返信ありません。)
- Alpha Maskのシェーダを標準のUI用シェーダ(UI-Default.shader)と比較して、相違点をひとつずつ変更して試しました。













































