Unityで図鑑のようなUIを作りたい ~ GridLayoutGroupを使ってスクロールさせて中にセルを生成 ~

こんばんは。VyseArtのトナカイです。

今回は完全に私のための備忘録記事です。

「odekakeneko 図鑑 UI 」(またはプラス「スクロール セル」)の検索ワードで引っかかったら私個人として使いやすいなと思います。

目次

現在VyseArtは新しいゲームを作成するするため打ち合わせをしております。

本日VyseArtチームで ゲーム案出し→絞り込み→一つに決める の工程が完了しまして、作りたいゲームのアイディアが決まりました^^

その後ゲーム案を具体化させたり、ゲームルールを作ったり、仕様書を作る前段階まで来ました。

良くまとまったので、さっそく帰宅してゲームに使いそうなコードを探しました。

本日探したコードは、表題の通りになります。

f:id:odekakeneko:20200119011803p:plain:w300
図鑑のようなUIを作りたい。

こちらのサイトのパクほぼリライトになります。
このサイトでは、縦のスクロール図鑑を作っていますが、
私の方では、横スクロールを作ってみました。

qiita.com

図鑑のようなUIを作るには、GridLayoutGroupを使いセルを生成していくことになります。

それではGridLayoutGroupを使って横にスクロールするUIを作ってみましょう。

図鑑のようなUIの作り方

f:id:odekakeneko:20200119012318p:plain:w300
初期画面

Create→UI→Canvas

Canvas ScalerをScale With Screen Sizeにします。


f:id:odekakeneko:20200119012422p:plain:w300
キャンバスを作る


次に、Create→UI→ScrollViewでScrollViewを作る、

ScrollViewのインスペクタから、画像の赤丸を選択すると、
Anchor Presetsが出てくるので右下の赤丸のstrechを選択。

f:id:odekakeneko:20200119012518p:plain:w500

Stretchは親オブジェクトから何ピクセル離れるか、ということらしいです。
私が作りたいのは、画面の下方に現れる図鑑なので、
Left : 50
Top : 600
PosZ : 0
Right : 50
Bottom : 50
にしました。こうすると、画像の白っぽい四角のようになりました。

今回は参考サイトとは異なり、横方向の移動だけでよいので、Scroll RectのVerticalのチェックを外して、Scrollbar verticalのオブジェクトをヒエラルキーから削除しました。

ScrollViewのViewPortの子にContentがあり、ここに画像やボタンを配置していくそうです。

ここに、GridLayoutGroupを配置していきます。

contentにAdd Componentし、
・GridLayoutGroup
・Content size Fitter
を追加します。

下記Unityのドキュメントから引用です。

以下は推奨される Content Size Fitter と Layout System を併用する方法です。

幅を可変にし、高さを固定する
要素が加えられるにつれて、グリッドが横に広がるように、グリッドを可変の幅と固定の高さで設定するには、以下のようにプロパティーを設定します。

Grid Layout Group コンポーネントの Constraint: Fixed Row Count
Content Size Fitter コンポーネントの Horizontal Fit: Preferred Size
Content Size Fitter コンポーネントの Vertical Fit: Preferred Size か Unconstrained
Vertical Fit で Unconstrained を使用する場合、特定のセルの行数に合うようにグリッドの高さを大きくするかは、ニーズに合わせて判断してください。

f:id:odekakeneko:20200119013016p:plain:w500
Grid Layout GroupとContent Size Fitterはこのように設定する
Preferred Sizeはレイアウト要素のPreferred Heightに基づいて高さを制御します。
UnConstrainedは高さにレイアウト要素に基づく制御を行わない、とありました。

あとは、下記スクリプトを作成してヒエラルキーのオブジェクトにこのスクリプトをアタッチ(普通GameManagerなどのマネージャーオブジェクトにアタッチ)し、インスペクタから
contentRectTransformにContent
buttonCellに作成したボタンを

ヒエラルキーからアタッチすればできます。

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


public class TestSpawnGridLayout : MonoBehaviour
{

    public RectTransform contentRectTransform;
    public Button buttonCell;
    public Sprite spriteCell;

    // Start is called before the first frame update
    void Start()
    {
        InstantiateGridLayoutCell();
    }

    // Update is called once per frame
    void Update()
    {
        /* ここはUpdateです */
    }

