20191112のUnityに関する記事は8件です。

Unity Scrollbarの使い方

はじめに

ステージ選択の画面など、スクロールバーを使いたい状況になったので
スクロールバーを利用する上でのメモ書きを投稿します。

  • 環境
    • Unity 2019.1.14f1
    • Windows10 1903

ポイント

  • スクロールバーを実装するための要素は3つあります。
    • Content:表示するコンテンツで、スクロールさせたい対象です。
    • Viewport:Cotentをマスクします。Viewportのサイズが表示領域となります。
    • Scrollbar:バーを動かすことで、Viewportの表示領域内をContentが動くようになります。
  • アタッチするコンポーネント
    • Scroll Rect:スクロールバーの制御(Content,Viewport,Scrollbar)を指定する
    • Rect Mask 2D:Viewportにアタッチして表示領域とする。子要素がViewportでマスクされると理解した。

作り方

UIを準備します。

UIのパーツは図のような階層構造にしました。
スクロールバー1.png
UIのパーツの種類とRect Transform は次のように設定しました。

項目 種類 Anchor PosX PosY PosZ Width Height
Panel Panel middle,center 0 0 0 200 100
Viewport Panel middle,center 0 0 0 200 100
Content Panel middle,center 0 -50 0 200 100
Image Image middle,center 0 0 0 100 100
Scrollbar Scrollbar middle,right 0 0 0 20 100

Scrollbar は今回縦方向のスクロールバーを実装したかったので
InspectorウインドウのScrollbarコンポーネントの
Direction を Bottom to Top に変更してください。

UIの完成図をGameウインドウで見ると以下のようになります。
この段階では、ContentパネルがViewportをはみ出しています。
スクロールバー2.png

ViewPort に Rect Mask 2D をアタッチします。

ViewportをInspectorウインドウからAdd Component で Rect Mask 2D を選択してください。
スクロールバー3.png
マスクの効果で、Content が隠されたことを確認できます。

Panel に Scroll Rect をアタッチします。

Panelを選択しInspectorウインドウからAdd Component で Scroll Rect を選択してください。
スクロールバー4.png

Hierarchy ウインドウからContent,Viewport,Scrollbar を指定します。
今回横方向へのスクロールは不要でしたので、Horizontalのチェックは外しました。

以上の手順で、スクロールを確かめることができます。(下までスクロールした図)
スクロールバー5.png

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

[Unity]オーディオクリップ セッティング メモー

Unityマニュアル一通り

Force To Mono

これを有効にすると、マルチチャンネルオーディオはパックする前にミックスダウンされモノラルトラックにされます。
結論:いつ(雑音で?)使われるんでしょう!!! 使ったことありません!(以降もなさそう!x1)

Normalize

これを有効にすると、Force To Mono ミックスダウン処理中にオーディオは ノーマライズ されます。
結論:いつ(雑音で?)使われるんでしょう!!! 使ったことありません!(以降もなさそう!x2)

Load In Background

これを有効にすると、メインスレッドを妨げることなく、クリップの読み込みは別のスレッドで遅延させて行われます。
結論:CPU負荷分担したい時に使えそうです!

Ambisonic

アンビソニックオーディオソースは、リスナーの向きに基づいて回転する音場を表す形式でオーディオを格納します。全天球型のビデオや VR や AR アプリケーションに便利です。オーディオファイルにアンビソニックでエンコードされたオーディオが含まれている場合は、このオプションを有効にします。
結論:立体音声の時に使えそうです!

Preload Audio Data

オンになっている場合、シーンの読み込み時にオーディオクリップもあらかじめ読み込まれます。Unity の標準挙動ではシーンが再生される前にすべての AudioClip が完全に読み込まれるため、通常はオンになっています。このフラグが設定されていない場合、オーディオデータは、最初の AudioSource.Play()かAudioSource.PlayOneShot() か AudioSource.LoadAudioData() で読み込まれて AudioSource.UnloadAudioData() で再び破棄されます。
結論:マニュアル過ち修正 AudioSourceでなく、Audioclip.LoadAudioData()、Audioclip.UnloadAudioData()のはずです。
オン:端末が起動されシーンに入った時読み込まれますが、大量の音声データがある時、起動が遅くなるのが現象です。
オフ:起動負荷はないですが、音声Play()時読み込み解凍でcpu負荷がかかるのが現象でフレームが落ちます。なのでフレーム保持したいアプリとかは、事前に(初期化タイミング?)LoadAudioData()を呼び出しする必要があります。

LoadType

Decompress On Load

