tanaka's Programming Memo

プログラミングについてのメモ。

Raspberrypi4にWindowsで接続してLaravel開発

ラズパイ上のLaravelをWindowsから開発できるように設定した時の手順です。学校などで利用することを想定して、複数のユーザーを登録して、お互いのユーザーフォルダーやデータベースは参照したり書き換えができないような設定をしました。

Laravelの環境構築は以下にて。

am1tanaka.hatenablog.com

目次

想定の動作環境

LAN内で、ラズパイを固定IPで接続する前提です。

Windowsからラズパイに接続する

WindowsPuTTYをインストールして、PuTTYからラズパイにアクセスします。インストールについてはこの辺りをご覧ください。

www.atmarkit.co.jp

インストールしてPuTTYを起動したら、ラズパイのIPを入力して接続します。

LaravelのページをWindowsから表示する

Laravelの開発用サービスを開始するだけだと、ラズパイのIPのポートにアクセスしても接続できないようだったので、ngrokを使って一時的にグローバルIPでサービスを動かします。以下を参考にセットアップしました。

its-office.jp

  • こちらのページを開きます
  • Linux (ARM) をダウンロードして、適当なフォルダー(/usr/local/bin/など)に展開します
  • chmod 755 ngrokで実行権限を与えます

LaravelのWebページを表示する手順

使い方は以下の通りです。

  • ngrok http 8000でngrokを起動
  • もう一つPuTTYを起動してログイン
  • 以下で、Laravelを起動
cd blog
php artisan serve

以上で、一時的なURLが作成されてWindowsスマホなどからアクセスできるようになります。Forwarding欄に表示されているURLをコピーなどして開きます。

利用が終ったら、[Ctrl]+[C]キーでサービスを停止して、PuTTYを閉じます。

Linuxのユーザーを作成する

ユーザーを作成します。newusersコマンドで一括で作成できます。以下に詳しいので割愛します。

4thsight.xyz

ユーザーごとにsambaにログインできるようにする

プロジェクトの編集はWindowsで行いたいので、ユーザーごとにログインして、ユーザーフォルダーをWindowsと共有できるようにします。

sambaの設定

先に以下を設定して、少しだけ追加します。

am1tanaka.hatenablog.com

以下、設定の参考にしました。

http://www.samba.gr.jp/project/translation/current/htmldocs/manpages/smb.conf.5.html

  • sudo nano /etc/samba/smb.confで設定ファイルを開きます
  • [homes]以下の設定をします
    • read only = no
  • sudo service smbd restart で再起動して設定を反映させます

ユーザー作成

全体的な手順は以下を参考にしました。

www.virment.com

一括登録スクリプトは以下を参考にしました。

qiita.com

登録済みのユーザー名でSambaにユーザー登録するためのシェルスクリプトファイルを作ります。以下のようにしてパスワード入力させるようにして、pdbeditのユーザー登録コマンドに既存のユーザー名を並べていきます。ユーザー名は、あらかじめLinuxに登録したユーザーと同じにします。

echo -e "password1\npassword1" | sudo pdbedit -a -t -u foo_user1
echo -e "password2\npassword2" | sudo pdbedit -a -t -u foo_user2
echo -e "password3\npassword3" | sudo pdbedit -a -t -u foo_user3

保存時は、ASCIIフォーマットかUTF-8Nで、改行をLF Onlyにします。

(pdbeditの-aはユーザー登録、-tはstdinからのパスワード入力、-uはユーザー名を指定を表します。)

作成したら、他のユーザーから見えないようにパーミッション700にします。

sudo chmod 700 foo_user1

接続方法

エクスプローラーか、或いは「ここに入力して検索」欄に\\192.168.11.5のようにラズパイのIPを入力すると、ユーザー名とパスワードの入力ダイアログが表示されます。登録したユーザー名とパスワードでログインできます。

切断方法

Sambaでは他ユーザーから同時接続ができないようです。Windowsを再起動したり、電源を落とせば切断されますが、他のユーザーが接続したままだったり、何らかの原因で接続しっぱなしだった場合、以下で切断できます。

  • Windowsのスタートメニューからcmdと入力して、コマンドプロンプトを開く
  • net useで接続状態を確認
  • 特定のものを切断したい場合は、net use /delete <リモート名>
  • 全て切断してよければnet use /delete *

MariaDB用のユーザーの作成

アクセス用のユーザーと、ユーザー用のデータベースを作成します。これはPHPのコードで実行しました。

  • ホームディレクトリーの適当な場所で、makeusers.phpなどの名前でファイルを開きます
  • 以下のPHPプログラムをコピーペーストします
  • 3行目と5行目を、MySQLを操作できるユーザーとパスワードに書き換えます
  • 8行目以降の配列に、作成したいユーザー名とパスワードに書き換えます
    • ユーザー名は、あらかじめLinuxのユーザーとして登録されている必要があります
    • ユーザー名にはハイフンは使えません
  • 書き換え出来たら上書き保存します
  • ターミナルでphp makeusers.phpを実行すれば完了です

以上で、設定したユーザー名とパスワードでユーザーが作成され、ユーザー名と同じ名前のデータベースが作成されます。ここで作成するユーザーは、ユーザー名と同名のデータベースにしかアクセスできないようになります。

権限を変更したい場合は、GRANTの部分を変更してください。

まとめ

Sambaのファイル共有でユーザーのホームディレクトリーに接続することで、WindowsからAtomエディターやらVS Codeなどでラズパイ上のファイルの操作、編集ができるようになります。

ngrokを起動しておくことで、Windowsをはじめ、スマホなどでもラズパイで作成中のWebページを表示することができます。

MySQL(MariaDB)のユーザーを作ったので、一つのラズパイを共有しつつ、他の人のファイルを覗いたりできない状況で開発を進めることができます。これは学校などでの利用を想定した設定です。1つのDBを共有するなら、それ用の権限を与えたユーザーを作ってアクセスします。

完成したサービスはXFreeあたりで公開を検討しています。Herokuだとクレジットカードが必要みたいなので。その辺りができたらまたブログに書きます。

参考URL

Raspberrypi4にLaravelの環境を構築する

ラズパイ4を入手したので、Laravelの開発ができるように環境構築してみました。その時のメモです。

目次

構築する環境

Laravelのインストールは、WindowsLinuxならHomestead、macならValetを推奨しています。しかし、Homesteadを使うにはVirtualBoxなどの仮想マシンのインストールが必要です。ラズパイでは荷が重そうなので、手動で環境を設定することにしました。

phpenvとphp-builderをインストールする

Laravelの公式ページではComposerの操作から書かれています。Composerを使うにはPHPが必要です。せっかくなので、PHPのバージョンを切り替えられるようにphpenvとphp-buildの環境を構築します。ラズパイにpiアカウントでログインしたらターミナルを起動して、以下を実行します。

sudo apt-get update
sudo apt-get upgrade

ここで、依存がどうのこうのというエラーが出たら、以下を試したら解決しました。

update / upgrade fails on older Raspian Installation - Raspberry Pi Forums

sudo apt full-upgrade
sudo apt dist-upgrade
sudo apt autoremove

以下を参考に、ビルドに必要そうなものを入れていきます。

Raspberry Pi 2 に Raspbian を入れた時にやっておいた方が良いことをまとめた - しばやん雑記

gitはあるので、以下ぐらいで。

sudo apt-get install autoconf libtool automake build-essential libxml2-dev libbz2-dev libcurl4-openssl-dev libjpeg-dev libreadline-dev libtidy-dev libxsltl-dev

