20200331のUnityに関する記事は7件です。

【爆速メモ】コンポーネントにヘルプボックスを出したい(unity)

コンポーネントにヘルプボックスが表示されていると非常にわかりやすいですよね。
自分はわかりやすいです。
たぶん一週間後の自分とかが非常に助かると思います。
a05.png

なので、自分でもコピペして使えるよう爆速しています。


まずはスクリプトを2つ作ります

ひとつは、コンポーネントをカスタマイズする用
(InspectorのEditの意でテスト命名しました)
a01.png

ふたつめは、普段どおりのスクリプト
(みんな大好き、当記事で好評のxyzの数値入力で自動回転する用のスクリプトです)
a02.png


【コンポーネントをカスタマイズする用のスクリプトはこんなかんじ】
(今回だと、InsEdit.csで作ったやつ)
はじめてさわる場合(自分がそうだった)、ものびへいばーが、えでぃたーに変わったり、
ぱぶりっく おーばーらいど とか書く必要があったり、
そもそも対象のスクリプトと双方向で指定し合う必要があるので、

そのあたりは、「自分はいま、なんのスクリプトを書いているんだろう?」の認識が求められます。

using UnityEngine;
using UnityEditor;

[CanEditMultipleObjects]
[CustomEditor(typeof(autorot))]
public class InsEdit : Editor
{
    public override void OnInspectorGUI()
    {
        //ヘルプボックスを表示 
        EditorGUILayout.HelpBox("x,y,zの数値入力で自動回転します", MessageType.Info);

        base.OnInspectorGUI();

        GUIStyle style = new GUIStyle(EditorStyles.label);
    }
}


【autorot.csは、カスタマイズするので少し追記するところがあります】

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[AddComponentMenu("InsEdit")]
public class autorot : MonoBehaviour
{
    public float Rot_x;
    public float Rot_y;
    public float Rot_z;

    void Update()
    {
        transform.Rotate(Rot_x, Rot_y, Rot_z);
    }
}

【できあがり】
a04.png


カスタム元の自動回転は、こちらの記事からどうぞ!!

【unity】x,y,zを数値入力すれば、ひたすら自動回転するオブジェクトであそぼう
https://qiita.com/sanpeita/items/96b937f3bfcf93382852

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

【Unity】EditorWindowのUpdate()とOnInspectorUpdate()の使い分け

前提

  • EditorWindowでポーリングがしたかった
    • 特定のファイルを監視し、変化があったら何かする
  • EditorWindow.Update() は呼び出し間隔が良くわからない
    • Called multiple times per second on all visible windows. って。。。
  • EditorWindow.OnInspectorUpdate() は10fpsって明言されてるぞ
    • あれ?呼び出されない条件がある。。。

調べてみた

  • というわけで、調べてみた
TestWin.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class TestWin : EditorWindow {
    [MenuItem("Window/TestWin")]
    static void Init()
    {
        TestWin window = (TestWin)EditorWindow.GetWindow(typeof(TestWin));
        window.Show();
    }
    private double[] ilog;
    void DumpFps(string label)
    {
        if (ilog == null || ilog.Length <= 1)
        {
            ilog = new double[10];
        }
        if (ilog.Length > 1)
        {
            double total = 0;
            ilog[ilog.Length - 1] = EditorApplication.timeSinceStartup;
            for (var i = 0; i < ilog.Length - 1; i++)
            {
                total += ilog[i + 1] - ilog[i];
                ilog[i] = ilog[i + 1];
            }
            Debug.LogFormat("{0}:{1}:{2}", System.DateTimeOffset.Now.ToString(), label, 1 / (total / (ilog.Length - 1)));
        }
    }
    private bool _onIns = true;
    private bool _onUpdate = false;

    private void OnGUI()
    {
        _onIns = GUILayout.Toggle(_onIns, "OnInspectorUpdate");
        _onIns = !GUILayout.Toggle(!_onIns, "Update");
        _onUpdate = !_onIns;
    }
    /// <summary>
    /// およそ6.5FPSで安定(2017.4.37)
    /// バックグラウンドになると止まる
    /// 画面がロックされていても止まる
    /// </summary>
    private void OnInspectorUpdate()
    {
        if (_onIns) DumpFps("OnInspectorUpdate");
    }

    /// <summary>
    /// 環境で可変。150だったり250だったり
    /// バックグラウンドになると10前後に落ちる
    /// 画面がロックされていても反応する
    /// </summary>
    void Update () {
        if (_onUpdate) DumpFps("Update");
    }
}
  • これを、Assets/Editor以下に作成して、Window/TestWinで起動

