あるみにメモ

技術的なメモをかくかもしれない

シェルスクリプトで実行プログラムの引数を変えながらまとめて実行して1つのファイルにまとめたい(バッチ処理)[1]

題のまんまの事がしたいあるみにの話.

ちょっとやらないとすぐ忘れてしまうので試したこととかを残す

引数を要求する自作プログラムを引数を変えながら代わりに実行させて,

シェルコマンドを上手く使って出力結果をそのまままとめたりしたいという話.

こういう処理のことをバッチ処理っていうらしい.



やりたいこと

  • 作成したプログラムを実行させる
  • ↑の引数を変えた複数の命令セットにして扱う
  • 同時に実行を指定のファイルに出力させる

初歩です.

前提条件

まず,実行したいプログラムコードを,

program

という名前の実行ファイルにコンパイルしたとしよう.


実行するときは,

./program

とすればいいし,引数が付くのなら

./program 0 10 200

という風になる.


例えば引数を2つとり,2数の結果を出力するcalc.cというプログラムを作成した.

#include <stdio.h>

int main(int argc, char *argv[])
{
    int a, b;
    a = atoi(argv[1]);//引数1番目をaに代入
    b = atoi(argv[2]);//引数2番目をbに代入

    printf("%d%dの和は%dです。\n", a, b, a + b);
    return 0;
}

このプログラムを用いて,様々な2数の計算結果を調べたいとする.


1+1を調べたいのであれば,

./calc 1 1

と実行する.


出力は,

1+1の和は2です。

となる.


1~100まで全ての組み合わせで全ての値を計算せよと言われたとき, 全パターンを1回ずつ入力,実行し,結果をコピペしたりするのは流石にキツイ.

まあこの例であればそもそも1~100の組み合わせ1つのプログラムの中で計算して逐一出力すればよいのだけど.

今回の目的はプログラムをいじるのではなく,プログラムの実行やその出力結果先を コントロールするシェルスクリプトを書くことで効率化を図ることである.

複雑なシミュレーション結果を出力するものであるとか,入出力機構をあまりいじるわけにはいかないプログラム(闇)だとか,とにかく引数を使って得るタイプのプログラムでも,いちいち入力,実行,記録のステップを踏みたくないので,シェルスクリプトをつかって自動化を試みる.


シェルスクリプトで「Hello,World」

まずはシェルスクリプトを書いてみる.

echo "Hello,World!!"

シェルスクリプトは拡張子を「.sh」にして保存する.

(つけないことが実は普通だとか)

「echo」は出力命令で(厳密にはそれだけでないが),このシェルスクリプトを実行すれば, 「Hello,World!!」と出力してくれるはずである.


シェルスクリプトの実行は他のプログラムの実行と同様に,

./test.sh 

とする.


シェルスクリプトは命令のまとまりを逐次解釈して実行するインタプリタなので,

コンパイルは必要としない.


シェルスクリプトの実行権限


./test.sh: 許可がありません

なんて言われて実行出来なかったかもしれない。

詳しい説明は省くが,ファイルには属性がある.

そのうち,実行権限という属性がある.

ls -a なんかをして調べられるが,シェルスクリプトに 実行権限を与えていない場合実行できないので, 信頼できるシェルスクリプトを作れたなら実行権限を与えよう.


chmod +x シェルスクリプト名

で実行権限を与えられる.


実行可能なファイルはlsなどをした時も色が変わって見えるようになっていると思う.

実行したいシェルスクリプトが存在するディレクトリで,

./test.sh 

とすれば,

Hello,World!

と出力される.

シェルスクリプトに実行権限を与える事を忘れないように.


改行コードの注意

もしかして

実行形式エラー.間違ったアーキテクチャです.

なんて言われている人もいるかもしれない.


f:id:aluminum_pepe:20190917155628p:plain

自分は先ほどの一行コード,こんな風にecho文の前に空行があると上のように怒られてしまった.

もっと言えば,

f:id:aluminum_pepe:20190916150423p:plain

上は空いてないでecho文のあとに空行がいっぱいあるようなコードだと,

f:id:aluminum_pepe:20190916145049p:plain

のように,謎のコマンド見つかりませんがたくさん出てくる.


我々捜索隊は原因を調査するためアマゾンの奥地に向かった-------------------



試しに空行とecho文を織り交ぜる.

f:id:aluminum_pepe:20190916145306p:plain

とすると,

f:id:aluminum_pepe:20190916145322p:plain

こうなる.

空行の数だけ,というより,命令が記述されていない行の改行に反応しているっぽい.

この問題,改行コードが「CRLF」になっていることが問題らしい.

というわけで,エディタの設定で「LF」にすると,改行をコマンドとして 検知しなくなり,上記の二つの問題が解決する.

f:id:aluminum_pepe:20190916150148p:plain

としても....


f:id:aluminum_pepe:20190916150210p:plain

ヨシ!!


他のプログラムを実行させる

シェルスクリプトでは他の実行ファイルを実行する事もできる

例えば,

echo "calcを実行します"

./calc 1 1

として実行すれば,

calcを実行します
1+1の和は2です。

となる.


test.sh内で先ほど作ったcalcプログラムに1と1を引数に与えて計算させることができる.

もちろん同じディレクトリにない実行ファイルも,パスさえ正しければ実行出来るはず.

引数をいちいち与える手間だけを省略したいのであれば,

echo "calcをいっぱい実行します"

./calc 1 1
./calc 2 1
./calc 3 1
./calc 4 1
./calc 5 1
./calc 6 1
./calc 7 1
./calc 8 1
./calc 9 1
./calc 10 1
・
・
・

なんてすれば,まとめて実行できる(脳筋).


実行結果の保存先(リダイレクション「>>」)

プログラム実行結果は

./calc > result.txt

などとすることで,「result.txt」に出力させることができる.

(リダイレクションは保存先を変えるという意味)

「>」は完全な上書きなので,

「>>」の追加を使うと良い


もちろんこのリダイレクションも,シェルスクリプト内にそのまま記述でき,その通りに実行させる事ができる

さっきの脳筋シェルスクリプトを,

echo "calcをいっぱい実行します"

./calc 1 1 >>result.txt
./calc 2 1 >>result.txt
./calc 3 1 >>result.txt
./calc 4 1 >>result.txt
./calc 5 1 >>result.txt
./calc 6 1 >>result.txt
./calc 7 1 >>result.txt
./calc 8 1 >>result.txt
./calc 9 1 >>result.txt
./calc 10 1 >>result.txt
・
・
・

とすればresult.txtに結果をどんどん記述していくことができるので,わざわざ黒い画面の結果を1つずつコピペして記録する必要はない.

f:id:aluminum_pepe:20190916152957p:plain

実行のさせ方が強引ではあるが, 必要に応じてこのシェルスクリプトを書き換えることで 様々な命令をまとめて実行し,指定したファイルに結果を出力できる.

また,シェルスクリプトそのものに対してもリダイレクトは有効なので,シェルスクリプト内のリダイレクトを無くし,

test.sh >>result.txt

としてもいいと思う.


全パターン列挙は流石に・・・・という人へ

当然1~100まで全パターンという処理を, シェルスクリプト内で書くことで, 全パターンを列挙する必要をなくすことはできるので, 最後にそれを記述しよう.

#!/bin/sh
for ((i=0 ; i<=100 ; i++))
do
    for ((j=0 ; j<=100 ; j++))
    do
    ./calc $i $j
    done
done
シェルスクリプトにも変数を使って数値計算処理できるということである


シバン行

今回のコード例では記述していないが, 大抵のシェルスクリプトの話題では,コードの最初のほうに

#!/bin/sh
とか
#!/bin/bash

記述してある

これはシバン行といって,

・・・・・・・・

・・・

qiita.com

スクリプトファイルの冒頭を#!にして、その後にファイル名を書いておくと、実行属性を付けてファイルを実行できるようになります。この冒頭行を「シバン」といいます。

・・・・

うーん?()

後ろにオプションを付ける事でいくらかなにかしら設定できるみたい(無理解)

あるとシェルスクリプトとして働くのかな・・・とおもったら無くても動いちゃったから分からん

それとも「.sh」があったからシバン行指定しなくても動いたとかいうオチかな? (無くても動きました)

自分の環境(Linux系サーバ)だと勝手に分かってくれるだけとかそういうこと?

ただ,そういった実効的な意味合いよりも, 「bashのコマンドや記法を含むよ!!」といったような説明的な効果の方が大きいようなイメージを感じている.

コード規約とかに近い感じかな


とりあえず自分も,

#!/bin/sh

を記述しておくことにする.



まとめとつづきのはなし

さて,シェルスクリプトをつかってプログラム(コマンド)の実行を代わりに行わせることができるようになったので, とりあえず「まとめて実行」「まとめて記録」ができるようになった.

今回は計算プログラムに対して引数を変えて指定のファイルに結果を出力させたが, これはCプログラム実行コマンドとUNIX/Linuxの「>>(リダイレクション)」の合わせ技をさせたことになる.

このようにしてシェルスクリプトでは UNIX/Linux上の複数のコマンド実行やファイル操作をまとめて実行できる利点を活かす事もが目的で使われることも多い(バッチ処理っていうんだって).

複数の既存のプログラムを繋げて実行でき,ファイル操作の場面でシェルコマンドもまとめて実行できるので,自動化にはもってこいといった感じ,一回実行しただけで面倒な手順を自動でやってくれると楽

自動化プログラムだけ上手くメンテナンスできれば人為的なミスが減る(保存先間違えたり設定値変え忘れたりしそうだった).

既存のプログラムの本体をいじるより,命令(引数)を入力して実行する工程に工夫をして自動化する方が効率が良い事もけっこうありそう


自動化するにあたってまだまだ改良の余地がありすぎるというか,コマンドの組み合わせをほとんどしてない段階.

続きとして用途に合わせたコマンドの使い方をメモ書きするつもり.

たとえば,ディレクトリを生成するmkdirを使って結果を出力するためのディレクトリをつくったり,出力結果保存用のファイルにリセットをかけられるようにしたり,シェルスクリプト自体が引数をとって扱う・・・・・とか


最後に

適当に検索かけつつ,ざっとシェルスクリプトを使ってみたときのことをまとめてみた

改行コードだったり実行権限だったり, とりあえず使ってみようとしたときに自分がつっかかった箇所を取り上げつつ シェルスクリプトを試せる/思い出せるようになっている気はする

自分もこれで何回忘れても大丈夫だね!!


知ってることをまとめたつもりだけど,初学者のガバガバ知識でうやむやにしてたりする


この記事を見かけた人へ

間違っている事がありましたら是非ともご教授(マサカリを投げて)くださるとありがたいです。

【第三回】 あるみに進捗発表 進捗無いと不安よな。いらすとや、うごめきます。 [2019/8/22]

第三回目の進捗発表にこぎ着けたあるみにの話。

aluminum-pepe.hatenablog.com



進捗発表日予定日の推移

  • 8/2
  • 8/10
  • 8/21 ←ココ!
  • 8/22(27:00) ←いまココ!


大☆遅☆刻

次からは頑張りましょう (失踪だけは免れてよかった)


前回の進捗発表はこれです。

aluminum-pepe.hatenablog.com




近況報告

大遅刻の言い訳もあります。(興味のない人は目次から進捗発表に飛ぼう)


ゲーム


プリコネ


夏キャラが当たりません。





遅刻の原因


進め、キノピオ隊長です。

f:id:aluminum_pepe:20190823030031p:plain


topics.nintendo.co.jp

