こんにちは栞です。
自分の性癖であるぽっちゃり・肥満化を
ゲームをいう形で具現化したく、
7月からUnityを触っています。
その内容ですが、
フラッピーバードをもとにしたゲームを作ろうと思っております。
フラッピーバードって?というかたは前回の記事↓をご覧ください。
![](https://shiorinoatelier.com/wp-content/uploads/2024/07/スクリーンショット-2024-07-22-024020-300x164.png)
- 障害物とアイテムのスクロール
- アイテムをとるとスコアが加算
- 地面と障害物に接するとロード
までは実装できたのですが、
あいにく、ひょんなことからオブジェクトが消えてしまったので
いったんスクールのカリキュラムに戻りました。
今はTanksというUnity公式のチュートリアルに沿って
学習を進めています。
https://learn.unity.com/project/tanks-tutorial?uv=5.x
3Dの物理演算ゲームとしては
すでにたまころゲームを作ったのですが、
今のところその応用といった感じですね。
あたらしい概念も特に出てくることもなく、
ただ知識を増やしていくフェーズっぽいです。
さいごにデータベースへのアクセスやAPIを用いたサーバー連携が絡んでくるので
そこだけやや難しそうですね。
ということでここ最近の気づきなど。
新時代のAIエディタ 「Cursor」 がすごい
ここまでPC標準搭載のVisualStudioを使っていたのですが、
どうやら便利なAIエディタがあるとのことで乗り換えてみました。
使ってみると、
というより使おうと思わなくても
いろいろやってくれるんですよね…この人。
コードを途中まで打って、改行して1秒くらい待つと
そこへ続くであろうコード群をグレーでサジェストしてくれます。
Tabキーを押すと確定。
「こういうコードを書いて」とコマンドに日本語で打ち込むと
それもコーディングしてくれる。
コードの意味も教えてくれる。
Claudeへのコピペ不要。
…とまだまだ機能はあるようですが
今のところはこれくらいしか使えてません。
もっと触って頭脳の一部かのように使っていきたいですね。
これでClaudeがおはらい箱かというとそんなこともなく、
Cursorは隣にエディタがある分質問へ回答してくれるスペースがだいぶ
手狭なのでその点はClaudeに軍配が上がります。
プロパティってややこしくない?
これで今日だいぶ混乱してました。
指してるものが2つある言葉…っぽいですね…
普段は知識のアウトプットはコメントアウトで
済ませてるんですが、
さすがに板書しないと頭のなかがこんがらがるので
がっつり書き出しました。
はじめの4枚はTanksゲームのコードについてです。
我ながら女子中学生みたいなノートの取り方ですね。
![](https://shiorinoatelier.com/wp-content/uploads/2024/07/1-1024x976.jpg)
![](https://shiorinoatelier.com/wp-content/uploads/2024/07/2-1024x976.jpg)
![](https://shiorinoatelier.com/wp-content/uploads/2024/07/3-1-1024x976.jpg)
![](https://shiorinoatelier.com/wp-content/uploads/2024/07/4-1024x976.jpg)
![](https://shiorinoatelier.com/wp-content/uploads/2024/07/5-1024x976.jpg)
![](https://shiorinoatelier.com/wp-content/uploads/2024/07/6-1-1024x976.jpg)
![](https://shiorinoatelier.com/wp-content/uploads/2024/07/7-1024x976.jpg)
![](https://shiorinoatelier.com/wp-content/uploads/2024/07/8-1024x976.jpg)
![](https://shiorinoatelier.com/wp-content/uploads/2024/07/9-1024x976.jpg)
![](https://shiorinoatelier.com/wp-content/uploads/2024/07/10-1024x976.jpg)
具体性の高い知識の量ではなく、
それらを抽象化してまとめ上げている概念への理解度を上げようと腐心してます。
具体的にはクラスとか、プロパティとか、関数とかですね。
新しく出てくる横文字に対し逐一処理や文法を覚えるのはあまりにも効率が悪いので
「ここで出てきたA(具体)はB(抽象)だから、同じBである既知のC(具体)とほぼ同じだな」
というスタンスでぱぱっと理解していきたいと思ってます。
はじめて見るコードも、抽象レベルでの既視感を覚えることができたら
ほぼ攻略済みみたいなものじゃないでしょうか。
追記 -長いコードには名前をつける-
コメントにて赤線の部分に改善の余地があるとの指摘を頂きました。
private void EngineAudio()
{
if (Mathf.Abs (m_MovementInputValue) < 0.1f && Mathf.Abs (m_TurnInputValue) < 0.1f)
{
if (m_MovementAudio.clip == m_EngineDriving)
{
m_MovementAudio.clip = m_EngineIdling;
m_MovementAudio.pitch = Random.Range(m_OriginalPitch - m_PitchRange, m_OriginalPitch + m_PitchRange);
m_MovementAudio.Play();
}
}
else
{
if (m_MovementAudio.clip == m_EngineIdling)
{
m_MovementAudio.clip = m_EngineDriving;
m_MovementAudio.pitch = Random.Range(m_OriginalPitch - m_PitchRange, m_OriginalPitch + m_PitchRange);
m_MovementAudio.Play();
}
}
}
判定内容をもっとわかりやすくせよ、つまり
条件式なのにどのようなときにtrueかが分かりにくいとのこと。
ということで改善。青線部分です。
private bool IsIdling()
{
return Mathf.Abs(m_MovementInputValue) < 0.1f && Mathf.Abs(m_TurnInputValue) < 0.1f;
}
private void EngineAudio()
{
if (IsIdling())
{
if (m_MovementAudio.clip == m_EngineDriving)
{
// アイドル状態に切り替える処理
m_MovementAudio.clip = m_EngineIdling;
m_MovementAudio.pitch = Random.Range(m_OriginalPitch - m_PitchRange, m_OriginalPitch + m_PitchRange);
m_MovementAudio.Play();
}
}
else
{
if (m_MovementAudio.clip == m_EngineIdling)
{
// 走行状態に切り替える処理
m_MovementAudio.clip = m_EngineDriving;
m_MovementAudio.pitch = Random.Range(m_OriginalPitch - m_PitchRange, m_OriginalPitch + m_PitchRange);
m_MovementAudio.Play();
}
}
}
たしかに見やすくなりました。感謝です。
メモもとったので残しておきます。
![](https://shiorinoatelier.com/wp-content/uploads/2024/07/補足-1024x976.jpg)
![](https://shiorinoatelier.com/wp-content/uploads/2024/07/補足2-1024x976.jpg)
スクールの感想
レスが遅い。
これに尽きます。
質問して3時間はまず返答が来ないのが今のところ確定してます。
だいたい5~12時間後に返ってくるのですが…
正直遅いです。
ユーザーの環境次第など、答えにくい質問なのか分かりませんが
丸二日以上放置されてる質問まであります…
答えかねるならそう返答してほしいです。
ここで愚痴るのもばかばかしいのでチャットを送っておきました。
3人体制ということでそこそこ返信速度は期待が持てるかな~と
思っていたので残念ですね…
他社に比べ1/3の価格なのでこんなものなんでしょうか。
2年前に受講したテックアカデミーというところは
レス速かったですね。
即時~30分くらいで返ってきていた印象。
質問するたびに違う講師の方が答えていたので
講師の数が今思えばだいぶ多いのかも。。。
なんで今回テックアカデミーにしなかったかというと
あそこは週2で30分の面談があるんですよね。
でも聞きたいことはわりと即時で答えてくれるし
私は口下手だしで
豚に真珠なサービスだったので
面倒に思ってその手のメンタリングのない
ところにしました。
決して値段で決めたわけではないので
「まあ、この値段だしね」と思えないのが
ちょっと悔しいですね…
冷静に考えるとプロ3人がついて2ヶ月10万円って
ビジネスモデルとして破綻してます。
そりゃ返信遅くて課題へのフィードバックもなくて当然ですよね。
でないと時給がかなり低くなってしまうので。
そこに気づけなかったのは反省です。
ちなみに教材も雑です。
α版みたいな動画教材がこちらの進捗に合わせて送られてきます。
内容も他所のブログのものそのままだったり
「あとは公式の動画を見て各自実装してね」だったり
で大変驚かされます。
チャットが遅いのは分かりますが
使いまわしが効くもののクオリティまで低いのは異常事態です。
そこが雑だから生徒の分からないところが出てきやすくなって
質問回答の労力が増えてしまうのでは…と内心思ってます。
今はAIがあるので良いですが
2~3年前とかに受講していたらと思うと恐ろしいです。。。
多分発狂してました
おわりに
ということでUnityの学習の進捗でした。
9月中にゲームとしての最小単位の完成品をリリースする予定なので
お待ちください!
あいかわらずコメントも募集中です。
それでは。
次の記事↓
![](https://shiorinoatelier.com/wp-content/uploads/2024/08/10-e1722741598795-300x122.jpg)
コメント
コメント一覧 (4件)
こんばんは。どんどん新しい内容に挑まれているので毎度記事を興味深く拝読しています。
さて前回コメントがページに載った際どれだけの行数になったか見て我ながら引きましたので、短めに…
if文が入ってきたところで「数式を数式のまま残さず、名前を付ける」ということが重要になります。EngineAudioの最初のifの中をbool IsIdling()として分離し名前をつけると、if (isIdling)…となり、判定内容が推測できるうえ分岐の中でやることも「アイドル中にしたい処理」とわかるので間違った分岐のほうにコードを追加してしまうことも減らせるためです。
さらに発展編としては、EngineAudioをクラス(MonoBehaviour継承なし)とし、フィールドにidleAudioClip, driveAudioClipを持たせ、インスタンスメソッドとしてAudioClip getClipToPlay(movementInput, turnInput)を作るということが考えられます。Start()の中でnewしたengineAudioインスタンスをフィールドに保持しておき、Update()ではinputをもとに「今のフレームで流すべきclipはどちらか」を取得できるようにすると、
var clipToPlay = engineAudio.getClipForMovement(move略, turn略);
if (movementAudio.clip != clipToPlay) { clip代入; pitch代入; Play呼び出し }
となり、elseの中で似たことを繰り返している部分をなくせて、また正しいclipToPlayが返せているかを実際のキー入力に頼らなくても
Debug.Log($”move0.9 turn0のとき流されるclipは{engineAudio.getClipForMovement(0.9f, 0f).name}”);
のように検証することができるようになります。
試作のリリースを楽しみにしております!
ありがとうございます!
式に名前をつけて関数にするところまでは理解できたのですが
(本文に追記しておきました)
後半についてはまだまだ…という感じです
if (movementAudio.clip != clipToPlay) { clip代入; pitch代入; Play呼び出し }
でelseを使わないとなるとどちらか一方の音源しか流せないのではと感じてしまいます。
ここ以外にPlay関数はどこかにもう一つ記述するんですかね?
ただクラスごとに責任をわけることとコードの重複を避けることが
ちゃんとした制作物を作るうえでは重要なんだなというのは分かりました
制作お疲れ様です。
Cursorすごいですよね~自分も業務で使うにはまだだろうな、くらいに思っていたら、もう現場での採用実績も多いですね。自分はAI補助ではGitHubのCopilot ってものを使ってRiderやVisualStudioでプラグインという形で入れてたりします。(高いですが。。)
栞先生は実装の時に細かく理解を進める形で学習されていてすばらしいですね。
最初からAudioSourceでの音源再生の際にもピッチ指定まで入れられているとは。
音源を鳴らす箇所だけをまとめて関数(メゾット)にしてみて、それに委託する形で再生部分を処理すると良いかもと思いました。
ついでに音量も調節可能にして、デフォ(引数なしの場合)は一倍再生とか。
public void PlaySound(AudioClip clip, float pitch, float volume = 1.0f) {
if (audioSource == null){
Debug.LogError(“AudioSource がないから再生できないよ”);
return;
}
audioSource.clip = clip;
audioSource.pitch = pitch;
audioSource.volume = volume;
audioSource.Play();
}
これを使って
if (IsIdling()){
if (m_MovementAudio.clip == m_EngineDriving) {
PlaySound(
m_EngineIdling,
Random.Range(m_OriginalPitch – m_PitchRange, m_OriginalPitch + m_PitchRange));
}
} else{
if (m_MovementAudio.clip == m_EngineIdling){
PlaySound(
m_EngineDriving,
Random.Range(m_OriginalPitch – m_PitchRange, m_OriginalPitch + m_PitchRange));
}
}
的な感じでもいいかも、
UnityはAudioSource再生前にClipとか空にしておいた方が良かったりするケースもありますが省略で。。
あ、書き込んでる中で気が付きましたが、上の方がすでに同じことを仰っていました。はずかしい。。
非MonoBehaviourクラスならいっそシングルトンにしてAudioManagerクラス化してしまうほうが良いかも?(単一クラスからしかアクセスしてない音再生機能をどこまで詰めるかという)
制作のんびり頑張ってください~
コメントありがとうございます!
入れ子になってるifの処理にもPlaySoundという名前をつけて読みやすくという発想ですね。
非MonoBehaviourクラスについてはまだ学習の中で出てきておらず心からの理解が難しそうなので
また実装することになった際にこちらのコメント思い出させていただきます~