オーディオファイルは読み込まれるとすぐに展開されます。サイズの小さい圧縮サウンドにこのオプションを使えば、その場での展開に伴うパフォーマンスのオーバーヘッドを防ぐことができます。ただし、Vorbis でエンコードされたサウンドを読み込み時に展開すると、圧縮されたままの場合の10倍程(ADPCM エンコーディングでは約3.5倍)のメモリーを使用するので、サイズの大きいファイルにはこのオプションを使用しないでください。
結論:大体この設定でいいかもですが、大きいサイズは使えません!(大きいサイズ?これは個人の心の中の基準でしょうか!)

Compressed In Memory

サウンドはメモリ中では圧縮されたままで、再生中に展開されます。このオプションは若干のパフォーマンスオーバーヘッドが発生します(特に Ogg/Vorbis 圧縮ファイルの場合)ので、メモリー使用量が大きすぎて読み込み時に展開できないファイルにのみに使用してください。展開はミキサースレッドで行われ、Profiler ウィンドウ内の Audio ペインにある “DSP CPU” のセクションでモニタリングできます。
結論:音声play()時のcpuの負荷は小さくなるが、パッケージ(apk/ipa)した時のサイズが大量に大きくなります!お勧めしません!

Streaming

サウンドをその場でデコードします。この方式では、圧縮データのバッファーのための使用メモリーが最小限に抑えられます。データはディスクから段階的に読み込まれて必要に応じてデコードされます。展開は別のストリーミングスレッドで行われますが、その CPU 使用量は Pofiler ウィンドウ内の Audio ペインにある “Streaming CPU” のセクションでモニタリングできます。
結論:パッケージ(apk/ipa)した時のサイズがほぼない、cup負荷は分担され Decompress On Loadより小さい

Compression Format

PCM

品質は高くなりますが、ファイルサイズが大きくなります。非常に短い音響効果に最適です。
結論:説明の通りですが、使ったことありません!(以降もなさそう!x3)

ADPCM

この形式は、足音や衝突音、武器などのノイズを多く含んでいて大量に再生される必要があるサウンドに便利です。圧縮率は PCM の3.5分の1ですが、CPU の使用量は MP3/Vorbis 形式に比べ格段に少なくなるため、上記のような種類の音には適しています。
結論:雑音でNormalizeと一緒に使えそうですが、使ったことありません!(以降もなさそう!x4)

Vorbis/MP3

圧縮ファイルは小さくなりますが PCM オーディオに比べると若干クオリティが落ちます。圧縮率は Quality スライダーの調整で可能です。この形式は中程度の長さの SE や音楽に適しています。
結論:参考からAndroidはVorbis、iOSはMP3が最適のようです

Quality

圧縮 クリップに適用される圧縮の度合いを決定します。PCM/ADPCM/HEVAG 形式には適用されません。ファイルサイズに関する情報はインスペクターで確認できます。この値を調整する方法としては、スライダーをドラッグし、ファイルサイズを小さく保ったまま「許容できるレベルの」再生クオリティになるポイントを見つけるのがよいでしょう。(注)Original Size は元ファイルのサイズなので、例えばこれが MP3 ファイルで Compression Format が PCM (非圧縮)に設定されている場合、Ratio は結果として 100% を超える値になります。これは、ファイルが非圧縮で保存されるために元々のソースの MP3 ファイルよりも大きなスペースを取ってしまうからです。
結論:Ratioが100%を超えた時に手動で100%以下に抑えることができるハンドルでしょうか!

汎用まとめ

  • 大体の音源データロードタイプ
    • LoadType=Decompress On Load
  • 大きいすぎて展開できない音源データのみ
    • LoadType=Compressed In Memory
  • 長い音源データロードタイプ
    • LoadType=Streaming
  • 遅延で行われてもよく、cup負荷かけたくない時
    • Load In Background
  • 起動時にロードさせたいが、起動時間長くしたくない時
    • Preload Audio Data
    • Load In Background
  • Compression Format
    • Android : Vorbis
    • iOS : MP3

音声データインポートした時自動設定エディタ拡張

using UnityEngine;
using UnityEditor;

public class UnityAssetImporter : AssetPostprocessor
{
    /// <summary>
    /// 音源データインポートした後呼ばれる
    /// </summary>
    private void OnPostprocessAudio(AudioClip clip)
    {
        var audioimporter = (AudioImporter)assetImporter;
        audioimporter.Setting("iOS", AudioCompressionFormat.MP3, clip.length);
        audioimporter.Setting("Android", AudioCompressionFormat.Vorbis, clip.length);
        audioimporter.preloadAudioData = false;
    }
}
public static class ImpoterUtility
{
    public static void Setting(this AudioImporter importer, string platform, AudioCompressionFormat acformat, float length)
    {
        var setting = importer.GetOverrideSampleSettings(platform);
        setting.compressionFormat = acformat;
        //適当に時間でロードタイプ決める
        if (length >= 5f)
            setting.loadType = AudioClipLoadType.Streaming;
        else
            setting.loadType = AudioClipLoadType.DecompressOnLoad;
        importer.SetOverrideSampleSettings(platform, setting);
    }
}

