20200924のUnityに関する記事は6件です。

UnityでVisual Stadio Codeをデフォルトエディターに設定する

Visual Studio Codeインストール
ダウンロード

拡張機能の追加
左ナビのアイコンから検索

  • C#
    スクリーンショット 2020-09-24 20.41.42.png

  • Debugger for Unity
    スクリーンショット 2020-09-24 20.42.10.png

Visual Studio CodeをUnityのエディターに設定

  • Unityを起動して環境設定を開く(ショートカット: ⌘ + ,
  • External Tools > External Script Editor > Visual Studio Codeを選択

[備考]Visual Studio Codeで補完が効かない場合

  • Visual Studio Codeを起動して環境設定を開く(ショートカット: ⌘ + ,
    スクリーンショット 2020-09-24 21.00.06.png
  • 検索欄に useGlobalMonoと検索 スクリーンショット 2020-09-24 21.01.18.png
  • Omnisharp:useGlobalMonoalwaysにする スクリーンショット 2020-09-24 21.01.25.png
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unityのバージョンで躓いたOculusQuest開発

1.はじめに

技術研究として2019年12月に実装された、OculusQuestのハンドトラッキング技術を用いた開発を行いました。
環境構築の部分で躓いてかなり時間を持ってかれたので備忘録としてまとめようと思います。
ちなみに開発したものはこちら ↓
https://lab.taki.co.jp/virtual-cube-puzzle/

2.開発環境

・Windows10
・Unity
・OculusLink
・AndroidSDK
・JDK

基本部分はググれば先人の方々がまとめてくださっているものがたくさんあるので最初はそちらを見るといいと思います。
それらを読んで上手くいけば万々歳です。
私は下記の記事を参考にさせていただきました。
躓いた部分以外は記事の内容の手順で上手くいきました。
https://framesynthesis.jp/tech/unity/oculusquest/
https://qiita.com/Kujirai_sakananosuke/items/f88e757eb7c70cdb1e4e

3.躓いた部分

タイトルにも書いた通りUnityのバージョン関係で躓きました。
公式のサイトには推奨バージョンは2018.4 LTSまたは2019.3と記載されていました。
私もそれに沿って開発を始めたのですが手のオブジェクトが表示されなかったり、ビルドエラーを吐かれたりで全く上手くいきませんでした。
調べると色んな人が色んなバージョンで上手くいっていてどれが正しいのかわからず困りました。
ビルドができる+ハンドトラッキングの開発ができる+OculusLinkで実機確認ができるという3点が必要だったのですが、調べて出てきたバージョンでは3点完璧に上手くいくバージョンはありませんでした。
もう片っ端から試すしかねぇとなりヒーヒー言いながら色んなバージョンで確認して見つけました。

Unity2019.4.3f

3点全部上手くいきました。
やっと落ち着いて開発を始めることができました。

4.まとめ

ググった時に色んなバージョンでの開発の情報があるのは使用機材によって変わるからなんでしょうか。
Unityに不慣れなのもありますが、今回のVR開発で環境構築が一番疲れた気がします。
もしかしたら他の人では2019.4.3fで上手くいかないのかもしれませんが、誰かのお役に立つかもと思い記事を書きました。(こうしてまた1つ迷わせる情報が増えたのかもしれない…)

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

Unity iOSの内部フォルダの保存、閲覧する方法

はじめに

UnityでiOSの「フォルダ」アプリに保存したい場合の方法について記述します。実装方法よりXcodeの設定方法がメインとなります。

実装について

UnityのApplication.persistentDataPathを使用します。
永続的なデータを保存する場所として用意されているパス先です。

一点気をつけたいのが、
iCloudバックアップ領域に保存されるので、容量が大きい場合審査に落ちる場合があります。基本的にはiCloudにはバックアップしないという設定をUnityメソッドで呼び出します。SetNoBackupFlagのパス先はバックアップ対象外となります。
余程大きくなるなら大人しくサーバにあげましょう。あくまで内部フォルダです。

using UnityEngine;
using System;
using System.IO;

public class save : MonoBehaviour
{
    private string _savePath;

    void Start()
    {
        //iCloudバックアップ不要設定
        UnityEngine.iOS.Device.SetNoBackupFlag(Application.persistentDataPath);
        //iOS   : /var/mobile/Containers/Data/Application/<guid>/Documents/Product名/hoge/
        //MacOS : /Users/user名/Library/Application Support/DefaultCompany/Product名/hoge/
        _savePath = Application.persistentDataPath + "/hoge/";
        Debug.Log(_savePath);
        Directory.CreateDirectory(_savePath);

        using (File.Create(_savePath + "test.txt")) {
            //今回は生成のみですが、記述、読込など
        }
    }
}

iOS側では「ファイル」アプリに保存されます。(Xcode設定するまでは見えません)
MacOS側では通常の状態では「ライブラリ」から隠しフォルダ設定になっているので「Command」+「Shift」+ 「.」のショートカットキーで閲覧可能になります。

Xcodeの設定について

展開したXcodeの設定画面で「Info」の中の「Custom iOS Target Properties」に
「Application supports iTunes file Sharing」
「Supports opening documents in place」
を追加してYESに設定します。

スクリーンショット 2020-09-24 11.18.18.png

項目の追加方法は、、、
+や-で追加と削除が行えます。
スクリーンショット 2020-09-24 11.24.32.png

まとめ

取り敢えずの保存はこれでできますが、保存方法はきちんと考えてユーザー側から見えていいデータなのか編集されても問題ないデータかなどを踏まえてお使いください。
データ確認時はいくらでも使って下さい。

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

ScrollView内のボタンが反応しにくい際の対応

ことの発端

Unityで作ったアプリをAndroidの実機で動かしてみたら、著しく反応が悪いボタンがあった。
具体的にはボタンの押下エフェクトは発生するが、押下された判定にならない(ButtonのOnClickメソッドが動かない)。

原因

突き詰めたところ、ScrollViewの中に組み込んだボタンでのみ発生していることがわかった。
ScrollView外のボタンは押下してから指を動かしても、ボタン座標内であれば押下状態が継続されるが、ScrollView内のボタンは押下してから少しでも指を動かすと、押下状態が解除される。
どうやらこれは仕様らしい。こちらの記事を参考にした。
上記は全ての端末で発生する訳ではなく、ハードウェアや機種に依存する問題のようだ。

解決策

該当のボタンに空のEventTriggerを追加するだけで解決した。
EventTriggerを追加することで、ScrollView外のボタンと同じ挙動になった。
ggった時にEventSystemのDragThresholdをいじるなど、色々な方法があったが影響範囲が大きそうだったので別の方法を試してみようと試行錯誤していたら、この方法で治ったというところ。

参考

uGUIのスクロールビューにボタンを並べるとボタンが反応しにくくなる際の対応
ScrollRectの要素にあるボタンのタッチ反応改善について
UnityのScrollRectを拡張しよう

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

C#のActionは途中でExceptionを起こすと中断される

思てたんとちがう!

C#Actionをコールバックのリスナとして利用していたところ「思てたんとちがう!」という挙動があったので、改めて検証しました。
Unity.NET 4.xで実行していますが、C#ならどのプラットフォームでも同じことが起こると思います。

テストコード

テストコード
// コールバック用のリスナー
public event Action OnSomething;

private void Start()
{
    // コールバックをそれぞれ登録
    OnSomething += OnSomething1;
    OnSomething += OnSomething2;
    OnSomething += OnSomething3;

    // イベントを実行
    OnSomething?.Invoke();
}

private void OnSomething1()
{
    Debug.Log("1");
}

private void OnSomething2()
{
    throw new NotImplementedException();
}

private void OnSomething3()
{
    Debug.Log("3");
}

このコードを実行するとこうなります。

ログ
1
NotImplementedException: The method or operation is not implemented.

本来ならばOnSomething1〜3は独立のため、2でExceptionが起きても3が実行されてほしいところですが、出力されていません。

こんな感じでtry-catchしてあげると3も実行されます。

try-catch
private void OnSomething2()
{
    try
    {
        throw new NotImplementedException();
    }
    catch (Exception e)
    {
        Debug.LogException(e);
    }
}
ログ
1
NotImplementedException: The method or operation is not implemented.
3

何が怖いか

「コールバック公開しておくから、誰でも好きにイベント登録しといてくれよな!」というのがわりと一般的な使い方と思いますが、この挙動だと「他のところで登録した誰かがthrowしたら自分のところにイベントが来なくなる(しかもそれを知ることすらできない)」というなかなか恐ろしいことになります。

C#Actionは他にもラムダ式でイベント登録すると解除できなかったり、いろいろ「コワ〜」な挙動が多いです。それすらもなかった昔よりはマシになっているだろうと言われればそうなのですが……。

なにはともあれ、良い子はイベント購読側で、イベントを購読しているという状態をインスタンスとして保持・破棄できるReactiveExtensionとかUniRx使おうね!1 という話でした。

おしまい。


  1. とはいえRxもまだ人類には早すぎる代物感がある。 

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

inputFieldのTMP版をスクリプトで使う方法。

最終的にはこんな感じになる。
ezgif.com-video-to-gif.gif

テキストメッシュプロで日本語が使える設定などは各自で済ませておいてください。
それについては参考になるようなサイトを貼っておきます↓
TextMeshProで日本語フォントを使用する【Unity】

では早速始めにCreate→UI→InputField - TextMeshProを選択。
その後空のゲームオブジェクトを作る。

“shot” 2020-09-24 0.01.34.png

次に新しくスクリプトを作る。
スクリプトの名前はなんでもよし。
スクリプトを作成したら

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

のusing〜と書いてあるところに

using TMPro;

を追加する。

その後「TMP_InputField」型の変数を宣言。↓のように書く。
ここでは変数の名前を「_inputField」としている。

public class Textscript : MonoBehaviour
{

    TMP_InputField _inputField;

    void Start()
    {

その後Startの中でInputField (TMP)のゲームオブジェクトを探し、そこに「TMP_InputField」をGetComponentする。

    void Start()
    {
        _inputField = GameObject.Find("InputField (TMP)").GetComponent<TMP_InputField>();


    }

その後「public」で「InputName」という関数を作ります。
↓関数の中身も含めこんな感じです。

    public void InputName()
    {
        string name = _inputField.text;
        Debug.Log(name);

        _inputField.text = "";
    }

中身の説明としてstring型のnameという変数に、先ほど作った「TMP_InputField」型の「_inputField」という変数の中のtextを入れる。
そしてDebug.Log(name)でコンソールに出力。
という感じ。
ここまでのスクリプトの全体を貼っておきます。

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

public class Textscript : MonoBehaviour
{
    TMP_InputField _inputField;

    void Start()
    {
        _inputField = GameObject.Find("InputField (TMP)").GetComponent<TMP_InputField>();
    }

    void Update()
    {

    }

    public void InputName()
    {
        string name = _inputField.text;
        Debug.Log(name);
    }

}

スクリプトはここまでで、作り終わったら先ほど作った空のゲームオブジェクトにこのスクリプトを貼っつける。

そしたら「InputField (TMP)」のインスペクタービューの「On End Edit(String)」の「+」を押し、「None」の部分にスクリプトがついている空のゲームオブジェクトをドラッグ。
右に色々選択できるところがあるので、そこで先ほど作ったスクリプトの名前を探し、その中に先ほど作った関数「InputName」があるのでそれを選択。
そうするとこうなる↓。

“shot” 2020-09-24 0.05.19.png

以上。
一番上のGIF画像みたいに入力した文字がコンソールに出力されるはず。

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