    //セルを生成する
    public void InstantiateGridLayoutCell()
    {
        for(int i = 0; i < 30; i++)
        {
            var obj = Instantiate(buttonCell, contentRectTransform);
            obj.GetComponent<Image>().sprite = spriteCell;
        }
    }
}

(このスクリプトパク上記サイトのスクリプトを参考にさせていただいております。)

f:id:odekakeneko:20200119012754p:plain:w500
完成図

FlutterのLocalizationについできたこと~CupertinoDatePickerを日本語にできた~

こんにちは。VyseArtのトナカイです。

最近Flutterを学んでいます。
私はIT関連企業の事務系で社内ツールを作っているのですが、
今後、今の仕事でもFlutterつかえたらいいなという淡い期待をしていて、
ちょっとずつ勉強しています。

あとFlutterを使ってどうしても作ってみたいツールがあるんです。
SNS要素があるのですが、使ってくれた人が希望を持てるようなツールを作りたいと思っています!

続きを読む

【Unity】Loypolyの魚AIを自由に泳がす~A* Pathfinding の使い方備忘録~

こんばんわ。VyseArtのトナカイです。

( ようやくはてな記法について理解しました笑)

先日unityのアセットストアで最大70%OFFの割引セールをやっていまして、目をつけていたアセットA* PathFinding Proが半額だったので購入しました^^

 

それを使うと簡単に人工知能AIの動きが作れるということだったので、実際に作ってみました。

 

タイトルの通り現在ローポリで探索ゲームを作成中です。

 

https://youtu.be/X4dhlfHO0CU

 

UnityはNavmeshAgentという機能があって、これも人工知能に関するものなのですが、私にはどうもうまく扱えず(何かが引っかかって動かなくなってしまったり)、人工知能は一端あきらめていました。

 

このアセットは何とか動画のような形にできました。

比較的簡単に人工知能を実装できたと思います^^

 

今回はその備忘録です。


f:id:odekakeneko:20191207223835p:plain
A*オブジェクトを作成

A* Pathfinding Pro(有料です!)をアセットストアからインポートしたらヒエラルキーに「A*」という 空のゲームオブジェクトを作ります(画像の他のオブジェクトはここでは無視してください)。そして、、


f:id:odekakeneko:20191207225001p:plain
A*オブジェクトのインスペクタ

A*のインスペクタはこうなっています。AddComponentで「Pathfinder」と検索してアタッチすると、A Star Pathというスクリプトが付きます。

 

Graphの名前はたしか「Grid Graph」だったのですが「Water Graph」に変えました。

こちら私がすごいなと感じたのは、このGraph、複数で作成ができてGraphごとに取得ができるようです。

 

それの何がすごいかというと、Water Graph内だけで動き回ってほしいAIにはそのグラフの範囲だけ設定すればよいのです。

 

NavGraph gg;

gg = GetComponent<Astarpath>.graphs[0];

グリッドグラフの取得の方法…添え字を使います。

 

AIとなるオブジェクトには、SeekerとAILerpというスクリプトをつけます。
Seekerスクリプトは必須で消せません。AILerpはSeekerに依存していると表示が出ました。

(ここら辺私なりに色々彷徨いました。A*Pathfindingが壊れているのかとまで思ったのですが、自分のコードと向き合って直したところ、動画のようなものが作れました)

 

AIとなるオブジェクトにつけたスクリプトFish.csは下記のようになります。

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

public class Fish : Item
{
    NavGraph gg;
    float radius = 20f;

    IAstarAI ai;

    void Start(){
        //グラフを取得する
        gg = GameObject.Find("A*").GetComponent<AstarPath>().graphs[0];    //WaterGraphを取得
        ai = Getcomponent<IAstarAI>();
    }

    void Update(){
        Swim();
    }

    private void Swim() 
    {
        if(!ai.pathPending && ( ai.reachedDestination || !ai.hasPath))
        {
            ai.destination = gg.GetNearest(PickRandomPoint()).clampedPosition;
            ai.SearchPath();
        }
    }

    Vector3 PickRandomPoint()
    {
        var point = Random.insideUnitSphere * radius;

        point.y = 0;
        point += ai.position;
        return point;
    }
}

Fish.csですが、動画の動きとは少しスクリプトを割愛をしてあります(例えば最初は泳いでなくて、くるくる回っているところとか、フラグを使ってifで条件分岐するとできますね)。

