【Editor拡張】条件によってインスペクターから編集不可能にする属性を作った

Unreal EngineにはEditConditionというメタデータ指定子があります。
Unityで例えると属性で渡された条件がtrueのとき
インスペクター編集が不可能になる動作。

誰かがパラメータ用のScriptableObjectを触るときに
不正な値を入れないように対策させるときに使えそう…。
docs.unrealengine.com

なので属性を作成しました。

github.com

使い方

READMEに記載されていますが一応。
属性パラメータに変数名を渡して判別します。

using UnityEngine;
using N3Utility.Attribute;

public class SampleComponent : MonoBehaviour
{
    [SerializeField]
    private bool m_flag = false;

    [SerializeField]
    [DisableBoolField(nameof(m_flag))]
    private string m_text = "Hello world!";
}

内部的にはPropertyDrawerを継承した描画クラス内で
property.serializedObject.FindProperty()を使用して変数を取得して判別しています。

余談

今回、属性を作るにあたってしっかりとお勉強しました。
これはそのメモ。きれいですね。これが完成する前は凄く汚かったけど…

それから初めてUnityパッケージからダウンロードできるように作っています。
今まで使う側だったので作った側に立ててとても嬉しい…!!


複数条件には対応していないので次改良するならそこを対応しよう…。

参考サイト

属性

【C#】【Unity】カスタム属性の基礎知識コンプリートガイド #C# - Qiita
Attribute クラス (System) | Microsoft Learn
Attributes and reflection - C# | Microsoft Learn
GitHub - Unity-Technologies/UnityCsReference: Unity C# reference source code.

UnityPackage

【Unity】Assembly Definition Filesという神機能 - テラシュールブログ
【Unity Package Manager】GitHubの自作ツールをUPM対応する方法メモ #Unity - Qiita
カスタムパッケージの作成 - Unity マニュアル
Unity Assembly Definition 完全に理解した #Unity - Qiita

【Unity】RigidBodyを使ったゲームらしい移動方法について探る

RigidBodyを使ったプレイヤーの動き、手早く作ると多分これが一番早いと思います。

Rigidbody2D rb = GetComponent<Rigidbody2D>();
if (rb)
{
    float hori = Input.GetAxis("Horizontal");
    float speed = 5.0f;

    rb.velocity = new Vector2(hori  * speed, m_rb.velocity.y);
}

ただ、この処理だと加速減速がありません。
ゲームのキャラクターの最高速までの動きはすぐに到達してほしい。
そして、ボタンを離したらいい感じに減速してほしい。

ゲームとしてちゃんとした移動を作りたい…と思って調べたら
分かりやすい解説動画がありました。
youtu.be

ありがたいことに、ソースコードも配布されているので
解析して自分なりに調べてみました。 github.com

解析

プレイヤーの移動についての処理部分のみを抜き取るとこのような形です。


加速率の(1.0f/Time.fixedDeltaTime)の部分は50というマジックナンバーでしたが
Unityの物理処理はFixedUpdate()で行われており
合わせるために50にしたのではないかな~…と思います。



良い感じの動きを作ることが出来ました。

他人が作ったコードを参考にして自分のソースコードに翻訳して取り入れてみました。
自分で一つ一つ手元で計算しながら取り入れていくと理解がしやすい!

海外の方なので関数名・変数名も参考になります。
この人は移動をRunダッシュDashという風に切り分けていました。
私なら雑にMoveとかにしてた。

参考資料

Improve your Platformer with Acceleration | Examples in Unity - YouTube
GitHub - DawnosaurDev/platformer-movement

【Unity1week】「1ボタン」に参加したゲームの振り返りを行う

Unity1week「1ボタン」に参加しました。
今回はこのゲームの振り返りを行いたいと思います。

unityroom.com

目標

個人的な目標

今回、全く関わったことが無い人とゲーム制作をしようと考えていました。
今までのゲーム制作で得た知見を、知らない人に上手に教えることができるのか
そして完成してUnity1weekに投稿できるのかが目標です。

今回、unity1week Team-Up!!という企画に参加しました。
この企画でDiscordに参加し、一緒に参加する人を募集しました。
note.com

募集板で、ガチガチに固めた文章で募集かけたのでそもそも人が来るのかな…
と思っていましたが、アート枠としてむてきいもさんに声をかけて頂きました。

むてきいもさんは可愛いケモノのイラストを描かれている人です。
語彙力が無いため良い言葉が思いつきませんがとにっかく良いイラストが多い…!
potofu.me

