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

UnityにgRPC導入時に出たエラーと解決

「gRPC」での通信のために、Unityに導入の際に以下の様なエラーが発生!

Error: Could not load signature of Google.Protobuf.ByteString:get_Span due to: Could not load file or assembly 'System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. assembly:System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51 type:<unknown type> member:(null) signature:<none>
Unloading broken assembly Assets/Plugins/Google.Protobuf/lib/net45/Google.Protobuf.dll, this assembly can cause crashes in the runtime

その解決までを書きます。

環境

  • Unity 2019.4.10f1
  • grpc_unity_package.2.33.0-dev
  • macOS 10.14.6

gRPC導入

以下のサイトを参考にUnityでgRPCを使えるようにしました。
gRPCとProtocol Buffersによるアプリケーション間通信 / Unity

すると、Grpc.Toolsとgrpc_unity_packageを追加し、最新のGoogle.Protobuf.dllに上書きした後、
Unityを開くと、Consoleに冒頭に記載したエラーがでました。

エラー内容

同様のエラーはネット上にもあがっており、
Google.Protobuf.dllはversion4.0.1.0 (4.5.2)のSystem.Memory参照してるけど、
Grpc.Coreはversion 4.0.1.1 (4.5.3)のSystem.Memoryを参照してるぞというエラーらしい。
https://github.com/grpc/grpc/issues/21908

grpc_unity_package.2.26.0-devとUnity2019.3.9f1では上手くいくという情報もありましたが、
私のとろこでは駄目でした。

解決策

Google.Protobuf.dllも4.5.3を参照するように変更することで解決できました。

  1. dotnetコマンドを使えるようにする
    https://dotnet.microsoft.com/download

  2. google protobuf sourceを落としてくる
    https://github.com/protocolbuffers/protobuf

  3. フォルダ内の以下を開き、System.MemoryのVersionを4.5.3に変更
    csharp/src/Google.Protobuf/Google.Protobuf.csproj
    <PackageReference Include="System.Memory" Version="4.5.3" />

  4. ターミナルで以下に移動
    csharp/src/Google.Protobuf

  5. コマンド叩く
    dotnet publish -c Release -f net45

  6. 以下にGoogle.Protobuf.dllが作成される
    csharp/src/Google.Protobuf/bin/Release/net45

  7. 作成されたGoogle.Protobuf.dllをUnity内に展開したgrpc_unity_packageの以下のGoogle.Protobuf.dllと入れ替える
    Plugins/Google.Protobuf/lib/net45/Google.Protobuf.dll

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

【Unity】gRPC導入時に出たエラーと解決

「gRPC」での通信のために、Unityに導入の際に以下の様なエラーが発生!

Error: Could not load signature of Google.Protobuf.ByteString:get_Span due to: Could not load file or assembly 'System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. assembly:System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51 type:<unknown type> member:(null) signature:<none>
Unloading broken assembly Assets/Plugins/Google.Protobuf/lib/net45/Google.Protobuf.dll, this assembly can cause crashes in the runtime

その解決までを書きます。

環境

  • Unity 2019.4.10f1
  • grpc_unity_package.2.33.0-dev
  • macOS 10.14.6

gRPC導入

以下のサイトを参考にUnityでgRPCを使えるようにしました。
gRPCとProtocol Buffersによるアプリケーション間通信 / Unity

すると、Grpc.Toolsとgrpc_unity_packageを追加し、最新のGoogle.Protobuf.dllに上書きした後、
Unityを開くと、Consoleに冒頭に記載したエラーがでました。

エラー内容

同様のエラーはネット上にもあがっており、
Google.Protobuf.dllはversion4.0.1.0 (4.5.2)のSystem.Memory参照してるけど、
Grpc.Coreはversion 4.0.1.1 (4.5.3)のSystem.Memoryを参照してるぞというエラーらしい。
https://github.com/grpc/grpc/issues/21908

grpc_unity_package.2.26.0-devとUnity2019.3.9f1では上手くいくという情報もありましたが、
私のとろこでは駄目でした。

解決策