私的にポイントは、関数Swim内の
ai.destination = gg.GetNearest(PickRandomPoint()).clampedPosition;
にあると思っています。
ランダムなポイントをとってくるのはA* Pathfindingを使わなくてもコードをかけるのですが、その近くのノードをとってきてVector3型で返すというのがこのアセットを使ってできることだと思います。

ほかにも、A*Pathfindingは動的にBake(このアセットではScan)ができるということで、それに関してはまだ勉強中というか効果もわかっていないところなのですが、それらもできたら掲載したいと思います。

以上。

 

最近の話 ~モチベーションが上がらなかった時は~

9月初め 銀河鉄道の夜 ~もう1つのストーリー~をリリース

9月半ば 東京ゲームショウ2019に初めて行く(小海とともに)

9月末  今後のゲームはAI(人工知能)を取り入れたいねという話になる

9月末(先週) 仕事(とラグビーW杯観戦)が忙しく開発なかなかできず

10月5日(土) 本日、進捗あまりよくなく思い悩む

 

==

 

上のような状態でして、新アプリをリリースしてから、あまり制作活動が進んでいません。

 

何かのブログで「成功するような人は呼吸をするかのように当たり前に努力をする」ということが書いてあって、私もアプリ制作で生活していきたいのだけどそのように努力できていない自分がいてじりじりとしてしまいました。

 

あまりに思い詰めて小海に電話。内容は以下です。

 

〇仕事が忙しくてアプリ制作がなかなか思うようにいかない

〇ゲーム作りはしたいけど、今後満足な収入を得ることは難しそう

〇収入が欲しいなら、今すぐブログとか書いた方がいいかも

 

小海からは以下のように言われました。

〇収益がなくても、コンテンツを自分たちで作り、それを世に出したい。一人でも共感してくれる人がいるといい。

〇周りは気になるけど、自分たちが何ができて、どう成長して、今度は何が作りたいという「自分たちベース」でいきたい

 

 

な、な、なるほど、、!!!!!

 

センターを取り戻した自分がいました。

 

==

 

ところで私はラグビーをやっていました。高校の時です。

 

何であんなに頑張っていたのだろうというくらい頑張っていた。がむしゃらでした。

 

そのあと大学に進んで、勉強がうまくいかず体調を崩したりして、そのあと何とか仕事にありつけたけど、そのあとの自分はちょっとよくわからない。

 

ほんとうは何がしたいのか、自分が好きか、ひたむきに頑張っているか。

 

忙しくなると忘れてしまうのですが、信じる気持ちは大切だなと思います。

 

大切なことは子供のころに知っていて、大人になって忙しくなると、それを手探りで思い出しながら再現させようと努力するのではないかなと思います。

 

それがかなわないでへこたれるけど、もう一度その気持ちを思い出したならば、せめて書き留めないといけないと思います。

 

というわけで、私はすごく頑張っていたということを書きます。

そして、小海という素晴らしいパートナーがいます。

 

そういうわけで、今後ともゲーム制作を続けていきます。

以上。

銀河鉄道の夜~もうひとつのストーリー~ 宣伝結果

<プレスリリース>

①SQOOL.NET

https://sqool.net/news/archive/20190902-458035.html

とてもお早いご対応をしてくださいました。

 

②appnavi

https://appnavi.info/app-info/app_page-202777/

ご掲載感謝です。

 

<プラットフォーム登録>

①NewAppPlace

https://www.newappplace.com/detail/102

Twitterでも弊方のアプリをツイートしてくださいました!

 

②放課後アプリ部

http://houkago-no.appspot.com/app_detail/5730368455966720

 

③ツクログ

http://creators.eightbit.jp/service/item3637.html

 

SNS

①note

https://note.mu/odekakeneko

エッセイ / Twitterやブログとの内容差別化

 

 

るいちゃんアバター ~Unity作業まとめ~

こんばんは。VyseArt(ヴィシェアート)のトナカイです。

 

先日東京ゲームショウ2019に行ってきましたー^^

いやーよかった!Indies Gameブースにて、実際にゲームを作っている人たちと話ができたこと、本当に良い経験になりました!

 

こういう祭典はちょくちょく顔を出した方がいいですね!

 

==

 

本日のゲーム制作進捗まとめをメモしたいと思います。

 

youtu.be

(この動画はRigidbody.AddForceで動かしています。この後にRigidbody.velocityで動かす方法に直しました。)

 