結果

FPS 特徴 確認したVer
Update() 150-250 常に動く。フォアグランド状態では激しく動く 2017.4.37
Update() 10 バックグラウンドや、画面ロックの場合FPSが下がる 2017.4.37
OnInspectorUpdate() 6.5 フォアグランド以外では停止する 2017.4.37

結論

  • 私の用途だと、Update()が良い
    • ただ、250fpsはちょっと多すぎなので、EditorApplication.timeSinceStartupを利用して1fpsにしてポーリングすることにした

参考

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

はじめに

Qiitaを始めた理由

簡単に言えば、メモ代わり。
メモを書くだけで他の方にも評価されたりするって結構便利じゃないか。(^▽^)/

……すいませんそれだけじゃないです。後輩がブログやってると聞いて、なんか負けたくなかったんです。

主に投稿すること

1. Unityについて
 サークルでUnityを使っていて分からないところが多々ある。(後輩にすら知識で負けた)
 そのたびに調べてたけど、面倒なので自分の使う分だけまとめてみよう!(≧▽≦)
 自分の書いた文の方が、自分で構成を練っている分読みやすいと感じるからね。

2. C#について
 理由は至極単純なもので、UnityでC#を使っているから。
 もしも、明日からC#禁止令なるものが出たら、掌を返して別の言語の話を書きなぐる!( ;∀;) 