re2cをインストールする

$ autoreconf -i -W all
$ mkdir /usr/local/bin/re2c
$ ./configure --prefix=/usr/local/bin/re2c
$ make
$ make install

最後に、.bash_profileファイルに以下を追加してre2cにパスを通します。

export PATH="/usr/local/bin/re2c/bin:$PATH"

phpenvをインストールする

phpenv-installerはエラーでうまくいかなかったので、手動でgitリポジトリーをクローンして構築しました。

github.com

今回、他のユーザーも使えるように/usr/local/bin/phpenv以下にクローンしました。

  • ドキュメントに従ってrootの.bash_profileに対して、パスとphpenv initを追加
  • exec $SHELL -lでシェルをリスタートしました

次に、/usr/local/bin/phpenv/plugins/php-build以下に、php-buildをクローンします。

github.com

クローンしたら、php-buildフォルダー内のinstall.shを実行します。

./install.sh

実行できなければ、sudo chmod 755 install.shで権限を与えます。

これで、phpenv installが利用できるようになります。phpenvが実行できない場合は、source ~/.bash_profileを実行します。

PHPのインストール

以下のコマンドでインストール可能なPHPのバージョンを調べます。

phpenv install --list

7.2以降をインストールします。7.2.26の場合、以下の通り。

phpenv install 7.2.26

ビルドには1時間弱かかりました。

The Log File is not empty,という表示が表示され、ログファイルを確認するか、--verboseスイッチをつけてリビルドするように表示されますが、ビルド自体は成功していました(今のところこの設定でそのまま使っていますが、あれこれ警告が出たのでインストール時に--with-libzipをつけた方がいいかも。)

以下で、PHPを全ユーザーから見れるようにします。

phpenv global 7.2.26

Composerをインストールする

getcomposer.org

今回はグローバルで使いたいので、composer.pharをダウンロードしたら、/usr/local/bin/composerにリネームして配置します。

curl -sS http://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

以上でComposerが利用できるようになります。これでようやくLaravelをインストールできます。

Laravelをインストールする

以下に従ってインストールします。

laravel.com

composer global require laravel/installer
  • sudo nano /etc/profileで共有プロファイルを開きます
  • 以下を最後に追加します
export PATH="/home/pi/.phpenv/shims:$PATH"
export PATH="/home/pi/.config/composer/vendor/bin:$PATH"
  • source /etc/profileを実行して、更新を反映させます

以上で、Laravelへのパスが通ります。

試す

一般ユーザーでログインして、以下を実行します。

laravel new blog

サンプルブログの生成が完了したら、以下でサービスを開始します。

cd blog
php artisan serve

サービスが開始したら、URLが表示されるので、ブラウザを起動してアクセスします。うまくいけば、Laravelのページが表示されます。

f:id:am1tanaka:20200215230725p:plain
Laravelのサンプルブログページ

少し変更してみる

ちゃんと変更できるか表示内容を変えてみます。

cd ~/blog
nano resources/views/welcome.blade.php

これで、ウェルカムページを構築するためのVueのテンプレートページが開きます。84行目付近に表題のLaravelとある行があるので、そこを適当に変更してみましょう。

f:id:am1tanaka:20200215230933p:plain
welcome.blade.php

  • 変更したら、上書き保存をして先ほど表示したらWebブラウザーをリロードします。すると、変更した通りに表題が変更されるはずです。

f:id:am1tanaka:20200215231114p:plain
変更されたか試す

MySQL(MariaDB)をインストール

Laravelを使うならデータベースも使うでしょう。ラズパイではMySQLから派生したMariaDBがよく使われているそうなので、そちらをインストールします。なお、使い方はMySQLと同じです。参考資料は以下の通り。

www.ossnews.jp

手順は以下を参考にしました。

nort-wmli.blogspot.com

  • 端末を開いて、以下でインストールします
sudo apt install maria-client maria-server
sudo systemctl restart mariadb

これでインストールは完了ですが、そのままだとsudo抜きでは接続できません。これを修正します。

  • DBに接続します
sudo mysql -u root
USE mysql;
UPDATE user SET plugin='' WHERE User='root';
exit;

設定ができたらDBを以下でリスタートして、sudo抜きで接続を確認します。

sudo systemctl restart mysql
mysql -u root

うまく接続できればOKです。exit;MySQLから退出します。続けて、セキュリティ設定をします。

  • ターミナルでmysql_secure_installationを実行します

rootのパスワードの設定をして、あとはそのままyesで進めれば完了です。

MySQL用のユーザーを作成

rootで操作するのも嫌なので、MySQLを操作するユーザーを作成しておきます。

  • mysql -u root -pでパスワードを入力してログインします
  • ユーザー登録をします。以下は、ユーザー名hoge、パスワードpiyoの場合の書き方です。適宜、変更してください
CREATE USER 'hoge'@'%' IDENTIFIED BY 'piyo';

以上で、最低限の準備は完了です。あとは、データベースを作成したり、作成したユーザーに権限を与えれば、PHPやLaravelから作成したユーザーでログインして作業をすることができます。

閉じる

MariaDB(MySQL)のクライアントから出るには、exit;と入力します。

Laravelを停止するには、php artisan serveしたターミナルで[Ctrl]+[C]キーを押して、サービスを停止します。あとはターミナルなどを閉じてOKです。

まとめ

以上で環境構築完了です。

  • phpenvとphp-builderのインストール
  • phpをビルドする環境のインストール
  • phpのインストールとグローバル設定
  • composerのインストール
  • laravelのインストールと環境設定
  • サンプルblogプロジェクトを作成して、表示と編集確認

調べながらだったので結構時間がかかりましたが、手順通りなら2時間ぐらいで設定できると思います。1万円ぐらいのPCで開発環境が作れるのは面白いです。実際には、このラズパイにユーザーを作って、そのユーザーがWindowsからラズパイに接続してLaravelの開発ができる環境を作りました。それは別のブログにまとめます。以下、Windowsとの連携のための設定ブログです(2020/2/16追記)。

am1tanaka.hatenablog.com

参考URL

CRI ADX2 LEを使ってみる(音が鳴らない時の対処を追加)

f:id:am1tanaka:20200116181208p:plain

Unityで音関連を制御するとなると、必ず名前が挙がるのがCRIWAREさんのADX2 LEです。これまでなかなか開拓する機会がなかったのですが、学校で音ゲーを作っているTさんが使い始めたということで便乗して使ってみることにしました。音を鳴らすまでにやったことのメモです。

game.criware.jp

基本はチュートリアルでできるのですが、ちょくちょく話が前後したり、別の場所に書いてある情報などがあったのをまとめた記事です。

目次

情報源

game.criware.jp

こちらの公式のチュートリアルにて。

ADX2LEを利用する前提

無償版だとWebGLで使えません!!unityroomなど向けの場合はお気をつけください。以下、通常版の手順が紹介されていました。

unityroomでADX2を使う - Qiita

無償で利用できる範囲を『CRI ADX2 LE』に関するユーザー使用許諾契約書 – CRIWARE for Games第3条 (別途使用許諾契約が必要な場合)で確認しておきます。以下、2020/1/16時点での抜粋です。更新される可能性があるので、利用時にはちゃんと本家で確認してください。

  1. 前年の年商が1,000万円を超える企業、団体が対象コンテンツの配信をする場合。
  2. 前項に該当する企業、団体の、関連会社及び子会社が対象コンテンツの配信をする場合。
  3. パブリッシャーまたはエージェントを介して対象コンテンツの配信をする場合。
  4. 対象コンテンツの配信による累計売上額(広告、アプリ内課金、サブスクリプションモデルの売上を含む)が1,000万円を超えた場合。