注意
手動で設定変更した時拡張ファイルも一緒に一回実行されますので注意しましょう!

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

Unity 2019.2でTile Paletteをインストールする方法(表示する方法)

以下の手順でインポートすれば表示される
スクリーンショット 2019-11-12 16.12.34.png
(packageでtileと検索すればこれが出てくるのでインストール)
スクリーンショット 2019-11-12 16.14.57.png

スクリーンショット 2019-11-12 16.15.28.png

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

[Unity] [SkinnedMeshRenderer] Humanoidで使われるMesh

Humanoidで使われるMeshに関する情報をまとめておきます。
Humanoidで使うということでboneへウェイトが塗られていたり, blendShapeが設定されていたりするものを想定しています。
(このようなMeshは毎フレーム、ボーンの変化に対する頂点位置の計算などをする必要があるのでMeshRendererではなく必ずSkinnedMeshRendererに設定されている必要があります)

SkinnedMeshRenderer 公式リファレンス

Mesh

Mesh 公式リファレンス
SkinnedMeshRenderer.meshとSkinnedMeshRenderer.sharedMeshから取得できるが
前者はそのオブジェクト特有のメッシュで、変更しても他に影響がない
後者は変更によって同じメッシュを共有するオブジェクトに影響を与える

これを変更しただけではUnity再起動時に初期化されてしまうので
新しいMeshアセットとして書き出しておく必要があります。

vertices

verticesに頂点の位置(Vector3)が入っている
vertices.Lengthが頂点数

メッシュ内のローカル座標なのでワールド座標として扱いたい場合はTransform.TransformPoint(Vector3 localPosition)で変換する

normals(法線), uvs(uv情報), boneWeights(ウェイト情報)はindexでverticesと対応させている
normals.Length == uvs.Length == boneWeights.Length == vertices.Length

triangles

trianglesはverticesのindex情報を持っている
(3つの頂点で1つのポリゴンとしているため, triangles.Lengthは3の倍数)
([0, 1, 2]や[3, 4, 5]が一つのポリゴン)
Unityでは時計回りがポリゴンの表である

SubMesh

小さなメッシュの単位。1つのSubMeshには必ず1つのマテリアルが適応されている
Meshのマテリアル数==submeshの個数==Mesh.subMeshCount

Mesh.GetIndices(int submesh)で特定のSubMeshに所属する頂点のindex配列を取得できる
(頂点そのものの情報ではない。あくまでMesh.verticesと対応付けられたindex)
SkinnedMeshRenderer.sharedMaterialsで得られるMaterials配列のindexを引数に入れるとそのMaterialsに対応したSubMeshの情報を取得できる
頂点以外にもポリゴン(Mesh.GetTriangles(int submesh))なども取得できる

boneWeights

SkinnedMeshRendererしか持ちえない
boneIndex0~3はSkinnedMeshRenderer.bonesのindex情報を持っている
weight0~3はウェイト情報(0~1)
Mesh.boneWeightsで得た配列を変更した場合元データも変わってしまうため,
元は変更させたくない場合はMesh.GetBoneWeights(List boneWeights)を使う

blendShape

SkinnedMeshRendererしか持ちえない
SkinnedMeshRenderer.blendShapesで取得可能

存在するblendShapeの名前や変化量の変更はできないので
Mesh.ClearBlendShapesで一度削除して
新しい名前や変化量を設定してMesh.AddBlendShapeFrameで作成する必要がある

関連リンク・参考

http://edom18.hateblo.jp/entry/2017/06/09/080802
https://qiita.com/keito_takaishi/items/8e56d5117ee90502e864

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

THETA Vを延長USB+USBハブ有線でUnityしたら動作不良

延長USBなしでは動作していたが

USBハブにバスパワーないタイプだったのが原因か
延長有線したらTHETAでLiveを設定してもカメラモードに勝手に戻ってしまった。。

延長USBしてるのを
PCに直接したら動作した。。

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

Unityでプロジェクトを作成する

はじめに

本章ではUnity Hubでプロジェクトを作成する手順を説明する。