今回はむてきいもさんの趣味嗜好に沿ったゲームを作成しました。



余談ですが、ケモノ系は小さいころに名探偵ホームズを見てから
好きになったジャンルの一つだったので一緒に制作が出来て楽しかったです。
www.youtube.com


今回のunity1week Team-Up!!で制作されたゲームはどれも魅力的なものばかりです!
他の人が制作されたゲームも是非…!
note.com

技術的な目標

UniTaskUniRxを使用することを目的としました。
github.com
github.com

どちらもとりすーぷさんのQiita記事を見て
実際にゲームに取り入れてみたい思った
のがキッカケです。
qiita.com
qiita.com
しっかりとゲームに組み込んだことが無かったので、いい機会だと思い使用しました。


それから、制作が始まってから決めたことなのですが、
UIBuilderを使ってEditor拡張をすることも目標に入れました。

少し古い資料ですが、とても役に立つ公演がありました。
learning.unity3d.jp

大体はこの公演で使用感を掴み、色んなサイトを転々として調べて
実際に必要そうなツールを作成していくことにしました。

チーム内の目標

チーム内の目標としては下記の2つを目標にゲームを制作しました。
・期日までに提出する
・楽しくゲームを作る

果たして達成できたのか。こうご期待。

良かった点

提出できた

評価期間中に提出が出来ました。えらい!
完遂できたことは素直に嬉しいです。

滅茶苦茶言い訳みたいになってしまうんですが
Unity1week開催時期から実際に提出するまでの期間
かなりお仕事が忙しい時期になってしまいました。

お仕事と1weekの〆に追われる中、せっかく作っていただいたイラストや素材を出さず
道半ばでチーム解散…とならずに、完成することが出来て本当に良かったです。

一緒に制作する人がいた

Unity1week開催期間及び遅刻期間の間、毎日21時から1時まで作業をしていました。
かなり遅い時間まで作業をしていたんですが
その間もむてきいもさんと一緒に作業をしていました。

ただでさえ遅刻をしている上、イラストや貴重な時間を預かっている以上
絶対に完成させてやるという執念がありました。

多分、私一人だけだったら途中で投げ出していたかもしれません。
本当に助かりました。。。 ありがとうございます…!

Git・SourceTreeの使い方を教えつつ作業ができた

今まではGit・GitHub・SourceTreeの使い方を
ある程度知っている人と作業をしていたのですが、
初心者に教える立場になって実際にSourceTreeを使って作業をしました。


「教える」ことがいかに難しいかが分かりました。
自分の中の理解について、あらためて振り返ることができて良かったです。

UniTask・UniRxを上手に組み込めた

ゲームの進行周りはUniTaskを使用しました。
ロードや準備などの「待ち」の処理を比較的綺麗に作成することが出来ました。


ほとんどのUIのパラメータ変化はUniRxを使用しています。
パラメータが変化した時にイベントが働くようにしたのでソースコード上はかなり綺麗。
実装面はModel-View-Presenterパターンを使用してサクサク作ることが出来ました。
qiita.com

UIBuilderを使ったEditor拡張が楽しかった

UIBuilderを使ったEditor拡張は、非常に使用感が良かったです。
ウィンドウのGUIの見た目と、実際の内部挙動を切り分けて考えることが出来ました。


例えば、マテリアルを再帰的に割り当てるツール。
普段であれば真面目にマウスで割り当てていたものを
ワンタッチでできるようになったのは感動もの。


一番のお気に入りはサウンドリソースをソースコード上から簡単に鳴らせるように
enum生成を自動的に作ってくれるツール。

サウンド周りの実装は比較的シンプルに作ることができ、
使用するときも使い勝手が良かったです。


反省点

遅刻した

シンプルに遅刻しました。
目標達成ならず。

時間をかけすぎた

今回、TogglTrackという時間が図れるツールを使って、作業時間を可視化してみました。
toggl.com


その結果がこちらです。
10/5(木)~10/7(土)の期間は計り忘れています。大体+12時間ぐらい。
トータルで120時間このゲームに費やしている計算になります。


一つ目は素直に「一つの実装に至るまでに考えすぎ」なことです。
綺麗な実装にしよう…綺麗な実装に…と設計レベルの事から考えていました。

一週間しかないので、もうすこしフットワーク軽く動いて、
できる・できない、やる・やらないの分別を早くした方が良かったです。


二つ目は「コードがまじめすぎる」ことだと思います。
滅茶苦茶丁寧にアサーションやログ出力に関する処理書いているんですよ。すごい丁寧。


