![見出し画像](https://assets.st-note.com/production/uploads/images/143203487/rectangle_large_type_2_8b9f918ad93eb8a17cfe769debb07e37.png?width=1200)
初心者がUnityでゲーム作る Day8 ~殴る蹴るの暴行
Day8まとめ
Unityでも上下左右に動けるようになった。
岩をブン殴って石を落とせるようになった。
やりたいことがいっぱい出てきた。
動く
アニメーション
Unrealでやった設定を再現してスクリプトで移動を実装した。
![](https://assets.st-note.com/production/uploads/images/143193910/picture_pc_cab6f62e8220ad0fe60edc03e189a0ac.gif)
アニメーションで困ったこと
idleとDashの切り替えで非常に悩んだ
UnrealのinputSystemみたいに「Completed」とかが設定できないため
結局、以下のように実装した。
// 移動速度変数
#region Inspector
[SerializeField]
private float _speed = 40;
private float _horizontalInput;
private float _verticalInput;
#endregion
// アニメーション遷移監視用
#region AnimTransition
public bool isMoving;
public bool isAnyInput;
public bool isTransition = false;
public bool isInputW;
public bool isInputA;
public bool isInputS;
public bool isInputD;
#endregion
// 関数を引っ張ってきたいクラスはインスタンス化する必要がある
public PlayerAnimationController Anim;
void Update()
{
#region MovementSettings
// 移動とアニメーションの制御用にWASD入力を監視する
isInputW = Input.GetKey(KeyCode.W);
isInputA = Input.GetKey(KeyCode.A);
isInputS = Input.GetKey(KeyCode.S);
isInputD = Input.GetKey(KeyCode.D);
// どれか一つでも入力があるか確認
isAnyInput = isInputA || isInputD || isInputS || isInputW;
#endregion
#region MovementAnimation
// 静止中 かつ Inputがあり、Transitionが切れてたらonに
if (isMoving == false && isAnyInput == true && isTransition == false)
{
isTransition = true;
}
// 移動中 かつ Inputなく、Transitionが切れてたらonに
if (isMoving == true && isAnyInput == false && isTransition == false)
{
isTransition = true;
}
// WASDどれか1つでも入力があればisMovingです
isMoving = isAnyInput;
「移動中」「キー入力あり」の2つのフラグを用いて「今トランジションしました」というフラグを立てるように設計した。
なんかもうちょいスマートで全然違うやり方がありそうな気がしている。
座標移動
結局新しいInput Systemは使わず既存の関数でなんとかした。
順応に時間がかかりそうなので知っているものでプロトを作り切ることを優先しちゃう。
岩を殴る
これを使って岩から石を採掘するプログラムを組んでみた。
![](https://assets.st-note.com/production/uploads/images/143198708/picture_pc_391a40bc2e195cf372e5559ca80565e9.gif)
public void OnPointerClick(PointerEventData eventData)
{
print($"オブジェクト {name} がクリックされたよ!");
// dropitem生成
GameObject obj = Instantiate(
dropItem,
new Vector3(this.transform.position.x, dropItemHeight, this.transform.position.z),
Quaternion.Euler(45, 0, 0)
);
// 生成したコピーをアクティブにしておく
obj.gameObject.SetActive(true);
createCount += 1;
print($"オブジェクト {obj.gameObject.name} が生成されたよ!");
}
直す必要のある部分が死ぬほどあるけど一旦よし。
Unityのチュートリアルをやって学んだ最大のポイントを実現している。
「最小の動きをするハードコード」をまず行う
危急の部分から1か所ずつ抽象的に落としていく
という手順。
いままで、あらゆるプログラムをいきなり抽象度MAXで書いていた。
だが、以下のような問題がある。
考慮すべき点が多いせいで考慮漏れ・想定外が頻発する
一気に色々作るせいでどこでバグってるのかわからない
なので、ハードコードを経由した方が、無駄が多いように見えて完成が早まりそうな気がする。
そしてそんな、抽象度MAXから書き始めた過去のプログラムがこちら……
かつて実装したブラックボックス
![](https://assets.st-note.com/production/uploads/images/143201920/picture_pc_5c97ae24450122b4ad6b9331ae4bb7cb.gif)
QEまたはホイールでアクティブなボックスを切り替え、その情報をDebug.Logに出力する。
アイテムにはIDとアイテム種別が振られており、それに応じて色々な挙動が取れるようになっている。
みたいなプログラムなのだが、デカすぎて全然中身がわかっていないし、どこでバグっているのか得体が知れない。
いずれこいつに直面するときが来るだろう。
岩に関連する今後のタスク
当面は今回作った岩を殴りつけるプログラムの改造を行う。
一旦ガーーっと書き出す。
やばい挙動の修正(まず手をつける)
生成したオブジェクトをどうにかDestroyする
存在上限数超えたら古い順に消してみる
コライダーがぶつかる挙動をなんとかする
コライダーを使わずプログラムで座標管理して重なりを許容
ブラックボックス読み解き系(ヤバ挙動が終わったらやってみる)
石をクリックで拾えるようにしてみる
拾ったら消えて、インベントリに入る
インベントリから石を落とせるようにしてみる
クリックした場所に落としてinstantiate
選択中のアイテムがピッケルじゃないと掘れないようにしてみる
インベントリブラックボックスから何とか条件式を拾う
クリック連打を防止するタイマーをつける
day7の、lapseTimeを使ったクールダウンが流用できそう
おそらく岩側じゃなくてピッケルにつけることになる
ゲーム的たのしい設定(これ自体も細かいタスクに切り分けるべし)
耐久力を削り切ったらドロップにしてみる
耐久力バーを仮UIで作ってみる
プレイヤーの攻撃力や攻撃スピードを上げられるようにしてみる
バフ!たのしいね!
ダイヤピッケルなら早く掘れるぜ、的な挙動を簡易的に実装する
広い範囲に散らばったアイテムを一気に回収する携帯掃除機を実装
クリックせずとも設置するだけで耐久力を削れる掘削機を実装
持続時間とか攻撃力とか付けることになろう
アイテムをしまっておけるチェストを実装
これがねえとな
独自のストレージを持ち勝手に動いてくれる設置型掃除機を実装
挙動は携帯掃除機からパクる
持続時間を掘削機からパクる
独自ストレージはチェストからパクる
そう、全てをマージしたものを作るんだ
汎用化の設定(たぶん大工事なので一番最後)
オブジェクトのクローン元がマップ内にあるのを何とかする
Spriteなどを変数化して関数の中で宣言することになるのかな?
prefabを入れたりできないものか
岩と石以外にスクリプトをアタッチして設定してみる
この時点で色々不都合が出て、多分汎用化のためにはどうするってタスクが切り分けられるはず
ドロップテーブルを親オブジェクトごとに持つ方法とか色々
色々なアイテムが確率でドロップするようにしてみる
色々なドロップアイテムが生じるので
何日かかるかな。でも全部作ったらゲームっぽいものになり始めるだろうね。
がんばりましょう。
この記事が気に入ったらサポートをしてみませんか?