20190522のUnityに関する記事は11件です。

�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.html

Vertical LayoutやHorizontal Layoutは必要な箇所だけに限るようにした方が良さそうです。

はてなブックマーク・Pocketはこちらから

はてなブックマークに追加
Pocketに追加

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】カウントダウンの作り方

概要

CountDown.gif

このようなよくあるカウントダウンを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-22 午後8.41.55.png

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AdMob for Unity の更新でハマったこと

前提

現象

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にする必要があります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VRMモデルの視線制御(目の可動範囲)の設定方法

はじめましておぐらです。
今回はVRMモデルの設定で忘れられがちな、目の可動範囲の設定方法をまとめます。

目の可動範囲がデフォルト設定のままだと、VRM対応アプリでこんな風に目が動く現象が起こり得ます。

Eye_setup01.gif

目が動きすぎてちょっと気持ち悪いですね。
これではせっかくのアバターが台無しなので、VRMLookAtBoneApplyerの設定を変えて、目の可動範囲を適切に設定してあげましょう。
公式のドキュメントにもこのコンポーネントについては記載されていますが、こちらは動作確認の仕方などの説明がありません。
https://vrm.dev/univrm/components/univrm_lookat/

1. VRMを読み込む

まずはUnity2017か2018で空のプロジェクトを用意し、最新のUniVRMをインポートします。もちろん、VRMを書き出した過去のプロジェクトを開いても構いません。
Unity2019もリリースされていますが、Shaderの仕様がやや変わっているらしく、表示が崩れることがあるので今回はUnity2018.2.21f1を使います。

VRMモデルをProjectにドラッグ&ドロップで配置します。
image.png

書き出されたPrefabをシーン上に配置しましょう。
image.png
同時にCameraやLightもいい感じに設定しておきます。
Cameraはモデルの前に移動、180度回転させてFieldOfViewを小さくしました。
LightはColorを白にし、回転させて前から光がさすようにしています。

2. VRMLookAtBoneApplyerを確認する

シーンに置いたモデルを選択して、Inspectorを確認します。
image.png
下の方までスクロールしていくと…
image.png
ありました。コレです。
Degree Mappingの下にある4つの▶を開きましょう。
image.png
この設定値がそれぞれ9010なら、それは初期設定のまま、という事です。
では、目線の様子を確認しながらいじっていきましょう。

3. 目の動きを確認しながらパラメータを編集する

VRMLookAtBoneApplyerの数値をそのまま編集してもいいですが、実際にどう目が動くかはよく分かりません。
実際に目の動きを確認しながら設定しましょう。

3-1 VRMモデルが「見る」オブジェクトを配置する

Hierarchyに適当にCubeを生成します。
(※Hierarchyで「何も選択していない状態」でCubeを生成してください。何かが選択されていると選択されたオブジェクトの子に配置されてしまいます。)
image.png
適当な位置にCubeが置かれるので、InspectorからTransformを操作してPositionをすべて0、Scaleをすべて0.1にします。

image.png

すると、Scene上ではモデルの足元にCubeが配置されます。
image.png

次に、このCubeをモデルの目の前まで移動させましょう。

Eye_setup02.gif
Gameビューはこんな感じ。
image.png

3-2 VRMLookAtHeadにCubeを設定する

シーン上のVRMモデルを選択して、InspentorでVRMLookAtHeadを探します。
image.png
ありました。

ここのTargetに、先程配置したCubeをドラッグ&ドロップで設定します。
image.png

これでOKです。
image.png

3-3 目の動きを確認しながらパラメータを編集する

では、シーンを実行して確認してみましょう。
image.png

実行中にCubeの位置を動かすと、モデルの視線がCubeを追うはずです。
Eye_setup03.gif

Cubeを向かって左端に移動させると、こんな感じになります。
image.png
デフォルトでは左目がやや内側に行き過ぎている気がするので、モデルのVRMLookAtBoneApplyerを編集します。
(まだUnityを停止させないでください)

内側に向きすぎている、という事は、Horizontal InnerCurve Y Range Degreeの値を操作してやればOKです。
image.png
103にしたら左目がいい感じになりました。
image.png

右目もちょっと外に向き過ぎですね。

では次は、Horizontal OuterCurve Y Range Degreeを操作します。
image.png
107にしたらいい感じになりました。
image.png
かわいい。OK!

今は左右の設定をしました。次は上下の設定です。
Cubeを中央の高い位置に移動させます。
image.png

ちょっと上を向きすぎですね。目のハイライトが隠れるとアレなので、もう少し小さい値にしてあげます。
操作するのはVertical UpCurve Y Range Degree
image.png
105にするといい感じになりました。
image.png

では最後に、Cubeを移動させて下の方に配置します。
image.png
う~ん、カワイクない!
ので、これも調整。残ったVertical DownCurve Y Range Degree値を操作します。
image.png
これも105くらいでいい感じになりました。
image.png

4. 最終確認をして値を適用する

まだUnityを停止しないでくださいね!
最後に、Cubeをぐるぐる動かして目の動きを確認しましょう。
Eye_setup04.gif

お疲れ様でした。
最後に、VRMLookAtBoneApplyerに編集した値を適用します。
Unityに慣れた方は分かるかと思いますが、実行中に編集したパラメータは一時的なもので、停止すると編集した値はすべて実行前の状態にリセットされてしまいます。