Google.Protobuf.dllも4.5.3を参照するように変更することで解決できました。

  1. dotnetコマンドを使えるようにする
    https://dotnet.microsoft.com/download

  2. google protobuf sourceを落としてくる
    https://github.com/protocolbuffers/protobuf

  3. フォルダ内の以下を開き、System.MemoryのVersionを4.5.3に変更
    csharp/src/Google.Protobuf/Google.Protobuf.csproj
    <PackageReference Include="System.Memory" Version="4.5.3" />

  4. ターミナルで以下に移動
    csharp/src/Google.Protobuf

  5. コマンド叩く
    dotnet publish -c Release -f net45

  6. 以下にGoogle.Protobuf.dllが作成される
    csharp/src/Google.Protobuf/bin/Release/net45

  7. 作成されたGoogle.Protobuf.dllをUnity内に展開したgrpc_unity_packageの以下のGoogle.Protobuf.dllと入れ替える
    Plugins/Google.Protobuf/lib/net45/Google.Protobuf.dll

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

[Unity事始め]WEBカメラの映像を表示してみた

とあるアプリケーションを作ろうかと思っているのですが、unityを使ってみようかと思ってます。
そんなわけで事始め。unityの知識はまだ皆無です。

環境

surface goなのでしょぼいです。果たしてこれでスペック足りるのか。。

  • win10 Home
  • MEM 4GB

ライセンス

unityは有料だっていう話を聞いたことがある。
でも試しに開発してみる程度なら無料でできたりするんじゃないの?って思ってる。

https://store.unity.com/ja#plans-individual

利用資格:

収入ならびに資金調達(自己資金を含む)の過去12ヶ月の合計が年間 10 万ドルを超えない場合、 Personal を使用できます。

なんだか不思議な条件だ。10万ドルって事は1000~1100万ぐらい。
・・残念ながら利用資格ありました。余裕で。

プラン比較:
Plusと比較して、できない事は以下。

  • スプラッシュスクリーンのカスタム化
  • Unity Teams Advanced(3 シート)
  • 高度な Cloud Diagnostics
  • コアアナリティクス

あんまりよくわからないので特に魅力は感じない。Personalでいいね。
学習コンテンツやら、サポートやらで付加価値がついてく感じなのかなぁ。

参考:
Unityのライセンスは何が違う?種類や内容を解説
https://www.capa.co.jp/archives/32867

install

https://create.unity3d.com/jp-howto-install-win

こちらを参考にしました。
Unity Hubからインストールするといいらしい。
nvmとかvenvみたいなやつかな。もしくはanacondaみたいな。

インストールは難しいことなかった。
Unity Hub入れて、そこからUnity入れて、アカウント登録して、ライセンス登録して起動する。

何はともあれチュートリアル

https://learn.unity.com/tutorials

2D Platformer Mod: Billboard Face
https://learn.unity.com/tutorial/2d-platformer-mod-billboard-face-jp

っていうのが気になる。10分って書いてあるし試しにやってみよう。

画像が常に正面を向くビルボードを試す

まずはMicrogameプロジェクトを開けとあります。何のことやら。
プロジェクト作ってみればいいかな、と思ってUnityHubを開くと、2D Platformer MicrogameってのをDLできるようになってた。
きっとこれのことやな。

unity2.png

そんなわけでこれを選択してプロジェクトを作ります。
プロジェクト名はとりあえず、Hello 2D Platformerにしておいた。

なんか起動した。

unity3.png

次にこれをやる。

Project ウィンドウの検索バーに「billboard」と入力してください(注意:入力後「Search」の横にあるフィルターが「All」に設定されていることを再確認してください)。
もし「billboard」アセットが表示されたら、ステップ 1 から始めることができますが...お待ちください!あなたはまだマイクロゲームの最新バージョンを持っていないかもしれません。これは、今後リリースされる Mods を完了する場合に必要になります。確認してみましょう…
ビルボードで検索したように、「donut」で検索してみてください。
検索しても何も表示されない場合は、それ以上の Mods を進める前に最新のマイクロゲームをこちらのリンク先 Get the latest Microgame から入手することを強くお勧めします。

「billboard」も「donut」も表示されたので問題なさそう。

で、ステップに従って進めると・・なるほどこういうことか。

unity3.png

マ〇オ兄弟的なゲームに看板を追加してみるっていうだけのチュートリアルね。

プロジェクト作成

今度は1からHello Unityしてみます。

よくわからんけど 2D 選んでみた。
作成を押した後、しばらく時間がかかる。

これ使ってみたいんですわ。

https://docs.unity3d.com/ja/current/ScriptReference/WebCamTexture.html

WEBカメラの情報を取り込んで表示できるらしい。

参考:
https://note.com/npaka/n/nbaa0e466b0de

この通りやってみます。

スクリプトの作成はこんな感じ。
https://docs.unity3d.com/ja/2018.4/Manual/CreatingAndUsingScripts.html