また、第4条 (対象コンテンツの配信を行う場合)で、ADX2LEを組み込んだアプリを配信する際には、以下が条件になります。

  1. ロゴ表示または文書による本ソフトウェアの著作権表記。
  2. 対象コンテンツ使用者に対する禁止事項、著作権、免責ならびに権利事項の表記。

無償で利用する場合、これらの条件に合致していることと、ライセンス表記と各種注意事項の表記が必要です。ロゴ表示は、自動的にやってくれるものがアセットに組み込まれています。詳しくは、公式サイトに記載されています。

音を鳴らすまでの流れ

Unityで音を鳴らすまでの流れは以下に記載されています。

game.criware.jp

ここでのポイントは以下の通り。

  • 鳴らしたい音源データ(wavのみらしい)を、AtomCraftというツールを使って、ADX2用のデータ(キューシート)に変換します
  • Unityにインポートできるように指定をしてエクスポートします
  • Unityに、ADX2LEを指示に従ってインポートして、初期設定します
  • 作成したキューシートをUnityのプロジェクトに読み込みます
  • 必要に応じて、再生するためのスクリプトを書きます

必要なものをダウンロードする

game.criware.jp

このページのダウンロードをクリックして、規約に目を通したらダウンロードをクリックして開発ツールを入手します。ダウンロードしたzipファイルは、ドキュメント内のToolsフォルダーなどの中に展開します。展開すると、criという名前のフォルダーが作成されて、その中にAtomCraftやUnityのプラグインをはじめ、必要なものがすべて入っています。

扱えるデータ

mp3やoggからを直接インポートはできないっぽいです。使いたい音源がmp3やoggなどの場合、オンラインのフォーマット変換ツールを利用するか、Audacityなどであらかじめwavに変換しておきます。

「Audacity」無料の音声編集ソフト - 窓の杜

Audacityは無音部を切り取ったりできる便利ツールで重宝してます。

キューシートを作成する

Unityで作業を始める前に、AtomCraftを使って音源データを作成する必要があります。AtomCraftを起動します

  • criフォルダーから、tools > criatomex > win と辿っていくと、CriAtomCraftがあるので、起動します
  • スタートページが開いたら、新規作成をクリックして、新しくプロジェクトを作成します。名前はFirstADXなど
    • 場所は、特に必要がなければそのままでよいでしょう。ユーザーのドキュメント内にCRIWAREというフォルダーが作成されて、その中にプロジェクト用のデータが設置されます
  • ワークユニットの追加ウィンドウが表示されます。とりあえずそのまま追加してOKです
    • 注意。プロジェクトは名前などを内部で紐づけているようで、AtomCraft以外の環境で名前を変更したり、削除したり、移動すると予想外のことが発生するようです。AtomCraft上で操作するようにしてください

あとは、以下のチュートリアルに沿えばおおよそ大丈夫でした。

game.criware.jp

2点だけちょっと注意。

  • 3のボリュームの一括確認方法がわからなかった
  • 最後のエクスポート時、Unityで利用する場合は、Unity Assets出力へのチェックが必要

以上でビルドして、出力パスを開くをしておけばデータの生成は完了です。

Unityで音を鳴らす

Unityも公式チュートリアルを見ていきます。入門編の01と02はバージョンアップで少し楽になっていたので、以下でいけます。

  • 先にダウンロードして展開したcriフォルダーから、unity > pluginフォルダーを開くと、criware_unity_pluginがあるので、これをUnityのProjectウィンドウにD&Dするなどしてインポートします
  • Windowメニューから、CRIWARE > Open CRI Atom Windowを選択します
  • ウィンドウが起動したら、Use Copy Assets Folderにチェックを入れます
  • Select Assets Rootボタンをクリックして、AtomCraftでビルドした時に開いた出力パスから、プロジェクトフォルダー > Public > Assets フォルダーのパスをコピーして、Unityの方に設定します
  • Update Assets of "CRI Atom Craft"ボタンをクリックします

以上で、必要なキューシートデータが、UnityのプロジェクトのStreamingAssetsフォルダーにコピーされます。

ここからは入門編03に沿って作業します。

game.criware.jp

  • 音を鳴らしたいシーンや、システムシーンがあればそこに、指示に従ってGameObjectメニューからCriWareLibraryInitializerCriWareErrorHandlerを読み込みます
    • CriWareErrorHandlerは開発用なので、必須ではありません
  • 指示に従って、空のゲームオブジェクトを作成して、Cri Atomスクリプトをアタッチします
  • 出力したAtomCraftのキューシートデータのファイル名を設定していきます。例えば、効果音用のSeCueとBGM用のBgmCueを作成していたら、以下のような感じです

f:id:am1tanaka:20200116140219p:plain
Cri Atomの設定

効果音はすべてメモリにしたのでawbファイルはありません。よって空欄です。BGMは、いくつかのものをストリーミングにしたので、awbファイルも指定しています。

これらのファイル名は自力入力です。

音を鳴らす

入門編04に従って、音を鳴らしてみます。

game.criware.jp

  • 先ほど開いたCRI Atom Windowを閉じていたらもう一度Windowメニューから開きます
  • UnityのPlayを開始します(Playしないとうまく動きません!!)
  • Reload Infoボタンを押して情報を取得します

以上で情報が取得できたらOKです。Playを停止します。

シーンにBGMを設定する

鳴らしたいBGMをウィンドウから選択したら、Create GameObject ボタンをクリックすると、BGM再生用のゲームオブジェクトがシーンに生成されます。

ここで作成されたオブジェクトを見ると、音の鳴らし方が分かります。

ここまでできたら、あとはやりたいことをチュートリアルやマニュアルから探せばOKでしょう。

game.criware.jp

音が鳴らない時(2020/1/31追記)

以下のようなエラーが発生する場合があります。これは、ストリーミングで出力したキューシートをCIR Atomウィンドウで自動生成した時に発生します。

[CRIWARE] Warning:W2010053100:An AWB file [CueSheet_0.awb] is not attached to an ACB handle.

原因は、自動的に生成したCRIWAREオブジェクトのAWBファイルの設定が空欄のままというものでした。手動でAWBファイルを入力することで、音が鳴るようになりました。

f:id:am1tanaka:20200131170817p:plain
AWBファイル

ライセンス表示

無償版サウンドミドルウェアCRI ADX2 LE – CRIWARE for GamesADX2 LEを使ったアプリ・ゲームを配布する方へのあたりに、ライセンス表示の仕方や、UnityでADX2 LEのロゴを表示するためのサンプルがあります。便利!

まとめ

音データを作成して、鳴らすことができました。Unityのオーディオシステムが不要な場合は、以下をしておくとよさそうです。

  • ProjectSettingsのAudioで、Disable Unity Audioにチェックを入れると、Unityのオーディオを無効にできる

AtomCraftというツールを使ってwavからキューシートを生成することと、Unityにちょこちょこと初期化設定が必要ですが、1時間もあれば音を鳴らすまではいけると思います。ちょっと時間がある時にやっておくと良さそうです。