進め!キノピオ隊長』を、自分のNintendo Switchでまるっとすべて遊べる特別イベント「いっせいトライアル」が、Nintendo Switch Online加入者限定サービスとして開催されることが決定しました。

期間は8月5日(月)12:00 ~ 8月11日(日)18:00 までの1週間。

Nintendo Switch Online加入者なら、期間内、何度でも、何時間でも、なんと最後までも、遊ぶことができちゃう特別なイベントです。

Nintendo Switch Online加入者の皆さんは、この機会に『進め!キノピオ隊長』を体験してみてください。


…てなわけで、Nindentdo Switch Online 加入者のみ、期間限定でNindentdo Switchである「進め!キノピオ隊長」が無料でプレイできるということで、これを始めたわけです。

8/10(投稿予定日)に。

なぜもっと早く始めなかったかについては後悔してもしきれないところがあるのですが、すぐ終わるだろうって、思っていたんですよ。


すげえボリュームあった。

とても記事書きながら片手間にできる作業じゃなかった。

そもそもニンテンドーソフトのゲームがすぐ終わるなんてないって少し考えれば分かるはずなのだが…

そんなわけで、途中から「明日終わるのに記事なんて書いてる場合じゃねえ!!」となって徹夜しながらキノピオ隊長をプレイしていました。なんなら記事さえとりかかってなければ…と後悔するクズさ。

まともに、素材を収集したり記事を書いたりできるのは土、日くらいなもんなのだけど、それをこの全て投げうちました。最低。


それはそうとして、自分の(「キノピオ隊長」の)進捗状況等を語るために、「キノピオ隊長」のゲームについて簡単に説明しましょう。

f:id:aluminum_pepe:20190823030314j:plain
5人に分身したときのキノピオ隊長


システムとしてはマリオに近い3Dアクションゲームで、1ステージ単位でクリアしていく、といったものです。

  • 方形の箱庭型の3Dステージを

  • ジャンプもろくにできないキノピオ隊長(キノピコもある)を操作して、

  • おたから?であるスターシャインのようなものを手に入れる

というようなルールです。


方形、というか四角柱型のほうがわかりやすい。

ステージ内の敵やギミックを乗り越えながらステージクリアを目指します。

f:id:aluminum_pepe:20190823030336j:plain
ステージ上部に輝くスターをとってゴール


キノピオ隊長には1ステージに対して三種類のやりこみ要素があります。

  1. ステージ内に隠された3つのジュエル。いわゆるスターコイン。

  2. ステージ課題(サブミッション?)。「コインを○○枚集めてクリア」や、「敵を全て倒す」など、1ステージにつき1つ。

  3. ドットキノピオとかくれんぼ。ステージのどこかに潜んでいるドットキノピオを見つけ出すというもの。※

※かくれんぼはステージクリア後に選択可能なかくれんぼモードでのみに出来、かくれんぼ中のプレイは他のミッション等の成果は反映されない

f:id:aluminum_pepe:20190823030432j:plain
ステージ選択画面


よくもまあ1つのステージにこれだけやることを詰め込んだものです。

クリアするにも、これらのやりこみ要素を埋めるにも、ステージのギミックの謎を解いたり、隠された仕掛けを見つけたりするので、アクションというより謎解きの要素が強い感じがしました。


f:id:aluminum_pepe:20190823030705j:plain
スタージュエルはステージのいろんな場所に隠されていたり、ギミックを越えた先にある


それから、ステージ数が結構あります。

ネタバレになりそうなので具体的に言いませんが、少なくとも1日でやるようなものではなさそう。


初見からキノピオ隊長RTAをしている気分でしたが、結論からいうと全然終わりませんでした。

追加で特殊な解放条件のステージがないのであれば、


  • ジュエルは全ステージ回収したが、

  • ステージ課題全制覇は後3ステージ程で届かず、

  • ドットキノピオに関してはほとんど探せていない


という有様で無料トライアルを終えました。

f:id:aluminum_pepe:20190821124537p:plain
キノピオ隊長プレイ中に制限時間を迎え、中断させられたあるみに


うーん無念。


もう少し語ることがあります。

先ほど「すげえボリューム」だとか、「詰め込まれている」なんて述べましたが、

ある種1、2日で全クリア出来そうだったとも言えます。

とはいえ、その分時間をかけているし、1、2日でクリアできないゲームもそうそうないですけどね。

もちろん次作にあたるスーパーマリオオデッセイやゼルダの伝説BotWに比べたらボリュームはないほうだと思います。(そもそもの値段も異なるので、比べるのもどうか)

個人的にはお値段以上の満足度ではあるのだけど、すげえボリュームだと感じた理由とかがあるんですよ。

f:id:aluminum_pepe:20190823031209j:plain
RTAしてたもんだからスクリーンショットがなさすぎる


なんというか、キノピオ隊長は丁度いいんです。

例に出したスーパーマリオオデッセイや、BotWにもパワームーンだとかコログだとか、真にボリュームのエグいやりこみ要素がありますが、いざやろうとするのには覚悟がいるものです。少なくとも初見から1,2日でやろうとは思わないです。自分は。

キノピオ隊長のやりこみ要素は1ステージ単位で完結しているので、与えられた一つの問題を全て解き明かせばそのステージは終了し、わかりやすい単位で、かつ細かいスパンで「やり切った感」が得られるような感じがしました。

1ステージごとのやりこみ要素も、詰め込まれているが、詰め込まれ過ぎていない、ような気がします。

ステージ課題が3つもあったら流石に覚えてられない&やる気がでにくいかも知れません。

そんなわけで、「これはやってやろう」と思えた範囲で最上のボリュームであったというのが正確な自分の感想です。


3Dステージは四角柱の側面視点も上からもたまに下からも余すところなくいかされていて、そんな箱庭ステージで頑張るキノピオ隊長がとても可愛かったです。

f:id:aluminum_pepe:20190823030804j:plain
座布団の上で寝るキノピオ隊長

追加ステージも追加課金であるみたいでしたし、「ふたりであそぶモード」は家で一人でこもってやっていてできなかったのでとても気になりますね。貧乏性が祟ってRTAのようなプレイしていましたが、またじっくりやってみたいですね。


お財布にめちゃくちゃ余裕ができたら、ね



遅刻の原因2


ふと始めてしまった。

f:id:aluminum_pepe:20190821135026j:plain
白猫プロジェクトの5周年イベント「DARK RAGNAROK」です

キノピオ隊長で記事執筆の出鼻をくじかれた後、モチベの下がるあるみにを襲ったのがこれ。

離反と小復帰を繰り返してるこれは、今年で5周年だそうで、なんだかんだ周年イベントだけは毎年やっていたので今回も手を染めてしまいました。

最近の白猫はこんな感じだよ(語弊)。


f:id:aluminum_pepe:20190821143234g:plain
はいちょっとそこ通りますよ~

ルーンセイバーで飛び回るのたのしいなあ~


ガチャが振るったのもあって、5周年イベントのステージをやりつくしましたとさ。

久しぶりにやったけどキャラ操作やつよつよスキル打つのは爽快で結構面白かった。


f:id:aluminum_pepe:20190821143438j:plain
けっこう大変だったってことです


……



つまりサボって遊んでました


研究室

プログラムかいてシミュレーションまわしてお勉強しての日々。

ここは以前と変わらず。


最近はデータとるためのプログラム実行の命令セットをまとめてシェルスクリプトで実行してくれるようにしたり、分かりやすい名前のファイルを作って結果を分けて保存してくれるような、「自動化(?)」にはまっています。

実のところシェルスクリプト自体あまり触ったことがなかったので、初歩的なことしかやってませんが、シミュレーションプログラムに対して汎用性のあるシェルスクリプトを書いたりとか結果をまとめるのに有用なものをつくって、効率化を狙いたいと画策しています。


肝心の研究も、中間発表に向けてのより本格化する空気を感じています。(遅いともいう)


あつい

あつい。

暑すぎてやる気が出ない。

なんなら進捗にも全然取り掛かれなくて…





進捗発表

どんなに遅れても近況報告はするのが信条。

ここから先が進捗発表です。


つくってるもの「ハロウィンゲート(仮)」

f:id:aluminum_pepe:20190608122340p:plain
タイトル画面。雑

これまではゲームというより「UI」を作っていましたが、今回からゲーム部分に入り始めたので、現在制作中のゲームであるハロウィンゲート(仮名だけどこのままいきそう)を作っていると言えそうです。

といっても、今回も「ソシャゲっぽいゲームのUI」づくりをすこーしだけやっています。

UIについても、ゲーム性についても、自分が好き(だった)ソシャゲディバインゲートをモデルにしつつ、

他の自分がやってるソシャゲのUIなんかを参考にしながら見よう見まねで作っています。

詳しくは前回、前々回の記事を見ていただければと思います。