RawImage側からScriptを紐づけたらできました!

unity4.png

デフォルトのカメラがsnap cameraのやつだったので、おとなしめのやつにして撮影。
テキストだけ乗せてみてます。ここまではけっこう簡単にできちゃうのですね。
Buildも簡単。Build and Runってやっただけ。

画像をリアルタイムで加工するアプリを作りたいのだけど、難易度不明。
でもC#でスクリプト書けるってことは自由度は高いのかも。

やってみて

  • 用意されてる事は簡単にできそう
  • android studioぐらいの重さを想像してたけど、(簡単なことであれば)あまりPCスペックは要求されない。
  • スクリプトを書く量はそれほど多くならない?
  • main cameraだとかそういう概念があまりわからない。(2Dアプリなら関係なさそう)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Unityやってみる(導入編)

プログラミング練習もかねて、興味のあったUnityをやってみることにした。
今回はダウンロードからプロジェクト新規作成まで。

事前準備

・Unityアカウントを作成
・PCのプロキシを解除

ダウンロード

・Unityの公式ホームページからダウンロードしてくる。
https://unity.com/ja

・右上あたりの「はじめる」をクリック
 Unityはちょくちょくホームページのデザインが変わるみたいなので、
 ボタンがなかったりしたら似たようなボタンを探してください。(ダウンロードとか)
image.png

・「個人向け」タブを選択
・Personalの「はじめる」をクリック
 今回は個人の趣味の範囲で使用するのでこれを選んだ。
image.png

・リピートユーザーの「こちらから」をクリック
 新規ユーザーの方はチュートリアルが用意されているが
 説明が全て英語なので最初から始める人にはむいてないっぽい。
image.png

・規約に同意できたらチェックをいれる
・「Download Unity Hub」をクリック
 Unity HubはUnity本体ではなくバージョン管理をしてくれるツール。
 バージョンを選択してプロジェクト制作をすることができるので
 アップデートで作ってたものが動かなくなることを防げる。
image.png

UnityHubのインストール

・「同意する」をクリック
image.png

・「インストール」クリック
 ※インストール先フォルダには日本語(全角文字列)を含まないようにする。
image.png

インストール完了後にUnityHub.exeができるのでダブルクリックすればUnity Hubが起動する。
すでにいくつか制作しているので、初めての人とは見た目が違うと思うが下画面みたいなのが出てればOK。
image.png

Unity本体のインストール

・サインインをする(登録したアカウントでサインイン)
image.png
※ライセンス認証を求められた場合、以下を行う
 ・右上の歯車クリックし、「ライセンス管理」をクリック
 ・「新規ライセンスの認証」をクリック
 ・Unity Personalを選択し、2つの選択肢のうちいずれかを選択
 ・「実行」をクリック

・Unity本体をインストールするため、左側の「インストール」タブを選択
・右上の「インストール」をクリック
image.png

・バージョンを選択
 今回はfix版かつLTS版のものを選択した。(fが付いていて、LTSと付いているもの)
・「次へ」をクリック
image.png

・お好みでUnityへの追加機能を選択する
 Dev tools:プログラミングツールをインストールするか(後から別にインストールできるのでチェックしなくてもいい)
 Platforms:選択したプラットフォームのプロジェクトをビルドできるようになる
 Documentation:オフラインマニュアル
 Language packs:Unity内の言語選択
 ※プロジェクト作成後に次のことを行うと日本語化できる。
  Edit>Preferences>Languages>Editor Languagesを日本語に変更
・「実行」をクリック
image.png

プロジェクト新規作成

・左側の「プロジェクト」タブを選択
・「新規作成」をクリック(バージョンを選択する)
image.png

・テンプレートの2Dまたは3Dを選択(今回は3Dを選択)
・プロジェクト名と保存先を指定
 ※日本語(全角文字列)は含めないよう注意
・「作成」をクリック
image.png

下画面のように表示されていればプロジェクト作成完了。
※バージョンアップデートを聞いてくることがあるが、絶対にアップデートしないこと(動かなくなる可能性が高い)
image.png

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

【Unity】ScrollRectを継承したクラスのpublic変数をInspectorに表示するEditor拡張

確認環境

Unity 2020.1.6fa

内容

ScrollRectを継承して無限スクロール、多重スクロールなどを実装しようとしたときに継承先のpublicやSerializeFieldの変数がInspectorに表示されなかったのでEditor拡張で表示させてみました。