なので、まずはVRMLookAtBoneApplyerの右上にある歯車アイコンからCopy Componentをクリックして値を保持しておきます。
image.png
では、シーンを停止します。
image.png
VRMLookAtBoneApplyerを見ると、値がすべて10になっていますね。
image.png
でも大丈夫。右上の歯車アイコンからPaste Component Valuesをすることで、値が復活します。
image.png

復活しました。
image.png

5. VRMファイルを書き出す

これで設定は完了です!
あとはVRMをExportしてお楽しみください!

…そういえば、Curve Y Range DegreeばかりでCurve X Range Degreeの設定は触りませんでしたね。あの90になっていた方のスライダーです。
こちらの値は、見る対象物に視線を向ける速さみたいなものです。値を小さくするほど速くなったかと…(曖昧)
可動域には影響しないので、説明を省きました。スミマセン!

Ex. VRoid Studioでの目の可動範囲設定

共通設定を選択し、左のメニューで目の可動域を選ぶと右側にスライダーが表示され、編集することができます。
image.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】モデルとHMDの位置をキャリブレーションする方法

概要

モデルの頭部とHMDの位置を同じ座標に合わせます。
FinalIKなどを使わない時に,モデルの視点とHMDの視点を合わせたい時に使いました。

※注意 CameraRigの位置を動かします。

環境

  • Unity 2018.3.14
  • SteamVR 2.2
  • Unity-Chan
  • HTC Vive

大まかな流れ

  1. Calibrator用のGameObjectの作成
  2. Caribrator.csの作成
  3. 1.のGameObjectに,2.のスクリプトをアタッチ
  4. Caribrator.csにCameraRig, Camera, モデルの頭部を設定
  5. オフセット値を設定(任意)
  6. 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は,モデルの頭部のオブジェクトを設定

スクリーンショット 2019-05-22 12.11.53.png

スクリプトの流れ・仕組み

  1. CameraRig, Camera, モデルの頭部の座標を取得。
  2. cキーの入力を待機。
  3. モデルの頭部の座標からCameraの座標を引いてズレを計算。
  4. CameraRigの座標に3で計算したズレを加算し,モデル頭部とCameraの座標を一致させる。

コード

Caribrator.cs
using 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); 
    }
}

実行結果

カメラの位置

ブログ図.001.jpeg

視点

ブログ図.002.jpeg

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity個人的メモ】Androidプロジェクトをビルド時に出力する。

Gradleで躓いたのでどこに原因があるのか調べたく、
--infoとか--debugとか--stackなどのオプションをつけて検証したかった。

Export Project
BuildSettingsのExportProjectにチェックを入れるとAndroidのプロジェクトを出力してくれるらしい
スクリーンショット 2019-05-22 13.54.17.png

既に他の方の記事もあった
リンク

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】Unity-Chan!(ユニティちゃん)でCS0234エラーが発生したときの調査結果と解決方法

開発環境

  • Windows 10
  • Unity 2018.3.1f1

事象

Asset Storeから、下記の「Unity-Chan! Model」をすべてImportしました。
image.png
「Assets」→「unity-chan!」→「Unity-chan! Model」→「Prefabs」の「unitychan.prefab」を配置したとき、下記のエラーが発生しました。
image.png

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?)

該当するソースコードを確認すると、
image.png

型または名前空間の名前 'Policy' が名前空間 'System.Security' に存在しません (アセンブリ参照があることを確認してください)。 (CS0234)

メッセージの通りですが、System.SecurityにPolicyが存在しないため、エラーになっています。

解決方法

多くの場合、System.Security.Policyのクラスを利用していないため、using節からSystem.Security.Policyを削除することで対処できるとのこと。

実際に消してみると、エラーはなくなりました。
image.png
image.png

調査してみた&解決方法その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になっていました。
image.png
これを.NET 4.xに変更しました。

これでも、エラーが出なくなりました。

おわりに

自分が調査して見つけた解決方法が正しいのか分かりません。
解決方法が間違っていたら、教えてください…

参考文献

Unityちゃんのインポート
"error CS0234: The type or namespace name 'Policy' does not exist in the namespace 'System.Security'" エラーが発生する (Unityプログラミング)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Unity】 AudioManagerの作り方

解説
https://youtu.be/0cms8lI8XEA

AudioManager.cs
using 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)のコードを書く

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UnityでSQLiteをAndroid(64bit対応)向けに導入する

概略の手順

  • 公式サイトから最新版を取ってきます。
  • パッケージ内のプラグイン名に合わせてDllImportの引数を書き換えるか、逆にAARパッケージ内のプラグイン名を変更します。
  • AARパッケージのままで、"Assets\Plugins\sqlite3\Android"とかに配置します。

留意点

  • AARパッケージはZIPファイルなので、ファイル名を「sqlite-android-xxxxxxx.aar.zip」などと変更することで内部にアクセスできます。
  • パッケージからフォルダ構造ごとファイルを取り出してAssetフォルダに配置することも可能ですが、そのままのファイル名だとビルドの際にUnityの同名チェックに引っかかります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

"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)と比較して、相違点をひとつずつ変更して試しました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

"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)と比較して、相違点をひとつずつ変更して試しました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む