現在私たちのオリジナルキャラクター「御筆(みふで)るい」ちゃんを、小海が3Dにしてくれたので、それをスクリプトで動かしてみています。

 

ただのメモですので、技術ブログとは違い、テーマも絞らずつらつら書いていきます。

 

キャラクターを動かすのに、Rigidbody.velocityを使った

キャラクターの動かし方は、このサイトにあるように3つ4つ方法があるそうです。

 

tama-lab.net

 

この中で私が好きなのは、Rigidbodyに力を加えるものでした。

 

Rigidbody.velocityに値を設定すると、人型のキャラクターでしたら(自動車とかではなく)思ったようにスッスッと動いていってくれます。

 

ただしここで問題があって、動画のようにジャンプさせるときに、RigidBody.velocity = new Vector3( moveX , 0 , moveZ )という風に(moveXとmoveZは変数)、Y軸方向に0の値を代入してしまうと、重力が働いていたとしても、ふわーっとゆっくり落ちるようになってしまいました。

 

ここで、重力計算をしようとして、下記のサイトを参考にしたのですが、、

Unityで間違った重力の計算をしているかも!? | Unityを使った3Dゲームの作り方(かめくめ)

 

こちらのコードで奮闘したところ、解決できました。要は、重力計算をRigidvody.velocityのy軸の中に入れてあげればよく、速度の物理法則v = v0 +1/2 at^2をこのRigidvody.velocityの中に入れてあげればよかったようです。

 

Rigidbody.velocity = new Vector3( moveX, 0.5f * Physics.gravity.y * jumpTime * jumpTime , moveZ)

 

みたいな感じ。Physics.gravity.yというのはUnity側で提供されている定数なので問題なく使えます。jumpTimeというのは自分で作った変数です。

onCollisionEnterで地面(タグをGroundとかにして)との接地状況を取得して、接地時はjumpTime = 0 とします。ジャンプさせたときにjumpTime += Time.deltatimeでジャンプの時間を累積させておき、それを物理法則の式に代入すれば、落下がより実際の物理法則のようにUnityで反映させることができます。

 

(実はこの記事を書いている間に修正点に気づき、直せたので、アップしている動画はRigidbody.velocityで動いているものではなく、Rigidbody.AddForceで動いています。)

 

Rigidbody.AddForceはカーレースゲームのようなより物理的なゲームといいますか、摩擦なども含めて楽しむときに使うもので、Rigidbody.velocityは人を思うように動かしたりして、人の挙動がメインではなくて3D脱出ゲームやノベルやシュミレーション要素が主となるゲームに用いられるコードという認識を持っています。

 

というわけで、これだけのコードに1日も2日もかけてしまった私の力量って、、という感じですが、るいちゃん新しいゲームに向けて、ちょっとずつ進歩していきます。

 

つまづいたとき、とことんやるか、違う方法を探すか、どちらがいいか

ゲーム制作をして1年半くらい経ちました。5つ以上アプリを出して、その間プログラムでうまくいったりいかなかったりすることがあるのですが、そういう場合どうすればいいか指針を考えました。

 

基本の知識はとことんやる、変わり種や難しいことは違う方法を探す

今回の人型の3Dのオブジェクトを動かしてみたい、という知識はUnityでは基本です。ググるとたくさん記事が載っていますし、本にもいろんな本で動かし方が書かれています。

 

そういう知識がたくさんあふれているものこそ、ちょっとこういうことを加えたい、など独自のアプローチがあるときに、つまずいてしまうことがあるかもしれません。

 

そういう時は「なんでこれができないのか」ということに関して妥協せずに考えるということも必要です。

 

私の場合は今回は、velocityのy軸に0を毎フレーム代入していたためふわっと落ちるようになってしまった

→velocityに重力計算したものを代入すればいい

→物理法則で速度の求め方を調べる(記憶でやっていたら間違ったままだった)

→接地判定のコードを見直す(Jumpしたときに接地判定をfalseにしなきゃいけなかった)

 

など、細かくて基本的なことを落としていたため、答えに到達できない長い時間が経ちました。

 

ここで、あきらめて違う方法をとってもいいのですが、もしそうしてしまうと、「Rigidbody.velocityってなんか難しいんだよなぁ、前できなかったよなぁ」という失敗体験ができてしまいます。

なるべくそういう体験が少ない方が成功に近づけると思います。