CustomScrollRect.cs
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace Custom.UI
{

    public class CustomScrollRect : ScrollRect
    {
        public Transform test;
        public GameObject hoge01;
        [SerializeField]private GameObject hoge02;
        public GameObject[] hoge03;
        public List<GameObject> hoge04;
    }

}

testやhoge01などが表示されていない。
image.png


ScrollRectなどは独自のEditor拡張されているので表示されないみたい。
ということで考えたらScrollRectEditor.csを継承したEditor拡張を作ればうまくいくと思いやってみました。

CustomScrollRectEditor.cs
using UnityEngine;
using System;
using System.Reflection;
using UnityEditor;
using UnityEditor.UI;
using Custom.UI;

namespace Custom
{

    [CanEditMultipleObjects]
    [CustomEditor(typeof(CustomScrollRect), true)]
    public class CustomScrollRectEditor : ScrollRectEditor
    {
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            if (serializedObject.targetObject is CustomScrollRect customScrollRect)
            {
                Type classType = customScrollRect.GetType();
                FieldInfo[] fieldInfos = classType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
                for (int i = 0; i < fieldInfos.Length; i++)
                {
                    FieldInfo fieldInfo = fieldInfos[i];
                    object[] attributes = fieldInfo.GetCustomAttributes(true);
                    bool isSerializeField = false;
                    foreach (var attribute in attributes)
                    {
                        if (attribute.GetType() == typeof(SerializeField))
                        {
                            isSerializeField = true;
                            break;
                        }
                    }
                    if (fieldInfo.Attributes != FieldAttributes.Public && !isSerializeField) continue;
                    SerializedProperty serializedProperty = serializedObject.FindProperty(fieldInfo.Name);
                    EditorGUILayout.PropertyField(serializedProperty);
                }
            }

            serializedObject.ApplyModifiedProperties();

            // 区切り線
            GUILayout.Box("", GUILayout.ExpandWidth(true), GUILayout.Height(2));

            base.OnInspectorGUI();


        }
    }
}

image.png

しっかり元のScrollRectの表示も維持してうまく表示されました。

最後に

ほかにもすでにEditor拡張されているクラスを継承したときにはこの方法を使えばうまく表示されると思います。

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

UnityでランダムMAP生成の方法【2Dゲーム】

UnityLearnで
用意されているローグライクゲーム。

2D Roguelike

これの
・MAPランダム生成
・オブジェクトのランダム生成
部分を解説して行きます。

この部分はローグライクの肝ですし、
何より他のゲームでも使い回せるテクニックになっています!

環境は
MacOS Catalina:ver 10.15.4
Unity:ver2019.4.3f1
です。

MAP&オブジェクトのランダム化

ランダム化のコード

BoardManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//Map生成のscriptを記述する
public class BoardManager : MonoBehaviour
{
    //Map上にランダム生成するアイテム最小値、最大値を決めるclass
    public class Count
    {
        public int minmum;
        public int maximum;

        public Count(int min,int max)
        {
            minmum = min;
            maximum = max;
        }
    }

    //Mapの縦横
    public int columns = 8;
    public int rows = 8;

    //生成するアイテムの個数
    public Count Wallcount = new Count(3, 9);
    public Count foodcount = new Count(1, 5);

    //MAPの材料
    public GameObject exit;
    public GameObject floor;
    public GameObject Wall;
    public GameObject OuterWall;
    public GameObject enemy;
    public GameObject food;

    //Object整理用(ランダム配置されたobjectの親に設定)
    private Transform boardHolder;

    //6×6のマスでobjectがない場所を管理する
    private List<Vector3> gridPositons = new List<Vector3>();

    void Start()
    {
        //Mapの生成
        BoardSetup();

        //gridPositionsのクリアと再取得
        InitialiseList();

        //ランダムに壁を生成
        LayoutObjectAtRandom(Wall, Wallcount.minmum, Wallcount.maximum);

        //食べ物生成
        LayoutObjectAtRandom(food, foodcount.minmum, foodcount.maximum);

        //出口の設置
        Instantiate(exit, new Vector3(columns - 1, rows - 1, 0), Quaternion.identity);
    }