で、これがマネージャクラスなどの取りまとめるクラスなら非常に嬉しいんですが
端っこの小さいクラスもこのレベルで書いています。真面目か!!!

提出までこのクソ真面目コードを書いていたんですが
ある程度小さなクラスは別に書かなくても良かったんじゃないかな…とおもっています。

予め用意して置いたゲーム進行形クラスが足枷となった

予めこの機能が必要そうだな…と思って用意して置いたゲーム進行形クラスがありました。
ですが使う上での制約が厳しくて、かなり使いずらかったです。


特にこのステートマシンくんがかなり暴れていました。
ツイートしているときはウッキウキでした。が、実際には制約が厳しすぎる。
制約をすこし緩める形で修正しました。もう少し柔軟に考えるべき…。

使用しなかった機能が存在した

今回、ADVパートを作りたい!という話をしていました。
で、お題が発表されるまでにGoogleスプレッドシートからcsvファイルを書きだして、
専用の拡張機能を使用すると会話用のScriptableObjectが作られる機能を作成していました。


(DataTableってなんだよ)

Googleスプレッドシート編集者はむてきいもさんにお任せしようと考えていたため
間違ったcsvファイルを出力しないように不正値には赤く表示するようにしたり
変な値を入れこまないようにドロップダウンを付けたりして
ヒューマンエラーを起こさないように工夫をしていました。

10時間ぐらいかけてこの機能を作ったのですが
お題が「1ボタン」で活かしにくいお題が来たため
今回は見送ることにしました;;

数学・物理学の知識が甘かった

今回、RigidBodyを使ってプレイヤーを飛ばしているのですが
AddForce()関数をかなり曖昧な理解で使用しています。

これはシンプルに勉強不足なので、現在進行形で色んな動画を見回って
次のゲームに活かせるようにします。

現時点で繰り返し見ているのは下記の3つ。
すべて安原さんの公演。すごく分かりやすいです。
[Unity道場 札幌スペシャル]プロが教える脱初心者スクリプト術! - YouTube
【Unite Tokyo 2018】誘導ミサイル完全マスター - YouTube
【Unity道場 博多スペシャル 2017】クォータニオン完全マスター - YouTube

おわりに

unity1week Team-Up!!、忙しい時期でしたが非常に楽しかったです!
企画者であるMetaFormingProさん、並びに湊あおいさんに感謝しております🙏

また、むてきいもさんにはかなりご足労をおかけしたと思います🙇
制作していただいてありがとうございました!

そして、次回開催時期がすでに出ている…!
unityroom.com

作ったゲーム

TRAMPO | フリーゲーム投稿サイト unityroom

【日記】9/11(月)~9/17(日)の間にu1w準備のために作ったもの

unity1weekが開催されてます!!!
お題は「1ボタン」!シンプル…。


Unity1weekのために裏で基礎部分を作っていました。

デバッグ機能


デバッグ機能。
泣きたくないので作りました。果たして有用なのか。

同時に進行周りもここで作りました。
下手すればデバッグ機能追加よりもてんこ盛り。

作りきってから実は設計が破綻していたことに気が付きました。
これがOneweek中ならやばかった。

Audio機能


Audio機能。
それぞれのクラスがAudioSourceを持たず、AudioManagerくんのみが音を出す設計。

AudioManagerにEnumを渡すことで音を鳴らすことが可能です。
AudioClipを直接使うのではなくてEnumで使えるようにしたかった。のでそうしました。

ADVパートメーカー


googleスプレッドシートcsvで出力して、DataTableを作成する機能。
滅茶苦茶丁寧にgoogleスプレッドシートを作りました。

慣れないスプレッドシートを調べに調べ、かなり時間がかかりました。
が、お題がお題なのでADVパートをやらなさそう。お蔵入り。。。

結構基盤はできた…。はず…。 あとは期限内にどれだけ作りこめるか…!

【Editor拡張】再帰的にマテリアルを割り当てるツールを作った

余談

来週にはunity1weekが開催されますね!


今回、私はMetaFormer様、並びに湊あおい様が企画されている
unity1week Team-Up!!に参加させていただいております!

私も参加してます。これをお読みのあなたもぜひ! まだ間に合います!

本題

SpriteStudioというものがございまして!
www.webtech.co.jp

今回のUnity1weekで使用しようとしているアプリケーションです。
2Dアニメーションで使用されているらしい。なるほどなるほど。

公開されている公式のインポートツールを使ってURP環境のUnityに持ってきます。
Unityエディターバージョンは2022.3.4f1。
assetstore.unity.com