質問をするなり、ブログに書くなりしているうちに、整理がついて答えが見つかることもあると思います(実際私がそうでした)

 

というわけで、基本的な知識と思われることは、自分で納得がいくまで突き詰めた方がいいと思います。自分の勘違いやケアレスミスの可能性が高いからです。

 

変わり種や、難しいことは別の方法を探す

私は数か月前、NCMBというモバイルバックエンドを使用することにはまっていたのですが、ビルド時に違うSDK(アドモブのもの)とNCMBのそれが競合して、死ぬような思いで解決に3日かかった経験があります。(そこそこ古くそこそこ新しいSDKを使用したら解決しました。でもそれにたどり着くのは至難でした)

 

一応その解決策もブログではいくつか載っているのですが、NCMBではなく、PlayerPrefsを使っても実際よかったですし、アドモブではなくて違う広告を使うなど別の道をとることもできます。

 

NCMB自体が一般的にすごく有名で避けて通れないUnityの知識というわけではないので、そいう言う場合は妥協して違う方法を考えることも大切だと思いました。

 

また、NCMBに画像を送信する際に、EncodeToPNGをすると送れるのですが、私は透過設定をしたEncodeToJPGで送りたくてしばらく格闘した時期がありました。結局、NCMBではEncodeToJPGができないということがわかり、格闘した時間がもったいなかった、ということもありました。

 

あとは、async/awaitなども一般的に結構難しいといわれていて、私も使いこなせていないのでコルーチンで済ませたりしています。コルーチン自体もそんなに使いこなせているわけではないのですが…頑張ります!

 

Unityを学習するにあたって、どの知識にどれだけつぎ込んで、どの知識は今はパスするか、ということも考えて作っていきたいと思います。

 

以上

宮沢賢治の特異性から考える派生作品について

宮沢賢治についての考察を整理するためのメモ①

 

宮沢賢治の特異性から考える派生作品について

 

〇はじめに

 

賢治の作品においては一貫する彼の思想が垣間見え、共通する要素が見られます。

 

①人間と自然の関係性

➁献身的な登場人物

法華経・・・

彼は生涯を通じて熱心な仏教徒で(信仰宗派の変遷あり)、作品を通して”法華経”の思想を伝えたかったとも言われています。

 

賢治は自分の思いや考えを伝えるために、童話というスタイルを選びました。難しく堅苦しい文章ではなく、未来を担う子ども達にも彼の思想を伝えたかったという意図が窺えます。

 

賢治作品を題材にした様々な派生作品によって、より多くの方に彼の存在が知られることは、嬉しい反面、賢治の意図していない形で作品のイメージが広まってしまうのはいかがなものか、とも感じます。

 

〇作品のロマンチックさの受け取り方

 

銀河鉄道の夜」は、想像性豊かな風景の描写が多くロマンチックな雰囲気を感じます。メインの登場人物2人はとてもピュアでまっすぐで、景色の描写と相まって美しくも儚い物語となっています。ただ作品のメインは恋愛か?と問われると答えはNOです。登場人物2人の心理的結びつきは恋愛と似て非なるものと捉えています。賢治の生涯を辿ってみても、もっと哲学的な何かがあると感じています。このような純真な心の結びつきから恋愛へとつながることが、人間関係においてあり得ると想像することはひとつの考察にもなりますが、安易に「銀河鉄道の夜」=ロマンチック=ピュアな恋愛、というふうに捉えられてしまうと、賢治の主張したかったもっと大切な要素が見えなくなってしまうのではないかという懸念を感じざるをえません。

 

銀河鉄道の夜」の派生作品で好きなのはプラネタリウム版です。KAGAYAさんの映像がとても素晴らしく、その美しさに感動しました。

(VyseArtのイラスト・デザインはそのような素晴らしい映像と比較してしまうと、まだまだ技術力が乏しく、申し訳なく思うのですが、少しずつ精進してまいります><)

 

f:id:odekakeneko:20190906212523p:plain

アプリ「銀河鉄道の夜~もうひとつのストーリー~」より、サザンクロスのイメージ

 

他の派生作品についても、機会があったら触れてみたいです。何か新しい発見があるかもしれないですね。

 

VyseArtのアプリゲームでは、当チームならではの考察や想いが詰まっていますので、ご覧になっていただければ幸いです(^^)

 

play.google.com