導入するだけで音周りの速度アップが期待できるのは大きいです。機能は大量にありますが、差し当たり以下のあたりを活用しようと思ってます。

  • 同じ音の最大音数の制限(効果音でこれはとてもありがたい)
  • いくつかの音のランダム再生(足音などで便利)
  • イントロを飛ばしたループの設定

Sofdec2を使えば動画もよしなに行けそう。もしかしたらVoxelorerBirdで難航していた部分もこれで解決できるかも?

WebGLが無償で使えないというのはありますが、スマホ版のアプリには早速導入してみようと思います!

参考URL

MK GlassとPro Texで氷を作る

この記事は、Unityアセット冬のアドベントカレンダー 2019 Winter!の17日目の記事です。

assetstore.info


氷のブロックが作りたい!と思い、MK Glassを購入しました!

assetstore.unity.com

こんな感じで利用しています↓

VoxelorerBirdの氷ブロック

この記事では、MK Glass - Refractive Shader | VFX Shaders | Unity Asset Storeと、テクスチャーをプロシージャルに生成するフリーアセットのProTexを使った氷ブロックの作り方と作例をご紹介します!

作例:氷に乗って迫りくるペンギン!

目次

MK Glassとは

MKさんことMICHAEL KREMMELさんというと、MK Glowで有名かと思います。

assetstore.unity.com

同じ作者さんが作成した透明な物体用のシェーダーです。機能限定のフリー版もあります。

assetstore.unity.com

目に付く違いは、最適化、ライトの数、反射といったところでしょうか。基本機能はFree版にもちゃんとあります。

正規版とFree版の違い

Pro Textとは

ざっくりというと、図形やノイズをグラフで組み合わせてテクスチャーを作成する今どきのプロシージャルなテクスチャー生成アセットです。

assetstore.unity.com

お気に入りのアセットで、前にブログに書きました。

am1tanaka.hatenablog.com

インストールとデモ

MK Glassを購入して、お試し用のプロジェクトを作成してインポートしました。以下の場所にExampleSceneMKGlassというPDFがあるので開きます。Exampleのunitypackageをダウンロードするリンクが開くので、ダウンロードしてインポートします。

Example

※Free版にはこのPDFはありません。

エラーの解消

2019/12/10現在、Unity2019.2.xで開くとMinDrawer.csがどうとかこうとかというエラーが発生しました。ポストプロセス用のものとUnityEngineに含まれるものが被っているとのことです。3行目に以下のようにusingを追加して、MinAttributePPMinAttributeに変えれば直ります。

using UnityEngine;
using UnityEngine.PostProcessing;
using PPMinAttribute = UnityEngine.PostProcessing.MinAttribute;

namespace UnityEditor.PostProcessing
{
    [CustomPropertyDrawer(typeof(PPMinAttribute))]
    sealed class MinDrawer : PropertyDrawer
    {
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            PPMinAttribute attribute = (PPMinAttribute)base.attribute;

            if (property.propertyType == SerializedPropertyType.Integer)
            {
                int v = EditorGUI.IntField(position, label, property.intValue);
                property.intValue = (int)Mathf.Max(v, attribute.min);
            }
            else if (property.propertyType == SerializedPropertyType.Float)
            {
                float v = EditorGUI.FloatField(position, label, property.floatValue);
                property.floatValue = Mathf.Max(v, attribute.min);
            }
            else
            {
                EditorGUI.LabelField(position, label.text, "Use Min with float or int.");
            }
        }
    }
}

デフォルトで入っているDemoシーンと、ダウンロードして読み込んだMKGlassExample0MKGlassExample1の3種類のデモを見ることができます。

シンプルなデモシーンです。

Demo

オブジェクトの種類や、シェーダーの設定をリアルタイムに変更してみることができるデモです。

MKGlassExample0

WASDで移動、マウスで見回しができるデモです。音が足りないようで、一歩歩くごとにWarningが表示されます・・・^^;

MKGlassExample1

氷を作ってみる

できることはおおよそ分かったので、氷のブロックを作ってみます。あれこれいじれるMKGlassExample0シーンを利用しました。

  • 新規にMaterialを作成して、IceBlockなどの名前にします
  • 作成したIceBlockマテリアルをクリックして選択します
  • InspectorウィンドウのShader設定を、MK > Glass > Defaultの順にクリックして設定します

Glassシェーダー

マテリアルは、Main Cameraにアタッチされているスクリプトで切り替えたりしているので、そこに作成したIceBlockマテリアルを設定します。

  • Hierarchyウィンドウで、Main Cameraをクリックして選択します
  • Projectウィンドウで、作成したIceBlockマテリアルをドラッグして、InspectorウィンドウのMK Glass Example 0 ControlコンポーネントにあるBase MaterialsElement 0にドロップします

マテリアルを設定

Playするとこんな感じになりました。見回してみるとすでにピカピカしてます。

デフォルトのままのGlassシェーダー

左上のボタンをクリックすると設定バーが表示されます。凹凸がないので、現状で有効なのはSpecular(光の反射)とReflection(周囲の景色の反射)ぐらいです。

パラメーターをいじる

デコボコさせてみる

デコボコを作るには、Normalマップのテクスチャーを利用します。サンプルには、以下のような12個のNormalマップが入っています。

Normalマップテクスチャー

先ほど作成したIceBlockNormal map欄の左の四角に、これらのNomalマップテクスチャーをドラッグ&ドロップするとCubeがデコボコになります。

Normalマップをアタッチ

Playを停止して、Sceneウィンドウで確認するのが手っ取り早いです。

デコボコ具合の確認

一通り見てみると分かるのですが、規則的な模様が入っているものがほとんどで、自然の氷っぽい表現のものはWall0_Nか、

Wall0_N

wall01normalぐらいです。

wall01normal

ちょっと物足りない感じ。ということで、ProTexの出番です!

ProTexでデコボコを作る

ProTexをダウンロードしてインポートします。無料なので助かります!

  • ProjectウィンドウのCreateから、ProTex > ProTex Textureを選択して、ProTex Textureを作成して、名前をIceNormalなどにします

ProTex Texture

  • InspectorウィンドウのOpenボタンをクリックして、エディターを開きます

ProTexテクスチャー

ノイズを利用します。ProTexでは、以下の5種類のノイズが作成できます。

ノイズ

今回の用途だとFBM Noiseがよさそうです。他のはクリックして選択したら[Delete]キーで削除します。

  • FBM Noiseoutをドラッグして、Outputnormalでボタンを離します

ノイズをNormalへ

これで、ノイズを使ったNormalマップが作成できました。ProTexウィンドウを閉じます。

Inspectorウィンドウでテクスチャーを作成します。サイズは512x512も必要なさそうなので、少し小さくします。

  • Texture Size 256x256などに変更します。オブジェクトをどのぐらいの大きさで表示するかに応じて変更してください

テクスチャーサイズを設定する

  • Generate Normalをクリックして、画像として保存します

以上で、自作のNormalマップができました。これをIceBlockにアタッチします。

自作のNormalマップによる氷

先ほどより、柔らかい感じの表面になりました。

イメージする感じに近づくようにProTexウィンドウでサイズなどを調整していきます。ProTexに変更を加えたら、先ほどGenerateしたテクスチャーを削除してから、テクスチャーサイズを再設定してGenerateし直します。

パラメーターを変更したら、Apply Changesをクリックするのを忘れずに!

作例

海の上に円盤状の氷を浮かべて、ペンギンを乗せてみました。

完成!

水面はDefinitive Stylized Water | VFX Shaders | Unity Asset Storeを利用しました。これもお気に入りのアセットで、使い方をこちらにまとめています。