マテリアルがピンクに…!
SpriteRendererにマテリアルが割り当てられていないのが原因ですね。

で、すべてのSpriteRendererに直接マテリアルを割り当ててもいいんですが、
階層が複雑かつ人力でやるにはあまりにも非効率なので
一括で割り当てるツールを作りました。

ソースコード

ソースコードはこちら。
一つのScriptファイルに2つのクラスが存在しますが、実際には分けてます。

余談2

今回、初めてUIBuilderを使ってウィンドウを作成しました。
下手すれば初めて目的をもったEditor拡張を作ったかもしれない。
docs.unity3d.com

あくまで個人的な話になるのですが、今までEditor拡張ってどうしても
最終の表示されるウィンドウのイメージを考えながら作るのが
かなりニガテだったので避けていた
のですが、
イメージしたものをUIBuilderを使用してGUIでサクッとつくることが作成できて便利。

Editorで使用するObjectField等は、
Libraryの詳細ボタンを押すと使用できるようになります。

UIBuilderを使ったEditor拡張については
Unity Learning Materialに投稿されていた動画で概要を掴み、
そこから既存のEditorのHow to記事を読み漁って作成していきました。
learning.unity3d.jp

何も情報がないところから自分なりにいいものを作り上げられて楽しかったです。
作りたいツールができて満足です。単調な作業とはおさらばだ…。

参考にしたサイト

UIElements と UI Builder で Editor拡張を作ろう | Unity Learning Materials
ユーザーガイド | OPTPiX Help Center
Home · SpriteStudio/SS6PlayerForUnity Wiki · GitHub

【日記】オレオレステートマシン最強伝説

再来週にはunity1weekが開催されますね!!!


今回、私はMetaFormer様、並びに湊あおい様が企画されている
unity1week Team-Up!!に参加させていただいております!

現在アートの方一名募集中です。ぜひ…。

本題

ステートマシンを作ったよ~~~っていう日記です。
今までその場その場で新しく作ってました。
ですが、今後ゲームロジック等々で汎用的に使いまわせて、
メンテナンス性が高いものが欲しかった
のです。

がむしゃらに作るのではなくて、一度どんな機能が欲しいか
ノートに書き出してから作りました。

これに沿って作ったらまあ納得のいくものが作れるのなんの!
ソースコードがすっごくシンプル!

しかもエラー文がやたらと丁寧です。
コンストラクタのエラー文や…



関数が使えなかった時のエラー文等。


これは使える…。次のUnity1weekで使うぞ~!!!
凄くきれいに実装できたので満足!

【モデリング】BlenderでモデリングしてBlockbenchで色塗ってBlenderで動作させる

2か月前ぐらいからBlockbenchを使ってローポリを作る海外動画を見漁っていました。
ローポリ、かわいい…。
youtu.be

で、実際に触ってみるとペイント機能がまあ使いやすい!
テクスチャが描けない私ですが、ペイント機能だと塗り絵のように色が塗れます。


しかし、難しい形のモデルを作成する際はBlenderの方が使いやすいと感じました。

そこで、Blenderモデリングを行い、
Blockbenchでマテリアルを作成する手法をまとめました。
我ながら頭が悪いタイトル…

Blender】モデルを作成する

モデルを作成します。
今回はヘッドホンを作ってみます。
気合で作ります。

作った後はCtrl+Tで面を三角形に分割しておきます。
分割しておかないとBlockbench側でうまく読み取れないためです

Blender】obj形式で出力する

File→Export→Wavefront(.obj)形式でモデルを任意の階層へ出力します。

【Blockbench】obj形式で読み込む

作成したモデルを読み込みます。

うまく読み込めました。

【Blockbench】テクスチャ作成

まず、右タブのメッシュ一覧上で
Shift+左クリック必要なものをすべて選択します。

選択した状態でPaintへ行き
Texturesの下にある+ボタンを押します。

押すと色々設定が出てきます。
エッジ角度とアイランドアングルのしきい値を10にすると
いい感じにテクスチャが出力されます。

【Blockbench】色塗り

色を付けていきます。
気合です。

【Blockbench】gltfで書き出し

File→Export→gltfで書き出します。

書き出し時はテクスチャと一緒に書き出しておきましょう

Blender】gltfで読み込む

作成したモデルを読み込みます。

ちっちゃくなっているはずなので…

スケールを調整して完成です。

おわりに

可愛いモデルが作れて楽しいです。
よきよき。