Unity Hubからプロジェクトを作成する

  1. Unity Hubを起動。
  2. [新規作成]をクリック。 01.png
  3. 作成したいUnity のバージョンが表示されるため、バージョンを選択(本環境では単一のUnity Editorしかインストールしていない)。02.png
  4. 新しいプロジェクトの作成画面が表示される。プロジェクト名、テンプレート、プロジェクトの保存先を決定し、[作成]をクリック。 03.png
  5. Unity Editorが起動し、新しく作成したプロジェクトが表示されます。 04.png

Unity Editorからプロジェクトを作成する

  1. Unity Editorを起動。
  2. Unity Editorの上部メニューより[File]-[New Project]を選択します。 06.png
  3. 新しいプロジェクトの作成画面が表示される。プロジェクト名、テンプレート、プロジェクトの保存先を決定し、[作成]をクリック。 03.png
  4. Unity Editorに新しいプロジェクトが表示される。

バージョン

ここで解説するUnity Hubのバージョンは2.1.3.0です
※Unity Hub.exeの[プロパティ]-[詳細]-[製品バージョン]で調べることができる。
05.png

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

[Unity] モデルの特定の場所のテクスチャの色を調べる

モデルの特定場所の色を調べたい場合は、
・モデルにMeshColliderがついている
・Convexがoffになっている
・マテリアルに使用されているメインテクスチャがRead/Wrightableになっている
必要があります。

2019-11-12_003151.png
2019-11-12_004141.png

その状態で
Physics.Raycast()でヒットしたときに返ってくるRaycastHit.textureCoordを調べるとテクスチャの場所(uv)が返ってきます。

かなり特殊な場合になると思いますが、マテリアルにタイリングやオフセットがかかっている場合があります。

2019-11-12_004840.png

そんな時は

Vector2 ofs = m_mat.GetTextureOffset("_MainTex");
Vector2 scl = m_mat.GetTextureScale("_MainTex");
uv = Vector2.Scale(uv,scl);
uv.x = Mathf.Repeat(ofs.x + uv.x,1f);
uv.y = Mathf.Repeat(ofs.y + uv.y,1f);

でuvを補正します。

あとはメインテクスチャの指定個所の色をtex2d.GetPixelBilinear(uv.x,uv.y)で取得します。

gif_animation_004.gif

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

UnityでAdMobを利用する(テスト広告)

はじめに

この内容は Google AdMob を利用してテスト広告を表示し
全体の流れを把握する目的で調査した内容のメモ書きです。

Google AdMob のガイドがわかりやすいので、そちらを参照すれば解決します。
テスト広告表示までのポイントと詰まった個所を投稿します。

  • 環境
    • Unity 2019.1.14f1
    • Windows10 1903

Google AdMob の ガイド

ポイント

  • IDはアプリIDと広告ユニットIDの2つあります。
  • アプリはその名の通り、アプリに対して1つです。(AndroidとiOSは個別に取得)
    • Unityのエディタで登録(Assets > Google Mobile Ads > Settings... )できます。
  • 広告ユニットは、アプリに対して登録できます。(アプリに対して複数登録できます)
    • 広告の種類は4パターンあります。(下のコードはバナー広告)
    • 広告ユニットID は 広告クラスのコンストラクタの引数で指定します(adUnitId)
  • アプリ・広告ユニットはAdMob の管理サイトで管理します
    • 開発目的では、広告ユニットIDはテスト広告専用のIDを利用します。
      • 実際のIDを使った場合は規約違反となるため注意します。

詰まった点

バナー広告のガイドを参照しながら、モバイル広告の初期化 MobileAds.Initialize() に
appId を引数に与えると動作しませんでした。
Assets > Google Mobile Ads > Settings... で指定しており
コードで指定するのも冗長で妙だと思い、スタートガイドの初期化に変更したら正常に動作しました。
(appId を引数として与えるコーディングは古いバージョンのものだろうか?)

using UnityEngine;
using GoogleMobileAds.Api;

public class GoogleMobileAdsDemoScript : MonoBehaviour
{
    private BannerView bannerView;

    // Start is called before the first frame update
    void Start()
    {
        MobileAds.Initialize(initStatus => { });

        this.RequestBanner();
    }

    private void RequestBanner()
    {
#if UNITY_ANDROID
        string adUnitId = "ca-app-pub-3940256099942544/6300978111";
#elif UNITY_IPHONE
        string adUnitId = "ca-app-pub-3940256099942544/2934735716";
#else
        string adUnitId = "unexpected_platform";
#endif

        bannerView = new BannerView(adUnitId, AdSize.SmartBanner, AdPosition.Top);

        AdRequest request = new AdRequest.Builder().Build();

        bannerView.LoadAd(request);
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む