assetstore.unity.com

ペンギンはSuriyunさんのPenguins | Characters | Unity Asset Storeを利用しました。

assetstore.unity.com

こちらは、Low Poly Series: Caverns | 3D Environments | Unity Asset Storeと組み合わせた例です。

洞窟のクリスタル

クリスタルのシェーダーをMK Glassに変更しました。

assetstore.unity.com

まとめ

MK Glassで氷を作ってみました。設定はマテリアルをいじれば確認できるのでとても簡単です。これで得点用のクリスタルも作ったりしようと考えています。

今回のようにProTexでNormalマップを作れば、応用範囲は広がります。CC0のPBRテクスチャーサイトなどから入手するのもよさそうです。

こんな感じで活躍してます!

VoxelorerBirdの氷ブロック

参考URL

ラズパイ4にSambaを入れてファイルサーバーにする

学校のファイルサーバーが不安定になることがあって、そんな時にささっと代替手段を用意したい。他にも、サーバーやWebの勉強の際に手軽にインストールができるサーバーが欲しいとか、Phaserを動かしてみたいとか、ルキグラの描画に使えそうとか、あれこれ野望が浮かび、ラズパイ4を購入しました!

購入したラズパイと、Sambaのインストール手順です。

2019/12/11 nanoの終了時にYキーを押す手順が抜けていたので追加。 2019/12/12 ラズパイが見えない時の対策を追加。

目次

購入したもの

購入したのは、千石電商さんの秋葉原店にあったスターターパックです。電源やMicro HDMIケーブルなどを自分で選ぶのに不安があったのと、ヒートシンクやファンを揃えるのが面倒というのがありました。それらが揃っている優れたパックでした。

f:id:am1tanaka:20191208203742j:plain
ラズパイ4スターターパック32G

ケースは純正のものではなく、200円上乗せしてヒートシンクとファンが付いているやつにしました。熱対策は万全!SDカードは32GB。これで税込み11,630円。お手頃価格!

最初のインストール時に、スターターパック以外に以下が必要になります。

  • USBマウス
  • USBキーボード
  • HDMIが繋がるモニター

以上は手持ちのを使いました。

下準備

以下の公式ページを見ながら初回のインストール作業を済ませます。

projects.raspberrypi.org

インストールが終わったら、SSHを使えるようにします。レグポンさんの以下のページを参考にしました。

regpon.hatenablog.com

  • ウィンドウの上からターミナルをクリックして起動したら、以下を入力します。
sudo raspi-config
  • 設定ウィンドウが開くので、5 Interfacing Options を選択します
  • P2 SSH を選択します
  • Yesを選択して、Okします

これでSSHは有効になりますが、外部から簡単に接続できるようにホスト名を設定しておきます。

  • ターミナルから以下を入力します
sudo nano /etc/hosts
  • 最後の127.0.0.1で始まる行の最後を以下のように書き換えます。raspの部分は好きに書き換えてください
127.0.0.1    raspberrypi.local
  • [Ctrl]+[X]キーを押すと保存するか聞いてくるので、[Y]キー > [Enter]キーで保存します
  • 続いて以下を入力します
sudo nano /etc/hostname
  • 1行目を、先に入力した???.localのホスト名に書き換えます
raspberrypi.local
  • 先ほどと同じく、[Ctrl]+[X]キーを押して、[Y]キー > [Enter]キーで保存して、エディターを閉じます
  • 以下で、ラズパイを再起動します
sudo reboot

以上で外部から接続できるようになります。Windowsからの場合、PuTTYなどのSSHクライアントソフトで接続します。

www.putty.org

接続時に設定したホスト名(この例通りならraspberrypi.local)を入力すれば、ラズパイに接続して、IDとパスワードの入力を求められます。IDはpiで、パスワードはインストール時に設定したものを入力してください。

これ以降の作業は、Windowsなどの端末側から操作できます。

Sambaの設定

Sambaの設定の情報は、Raspberrypi公式マガジンのWebサイトのものが参考になりました。

magpi.raspberrypi.org

ここからは、PuTTYを使ってSSH接続をして操作しました。ログインは、ユーザーIDをpi、パスワードはインストール時に設定したものです。

Sambaのインストール

  • ターミナルを起動して、以下を入力してSambaのインストールをします
sudo apt update
sudo apt upgrade
sudo apt install samba

元のドキュメントにあったsamba-common-binはなくても大丈夫でした。

  • キー入力を求められるので、Yキーを押します

以上でインストールが始まるので、終わるまで待ちます。

共有フォルダーの作成

以下を入力して、Sambaで共有するフォルダーを作成します。

sudo mkdir /home/pi/shared

piのホームディレクトリー下にフォルダーを作ることで、そのまま権限の管理ができます。

pi以外のユーザーでやろうとすると権限周りの設定がややこしくなります。特に問題はなさそうなので、piのままでよいかと思います。

Sambaの設定を行う

まずは、以下を実行して、最初の設定のバックアップをとっておきます(最初の1回目でこれをやらずに設定ファイルの変更を間違えて、ラズパイの再インストールからやり直しました^^;)。

sudo cp /etc/samba/smb.conf /etc/samba/smb.conf_backup

以下で、設定ファイルを開きます。

sudo nano /etc/samba/smb.conf

ファイルの一番下に、以下を入力します。

path = /home/pi/shared
available = yes
valid users = pi
browsable = yes
writable = yes

詳細は、Samba.orgのドキュメントにありますが、一先ず上記のように追記すればOKです。

[Ctrl]+[X]キーを押したら、[Y]キー > [Enter]キーを押して、エディターを保存して閉じます。

念のため、以下を実行して、設定に間違いがないかを確認しまs。

testparm

色々と表示されますが、最後にLoaded services file OKと表示されれば問題ありません。違う表示が出たら設定を間違えた可能性があるので、smb.confをnanoエディターで開くところからやり直して、入力した文字に間違いがないか確認してください。

パスワードの作成

Samba用のパスワードを設定しておく方が安全でしょう。以下を実行します。

sudo smbpasswd -a pi

パスワードの入力を促されるので、ラズパイへのログイン用のものとは違うシンプルなパスワードを決めて入力してください。入力して[Enter]キーを押すと、もう一度確認を求められるので、同じパスワードを入力して[Enter]キーを押します。

以上できたら、Sambaサーバーを再起動するために、以下を入力します。

sudo service smbd restart

これでラズパイ側の設定は完了です。

Windows側の設定

この段階では、まだWindowsからラズパイが見えません。Windowsの設定が必要です。

  • 検索バーにcontrolと入力して、コントロールパネルが見つかったらクリックします
  • プログラムの文字をクリックします
  • Windowsの機能の有効化または無効化をクリックします。管理者権限が必要です
  • 下にスクロールして、SMB 1.0/CIFSファイル共有のサポートの左の+をクリックして開きます
  • SMB 1.0/CIFSクライアントにチェックします
  • OKをクリックしてウィンドウを閉じます

再起動が必要な場合は、再起動してください。以上完了したら、エクスプローラーのネットワークにラズパイのファイルサーバーが表示されます。

接続時には、IDとパスワードが必要になります。IDはpi、パスワードはSambaのインストール時に設定した簡単なパスワードです。

pisharedの2つのフォルダーが見えるようになると思います。piホームフォルダーが丸ごと見えるのでぎょっとしますが、読み取り専用なので悪さはできません。ラズパイ上で作業する時は、piではないユーザーを作った方がよさそうです(Linuxなので、管理者であるpiで通常の作業をしないのは当然ではありますが)。