    //フィールド生成
    void BoardSetup()
    {
        //Boardをインスタンス化してboardHolderに設定
        boardHolder = new GameObject("Board").transform;

        for (int x = -1; x < columns + 1; x++)
        {
            for (int y = -1; y < rows + 1; y++)
            {
                //床を設置してインスタンス化の準備
                GameObject toInsutantiate = floor;

                //8×8マス外は外壁を設置してインスタンス化の準備
                if (x == -1 || x == columns || y == -1 || y == rows)
                {
                    toInsutantiate = OuterWall;
                }

                //toInsutantiateに設定されたものをインスタンス化
                GameObject instance =
                    Instantiate(toInsutantiate, new Vector3(x, y, 0), Quaternion.identity) as GameObject;

                //インスタンス化された床or外壁の親要素をboardHolderに設定
                instance.transform.SetParent(boardHolder);
            }
        }
    }
    //gridPositionsをクリアする
    void InitialiseList()
    {
        //リストをクリアする
        gridPositons.Clear();

        //6×6のますをリストに取得する
        for(int x = 1; x < columns -1; x++)
        {
            for(int y = 1;y < rows -1; y++)
            {
                //gridPositionsにx,yの値をいれる
                gridPositons.Add(new Vector3(x, y, 0));
            }
        }

    }

    //gridPositionsからランダムな位置を取得する
    Vector3 RandomPosition()
    {
        //randomIndexを宣言して、gridPositionsの数から数値をランダムで入れる
        int randomIndex = Random.Range(0, gridPositons.Count);

        //randomPositionを宣言して、gridPositionsのrandomIndexに設定する
        Vector3 randomPosition = gridPositons[randomIndex];

        //使用したgridPositionsの要素を削除
        gridPositons.RemoveAt(randomIndex);

        return randomPosition;
    }

    //Mapにランダムで引数のものを配置する(敵、壁、アイテム)
    void LayoutObjectAtRandom(GameObject tile,int minimum,int maximum)
    {
        //生成するアイテムの個数を最小最大値からランダムに決め、objectCountに設定する
        int objectCount = Random.Range(minimum, maximum);

        //設置するオブジェクトの数分ループで回す
        for(int i = 0; i < objectCount; i++)
        {
            //現在オブジェクトが置かれていない、ランダムな位置を取得
            Vector3 randomPosition = RandomPosition();

            //生成
            Instantiate(tile, randomPosition, Quaternion.identity);
        }
    }
}

コード解説

BoardSetup

ループを使いフィールドを生成しています

下記の図を見てください

スクリーンショット 2020-09-01 20.30.28 2.png

フィールド全体は
10×10
で生成されており、
一番外側は
破壊不可なOuterWall(外壁)を設置する場所です。

8×8はPlayerが移動可能な範囲で、
なおかつfloor(床)を設置する場所。

Playerが現在立っている位置を
(0,0)としているため、
外壁が配置されるのは
x,yのどちらかまたは両方に-1or8の位置がある時になります。

なのでループの開始を-1から始め10進んだ数値の8までループが回るようにし、
x,yに-1or8が含まれていたらOuterWall(外壁)、
それ以外はfloor(床)を配置するようにしています。

InitialiseList

上記画像の6×6の場所を
リスト(gridPositons)に数値としてに保持する

このgridPositonsに保持されている数値は、
objectが無い状態です。

アイテムを配置する際にこのリストを使って
Objectがない位置を把握して、配置して行きます。

RandomPosition

randomIndexに
gridPositonsに保持されている位置の要素数から
ランダムに数値を選び設定する。

randomPositionにgridPositonsの
randomIndexに保持されている場所を設定する。

一度randomPositionに設定された数値は削除して、
アイテムが二重で置かれることがないようにしている。
スクリーンショット 2020-09-26 11.12.10.png

LayoutObjectAtRandom

アイテムごとに決められた、
最小最大値からランダムでアイテムを設置するべき数値を決める。

決められた数値objectCount分ループで回して、
randomPositionに設置していく。

最後に

MAPのランダム生成について解説して行きました。
今後もゲーム開発に役立つテクニックを
投稿していこうと思っています!

また自分のブログでは
初心者でもゲーム開発ができるように1から丁寧に解説しています。
ローグライクのゲームの作り方を
1から知りたい方はぜひブログを覗いてみてください!
ブログを覗いてみる

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

Unity から Xcode経由でiOSへビルドするときのエラー「library not found for -liPhone-lib」

バージョン

Xcode Version 12.0.1
Mac OS Catalina
iOS 13.7

エラー

Unity から Xcode経由でiOSへビルド
Xcodeのビルドの最後の方で、こんなエラー

ld: library not found for -liPhone-lib
clang: error: linker command failed with exit code 1 (use -v to see invocation)

原因

Unityのプロジェクト名が全角の文字を含んでいたため。

(誤) TEST1

(正) TEST1
 

以上



これだけで、半日悩んだ・・・・・

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