環境

  • Uinity2019.1.0f2(C#)
  • VisualStudio2017
  • GitHub , SorceTree

  • Androidビルド

特出して使ってるアセットも載せときます。

  • DOTween
  • TextMeshPro(kazesawafont)
  • Anima2Dnew!!


前回の進捗

前回のおさらいからしていきたいと思います。

前回は、よりソシャゲっぽくするために、かなりいろいろな実装をしました。

こんな感じ。

f:id:aluminum_pepe:20190708065729g:plain


各所にUIアニメーションを適応させました。

ノードの自動生成、データや画像テキストのデータ反映、表示するためのアニメーションまで、

内部的にも外面的にもソシャゲっぽさには重要なシステムをいくつか実装できたと思います。

作ってきたUIに対して素材を貼り付けることもしたので、大分「ぽさ」はでたんじゃないかと。


こうやってみると、先月の自分はよく働いてますね。



UI

ではまずは今回のUIの進捗の様子を見せていきたいと思います。

大きく一つだけです。


ボタンのアニメーション

前回はボタンにアニメーションはついていませんでした。

f:id:aluminum_pepe:20190821151452j:plain


要求

ソシャゲっぽいボタンのイメージは自分的にはこうです。


  • 選択されてる状態と対応するボタンは強調(ハイライト等)される
  • アイコンが強調時とそうでないときで絵が少し変わる(キャラの顔→笑顔みたいな)
  • 強調時はアイコンがぴょんぴょん跳ねたりアニメーションする


ソシャゲ関係なく、UIとしてボタンが分かりやすくあるために強調するのは当然として、画像差し替えやらアニメーション当たりが実装したいところですね。


できた

そんなわけでできたのがこちら。


f:id:aluminum_pepe:20190821151655g:plain


どうでしょう、結構それっぽいのでは。

ここからもう少しだけいじってみる。そこも含めて、実装の話をしていこう。

実装の話「画像入れ替え」

選択したときとそうでない時で2パターンの画像を用意しました。

以下一覧


f:id:aluminum_pepe:20190821181631p:plain:w300


f:id:aluminum_pepe:20190821181731p:plain:w300


f:id:aluminum_pepe:20190821181931p:plain:w300


f:id:aluminum_pepe:20190821181509p:plain:w300


あとは状態に合わせてどちらかをアクティブにして見せるだけ。

気に入っているのは、図鑑(Book)ボタンの本が開いたり閉じたりする所です。

あとはパネルそのものにも色をつけてみたのも分かりやすいでしょ?


実装の話「UIアニメーション」

アクティブ状態のオブジェクトには、待機UIアニメーションを設定してあるので、有効になった瞬間に動き出します。

これまでは「UI要素をアクティブ/非アクティブにして、拡縮や移動をする」という、ある種一方通行のアニメーションを作ってきました。

今回はそれらとは異なり、「UI要素がアクティブな間は常に発動する待機アニメーション」をいくつか作ったので紹介します。


例えばこれはぷにぷにしたジャンプをする「Idlepunipuni」です。

f:id:aluminum_pepe:20190821185459g:plain

ぷにっと跳ねさせたかった。Homeボタンに採用で

DOTweenにある「DOJump」メソッドをつかってみました。

始めはこれ一つしか作るつもりがなかったのですが、単純なアニメーションを複数作って同時に付けた方が面白いのでは?と思って以下を制作しました。


ボタンアニメーション紹介と試行錯誤

イカれた仲間たちを紹介するぜ!!!



ただジャンプするだけの「Idlejump」

f:id:aluminum_pepe:20190821193302g:plain


とってもシンプル。

さっきのIdlepunipuniからぷにぷにを除いたやつ。


コードも載せよう。(スマホからだと見にくくて申し訳ないです)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

public class Idlejump : MonoBehaviour
{
    [SerializeField, Tooltip("アニメーションさせたい要素を指定可能")]
    RectTransform rect;

    [SerializeField, Tooltip("ジャンプパワー")]
    float jumpPower = 30;

    [SerializeField, Tooltip("アニメーション時間")]
    float time = 1.0f;

    private Sequence sequence;

    public  void animation()
    {
        sequence.Play();
    }

    private void Awake()
    {
        //特にアタッチされていなければそのまま取得
        if (rect == null) rect = this.GetComponent<RectTransform>();
    }


    private void OnEnable()
    {
        //アクティブになったときアニメーションを再生
        animation();
    }

    private void OnDisable()
    {
        //非アクティブになったときシーケンスを初期化する
        sequence.Restart();
        sequence.Pause();
        rect.anchoredPosition = new Vector2(0f, 0f);
    }


    void Start()
    {
        //Startで定義
        

        sequence = DOTween.Sequence();

        //無限ループ設定
        sequence.SetLoops(-1);

        sequence
            .Append(rect.DOJumpAnchorPos(new Vector2(0f, 0f), jumpPower, 1, time));



        sequence.Play();
        
    }
}


自作した待機アニメーションはsequenceの中身がちょっと違うのみで、大抵こんな実装です。


アタッチしたオブジェクトの有効状態の変化をOnEnableやOnDisable関数で検知して、DOTweenアニメーションの実行や、初期化を行っています。

DOTweenは、そのTweenさせるオブジェクトが非アクティブであっても、「Complete」という完了状態や、「pause」という停止状態、またはTweenが「kill」=破棄されない限りは処理され続けるようです。

多重にDOTweenを実行させると、なんだかよくないことが起きる(起きたので)、無駄なTweenは起きないように管理します。

setLoop(-1)で無限ループ設定をしているときは、完了状態にならないので、非アクティブの場合はpause(停止)状態にし、周期が中途半端な状態で止まっても初期状態に戻せるようにRestartさせています。


紹介にまた戻る。


ゆらゆら揺れるだけの「IdleYure」(酷い名前だ)。

f:id:aluminum_pepe:20190821185727g:plain

これを図鑑ボタンに採用する。


この2つを同時に適応することで、揺れながらジャンプのアニメーション。

f:id:aluminum_pepe:20190821185836g:plain

ちょっと違うアニメーションを作れた。

これにはあるみにもにっこり。

いろいろ組み合わせられそうと感じて手を叩いて喜んでました。

これはそのままQuest(StageSelect)ボタンに採用。なんか はしゃいでるっぽくなった?


薄くなって消えたり濃くなったりする「Idletikatika」(チカチカするってことです)。

f:id:aluminum_pepe:20190821193413g:plain


これは、「Idlejump」と組み合わせつつ、その他ボタンの幽霊くんを透かしてみた

f:id:aluminum_pepe:20190821193635g:plain



採用してませんがひっくり返るような回転をする「IdleZRotate」(急にまともな命名)。

f:id:aluminum_pepe:20190821193454g:plain

なんてものも作ってみた。



個人的に、指定したImageの画像を明滅させられる「Idletikatika」はけっこう気に入っています。


コードはこんな感じ。(さっきと似通っている部分は省略・スマホからだと見にくくてry)


      :
      :
public class Idletikatika : MonoBehaviour
{

      :
      :

 private void OnDisable()
    {
        //非アクティブになったときシーケンスを初期化する
        sequence.Restart();
        sequence.Pause();
        //アルファ値を初期化
        rect.GetComponent<Image>().color = new Color(255, 255, 255, 1);

    }

    float nowAlpha = 1f;
    float goalAlpha = 0f;//目的

    //ゲーム実行中はアルファ値は0~1で変化する。0~255ではない


    void Start()
    {
        //Startで定義


        sequence = DOTween.Sequence();

        //無限ループ設定+折り返す設定
        sequence.SetLoops(-1,LoopType.Yoyo);

        sequence
            .Append(DOTween.To(() => nowAlpha, (n)=> nowAlpha = n, goalAlpha, time/2f)).OnUpdate(()=>rect.GetComponent<Image>().color = new Color(255, 255, 255, nowAlpha));
        //OnUpdateで値の変化をImageに常に伝えることができる

        sequence.Play();
        
    }
}


qiita.com


にあるように、アルファ値を変更して明滅させるものに、DOTweenのCanvasGroupの拡張メソッドである、「DOFade」があります。

これを使えば同じCanvusGroupがアタッチされたGameObjectすべてのアルファ値をTweenできるのですが、Canvusを隔離せずとも特定の要素のアルファ値をいじりたかったので満足はしています。


ただ単にコンポーネントを付けた場合はそのオブジェクト直下のImageのアルファ値を取得してTweenさせますが、Inspectorから特定のImageをアタッチしたときは、そのImageのアルファ値をTween出来ます。

コンポーネントを適用したオブジェクトの有効状態を取得して、ループの中断やRestartするので、特定の一つをTweenさせるときは親オブジェクトに適応させる運用。


f:id:aluminum_pepe:20190821231742p:plain

↑はその他(Others)ボタンに適応されたUIアニメーション用のインスペクター。

Rectは指定しなければImageをまとめたPanelそのものをまとめてTweenさせ、uGUIの要素を指定すれば一つをTweenさせます。

「Idletikatika」において、幽霊くん(ghost)を指定しているので、幽霊くんが明滅してくれるというわけです。

「Idlejump」は指定していないので、そのままImageを複数含むオブジェクトごとjumpし、アイコン全体に影響があります。


今のところ、1つの明滅スクリプトにつき1つのImageしか変化させられないので、リスト登録型にしたり、下層全てに影響を及ぼすようにした方がいいかも。 (それをするとDOfadeでよさそう)



……とまあ、ボタンアニメーションとかいう地味な部分でけっこう色々試して見てみました。

むしろ時間をかけすぎたまである


最終的に実装したボタンアニメーションをまとめるとこう。


f:id:aluminum_pepe:20190821201408g:plain


それなりに「ぽい」ものが作れたんじゃないかな?




f:id:aluminum_pepe:20190821194157g:plain
透かし x Z回転 x ジャンプ をしてみたらこうなった。




ゲームシーン始めました。

やっとゲームシーンを作り始めました。

改めて説明すると、1年ほど前にゲーム部の実装をちょっとだけしていて、それをほったらかしにしていた。という背景があります。

そんなわけで、ほったらかしにしていたものを移したのがこちらです。


見た目こんな感じになりました。

f:id:aluminum_pepe:20190822235054p:plain


手前から、キャンディーの入ったバスケットが5つ、机、敵が迫ってくるゾーンです。


動いているところはこれ。

f:id:aluminum_pepe:20190823001711g:plain


アッ、アメのカウントがマイナスいってる!

ルール説明

  • いらすとやのハロウィン仮装キャラが、うごめきながらにじり寄ってくるのを、欲しがっているキャンディーを与えてお帰りいただく。

  • バスケット内のキャンディーはランダムに出現し、机にはキャンディーをおいておける。

  • キャンディーをタップして運び入れる操作のみ。

  • 現状間に合わなかったときのペナルティがないので、右上にあるライフのようなものは現状飾り。

  • イメージは、現状、ディバインゲートの仕分けに近い、リアルタイム操作。(?)


といった感じ。



そのいらすとや、動くよ

現状のゲーム性のガバガバさは要検討で今は置いておくとして、

Anima2Dを用いたいらすとやのアニメーションが今回の進捗のもう一つのウリです。

詳しくはこの記事でも触れてます。

aluminum-pepe.hatenablog.com


250日くらい前の記事って表示されてたんだけど…どんだけほったらかしにしてたんだ


この記事を見つつ、Boneを設定し直しました。

かつてのこれが、

f:id:aluminum_pepe:20190821202400p:plain


こう。

f:id:aluminum_pepe:20190821202417p:plain


前より現実的な骨構成になった。


f:id:aluminum_pepe:20190823013506g:plain

ボーンに合わせていらすとやが動くぞ……!!


こんな記事も参考にしてます。


mankindinc.jp

あんまりよく理解していなかったIK(limbとCCD)について、理解を深めてつかえるようになりました。

相変わらずMeshを切り分けていません。なんか、これはこれで味があるかなって思ったんですけど…


techblog.sega.jp

同じAnima2Dでここまでできるんだ……!!と思わせられる記事。

この記事を見れば見るほど切り分けなきゃなと思うので、次回は切り分けにも挑戦してみようかなと思います。



f:id:aluminum_pepe:20190823020733g:plain


このBoneの動きはUnityの機能であるAnimatorAnimationで実装しています。

Boneのアニメーションとして保存してみたので、使いまわせるのですが、Meshを切り分けていないものに使うのはちょっと微妙そう。


f:id:aluminum_pepe:20190823015013g:plain

もう一つ違うモデルを生成したので、同じBoneアニメーションを適応してみた。(なんかかわいい)

足の開き方が最初のモデルに合わせてるせいで不自然だ。使いまわすのは厳しそう。

こうやって見るとモデルをTポーズで統一する大切さとかがわかる気がする。



実装の話「敵オブジェクトの階層構造」


f:id:aluminum_pepe:20190823021129p:plain

Anima2DのMeshやBone、IKを空のラップオブジェクト(Warp_Enemy)に入れています。

必要なアメを表示するオブジェクト(EnemyDemand)も、同じラップオブジェクトに入れて一緒に動かしています。

迫りくる様子は、ラップオブジェクトを拡大させながら移動させるだけです。

以前はここもAnimationで実装していましたが、DOTweenで作り直します


実装の話「キャラの移動」

かつては拡大するだけで近づいてくる様子を表していたのですが、今回はキャラの移動経路を、「DOPath」を使って実装してみました。

DOPathは、座標情報の配列を登録することで、登録した座標を順に通るような移動Tweenをしてくれるメソッドです。


ただし、ただ通って欲しい座標をSceneで調べながら数値を入力するのは効率が悪すぎるので、Path用に生成したGameObject群を作ってみました。

その名も「EnemyPath」。


f:id:aluminum_pepe:20190823022807p:plain


この、ゲームオブジェクトである「○」を置いた座標を通る仕組みです。

実際のシーンではこう。


f:id:aluminum_pepe:20190823023538g:plain
左のSceneウィンドウでは実行中のDopathの経路が白線として見える

キャラが「○」の上を通ってるでしょ。


キャラが通って欲しい経路にpathpoint =「○」を複製しながら配置して、

これらのをまとめた親オブジェクト(EnemyPath△△)を、キャラ用のスクリプトに適用することで、

その経路通りに動くようになりました。


f:id:aluminum_pepe:20190823023905p:plain

↑は弧を描くように配置されたpointを子にもつ「EnemyPath01」をキャラの移動を管理するスクリプトに読み込ませて、positionを取得している様子です。


キャラごとの個性ある移動パターンがつくれる……かはさておき、エディタ上でキャラの移動経路を簡単に作れるのはいいことな気がしますね。

(まあ、有料版にはデフォルトでこの機能がついているらしいですけど)



なお、アメの生成の拡大なんかも、DOTweenに置き換えています。けっこう書き換えることが多くって大変だった。

前回に比べてBone構成やアニメーションを若干丁寧に作り直してゲームシーンを実装中…というのが今の進捗状況です。



まとめ

まとめるとこんな感じです。


ボタンアニメーションの実装

f:id:aluminum_pepe:20190821201408g:plain


ゲームシーンの移植・改装

f:id:aluminum_pepe:20190823001711g:plain



ゲームバランスについての反省、検討とかもしたかったけど、分量もきつくなってきたので今日はここまで。






締め


とにかく今回の記事は難産でした。

序盤のやる気のなさに加えて、

「どうせ遅刻してしまったしキリのいいところまで実装しちゃおう」

なんて考えてちょっと実装増やしたのが良くなかった。

なんならボタンアニメーションの話だけすればよかったんだ……


???「実装量が増えるとどうなる?」



???「記事の量が増える」


というような事で、実装で期間は伸びてるわ、記事の量も増えてまとまらないわで大変。

ただでさえまとまりのない記事がより煩雑になってしまったような感じ。

余計にグダグダしてしまったので、期限を守ることはやはり大事だなあ。

…といつまでも出さないままではマズイので,公開になんとか踏み切れました。


アメ生成や吹き出しの実装は、以前作っていたものを移していますが、若干オブジェクトの階層を見直したり、Animationを使っていた部分をDOTweenに置き換えたりしたので思ったよりもかなりボリュームのある作業になりました。


何だかんだでゲームに必要なシステムもいくらか用意できたので、これからはゲームシステムをもう少しマシになるように考えつつ、

ゲームオーバーやリザルトまでの一連の流れを仮でも実装できたらいいなと思います。

あとは、ステージデータのやり取りの仕方だとか、動くキャラを増やしたり、図鑑やホーム画面でも動くようにだとか、機能追加もできたらいいな

仮にもハロウィンには間に合わせたいので、ほどほどに完成できるように頑張ります


今回も実際にAndroidビルドしながら開発してみています。

自分の作ったアプリが動いているのを見るのはいいね。

f:id:aluminum_pepe:20190828173653j:plain


今回も読んでくださった人がいたとしましたら、ありがとうございました。




次回予告

次回進捗発表、「9/28(土)」予定。

頑張って自分。



【第二回】 あるみに進捗発表 ソシャゲっぽいUIをUnityで作るチャレンジってまだやってるんですか? [2019/7/6]

第二回目の進捗発表にこぎ着けたあるみにの話。

aluminum-pepe.hatenablog.com

なんとか初回坊主になる事は避けられたみたいですね。

なんとか3ヶ月くらいは持ってほしいですね()


前回の進捗発表はこれです。

aluminum-pepe.hatenablog.com


あれからどれくらい進んだんでしょうねえ。

近況報告

毎回やりますけど何か?(目次から進捗発表に飛ぼう)


ゲーム


プリコネ

f:id:aluminum_pepe:20190707222407j:plain

あいかわらず、プリコネにハマッています。


ダンジョンEx2をクリアして、ダンジョンコンプリートしました。

f:id:aluminum_pepe:20190706140612j:plain

やったぜ。


と、いうことで。


プリコネRダンジョンEx2「毒瘴の闇稜」耐久攻略レポ


Ex2のダンジョンボスである「ジャバウォック」はとんでもない威力の毒攻撃を放ってくる厄介なボスです。

f:id:aluminum_pepe:20190706161016j:plain

レベルも160と高く、自分のパーティーでは火力でどうにかなるような相手ではないです。

ユイが☆5になり、専用装備もとりあえず持たせたということで、クランメンバーの正月ユイを借りて挑戦した結果勝てました。

パーティはこんな。

f:id:aluminum_pepe:20190706141749j:plain

  • Lv133 ☆5ユイ RANK12 専用Lv30
  • Lv128 ☆4ミサト RANK11 専用lv30
  • Lv125 ☆5シズル RANK12 専用Lv30
  • Lv126 ☆5ノゾミ RANK12 専用Lv90
  • (サポート) Lv130 ☆4 正月限定ユイ RANK??

備考: ストーリーステータス補正フル


ガチガチの耐久パーティです。

ダンジョンボス戦闘では、1:30の制限時間が設けられていて、ボスは戦闘終了時のHPをそのまま引継ぎ、攻撃するこちら側のキャラたちも同様です。

制限時間に間に合わなくても、編成したキャラが倒れていなければ何度でも戦えるため、回復を重視したパーティで挑み、少しづつ削って倒す作戦です。

どう考えても時間がかかるので「とりあえず一回勝って報酬が欲しい」ときのための戦法。


ミサトの育成が不十分なのもあって適当にやってると勝てなかったのですが、だんだん慣れてきたのでその様子を載せておきます。

ジャバウォックは最後の20秒でものすごい毒を放ってくるのですが、それまでは大したことがないので、最初は三倍速で流してもいいでしょう。

残り20秒で正月ユイのUBをうてるようにしておけば、強毒と拮抗して3回スリップダメージを耐えるので、そこからユイのUBで回復してます。

あとは、

  • 2回スリップダメージ→ミサトのUB(手動の方が暴発しない)

  • autoにしてユイにUB打ってもらう(安定)

  • autoを外してミサトでUB打って回復

  • 以下交互回復

で耐久できました。


発狂状態の動画で申し訳ないんですが、発狂状態かそうでないかはたぶん関係ないと思います。

見てて分かると思うんですが、強毒のスリップダメージによるTPの回復がものすごいため、

回復UB2種を交互に打つことが出来れば耐えることができそうです。

また、戦闘終了20秒までのジャバウォックの攻撃は貧弱かつ後ろにも攻撃してこないので、生き残ってさえいればループ戦闘できそうです。


最後10万くらいは火力高めのパーティで押し切りました。

f:id:aluminum_pepe:20190706151450j:plain


まあ火力出すキャラ皆無なので、めちゃくちゃ時間かかるんですけどね。

どこかの攻略サイトだと上記のシズルがアカリになってるんですが、全然育ってないので安定をとってシズルにしました。

とはいえ、アカリを編成しているということは、そこまで丈夫なキャラじゃなくてもいいのでは……

となったのでお試し編成2。

f:id:aluminum_pepe:20190706152908j:plain

シズルの代わりに、

を入れて若干の短縮を狙ってみました。

戦法はさっきと同じです。TPも貯まりやすいだけあって、クリスがいっぱい攻撃してくれるのでさっきの耐久パでやるよりは早そう。



こんな個人の個人の育成状況やら環境に左右される立ち回りをしてもなんの為にもならないと思いますが、とりあえず載せてみました()

効率の悪い耐久しなくても5チャレンジくらいで倒せるようになったら継続的に倒していきたいですね。


攻略レポおしまい。



一周年記念の無料10連から初めて4ヶ月ほどになりますが、ランクも上限に辿り着き、キャラ育成もある程度高い水準までまとまってきた気がします。


マスターコイン、いいよね

ランク上限になると、得られる経験が全て無駄になってしまうので、なんだかもったいない、という事ってランク上限が比較的低いところにあるソシャゲにはあることだと思います。

じゃあ上限上げろやって感じなんですけど、プリコネはキャラの育成とランクの関係が深すぎるので簡単には上げられないようですね。

最近導入された「マスターコイン」制度は、溢れた経験値をそのままゲーム内通貨の1つに変換して、別のゲーム内のアイテムと交換できる仕組みです。


f:id:aluminum_pepe:20190706161333j:plain

やりこんでるからこそ欲しいアイテムがあったり、誰でも手に入るわけではないゆえのラインナップがいいと思います。


f:id:aluminum_pepe:20190706154127j:plain
マスターコインで交換した1000万マナ。これはうまあじ



夏。


f:id:aluminum_pepe:20190706153937j:plain
ばきゅーん♪

今は夏イベント中という事で、夏スズナがとても可愛くて、書いてあることも全部強そうなんですけど、持ち石からしても引ける気がしません。現場からは以上です。



……



……だから何の話してんの???????


研究室

プログラムかいてシミュレーションまわしてお勉強しての日々。

研究室にいる間は「職場に来て仕事してる」みたいな気持ちでやってるつもりです。

これを聞くとブラック研究室か??とかなるんですけど、そのスタイル自体は性に合ってるかなと思っていますね()、特に強制されてるわけでもないです。

周りがちょいちょい心配してくれるんですけど僕は元気です。


生きがい


完結↓↓



次回最終回(2019/7/6現在)↓↓


最近見ている実況グループナポリの男たち」のシリーズが1つは完結、1つは次回最終回(2019/7/6現在)というところまできてます。


生きがいが……


個性ある4人の実況者が集まっているグループ実況で、1人1人のポテンシャルがあって全員推せますね。

編集がものすごく丁寧で分かりやすく、ユーモアが聞いていてめっちゃ面白いです(べた褒め)


まだ見てない人は僕の進捗発表なんて見ている暇があったら↑のリンクから動画を見てください。



ゲーム制作

研究の合間を縫って、何なら2日くらい進捗のための日を作ったくらいにはやってるので、それなりにやる気をもって挑めてるんじゃないですかね。

新しく得る知識が多すぎて死ぬ



進捗発表

近況報告をわざわざ読んだ人がもしいましたら、本当にお疲れ様でした。

出来ればこの先も見て行って欲しいなあ……?


つくってるもの「UI」

まだUI作ってますよ。

厳密には、「ソシャゲっぽいゲームのUI」ですね。

自分が好き(だった)ソシャゲディバインゲートをモデルにしつつ、

他の自分がやってるソシャゲのUIなんかを参考にしながら見よう見まねで作っています。

詳しくは前回の記事を見ていただければと思います。


前回のおさらいからしていきたいと思います。

環境

  • Uinity2019.1.0f2(C#)
  • VisualStudio2017
  • GitHub , SorceTree

  • Androidビルド

特出して使ってるアセットも載せときます。

  • DOTween(アセット)
  • TextMeshPro(kazesawafont)

前回の進捗

前回はUIアニメーション遷移の仕組みを実装し、

ホームシーン内のいくつかのUI遷移を実際に適応させてみました。


f:id:aluminum_pepe:20190609044023g:plain

そうそうこんなやつ。


今の制作物について

前回も制作物について説明していますが、ここでも少しだけ。

現在制作中のゲームは、実は一年ほど前にゲーム部分のプロトタイプを既に作ったまま、ほったらかしにしていたものがベースになっています。

つまり、「ゲーム部分がちょっとできているのでUIつくって組み合わせるか!!」という前提で進んでます。

UIに力をこめるのもそうそうない機会なのかなと思うので、いろいろ発見があって楽しいですね。



UI

ではさっそく今回のUIの進捗の様子を見せていきたいと思います。

相変わらずUIしかやってません。


■タイトル

前回こんなでしたね。

f:id:aluminum_pepe:20190608235803g:plain


こうなってます。

f:id:aluminum_pepe:20190706164143p:plain

色々素材貼り付けまくってます。

機能も紹介しましょう。

UIアニメーション

「遊び方」、「キャラ変更」ボタンを押すと、"ボタンから出てきて見えるように"ウィンドウが拡大します。

f:id:aluminum_pepe:20190706165037g:plain

UIアニメーションの記事がまだできてないのでここで軽くInspector画面を。

f:id:aluminum_pepe:20190706230517p:plain


作成したDOTween製のアニメーションスクリプトであるScaleUPやScaleDownはUnityEditorで時間や拡大しつつ移動する値を設定できるようにしてあるので、

アタッチしたオブジェクトをアニメーションさせるのは簡単です。

どっちが「出てくる」用で、どっちが「引っ込む」用なのかは、これまたお手製のUIAnimationCont"o"roller(スペルミスしてるやんけ……)で管理し、呼び分けられるようにしてあります。


キャラ変更

前回実装できていなかった「キャラ変更」機能が付いています。

ホームに表示するキャラを設定できるとかいう、よくあるやつです。

f:id:aluminum_pepe:20190706171125j:plain
こんなやつ。カスミかわいい。


こんな風に動作します。

f:id:aluminum_pepe:20190706171001g:plain


ポイントとしては、

  • キャラサムネイル画像つきのボタンを生成
  • 生成したボタンをアニメーションしながら表示
  • 選択したキャラの画像を黄色枠でハイライトする
  • OKを押さない限りキャラは変更しない
  • 途中で違うUIに飛んだりしても矛盾が生じない

といったところですかね。

正直上の2つが今回の進捗の全体のすべてと言っても過言ではないですね。


ボタン(ノード)生成して並べる

イメージとしては、プリコネのキャラ画面です。

f:id:aluminum_pepe:20190707224216g:plain


ステップとしては、

  • ゲーム開始時にUnity内のデータベース()から画像を読み取る
  • 予めつくっておいたボタンのprefabに貼り付けて複製し、並べる

です。

f:id:aluminum_pepe:20190706172317p:plain

これは試しにprefabに男の子の画像をいれてみてる様子です。

Mask機能が便利で、特定の箇所だけイメージを有効化してくれるのがいいですね。

Mask機能をはき違えるとこうなります。

f:id:aluminum_pepe:20190707223838p:plain
狂気。


そんなこんなで、複製する過程で、表示する画像と、そのボタンが押されたときに渡す情報を設定してます。


f:id:aluminum_pepe:20190706172841p:plain


後述しますが、データベースといっても今は仮置きしたデータを"""Resorces"""に放り込んで読みだしているだけなので、

ここは読み出し方も含めてまだまだ要検討です。

あと、Imageの位置も調節できるようにデータにオフセットの情報を入れるか、Maskやめてbutton用に一つずつ切り出すかしないとね。


ボタン有効化アニメーション

アニメーションの様子


f:id:aluminum_pepe:20190706173700g:plain


UIアニメーションが完全終わった後にUIアニメーションをする

ポイントはそれしかないですね。

拡大やら縮小アニメーションは一度つくってしまえば使いまわせるのでいいとして、

実装しているときは終了を検知する方法を用意していませんでした。

ので、しました。

終了検知だけのためにupdateでを垂れ流すのに抵抗があったので、必要に応じてコルーチンで待ちたいフラグを待つようにしてみたけどどうなんでしょうかね。




//コルーチンが呼ばれたら{}の最後にたどり着くまで毎フレーム呼ばれるようになる
IEnumerator HomeCharacterPanelCoroutine()
    {
        while (animationflagCheck() == false)//終了検知できていない限り
        {       
            yield return null;//ここで処理を中断=次のフレームで続き(Whileの判定)からまた呼ばれる
        }
        //終了検知できていればWhileを抜けてアニメーションを呼ぶ
        CharacterButtonNodeAnimation();
    }


//コルーチンは
StartCoroutine(HomeCharacterPanelCoroutine());
//で呼ばれるよ


上のコメントアウトをつけてわかりやすくしてみたつもりなんですけど、

「コルーチンというのは,処理を中断した後、同じ部分から続けて再開できる処理のまとまりである」

って色んな場所に書いてあります。

特定の時間待つ動作にオススメという事で使ってます。

僕も初めて使いました(未熟)。

今のところ上手く動いているのでこれでいいかなーと思っています。


これでHomeの説明はおしまいです。


……



なんだこの分量!?

まあ、ほとんどやってきたことが説明されつくされているので、あとはスッキリしそう。


■図鑑(Book)画面

前はこう。


f:id:aluminum_pepe:20190608233923p:plain


これが、


f:id:aluminum_pepe:20190706180631p:plain


こう。

まあ、さっきとほとんど一緒ですよ。

アニメーションはコチラ。


f:id:aluminum_pepe:20190706181719g:plain


一回拡大されているキャラが縮小するようなアニメーションをしています。

これ、かつてディバゲでキャラが表示されるときのアニメーションなんですけど、わかる人いるのかな……


f:id:aluminum_pepe:20190707144731p:plain
ディバゲでは、このアニメーションを利用してこんなスクリーンショットを撮るのがはやってました。


テキストの読み出し方も、テキストファイルをとりあえずResorceにいれて読み込んでいます。

Resorcesとは

Resorcesというのは、Unityの「Resorces」と名のついたファイルに入っていれば中のデータをどこからでも読み出せる素敵な機能です。

こんな素敵な機能のUnity公式チュートリアルページを見てみましょう。


unity3d.com


f:id:aluminum_pepe:20190706182811p:plain
Resorcesシステムのベストプラクティス :使用しないでください。


「最も最善の方法は使用しないこと」……だと!!??


僕も詳しくないので理由の説明は丸投げしますが、Resorces調べると大体この話題で持ちきりです。

メモリ的によろしくない、またはメモリ管理が難しい。という事です。

まあ、Resocesが便利であり、試験的に動かす分には使いやすい、とかスマホアプリ程度ならまあ、、みたいなことも見かけたんですが、

とりあえずResorcesすらほとんど使ったことないので、他の方法を調べつつ使ってみる方針です。



というわけで図鑑の紹介おしまい。


f:id:aluminum_pepe:20190706180956p:plain
試験的に書いたテキスト。最後の2行が書きたかっただけなんだ……


■ステージセレクト

前回まではこう。


f:id:aluminum_pepe:20190608124706p:plain


これが


f:id:aluminum_pepe:20190706183751p:plain


こう。

結構大幅改修してます。

動かしてるところはコチラ。

f:id:aluminum_pepe:20190706233348g:plain

こんな感じ。

ここもステージ用の画像からボタンを生成して配置させたり、

ステージに関する情報のテキストを表示できるようにしています。


f:id:aluminum_pepe:20190706233637p:plain

テキストはみんな適当です。


選択したステージの情報を各所に反映して見せるにはこだわってます、

が、あんまハロウィン関係ないね。

デザインはいろいろこれからも試すとする。


これでステージセレクトもおしまい。



■Others

前回まではこう。


f:id:aluminum_pepe:20190608233959p:plain


これが


f:id:aluminum_pepe:20190707145035p:plain


こう。


なにもいじってません。


アザーズ終わり!


まとめ

まとめるとこんな感じです。


f:id:aluminum_pepe:20190708065729g:plain


初回と比べてイメージが形になってきました。


f:id:aluminum_pepe:20190708070558j:plain


もちろんビルドして実機でも動かしてみてます。

自分の作ったアプリが動いてるのを見るのはやっぱりいいね。



締め

今回は以上になります。

時間がなさ過ぎてかなり適当な文章になっているが、とりあえず公開します。

機能自体はいっぱい追加して、かなり雰囲気も変わったので発表出来ることは多かった気がします。


本当はフッターのボタンにアニメーションをつけたり、選択状態によって表示する絵を変えたりもしたかったですね。

ノード生成、、配置、アニメーション終了検知、Mask機能、他uGUIのコンポーネントいろいろ。

UIに必要な機能の実装をするにあたって、試すことが多かったのでかなり勉強になりました。

データの格納方法だったり、読み込み方も要検討。SprictableObject?Assetbundle?なんかを試してみようかなと思っています。


コードを見直すとか、UIもう少しいじるとか、やれることはまだあるんですが、

そろそろゲーム機能の調整もしなければならないですね。


本日も、最後までお読みいただきまして、ありがとうございました。




f:id:aluminum_pepe:20181119135346g:plain
バイバ~~~~~~イ



次回予告

次回進捗発表、「8/21(土)」

頑張って、自分。(予定が詰まってるので8/10(土)にする可能性高)

↑カスが参ったので8/21(水)予定


↓さらに遅刻した続きです

aluminum-pepe.hatenablog.com


【第一回】 あるみに進捗発表 ソシャゲっぽいUIをUnityで作るチャレンジ [2019/6/8]

進捗発表してみるあるみにの話。

aluminum-pepe.hatenablog.com

本日より進捗発表という名の落書きを公開していきたいと思います。

いいですか今は6/8の、24:18です。6/8に間に合ってますね。ええ。

こんな調子で、いつまで続くことやら。



近況報告

近況報告なんていらん!という方は目次から「進捗発表」へ飛ぶといいです。

ゲーム


プリコネ

最近やってるゲームは、もっぱら「プリンセス・コネクトRe:Dive」です。

f:id:aluminum_pepe:20190609024609j:plain


サブ(でやる)ゲー(ム)にはピッタリとの触れ込みで、研究やらで忙しい自分も片手間でできるかな? という感じで1周年記念の無料10連から初めてはや4ヶ月になろうとしていますが、今も継続して楽しんでます。


このゲームは、ゲーム内通貨というか、育成やゲームを有利に進めるためのリソースの種類がとにかく多いゲームですね。


f:id:aluminum_pepe:20190609014525j:plain
「ショップ」の画面。上のタブの数を見てもわかるように「通常(マナと呼ばれるものを消費)」から「女神の秘石」まで、色んな種類のゲーム内リソースがあって、これまた経験値アイテムやらキャラを開放するアイテムと交換したりする。


それでいて、それらのリソースを回収できるあらゆる手段に対して、「1日に○○回or個まで」という制限があるんです。

普通、課金アイテムを使うとそういった制限は無限に突破できるはずが、このゲームではスタミナ回復や、特定のクエストの周回回数まできっちりと制限(※1)がある。

逆に、そのスタミナ回復等に使う課金アイテムの消費量はかなり少なく(※2)、無課金ですら数回であれば費用対効果が圧倒的に高いのです。

f:id:aluminum_pepe:20190609023356j:plain


※1 :スタミナ回復は1日30回、有用なリソースの手に入るクエストは周回回数を1日2回しか増やせない

※2 :スタミナ回復は初回~3回程度まで格安。回数を追うごとに消費数が増える。初回のスタミナ回復の石数は30回目の5分の1ってくらい最初安い


自分もかつて、「スタミナ回復やコンティニューに石を使うなんてありえない、そういうのは課金廃人のすることだ、僕はガチャにしか使わない」、そんな風に思っていました。

実際、ガチャで新規キャラがやってくることによる戦力の変動を考えれば、それ以外に石など使っていられないものです。

しかしプリコネの場合、前述した「あらゆるリソース」を使うことでほとんどのガチャキャラを入手する機会があります。つまり、ガチャに石を突っ込まなくとも、日々の限られた周回数によって、運にたよらずとも戦力を伸ばしていけるのです。


f:id:aluminum_pepe:20190609024054j:plain
キャラ開放アイテムを集めると、未所持キャラを開放できる

しかもこちらのほうが「運にたよらない=確実」なため、周回数の拡充に石を使ったほうが良いとすら思えてきます。

もちろんガチャでしか手に入らないキャラも存在しますし、ガチャで当ててしまうほうがいいに決まっています。それでも、「石をガチャ以外に使ってもいい」と自然に思えたのはこのゲームが初めてでした。

ガチャ以外に、「ゲーム内リソースを集めるために、課金アイテムを運用する」考え方をより自然にユーザーに対して与えることができていて、アプリゲーの新しい可能性を見た気分でした(小並感)


ある種、「白猫プロジェクト」というゲームとは対極な気がしています。

あっちは無限に周回する機会が与えられていて、やろうと思えば一日でほとんどのリソースを集めることができます(たぶんガチャキャラが手に入ったりはしないと思いますが)。

それに対してプリコネでは周回回数が限られているが故に、少ない周回回数を増やすために石を使おうと思いますし、無限に周回する必要はないのである意味気が楽ですね。

与えられている機会(例えばスタミナ)をMaxに使えない状態ってモチベーションが下がるんですよね。

過度なゲームプレイを求められていないからこそ、継続してプレイする気持ちになっている、みたいな。

最近はものすごい勢いでイベント開催しているからか、やっぱり忙しい気はします。



自分の場合、結局のところ「ガチャでしかあたらないキャラ」が現状ほとんど当たっているからモチベーションがあるだけかもしれないですね()


f:id:aluminum_pepe:20190609000620j:plain


先日もリゼロコラボの「レム」という子が当たりました。嬉しい。そんなわけでちまちま課金もしつつやっていますね。みんなもやってみよう。



……何を長々と話しているんだ自分は???これは何のための記事なのか……???



研究室

研究室に配属になって、なんとなくやる方針も決まって……というような状態です。

ほぼ自分の使える日中の時間は研究室にいって研究のためのプログラム書いたりお勉強しています。

プログラムいじるのは楽しいですね。

人のプログラムを読むということを初めて真剣にやりました。

それはそれで勉強になるので今のところ悪くはないです。

特に、プログラムを理解して新しく機能を追加できると気持ちいい。

でも、こんなに忙しい(というか時間を使う)と思ってなかったので、他のこと、ほとんどできないよう。

正直行くか行かないかも行く時間も帰る時間も指定されていませんが、取り敢えず己を律して早く成果を出したいですね。


アルバイト

バイト先がつぶれました。時間が増えるね(お金はなくなるね)


ゲーム制作

やろうと思えば帰ってから寝るまでに2~3時間は使えそうじゃん?

まって、YouTubeを、ニコニコ動画を開かないで……(一日終了)



進捗発表

というわけで本題。


つくったもの「UI」

自分がここ最近何をつくったかといえば「UI」になると思います。

とりあえずは制作物そのものの紹介等、軽くしたいと思います。

簡単に説明すると、Unityでゲームを作っています。

環境

  • Uinity2019.1.0f2(C#)
  • VisualStudio2017
  • GitHub , SorceTree

  • Androidビルド


スマホアプリつくりたい

去年自分はゲーム開発インターンに参加し、その中でスマホアプリゲームを一つ作りました。

このとき、自分たちがつくったゲームが(チームプロジェクトだった)、普段使っている携帯端末で動いてることにものすごく感動しました。

気分ブチ上がりました。

ちなみにそのゲームはGooglePlayで配信してるらしいのでよかったら覗いてみてください。

play.google.com


そういった事で、まず「自分だけでもスマホアプリがつくりたい」となったわけです。


ソシャゲっぽいアプリがつくりたい

同じインターンで一つ感じたのが、「UnityのUIのそれっぽさ、すごいそれっぽいな」でした。

Unityを触ったことないメンバーが主にUnityのUIを調べながら実装してくれていたのですが、

正直期待してなかったくらいまでそれっぽい見た目になったんです(失礼)

それはきっとメンバーの頑張りが大きかったと思うのですが、初心者がここまでそれっぽく見せられるのってすごいなって素直に思いました。

そこで、今回はUIにも気を使っていこうと思ったわけです。

スマホアプリのUIといえば……そんなのソシャゲのよくあるアレしかないじゃないですか。

上にユーザー名、スタミナ、下はクエストとか編成とか選べるボタン群。これを固定して、真ん中は選択したボタンによって変わるヤツ。


f:id:aluminum_pepe:20190608114050p:plain


そう、こんなのです。(汚い絵ですみません)

せっかくだからこんなのを作りたいわけです。


目指すソシャゲのUI

ソシャゲのUIを再現すると決まった所で、とあるアプリをモデルにしたいとすぐに考えつきました。

それはディバインゲートです。


f:id:aluminum_pepe:20190609001016p:plain


下はゲームUIをまとめて上げているブログの「ディバインゲート」のページです。

http://gameui.matme.info/blog/archives/1600

「ディバゲ」のUIは時期によって大きく3タイプあるのですが、一番初期のものがまとめられているみたいです。

「ディバゲ」のUIもゲームも好きだったんです。

サービス終了しましたが。


小一時間程度このゲームについて語りたいところですが、今の本題はそれではないので思い切って割愛します。

1つだけ強調しておくとすれば、「ディバインゲート零」ではない、ということでしょうか。

もっというと「旧ディバインゲートUI」なのですが、その説明も別の機会にするとします。

ゲーム性についても少し似たモノ?にするつもりです。

現状の方針としては、



というような感じです。ただし色々見よう見まねです。

真似するだけで、UIデザインそのもののに関しては詳しく調べていないのですが、いずれは調べるかもしれない。

素材

インターンから得た学びとして、「素材は使うと見栄えがいい」がありました。

当たり前のことなんですけど、どうしても細かいところまで素材を集めるのは面倒です。

大抵、用途に対して思い通りの素材なんてフリーだけでは見つかるものではないと思います。

ただ、加工OKの素材であれば、多少編集することで、差分を作ったり、用途に近いものを作り出すことができることに気が付きました。利用規約に注意!)

前の項で紹介した「それっぽいUI」も、素材を貼ることで機械的なボタンから、ゲームの世界観にあったものになっていました。


f:id:aluminum_pepe:20190609030103j:plain
はむちゃんGo!のタイトル。それっぽくない?


ということで、素材に対してもそれなりに気を使っていきたいと思います。


そこで、

使う素材は「いらすとや」に縛る

ことにしました。(なんで?)


一応、「いらすとや」さんのよくあるご質問より、

イラストの一部を加工して使うことはできますか?

問題ありません。ただし過激な表現やグロテスクな表現、法的に問題のある表現など、素材の印象を損なうような利用はやめてください。また、いらすとやのものと分からなくするための加工もご遠慮ください。

加工・トレースをしても素材部分の著作権は作者に帰属しますので規約に沿ったご利用をお願いいたします。


とか、


スマートフォン用のアプリに利用できますか?

問題ありません。ただし広告を掲載しているものや課金システムが導入されているものについては商用利用となりますので点数制限があります。

また「課金をすることでイラストやキャラクターが手に入る」といった形ではご利用できません。


とのことで、加工したりスマホアプリにするのは問題なさそうです。

ついでに商用利用するつもりもないので、点数縛りも考えなくていいと思います。

(商用利用する際は、20点まで自由、それ以上は有償だそう。)

いらすとや素材をうまく使わせて頂きたいと思います。


UI

そんなわけで、「UI」の話に戻ります。

今回の進捗はゲーム部分ではなく本当にUIの部分しか進めていないからです。



タイトル画面

まずはタイトル画面です。


f:id:aluminum_pepe:20190608122340p:plain


はーい強烈ですね()

こんな雰囲気で作っていくと思います。

タイトルに関しては色々と雑で思うところはあるのですが、「はじめる」ボタンは、



f:id:aluminum_pepe:20190608122632p:plain


この、毎月のタイトル文字の10月を表すイラストを少し加工してボタンにできるようにしています。



ホーム画面構成

一番ソシャゲっぽい場所です。


f:id:aluminum_pepe:20190608123321p:plain


構成としては、上から

  • ユーザー名などが表示される(はず)の上側のステータスパネル(と名付けました)、

  • ボタンによって中身(クエスト選択やユニット図鑑)の変わるコンテンツパネル、

  • コンテンツパネルの中身をボタン操作で決めるボタンパネル

と大きく3つに分かれていて、ステータスパネルとボタンパネルを固定しながら、コンテンツパネルの中身が遷移するような仕組みです。


■ホーム


f:id:aluminum_pepe:20190608123321p:plain

これは、「ホーム画面」です。

ボタンパネルの、「Home」を押すとコンテンツパネルの中身がこうなります。

ソシャゲで言う、タイトル開いてまず出てくる画面という位置付けです。


f:id:aluminum_pepe:20190609031900j:plain
こんなやつ。ぺコリーヌかわいい。


多分イベント情報が出てたり、ここからでも主要なシーンに遷移できたりするんですよね。

実装内容としては、

  • 時間が分かるデジタル時間表記

  • 遊び方が見れる(遊び方ウィンドウが開く)ボタン

位しか今は実装できていません。

「キャラ変更」とは、ホームに配置できるキャラを設定できる機能のことです。

さっきのホーム画面例にいた、キャラクターの事です。

これだけ旧バージョンの画面なのですが


f:id:aluminum_pepe:20190609032553j:plain

こんな感じになる予定です。



f:id:aluminum_pepe:20190608235803g:plain


遊び方ボタンを押すとこんな風に遊び方が書かれたウィンドウが出ます。(雑文章)


■ステージセレクト


f:id:aluminum_pepe:20190608235705g:plain


ゲーム画面へ移行する前の、ステージ選択画面です。

ここはかなり「ディバインゲート」を意識したUIになっています。

上のステージが並んでいるボタンを押すと、下のパネルに押したステージの詳細が表示され、「START」を押せばゲームが開始します。


f:id:aluminum_pepe:20190609034423p:plain
旧ディバゲUI。ステージセレクトと詳細はこっちは2回に分かれてる。



■ブック(図鑑)


f:id:aluminum_pepe:20190608235616g:plain


キャラクター図鑑です。

いままで遭遇したキャラが一覧として表示される予定です。

ボタンを押すと対応するキャラの詳細が見れる予定です。


f:id:aluminum_pepe:20190609043046p:plain

キャラリストはプリコネ、キャラ詳細画面はディバゲを参考にしている感じ……かな?


アザーズ(その他)


f:id:aluminum_pepe:20190608233959p:plain


その他です。何か用途があるはずです()

もともとBGMやSEの音量が設定できるオプション画面にするつもりでしたが、今は手が空いていないので、開発環境だとか使用アセットを記述したクレジット場面みたいになっています。これはこれで必要だと思いますね。


UIアニメーション

今回一番頑張ったところです。

むしろここだけ書けばよかったのでは()

UIが遷移するときに、ただ「カチカチ」と切り替わるのは今時のソシャゲUIとしては、ありえないですよね。

というわけで最低限のアニメーションを付けました。

それが、こんな感じです。


f:id:aluminum_pepe:20190609044023g:plain


どうですか、それっぽく出て来たり引っ込んだりしてるよね!!?


一度はUnityの機能である「Animation」をUIオブジェクトに適応してはいちいち設定して動かしていたんですが、なんだかすごくめんどくさかったんですよ。

Unityのためのアニメーションの設定をいじったり、animatorに変数渡したり……、

大した事のないアニメーションにいちいちキーフレームを打つのがなかなかしんどかったのです。

自分のやり方もきっと悪かったんでしょうけど、「これくらいならスクリプトだけで動かしたい」みたいな気持ちが強くなったため、DOTweenを使ってみることにしました。


DOTweenの知識もゼロからはじめたので、色々詰まりましたが、少しずつ慣れてきて、UIアニメーションを設定するシステムを作れたので満足です。

今は遷移アニメーションがごちゃごちゃで統一感がないですが、色々試してみてるということで。

「UIアニメーションを設定するシステム」についても説明したい(というかここが最大のポイント)のですが、締め切りが近いのでここでいったん公開してしまいしょう。(いっそ別の記事で書くかも)

え?過ぎてるって???


Androidビルド


もちろん実際にAndroidビルドもして、実機でも見てみてます。


f:id:aluminum_pepe:20190609045016j:plain

やっぱり目の前で自分の作ったアプリが動いているのはいいね。

スマホアプリは画面サイズがまちまちのため、それに対応できるようにCanvasは設定しているはずです。

ちなみウチのDIGNO T 君は調べたところ540x960だったため、UnityのGameウィンドウでのテストはそのサイズに合わせています。



課題

まだまだUIだけでも未実装の機能が山ほどありますし、UIアニメーションも全部には設定できていません。

UIに画像素材も貼り付けられていないので、見た目もまだ、Unityって感じですね。

ゲーム機能の方も調整が必要なのでUIばかりにうつつを抜かしてないで、作りたいと思います。



締め

というわけで、終わり。


お疲れ様でした。多分加筆修正します()

宣言した締め切りにはとりあえず間に合わせるぞ(間に合ってなかったよ)


見てくださった方がいましたら、ありがとうございました。




次回進捗発表予定日 7/6(土)

頑張って自分。




進捗発表をすることにした

ブログ書くのをサボりまくっているあるみにの決意表明のお話。

かつては自分の制作物を発表する機会があって、ある種の制作のペースを作っていたのですが、

今や研究に明け暮れる日々で、すっかり制作活動だの趣味の勉強ができてないんですよね……


……



それ、言い訳だよね

ええ全くその通り()。研究が忙しいにせよ、かつての自分だってレポートに追われてヒイヒイ言いながらも時間見つけて何かしら作っていたと思うんですよ。

そこで、


進捗発表をブログでやっていこうかと思います。


進捗発表というのはまあ、自分の制作物だとか、勉強している事柄の現状を紹介する事です。

やはり定期的に何かを見せる機会があるのは、モチベーションにつながるので、このブログを使ってそういった事をしていきたいと思います。

ブログもすっかりほったらかしだもんね。記事もかけ。


でも、続けられるの?

〇ャレンジのママかな?

続けようとは思っているけれど、その結果は3,4か月後にわかることになりそうですね。


進捗発表の概要

みたいなのを必要があれば書いたりとか、かつての進捗発表をまとめるページにできたらいいと思います。(逐次編集予定)

取り敢えず、「どんなにしょぼくても発表はする」みたいな気持ちでいけたらなと思います。

近況報告

毎回進捗発表のはじめに近況報告を入れます。

近況報告とは、自分の今やってるゲームやら生活の話を一方的に語る自分語りのコーナーです。

「相手を置いてけぼりにする」がモットーなので、「知らねえよ!」という人は飛ばしてください。

今追いかけているコンテンツの話とか、布教活動をしているのでぜひ見てください(支離滅裂なry)


f:id:aluminum_pepe:20190628154959p:plain

第一回進捗発表 7/8(土)


無事投稿できました(18分遅刻)。

aluminum-pepe.hatenablog.com


第二回進捗発表 7/6(土)


無事投稿出来ました。(後出し修正多すぎの件)

aluminum-pepe.hatenablog.com


第三回進捗発表8/22(水)

めちゃくちゃ遅刻しました。

aluminum-pepe.hatenablog.com



OpenSiv3DのSimpleGUIを使ってみる-1-

OpenSiv3Dを久しぶりに使うあるみにの話。


今回はOpenSiv3DのSimpleGUIを使って

表示したRectの大きさや回転角、回転速度などをいじれるGUIを作りたいと思います。

環境

  • VisualSudio2017
  • OpenSiv3D v.0.3.1

要求

今回実現したいスライダーの要件は、

  • 値をハイライトする
  • 取り得る値に範囲がある
  • ボタンを使用して特定の単位ごとに値を変更できる
  • 「0」ボタンで値を0に初期化できる

みたいな感じで。


イメージ図はこんな。

f:id:aluminum_pepe:20190304032649p:plain

旧Siv3Dではこんな感じでした。

f:id:aluminum_pepe:20190304044957g:plain

「0ボタン」はこの時はないですね、だからこそ、これを機に作るんですけど


ライブラリ確認

今回はOpenSiv3Dにある「SimpleGUI」というのを使っていきたいと思います。

F12で実装を軽く見てみる。

f:id:aluminum_pepe:20190304030240p:plain
SimpleGUIの実装


知りたいのはスライダーなので…

    bool Slider(double& value, const Vec2& pos, double sliderWidth = 120.0, bool enabled = true);

    bool Slider(double& value, double min, double max, const Vec2& pos, double sliderWidth = 120.0, bool enabled = true);

    bool Slider(const String& label, double& value, const Vec2& pos, double labelWidth = 80.0, double sliderWidth = 120.0, bool enabled = true);

    bool Slider(const String& label, double& value, double min, double max, const Vec2& pos, double labelWidth = 80.0, double sliderWidth = 120.0, bool enabled = true);


今回見るべきなのはこの辺かな、訳すと、


  1. Slider(値,座標,スライダーの横幅,有効状態):

  2. Slider(値,最小値,最大値,座標,スライダー横幅,有効状態):

  3. Slider(ラベル,値,座標,ラベルの横幅,スライダーの横幅,有効状態):

  4. Slider(ラベル,値,最小値,最大値,座標,ラベルの横幅,スライダーの横幅,有効状態):


といったところですね。

fontと「2」の実装を組み合わせればいいかな。

できた

というわけでできたのがこんな。

f:id:aluminum_pepe:20190305145615g:plain

github.com

やっつけですがGUIに合わせて図形が動くようにしてあります

詰まったところ

ToRadians

回転をさせる処理は

rotated(ラジアン角) 

な訳ですが、GUIのハイライトでラジアン角を表記するのは分かりにくいです。

そこでGUIの値は-360~360の度数で扱い、処理の段階でラジアン角に変換することにしました。

というわけでRectの回転を、

RectF(100,100,block_w,block_h).rotated(Radians(block_r)).draw(Palette::White); 

としていたら、Radiansで怒られました。

f:id:aluminum_pepe:20190304065334p:plain

OpenSiv3DではToRadiansを使うみたいですね。

エラーコード見れば一目瞭然なんですが、焦っていたみたいで気が付かずウンウン言ってました()

値の表記

先ほどの話の続きになりますが、

GUIのスライダーによって値を変更するとき、値がdouble型なだけあって、かなり中途半端な値を取り得ります。

例えば127,345…………みたいな事です。

2つ問題があります。

こんな風に、ただ表示してると値が表示され過ぎる

f:id:aluminum_pepe:20190304131748p:plain

表示され過ぎてUIとびぬけてる。

0と1の間に差が生じる

f:id:aluminum_pepe:20190304131323p:plain

↑明らかに0じゃない0だ。この値は、有効範囲が-10~10と狭い。スライダーは長いのでこういった表示だけ誤魔化しても中途半端な状態が生まれる。

こっちの方が重いです。表示だけ直したとしても表記上0で0でない値はあまり良くない。

特に角速度、x移動速度、y移動速度は0であるのと0出ないのとでは大きく異なるため、厳密にする必要がある。

値をint型にしてしまいたいところですが、スライダーで扱う値はdouble型でなければならないので、intにキャストしてから代入しなおしてます。

なお、この場合値を変更している最中はSliderの処理中だからなのか気持ち悪い表示のままです。

f:id:aluminum_pepe:20190305004900g:plain

こんな感じで、カーソルを離した瞬間は補正がきくものの、変更中は補正されてないのでそのまま表示されてしまう。

加えてスライダー処理中の値の変化についてはいじり方が分からなかったので手が出せません。

そこで、たまたま知ったのですが、

U"{:.1f}"_fmt(変数) 

とする事で、表示する変数の桁数を定めることができるみたいです。(この場合小数点以下1桁まで)

というわけで使いました。まあつまり、基本的に補正はかけているので、結局見た目も誤魔化しちゃおうということです。

今回、小数点以下を全部なくしてるだけなので、表記する値をintにキャストするだけで良かったのでは…………?

レイアウト

GUIのレイアウトは1つのウィンドウ用のRect(=BlockGUIBox)の座標を基準に、特定のVec2を加算して相対的に決めています。

    if (SimpleGUI::Button(U"-", BlockGUIBox.pos + Vec2(65, 40), 20))
    {
            block_w--;
    }

基準にしているBlockGUIBoxが動けば一緒についてくるので、持ち運ぶ挙動ができました。

f:id:aluminum_pepe:20190305144049g:plain

バーの部分だけ持てるようにしてあります。あとバーは画面外に出ません。

前のGUIのウィンドウみたいになった気がする。

今後

とりあえずここまでで一度公開してしまって、クラス化?みたいなのをざっくりやってもう一度上げたいな

元々自作クラスで実装したものを引っ張り出してMainに直書きしたのであんまり見やすくないかもしれない。

とはいえクラスで見せるのもアレなので………

というか公にするにはコードがガバガバ過ぎるよう……


いい感じに汎用クラスみたいにできたらいいんだけどなあ、定石がわからんなあ


処理と描画を分けようとして失敗(?)した話とかしよう

まとめ

OpemSiv3Dに久しぶりに触れ、新しい仕様のSImpleGUIを触りました。

前よりはレイアウトや動かし方に若干自由度が増えた?前よりは扱い方がわかりやすくなったような気がします。

他の図形なんかと扱い方が近くなった?からかな

SimpleGUIが値の変更とGUIの描画そのものを同時に担っているので、処理部と描画部は分けられなさそうだなーと思いました。

ちょっと機能使ってないと忘れそうなので、備忘録的に使っていけたらいいな

今回はGitでコードの公開もしてみたけど、Gistの方がよかったかもしれん

あと「何やこれひどいな!こうしたほうがいい!!」という人がいましたらマサカリ投げてください(震)

自然なジャンプをしてほしくて-Unityでジャンプアニメーションをいじいじする-

Unityで自然なジャンプを目指したあるみにの話。

一年前くらいに頑張った事を再現しつつまとめておく記事。

3Dキャラクターを動かすゲームを作りたい!

せっかくならばキズナアイちゃんに動いてもらいたいところですね。

アニメーションを仕入れるためにもアセットの力を借りよう。

……ということでUnityちゃんアセットから色々持って来てみる

assetstore.unity.com

一度Unityちゃんに元からある移動スクリプトで動かしてみよう。

f:id:aluminum_pepe:20190106232921g:plain

動いてくれたね。

上キーで進み、左右キーはその場で止まって方向転換するみたい。ちょっと使いにくい。

カメラの視点を背面に固定すれば(もともとはそうなっている)違和感がないのだけど。

他のアセットの移動スクリプト、、例えばいつかの記事の「とりあえず操作する編」のものを使ってもいいのだけど、

自由に機能を追加しようとすると元々のスクリプトを完全に理解して改変する必要があるので、

なかなか闇が深くなってしまいそう、、、、

今のレベルで読み解くのは難しいので、移動スクリプトも一から書いていこう。

目標

  • カメラをグリグリ動かしながら移動する
  • 目の前にもカメラが回り込めたりする
  • イメージはマリオ64モンスターハンターのような三人称視点
  • なるべく人間的で自然な動き

三人称視点とはいえ、ただ後ろにカメラが周りこんでくるだけなのは少し寂しいので、プレイヤーがカメラを操作するやつをやりたい。

あとは人間的で自然な動き……これが大変そうな気がしますね()

とりあえず移動とカメラ

と、いうことで自分たちで、一連のスクリプトを書いてきました。

”たち”、というのは、3Dキャラを動かしてゲームを作ろうとしている過程で、友人を1人巻き込んでペアプロジェクトのようなものをしているためです。

その話はまあおいおいしていきたい。(そういうのを書いていくべきなんじゃないですかね)

ともかく3Dキャラを動かす勉強だって事で、いろいろ調べつつ移動スクリプトを書きました。



こんな感じになりました。

f:id:aluminum_pepe:20190107015330g:plain

マウス操作で視点をグルグルいじりながら、WASDキーで移動するものです。

移動&カメラ処理について

ChatracterContolloerを使った移動は自分が、カメラ処理は友人が主に書いてくれました。

カメラ移動はそのカメラの正面を軸に、WASDで移動になるようにお互いにかみ合わせたのがアピールポイントですかね?

まあそうじゃないとカメラに対して反対向きのときは行きたい方向と逆に入力しないといけないだとか、おかしいことになりますからね。

一番はじめのUnityちゃんの移動スクリプトは、カメラの位置にかかわらず、上キー入力でその時向いている方向へ進むので、

ただの三人称視点カメラでは操作しているうちにどんどん感覚がずれてくるという問題がありました。

何度も言う通りカメラが基本的にUnityちゃんの後ろにまわる事が前提のスクリプトだったわけですね。


かみ合わせたといっても、カメラの正面方向と入力方向のベクトルと掛け合わせたものを実際の移動に使ってるだけですが、、、

お互いググりながらとはいえ、カメラをグリングリン動かす方が大変な気がするので友人に感謝。

今はお互いにこの手の実装はできるようになりました。多分。


f:id:aluminum_pepe:20190107021950g:plain

グリグリカメラ移動、いいですねえ


ジャンプ実装

というかここからが本題なんですが。

今のでカメラに関する目標はほとんど達成されたとみていいでしょう。

あとは操作面でどれだけ"人間的にできるか"ということになりそうです。

ということで実際のジャンプに移りたいわけですが、これもUnityちゃんのジャンプモーションがあり、これを使ってみるわけですよ。

f:id:aluminum_pepe:20190107023934g:plain

この感じだとうまくジャンプできている気がするが、、、




ジャンプしてないよ

これ、ジャンプしてません。

どういうことかというと、これ、ジャンプのモーションだけ再生して判定は跳ねてないんです。

f:id:aluminum_pepe:20190107024603p:plain

こういうことです。

これだど当たり判定が残ったままなので、障害物を乗り越えるということがまるでできないですね

まあこれは、ジャンプ時に上方向の力をこちらで付ければいいだけなので、やってみる。



不自然だよ

f:id:aluminum_pepe:20190107030053g:plain

おわかりいただけただろうか……


そうこれ、ジャンプの入力とともに上方向の力を与えただけなんですが、

ジャンプの予備動作から飛んじゃってる。

もっというと、

着地モーションと全くあっていない。

というね。

実はこの問題、一番はじめのUnityちゃんのときから既に垣間見えていたんですよ。

f:id:aluminum_pepe:20190107030638g:plain

これとか。モーションが早く終わって空中に着地して空中を走ってますね。

さらに言えば、着地モーション中に移動できてしまうので足を動かしてないうちに滑るように移動してしまったりしてしまってます。

うーーん不自然。

これらを解決するためにどうしたらいいのか。

予備動作を切り取って、着地モーションも切り取るかすぐに移動に遷移させれば見栄えは解決するかもしれない。

ジャンプモーションに合わせて当たり判定を動かしたり、加える力を調整したらいいかもしれない。


しかし、これからジャンプの高さは調整できるようにしたい。

もしトランポリンに乗せるとか、能力上昇のために倍率をいじるのであれば、

当たり判定に合わせてモーションは再生されるべきでしょう。

そして、予備動作とかも再生した人間的な部分を再現しておきたい。

どうしようか……


…………


……


ジャンプモーションを切り刻もう。



切り刻もう、ジャンプモーション。

ググる力が弱いのか、有効そうな策を見つけられなかったあるみにの苦肉の策です。

問題は、ジャンプモーションが予備動作、ジャンプから着地まで一つのアニメーションになってるのが問題なんですよ。

とはいえ、自分に着地モーションを作ったりする技術はいまのところ持ってない……


いや、着地モーション、ありますね、そこに。部分に。


ということです。

f:id:aluminum_pepe:20190107035602p:plain

はいUnityちゃんのジャンプモーションである、「unitychan_JUMP00B」をいくつか切り分けで保存してみました。

同じアニメーションから、元々のアニメーションも合わせて10個のAnimationClipがあります。

StartとEndの標記のおかげでわかりやすくなってるのだが、状態に合わせて時間で区切って作っています。

10個ありますが、最終的には4つくらいしか使ってないんですけどね()

使ってる奴だけ紹介しましょう。

切り刻んだジャンプモーションたち

f:id:aluminum_pepe:20190107042000g:plain

まず、ジャンプをはじめる「JampStart」です。

f:id:aluminum_pepe:20190107042115g:plain

次に、滞空アニメーション(上昇中)の「Jump04」です(名前つけろ)。

f:id:aluminum_pepe:20190107042248g:plain

そして落下モーションの「Fall」です。

f:id:aluminum_pepe:20190107042409g:plain

最後に、着地モーションの「Jump07」です(Landingとかにしろ)。

これらを一連で再生すれば、元のジャンプアニメーションになります。

これらを状況にあわせて制御することで自然なジャンプアニメーションを表現するもくろみです。

いざ改修

まず、以前のジャンプアニメーションのアニメーションコントローラーがコチラ。

f:id:aluminum_pepe:20190107043249p:plain

シンプルですね。


そして次、自然なジャンプアニメーションを目指したアニメーションコントローラがコチラ。

f:id:aluminum_pepe:20190107050142p:plain

デデドン。

一気にStateが増えて遷移する矢印も入り組んできました。

実際に実行するとこんな感じです。

f:id:aluminum_pepe:20190107051856g:plain

さっきと同じだけの力でジャンプさせてますが、かなり安定した見栄えになってるのでは??


簡単に言うと、ジャンプ開始アニメーションのあと、上昇アニメーションにはいり、

キャラのy方向の速度が負の値になる=落下するときに落下モーションに変更、

地面を検知したときに着地モーションを再生する。


と、いう感じです。


サラッと言ってますがコードのほうは70行くらい増えました。

具体的には、床の判定をより正確にとるために、下方向にレイを飛ばすことにしたのと、

各状態が整合性をもって遷移できるように条件分岐を書いたりしました。

コードとかも載せた方がいい……と思うのだがうまい載せ方を考える気力がないので、また別で紹介するか、GitHubで紹介するかもです。

(いまのはキズナアイとかいるので簡単に公開できないというアレ)


おかげで、かなり汎用性のあるモーション再生ができている気がします。

例えば、ジャンプ地点と着地地点の高さが異なっても、違和感ないのがいいですね

f:id:aluminum_pepe:20190108031232g:plain


また、副産物的に落下モーションだけを使って、「ある程度の高さから落下した場合落下モーションをする」こともできるようになりました。

f:id:aluminum_pepe:20190108031909g:plain

アニメーションイベントってすごくね?

もうひとつ、予備動作はそのままでモーションで跳ねたときに合わせてジャンプができてます。

これはアニメーションイベントを使いました。

f:id:aluminum_pepe:20190107054818p:plain

ジャンプモーションのうち、跳ね始めである「JumpStart」のアニメーションのインスペクターから、「Events」という項目を開くことができます。

上の写真では、タイムライン上にJumpStartと表記された場所があると思います。

アニメーションイベントとはアニメーションの進行中に設定した関数を呼ぶ事ができる機能です。

つまり、跳ねる瞬間の時点で「上方向に力を加える処理」を登録すれば、そのタイミングでアニメーションがその処理を呼んでくれるわけです。

f:id:aluminum_pepe:20190107055120p:plain

↑跳ねるタイミング、、、、ココ!!!!!


それから、最後の着地モーションにまだ滑っていたので、一定の時間移動処理しないようなアニメーションイベントを追加しておきました。

f:id:aluminum_pepe:20190108032549g:plain

ジャンプ中も入力しっぱなしにしてます。比較すると分かりやすい。

モーションに合わせて当たり判定を伸縮させる

ジャンプ中、体を反るアイちゃんですが、足を上げて乗り越えられるようにみえるブロックが乗り越えられない。

f:id:aluminum_pepe:20190108033545p:plain


f:id:aluminum_pepe:20190108033528p:plain

それもそのはず。当たり判定自体はしっかり引っかかっているのだ。


ということで、ジャンプモーション中の体の"そり"に合わせて当たり判定が伸縮するようにもしてみたりしました。

f:id:aluminum_pepe:20190108034128p:plain

アニメーションイベントのときと同じ要領で、

ジャンプモーションのうち、反ってる「Jump04」のアニメーションのインスペクターから、「Curves」という項目を開くことができます。

ここでは特定の変数に対して、アニメーションの進行に合わせて値を変化させられます。

ここに当たり判定の大きさを決める三要素に対応する変数を作り、モーションに合わせて伸縮するように値を設定。

上の写真のように値がグラフのような変化をしてくれます。

ここの変数はAnimationControllerに対応するので、移動スクリプトから読み出して当たり判定に実際に適応させるようにします。

f:id:aluminum_pepe:20190108035103p:plain

これならば実際に乗り越えられますね。

f:id:aluminum_pepe:20190108035835g:plain

乗り越えられました。


一応、当たり判定の変化の様子を載せておく。

f:id:aluminum_pepe:20190108040140g:plain



かなりジャンプは突き詰められたかな。



まとめ

移動スクリプト、もといジャンプを自然に見せるためにいろいろしてみました。

個人的にかなり完成度の高いものにできたのではないかなーと思っています。

でも、実際この解決法って、どうなんだろう?

けっこうな力技である気がしないでもないし、もっとうまい方法があったのかも……

そんな情報をお持ちの方がいましたら是非教えて頂きたいです。

ヒントだけでも()


今回、GIFをいっぱいつかうというのが裏目標みたいなところがあったんですが、

わかりやすくなってましたかね、、

あとはコードを載せるか否かというところは、まあおいおい追加するかもしれない

自分が必要な部分だけ思い出せるようになるかもしれないし。

もっと具体的な実装方法もいずれ述べるかもしれない。

いままでで一番開発ブログという感じのする記事になったかなと思うので、

これからも記事をかきつつ開発を進めていきたいですねえ


まあ今回の内容、一年前くらいにやってたことなんですけどね。

状況再現なんかやったりしたので、色々思い出せてよかったです。


これからも過去にやった事とか新しくやる事をどんどん記事にしたいぞ

ライセンス

Unityちゃん

f:id:aluminum_pepe:20190107170135p:plain

http://unity-chan.com/contents/license_jp/

このコンテンツはユニティちゃんライセンスより提供されています。


キズナアイ

(c)Kizuna AI