macからのアクセス

maciOSAndroidのデバイスからなら、そのままファイルサーバーにアクセスできるそうです。macの場合、FinderのNetworkを開けば見えるので、Windowsと同様に操作できます。

ラズパイが見えない時の対処(2019/12/12追記)

PuTTYなどのSSHクライアントからの接続失敗

SSH????.localに接続しようとして失敗した時は、IPアドレスで接続して、設定を保存したらそれ以降は接続できるようになりました。

ネットワークにラズパイが出てこない

直に接続を試みます。Windows10で、[Windows]キー+[R]キーを押して、ファイル名を入力して実行するダイアログを表示して、以下を入力します(\は円記号)。

\\IPアドレス\pi

例えば、ラズパイのIPアドレスが192.168.1.2の場合は、\\192.168.1.2\piと入力します。ユーザーとパスワードの入力画面になったら、ユーザーをpi、パスワードはSambaで作成したパスワードを入力します。

これでダメな場合は、Sambaが動作しているかを確認します。ラズパイのターミナルで以下を実行します。

service smbd status

動作していない場合は、sudo service smbd restartで再開します。

また、有線で接続しているラズパイに、無線LANで接続しているPCから接続しようとした時に、ネットワークの場所が違っていたようで見つかりませんでした。どちらも同じルーター下の有線で接続したら見えるようになりました。

まとめ

以上で、外部ストレージを使わないラズパイ単体での簡易ファイルサーバーの出来上がりです。自分の用途は、ちょっとしたリソースの共有が目的なので30GBもあれば十分です。もっと大容量で、という場合は、外部ストレージの設定例もあちこちありました。日本語の情報はほぼ外部ストレージを利用するものでした。

ラズパイをカバンに入れておけば、LAN環境ですぐにファイルサーバーにできて重宝しそうです!

参考URL

高さでグラデーションをかけるシェーダーをUnityで作ってみた

この記事は、シェーダーアドベントカレンダー Advent Calendar 2019の8日目の記事です。

qiita.com


ローポリでアンビエントオクルージョンが効かないような形だとのぺっとしてしまいます。頂点色を手動で設定するのは面倒だし、その程度のシェーダーなら自作できるかな?と思って作ってみたので公開します。

https://cdn-ak.f.st-hatena.com/images/fotolife/a/am1tanaka/20191209/20191209133511.png

2019/12/9 シェーダー言語はCgは廃止の方向であり、HLSLの方を調べるのがよいでしょうと、さやちゃんぐbotさんから教えていただきましたので追記しました。

2019/12/12 Cg/GLSLについて、さやちゃんぐbotさんから追加で教えていただいたことについても追記しました。

目次

高さグラデーションシェーダーHeightGradationShaderの使い方

まずは作成したシェーダーの使い方をご紹介します。

シェーダーの作成

  • UnityのProjectウィンドウから、Create > Shader > Unlitを選択して、Unlitシェーダーを作成します

f:id:am1tanaka:20191209131154p:plain
Unlitシェーダーを作成

  • 名前はHeightGradationUnlitShaderなどでOKです
  • 作成したシェーダーをダブルクリックしてエディターで開きます
  • 元のスクリプトを消して、以下のスクリプトを貼り付けて保存してください

以上でシェーダーの準備完了です。あとはマテリアルに設定すれば動作します。

マテリアルの作成とオブジェクトへのアタッチ

  • マテリアルを作成して、シェーダーをUnlit > HeightGradationShaderに変更します

f:id:am1tanaka:20191209132103p:plain
シェーダーをマテリアルに設定

  • SphereでもCapsuleでもQuadでも、適当な3Dオブジェクトを作成して、作成したマテリアルをアタッチします

f:id:am1tanaka:20191209133058p:plain
デフォルト設定でアタッチした例

パラメーター

設定できるのは、テクスチャー、上端の高さと色、下端の高さと色です。

f:id:am1tanaka:20191209133511p:plain
パラメーターの調整

以上です。

このシェーダーはUnlitなので光の影響は受けません。フォグは有効です。


ざっくりと考え方

シェーダーは時々気が向くと触る程度で、記憶には何も残っていない初心者です。天神いなさんのこちらのブログを読みつつ作成しました。基本的な知識はほぼこれで得られました。

amagamina.jp

やりたかったことは以下の通りです。

  • オブジェクトの上端と下端の高さと色を設定する
  • オブジェクトの各頂点の高さから、設定に合わせた頂点色を計算して頂点カラーを設定する

以上から、必要な仕様は以下の通り。

  • float型の値を2つと、色を2つ、マテリアルから設定できるようにする
  • 頂点の高さから、上端と下端に対する内分率を求める
  • 上端の色と下端の色と求めた内分率から、頂点の色を決定
  • 求めた頂点の色を適用する

実装の解説

ブログに従って、Unlitシェーダーから作成しました。

パラメーターの設定

マテリアルで設定するパラメーターはPropertiesで宣言します。高さはFloat、色はColorで宣言すればよいので、以下の通りです。

// 3:
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _TopY("TopY", float) = 0.5
        _TopColor("TopColor", Color) = (1, 1, 1, 1)
        _BottomY("BottomY", float) = -0.5
        _BottomColor("BottomColor", Color) = (0, 0, 0, 1)
    }

MainTexはもともとあったテクスチャの宣言で、それ以外が追加したパラメーターです。これでマテリアルから欲しいパラメーターを設定できるようになります。ここで使える変数型はこちら

処理に必要なデータの定義

頂点シェーダーからフラグメントシェーダーに渡すデータを定義します。v2fというのがそれです。頂点色を渡したいので、vert_colorという名前のfloat4型のパラメーターを追加しました。

// 32:
            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vert_color : TEXCOORD2;
                float4 vertex : SV_POSITION;
            };

プロパティの値を受け取るための変数を定義します。プロパティの最初に書いたのと同じ名前の変数を定義すればOKです。高さの値は制度はそれほど必要ないのでhalfにしました。floathalffixedのどれを使うかの基準はこちらにあります。

// 42:
            half _TopY;
            half _BottomY;
            float4 _TopColor;
            float4 _BottomColor;

頂点シェーダー

今回の肝はここです。追加したのは以下の52,53行目の2行です。

// 47:
            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                half t = (v.vertex.y - _BottomY) / (_TopY - _BottomY);
                o.vert_color = lerp(_BottomColor, _TopColor, saturate(t));
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

頂点の座標はv.vertexで渡されます。これはモデル座標系、つまり親のオブジェクトを原点とした座標です。今回やりたかったのは、正にこの座標系での高さでの判定だったのでそのままこの値が使えます。

与えられた高さを、下端なら0、上端なら1になるように変換します。

  • y座標から下端を引いて、下端の高さが0になるようにする
  • 求めた値を、上端-下端で割って、上端の高さが1になるようにする
  • saturateを使って、0未満は0に、1以上は1に丸め込む
  • lerpに下端の色、上端の色、求めた内分率を渡して、頂点に対応する色を求める

以上で求めた色を、宣言しておいたvert_colorに放り込んで頂点シェーダーは完了です。

saturateについて

saturateは組み込み関数です。最初はmaxminで求めましたが、Clampぐらいあるだろうと調べて見つけました。UnityのシェーダーはCg/HLSLと名乗っているnVIDIACg言語MicrosoftのHLSLを混ぜた怪しいやつなのですが、とりあえず同じようなものらしいので、どちらかのリファレンスに載ってるやつは使えるだろうということで試したら的中でした。