3. 競技プログラミングについて
 AtCoderは楽しいぞい!
 C#で競技プログラミングの記事を書いている人は少ないから、需要があまりないのかもしれない。
 関係ねえ!私は書くぞ! だってこれメモ代わりなんだもん。( `ー´)ノ

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

Unity The referenced project does not exist が出てた件(メモ)

Qiitaで公開するレベルではない文章だけど、同じエラーにハマってる人へ

現段階(3月31日)であれば、UnityのVisualCodeEditorのバージョンを1.2.0にすればでなくなった
以下、雑感

1.経緯

1月末くらいにUnityを開いて2019.3.0f6にしたところ、VisualStudioCode側で大量の

The referenced project does not exist

が出ていた。情報的には、UnityのVsCodeEditorのバージョン1.1.4が悪さをしているように見えた。
1.1.3にダウングレードしたらなおった、というのもあった。
私のほうは治らず、八方塞がり。

別件(GAS)を調べることもあったため、すっかり後回しにしてた。

2.解決

GASがほぼ片付いたので、そろそろ解決してるだろう、とUnityで新しいデモプロジェクトを開くとプロジェクトのバージョンアップ後、やはり大量のワーニング。

これがでると、コードヘルプに支障がでるので、やはり調査しなきゃ、と検索をかける

どうも、どのバージョンとどのバージョンなら動いた、という情報はあれど、その場限りの解決歩法のようだ

明らかに、2つのアプリで、プロジェクトファイルの扱いに差異があるために発生している問題なので、
VisualCodeEditor側が更新されれば修復するはず

というわけで、最新バージョンである、1.2.0に変更したらワーニングは収まった。
ウィンドウ→PackageManager

VisualStudioCode.png

Unity側のバージョン変更に伴う問題なので、プロジェクト進行中はバージョンをなかなか変更しないので、問題は大きくならないけど、新バージョンが出ると、Unityを開くたびにバージョンアップしろ、と言われる

もはやUnityは単体で動くものではないので、使う側も気をつけないと余計な時間をとられちゃうますな。

3.ついでに

今回は、2D IsoTilemapsのサンプルプロジェクトを開きたかったんだけど、上のエラーのほかに、

GameObjectBrush.cs
  if (PrefabUtility.GetPrefabType(go) == PrefabType.Prefab)

の部分がObsoleteだったので、エラーメッセージの言われるままに以下のように修正。

GameObjectBrush.cs
  if(PrefabUtility.GetPrefabInstanceStatus(go) != PrefabInstanceStatus.NotAPrefab)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Unity]コルーチンの中で他のコルーチンが動作完了するまで待つ

yield return コルーチン
コルーチンを動作させ、そのコルーチンが動作完了するまで待つ。

sample
IEnumrator sample() {
   yield return ShowStageTitle();
   yield return CountDown();
   GameStart();
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【blender2.8】操作UIでイラついたら見る記事[随時追加]

スクリーンショット 2020-01-02 0.21.30.png

はじめに

  • blender2.8を始めて3ヶ月くらいです
  • 操作UIでイラついてたけど解決せずに我慢してきた部分が、だんだん解消してきているので解決したことをメモっていきたいと思います

環境

  • blender2.8
  • macOS Catalina

イラついたことと解決策

1. 操作のビューを拡大する際に、なぜか固まる

  • 固まってると見せかけて、これ以上拡大できない感じになっていることがあります。イラつきます> <
  • 十分近づいてから操作したいのに...もっと拡大したい!ってことがよくあります

<解決策>

  • こちらの記事などを読みながら、なんとなく問題を把握します
  • blenderでのスクロール時の拡大縮小は、ある一点に対しての拡大縮小調整であることがわかります
  • 故に、その一点(原点)に対して最大限近づいてしまった時は、それ以上拡大できなくなるのです
  • そこで、この原点を任意の場所に動かせればいいとわかります
  • (これは経験則ですが)拡大縮小の原点は、スクロールボタン押下(面移動っぽいやつ)操作で切り替わるみたいです

つまり、上の問題に対しては面移動で原点切り替えすることで対処できます!

2. 操作のビューを拡大縮小する際に、よくわからん方向に拡大縮小される

<解決策>

  • おそらく、viewをロックしちゃってることが原因です
  • 編集画面の右側の「View」というタブの中からView>View Lockと進み、「Lock to 3D Cursor」にチェックがついていないか確認してください

これですね↓
スクリーンショット 2020-03-31 12.22.25.png

3. 編集していたオブジェクトを見失う

迷子になるってやつですね、オブジェクトは存在するはずなのに...と、ほんと泣きそうになります(笑)

<解決策>
- この記事などをまず試す
- それでもダメなら、カメラをロックしてる問題の可能性もあります(その場合、問題2と同じ解決策でいけます)

まだまだあるのですが、とりまこの辺りで。
随時追加していきます!!

参考

Blenderでカメラ移動時にズームができなくなる問題の対処方法
Tips:3Dビューで迷子にならないためには

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

ゲームの状況に合わせて音のエフェクトの掛かり具合を変える その2

この記事は「ゲームの状況に合わせてサウンドエフェクトのかかり具合を変える」https://qiita.com/Takaaki_Ichijo/items/957dd09112b9939ff083
の続編です。

また、本記事はサウンドミドルウェア「CRI ADX2」及びAtom Craftの触り方をある程度理解している方向けの解説です。
初めてADX2を使う、という方は各エンジンへの導入の記事を先に参照ください。

Unity: Unityのサウンド機能をADX2で強化する
https://qiita.com/Takaaki_Ichijo/items/16e6501fc07f5b3b3377

UE4: ADX2 for UE4の導入で、一歩上のサウンド表現を(導入編)
https://qiita.com/SigRem/items/4250925f6d66a4fd287a

音を変化させる対象がゲーム内にたくさんある場面を考える

前回の記事では、ADX2のキューに複数の「ラベル」を指定し、「ラベル」によってエフェクト設定を切り替える「セレクタラベル」機能について紹介しました。
スクリプト側でこまかいエフェクトの設定を変えることなく、あらかじめAtom Craft側でエフェクト設定を作り込んでおいて、名前でそれを指定するアプローチです。

前回の記事では「銃の音」に「リバーブをかける / かけない」を設定するものでした。セレクタラベルによる切り替えを実行するには、キュー再生時にどのラベルで再生を行うか指定する必要があります。

ですが、たとえばゲーム中で場面が「屋外」から「室内」に切り替わり、効果音やセリフすべての設定を一斉に変えたいとします。

「セレクタラベル」を使って一つ一つのキューにラベルを指定する方法も使えなくはないですが、「ゲーム変数」という機能を使えば一括で切り替え指定ができます。

ADX2側に「ゲームの状態」変数を作り、自動的にエフェクトがかかるようにする

自前でコーディングする場合のアプローチでは、「今ゲーム内の状況がどうなっているか」のステートをenumなどで保持しておき、音の再生時にそのパラメーターを判定して「この音を鳴らす」「このエフェクト設定で鳴らす」といったような切り替えが必要になります。

ADX2の「ゲーム変数」機能を使うことによって、ゲーム状況の情報をADX2のランタイム側で持たせておき、キュー再生時にその情報を参照して自動的にならす音を切り替えることができます。ゲーム変数は0から1までの値として管理されています。

「セレクタラベル」がキューそれぞれの設定値だったことと対照的に、「ゲーム変数」はADX2のシステムでグローバルな値で、すべてのキューから参照できます。

実際にツールを使って設定を見ていきましょう

例:洞窟に入ったシーンですべての効果音のエフェクトを変える

前回の記事で作成した「セレクタラベルを使って音を切り替える」処理を、ゲーム変数を使って切り替える形に作り替えてみます。

ゲーム変数の新規作成

まずはAtom Craftのプロジェクトツリーから「ゲーム変数」を選び、設定に使うゲーム変数を作成します。右クリックから「新規オブジェクト -> ゲーム変数の作成」を選びます。

新期ゲーム変数の作成.png

ゲーム変数が作られるので、名前を「Cave」などに設定します。
この「Cave」の数値をキューが参照し、音が自動的に切り替わる設定をしていきます。

キューへゲーム変数設定を適用する

キューを「ゲーム変数」に応じて変化させたい場合、キューのシーケンスタイプ(トラックをどのような処理で鳴らすか)を「スイッチ」に変更させる必要があります。
※図のキューの設定は前回記事を参照

スイッチに変更.png

次に、キューのインスペクターのスイッチ設定で、スイッチ変数を先ほど作成した「Cave」に指定します。

スイッチ変数にゲーム変数を指定.png

ゲーム変数は0から1の数値を持ちますが、その値に応じてどのトラックが再生されるかを設定します。
デフォルトでは、トラックの上から順に等分で鳴らすトラックが指定されます。
この例では2トラックありますので、0から0.5が1段目のトラック、0.5から1が2段目のトラックの再生になります。

つまり、ゲーム変数Caveの値を0にすれば1段目のトラックが、1にすれば2段目のトラックが再生されます。

ゲーム変数を変えながらプレビュー再生する

では、このキューを鳴らしながらゲーム変数を変えるとどうなるかツール上で試してみます。

メニュー -> 表示 -> セッションウィンドウをクリックし、セッションウィンドウを開きます。

セッションウィンドウ.png

左上の「ゲーム変数」タブをクリックすると、最初に登録したゲーム変数の数値を変えるスライダーが表示されます。チェックボックスをクリックしてスライダーを有効にし、「0」のときと「1」のときのキューの聞こえ方を比べてください。

セッションウィンドウでゲーム変数をテスト再生する.png

スイッチはADX2のAISAC機能と異なり、再生開始時にのみゲーム変数を参照します。そのため、音声再生中にゲーム変数が変わった場合でも途中で変わったりはしません。
(逆に数値に対してリアルタイムにエフェクトを変えたい場合はAISACを使います)

「ゲーム変数」」を使うメリットは、ゲーム内の状況がたくさんのキューに影響を与えるときに、いちいちキューにステートを指定せずに一括して操作できる点です。

ゲームエンジンでADX2を使う場合のゲーム変数適用方法

Unityの場合

CriAtomEx.GameVariableInfo構造体でゲーム変数を管理します。

ゲーム起動時にランタイム側のゲーム変数をリストとして取得しておき、値を変えたいときにリストを用いてCriAtomEx.SetGameVariableメソッド経由でセットします。

GetGameVariable.cs
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class GameVariableTest : MonoBehaviour
{
    private List<CriAtomEx.GameVariableInfo> gameVariableInfoList = new List<CriAtomEx.GameVariableInfo>();

    //ゲーム開始時にゲーム変数をリストとして取得
    private void Start()
    {
        int gameVariableCount = CriAtomEx.GetNumGameVariables();

        for (int i = 0; i < gameVariableCount; i++)
        {
            CriAtomEx.GameVariableInfo gameVariableInfo;
            CriAtomEx.GetGameVariableInfo((ushort)i, out gameVariableInfo);
            gameVariableInfoList.Add(gameVariableInfo);
        }
    }

    //ゲーム変数の名前でリスト内から検索、値をセット
    public void ChangeGameVariable(string gameVariableName, float value)
    {
        if (gameVariableInfoList.Any(gv => gv.name == gameVariableName))
        {
            var id = gameVariableInfoList.FirstOrDefault(gv => gv.name == gameVariableName).id;

            CriAtomEx.SetGameVariable(id, value);
        }
    }
}

UE4の場合

Set Game Variable by Nameノードを使って値をセットします。

nd_img_CriWareFunctionLibrary_SetGameVariableByName.png

https://game.criware.jp/manual/ue4_plugin/contents/criware_ue4_api_CriWareFunctionLibrary_SetGameVariableByName.html?highlight=%E3%82%B2%E3%83%BC%E3%83%A0%E5%A4%89%E6%95%B0

例2:キャラクターの残りダメージで再生するセリフ音声を切り替える

プレイヤーキャラクターがアクションする際のセリフ音声として「ダッシュしたときの息遣い」「攻撃したときの掛け声」「攻撃を受けた時の声」などを再生する場合を考えてみます。
サバイバルホラーなどでは、臨場感を出すために「ピンチの時は苦しそうにそれぞれの声を出す」という仕掛けを実装したいとします。
例えば最大の体力が100で0になると死んでしまうとして、元気いっぱいなボイスは体力100から40まで、39以降はぐったりした様子のボイスを流して、10切ったぐらいから瀕死ボイスに変化させる。という仕様を考えます。

体力値に応じて再生するセリフ音声を変えれば良さそうですが、そもそも音のバリエーションをプログラムで書き分けなければいけない手間と、たとえば体力が回復した瞬間に一時停止されて解除された場合にどう処理分けするかなど細かな課題があります。

そこでADX2の「ゲーム変数」を使って、プログラム上は同一の再生処理をしつつ、データ側で「体力の変化」を読み取って再生データを自動的に切り替える仕組みを作ります。

ゲーム変数の値と再生トラックの紐づけを変える

数値がいくつのときにどのトラックを再生するか、という割合の設定はインスペクターのスイッチタブから指定できます。

ダメージボイスのゲーム変数による変更.png

この例では、キューAttackedの中に3つ異なる音声素材のセリフデータが入っており、ゲーム変数が0.1までは「大ダメージ中の攻撃を受けた音声」であるHardDamagedAttackedが再生され、0.3までは中ダメージ用のMiddleDamagedAttackedが再生され、0.6からは通常状態のNormalAttackedが再生されます。

重要なポイントは、ADX2側に体力データを送り続けていれば、キューの再生だけで内部の切り替えは自動で処理されるという点です。

セレクタラベルと違ってゲーム変数は0から1までのリニアな数値なので、それぞれのキューに必ず同じ数のバリエーションが必要なわけではありません。他のアクション用ボイスデータに「中ダメージ」にあたる音声素材が無い場合は、0.2あたりで「大ダメージ」と「通常」の2段階のデータにして対応できますし、逆に変化にこだわったキューがある場合は5段階にしたりと、変化の細かさをキューそれぞれで自由に指定できることにも利点があります。

セレクタラベルか、ゲーム変数か?

ADX2には「同じキューのリクエストで異なるトラックを再生する」アプローチにセレクタラベルとゲーム変数の2つの方法があります。また、AISACというパラメーター操作の方法もあります。

セレクタラベルは文字列で明示的に「切り替え」ができる反面、ひとつひとつのキューにその切り替えを行う必要があります。ゲーム変数は一括で切り替えができる反面、参照する値が0から1までのリニアなものになるので、数値がいくつのときに切り替えがされるのか定義する必要があります。

ざっくり方針を作るならば、
・キューひとつひとつにゲーム内状況を与えて音を切り替えたい=セレクタラベル
・たくさんのキューに対して音を切り替えたい=ゲーム変数
・音を再生しつづけながらエフェクトを変えていきたい=AISAC
といった使い分けになります。

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