HLSLのリファレンスはこちら

Cgの組み込みライブラリのリファレンスはこちら

追記

CgとHLSLについて、さやちゃんぐbotさんからコメントいただきました!

HLSLの方で調べるのがよさそうです。この辺もやもやしてたのでスッキリしました^^

フラグメントシェーダー

フラグメントシェーダーは簡単です。受け取った色を、テクスチャーの色に掛けるだけです。以下の63行目がそれです。

// 58:
            fixed4 frag(v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                // gradation
                col = col * i.vert_color;
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }

これで出来上がり!!

Cgか、HLSLか、GLSLか(12/12追記)

今から始めるならどれだ、というのが悩みどころです。Unityは当初はCg言語を採用していたようですが、開発元のnVIDIACg言語の開発から手を引くと宣言してしまいました。Cgのリファレンスに「これからWindows向けにシェーダーをやるならHLSLがいいよ~」的に書いてあります。

この辺りの流れについて、さやちゃんぐbotさんの以下のスライドの11~14ページあたりで触れられています。

learning.unity3d.jp

しかし、ターゲットがスマホの場合はどうなんだ?となります。AndroidはGLSL、iOSは古いのはGLSLで最近のはMetalです。この辺りについては、Cg/HLSLでも問題が起きることがあるそうです。

UnityはGLSLには対応はしてはいるけど、HLSLの方を主に据えているのでGLSLを使うには注意点があるっぽい。iOSはMetalだからGLSLで書いたとしても安泰ではありません。結局、オールラウンドな選択肢はないというのが現状のようです。開発リソースが小さい個人開発の場合は、Unityさんの仕組みに乗っかってHLSLベースで開発して、不具合が発生したらGLSLやらMetalやらと仕様を突き合わせて対応する、というのが現実的っぽいです。

まとめ

高さ限定という用途が制限されまくりの習作シェーダーの完成です。

  • 必要なプロパティを定義
  • 利用する機能を指定
  • 受け渡したいデータを定義
  • 頂点とフラグメントシェーダーを書く

という流れがおおよそ把握できたので、簡単なシェーダーなら自作できそうです。画面中心から同心円状にグラデーションをかけるのも作りたかったので、それもおおよそ見当つきました。

今回のは高さ限定でしたのでとてもシンプルでしたが、高さ以外の方向を基準にする場合は、基準となる向きベクトルをプロパティに追加 > 向きベクトルを単位ベクトルにする > 単位向きベクトルと座標の内積を求める > 求めた内積の値に対して、今回と同じ処理をする、でいけると思います。

何かのお役に立てば幸いです!

参考URL

Unityの命名規則とエディター設定

2023/8/18 あれこれ調べてprivate変数の前に_を付ける記法はまだ採用が少なかったので元に戻しました。

2023/8/17 情報が古くなったので一部改訂しました。

  • プライベート変数はキャメルケース_からはじまるキャメルケース 2023/8/18に取り消し
  • パブリック変数は原則としてプロパティーにすることを追記
  • 変数は名詞、インターフェースは形容詞、関数は動詞からはじめる、boolは疑問形にする
  • イベントの命名ルールを追記

この記事は、Unity #2のカレンダー | Advent Calendar 2019 - Qiitaの7日目の記事です。

qiita.com

前日の記事は、@ma_shさんのGraphView完全理解した(2019年末版) - Qiitaでした。

qiita.com


色々な言語を渡り歩いていたことで、変数名やら関数名の書き方になんとなくルールはあるけどその時の気分でブレる、というのが最近の状況でした。Unityのアセットでも違うし・・・。

ぼちぼちちゃんとしようと思い、Unityではどんな感じなのかを調べてみました。併せて、Visual Studio Community(多分Codeとか他のエディターでも使える)で自動的に規則をチェックしてくれる設定ファイルも用意してみました。

目次

まず結論

あれこれは後回しにして、今回まとめた内容です。

大文字と小文字のルール

  • Unityで作成するアセットやクラス名、メソッド名、プロパティー名など、原則としてはパスカルケース
    • PascalCase (単語ごとに頭文字を大文字で書く)
  • メンバ変数、ローカル変数、パラメーター(引数)は、キャメルケース
    • camelCase (パスカルケースの頭文字を小文字にした版)
  • インターフェースは頭文字をIにして、パスカルケースで続ける
    • IMyInterface
  • Unity以外で作成する画像や音声データなどは、小文字のスネークケース
    • snake_case (小文字のみで、単語の区切りはアンダースコア_)

Visual Studioなどで、自動的にやるには以下の手順を。

  • Unity用の.editorconfig | たなかゆうを開いて、.editorconfigという名前で、Unityのプロジェクトフォルダー直下に保存
  • Unityからプロジェクトを開いて、何かスクリプトを開く
  • プロジェクトメニューから、既存の項目の追加をクリック
  • コピーした.editorconfigファイルをダブルクリックして追加

以上で、エラー一覧ウィンドウのメッセージのところで、規則違反を確認できます。

命名規則違反の例

名前に使う単語

  • 変数名は名詞。ただし、bool型の場合はiscanをつけて疑問形にtrueやfalseで答える形にする
  • 関数名は動作を表す動詞ではじめる。これもbool型を返すものについてはIsCanHasなどを頭にもってきて疑問形にする
  • インターフェース名は形容詞
  • イベントのデリゲート名は、処理前なら進行形の動詞、処理後なら過去形の動詞を付ける
  • デリゲートをInvoke()するための関数はOnを頭につける

public変数について

原則としてpublicな変数は使わず、値を公開したい場合はプロパティーを使います。

// 読み出しだけなら => か自動実装書式が便利
int _myData;
public int MyData => _myData;

public int MyData2 {get; private set;}

// 読み書きなら自動実装書式
public int MyData3 {get; set;}

これらをまとめたサンプルを以下のリポジトリーで公開しています。

GitHub - am1tanaka/Unity-Code-Style-Guide: A inspirational C# code style guide for Unity projects

以下、お暇ならどうぞ。

命名規則とは

ファイル名やクラス名、変数名などをつける時の規則のことです。

一番の役割は問題を予防するためでしょう。Unityの場合であれば、ファイルやフォルダー名にはユーザーフォルダーも含めて日本語にしない!というのがあります。常に問題になるわけではありませんが、WebGLだとビルドに失敗する爆弾を抱えることになります。Unity1週間ゲームジャムの締め切り間際に時々、断末魔がTLに流れますが、そのような事態を防ぐことができます。

プログラミングの場合は、変数や関数がどのようなものか予想しやすくするということが挙げられます。ぱっとコードを見てなんとなくやっていることが予測できればバグの予防や保守性の向上に繋がります。また、変数や関数名を考えるのが苦手な人は多くて、そういう人たちには命名のヒントになります。

バイブルはUnity Communityに決めた!

まずは宗派を決めます。なるべくオフィシャルの近くで議論されているところがいいなぁということで、Unity Communityのものを柱にすることにしました。

http://wiki.unity3d.com/index.php/Csharp_Coding_Guidelines

調べると大体ここが出てくるので、総本山と見てよさげです(シングルトンのひな形などもあちこちで散見しますが、自分はUnity Communityのものを利用しています)。 → 2023/8/17現在、ページが消えてました。

和訳は @shun-shun123 さんがしてくださっています。

qiita.com

新しいドキュメントがUnity公式から公開されて、2023/8/17にこちらに乗り換えました。

Create a C# style guide: Write cleaner code that scales | Unity

Unityにおける命名規則

個人的には、かっこの位置とか細かいことは全く気にならない(違いに気づけない)ため、Visual Studioさんにお任せです。ということで、重要なのは命名規則のところです。以下に抜粋。

  • ハンガリアン記法は使わない
  • 接頭語(, m, s_, etc)は使わない使うか使わないかを決めて、その方針を一貫させる
  • ローカルとメンバ変数を判断するときは"this"を使う
  • メンバ変数にはキャメルケースを使う(e.g myData)
  • パラメータにはキャメルケースを使う
  • ローカル変数にはキャメルケースを使う
  • 関数、プロパティ、イベント、クラス名にはパスカルケースを使う(e.g MyData)
  • インタフェースの名前は"I"から始める
  • enums, classes, delegatesの先頭は文字で修飾しない

原則としては、マイクロソフトC# プログラミングガイドに従おう、ということだそうです。こちら、とても参考になります。

docs.microsoft.com

そして日本の場合、

  • 日本語や全角文字を使わない

も加えておくのが良いでしょう。せっかく規則を作るのだから、要らぬ混乱の元は断ち切っておくのが吉。

ハンガリアン記法DirectXの頃は使ってたなぁ。その下の「接頭語は・・・」や「enums, classes, delegatesの先頭は・・・」もハンガリアン記法ですよね。昔は今みたいにコードの説明を自動的に表示してくれるなんてしてくれなかったので役立ちましたが、今どきの頭のよいエディターは全部表示してくれるから確かに要らない気がします。時代に合っていてよいですね。インターフェースのIが生き残っているのは趣深い。

パスカルケース

ざっくりとまとめると、基本的にはパスカルケースを採用しています。パスカルケースは、単語の頭文字が大文字であとは小文字で書く方法です。

// :
PascalCase

というような感じです。

キャメルケース

メンバ変数、ローカル変数、パラメータ(引数)にはキャメルケースを使います。キャメルケースとは、最初の文字が小文字のパスカルケースです。

// :
camelCase

となります。ルールはこれだけで、列挙子や定数、プロパティなども、ここに登場しないものはパスカルケースです。統一されていて守りやすい規則でいいですね!

staticと公開範囲はどっちが先?

// こんな順番のと
static public int staticFirst;

// こんな順番のがある
public static int staticSecond;

アセットの中身見てると、ちょいちょい前者の順番を見かけます。そう書いてもVisual Studioさんが逆にしちゃうのでもっぱら後者を使ってます。C# プログラミングガイドでも後者の順番でしたので後者でよさそうです。

docs.microsoft.com

ファイル名の命名規則

Unityで作成するファイルはビルドされてるのでこれでいいのですが、画像や音声など外部から読み込む可能性のあるファイルについては別規則の方がいいかも・・・という気がします。Linuxなどでファイル管理する場合、大文字小文字が入り乱れるのはなんとなく気持ち悪いし・・・。ということで、Unity以外のツールで作成するリソースについては、他の命名規則の方がいいかもしれない、ということで探したところ、クラスメソッドさんの以下の記事がよさそうです。

dev.classmethod.jp

命名規則の必要性などについても、しっかりと書かれております。

ファイル名やレイヤー名はスネークケース

スネークケースとは、単語をアンダースコア(_)でつなげる書き方のことです。上下にうねうねして見えるのが蛇っぽいからとかなんとか。

// :
snake_case

Linuxファイルシステムは大文字と小文字を区別するため、大文字小文字を混ぜたファイル名のつけ方をすると、同じファイルのつもりが別のファイルになってしまっていたというような問題が発生します。さらにその状態で大文字小文字を区別しないWindowsとやり取りするとえらいことになります。ということで、識別がしやすい小文字に統一するのが一般的だと思います。そして、こちらでも日本語は封印されています。

単語の並べ順や単語数は、プロジェクト次第で決めることになると思います。リソース数が数十程度の小さなプロジェクトなら名称_目的や行動[_通し番号]で、あとはフォルダー分けするぐらいでしょうか。

haku_walk_00.png
haku_walk_01.png
block_albedo.png
block_normal.png

何千とか何万のリソースを使うプロジェクトでは、カテゴリーや種類なども含めたり、解像度によってリソースを切り替えたい場合などもそれ用の記載が必要になると思います。プロジェクトの規模や、扱うリソースの複雑さ次第で、適した命名ルールを決めていくことになると思います。綺麗に種類ごとに並ぶような命名方法が使いやすい方法だと思います。

コード規則を自動化するEditorConfig

規則を決めても、守られているかを人力でチェックするのは辛いです。これを自動化してくれるのがEditorConfigです。

editorconfig.org

docs.microsoft.com

仕様に従って作成した.editorconfigという名前のテキストファイルをプロジェクトフォルダーに入れておくことで、命名規則やかっこの位置などについてのチェックをしてくれます。Visual Studioをはじめ、コードエディターなら大体機能を持っていると思います。以下、Visual Studio 2019 Communityで作成した設定ファイルです。

この.editorconfigをUnityのプロジェクトフォルダーの直下に置いておけば、エラー一覧のメッセージに以下のように規則違反があれば表示されるようになります。

命名規則違反の例

ただ置くだけでは機能しないかもしれません。その時は、以下の手順でプロジェクトに読み込みます。

  • プロジェクトメニューから、既存の項目の追加をクリックします
  • コピーした.editorconfigファイルをダブルクリックして追加します

以上でプロジェクトに設定が読み込まれて規則のチェックが動作すると思います。それでも表示されない場合は、エラー一覧ウィンドウのメッセージボタンの右にあるコンボボックスを確認してください。IntelliSenseが含まれていない場合は動作しないので、ビルド+IntelliSenseにしてください。

改行コードの不一致の修正

改行コードがLFやらCR+LFやら混在しているとUnityがwarningを出します。上記の.editorconfigでは改行コードをWindowsに統一する設定をしているので、警告が出たスクリプトVisual Studioで閉じて開けば修正してくれます。

規則をカスタマイズする

この設定ファイルはざっくり作ったもので、運用はこれからなので抜けがあるかも知れません。.editorconfigを直接書き換えるか、Visual Studioで設定を編集することができます。

Unityからソースコードを開いて、ツールメニューからオプションを選んで、左のメニューからテキストエディタ > C# > コードスタイルを開くと、設定を確認できます。

コードスタイルの設定

設定方法はコガネブログさんで紹介されています。

baba-s.hatenablog.com

まとめ

Unityで作成するアセットやファイル、クラス名、メソッド名などは、原則として頭文字を大文字で表すパスカルケースにします。

メンバ変数、ローカル変数、パラメーター(引数)のみは最初の文字が小文字で、それ以外は単語の頭文字を大文字にするキャメルケースにします。

Unity以外で作成する画像ファイルや音声ファイルについては、単語の区切りをアンダースコア(_)で区切って、小文字の英語と数字を使うスネークケースを採用することにしました。

.editorconfigはとても強力です。うっかり名前を付け間違えても教えてくれるので、チームで共有すると便利です。

この方針で運用してみて、何か出てきたら見直していこうと考えています。これまで微妙にブレていた方針が統一されてすっきりしました。

見落としや誤り、こっちの方がいいよ、というところがございましたらお知らせいただければありがたいです!

明日は、@su10さんの番です!!

参考・関連URL