Unity3DでH◯L研ジャンプが作りたかったお話
Unity 2020.2.7
参考
モチベーション
一言でジャンプといっても色んな手法がある。
思いつくもので3通り
- 重力が働く環境下でジャンプボタン押下時にy軸に初速を与える方法
- 放物運動の公式を使う方法
- 物理挙動を無視した方法
この3通りのジャンプにおいて、ロジックはこのように分けられると思う
番号 | ロジック |
---|---|
1と2 | 常に同じ計算処理が走っていて、ボタンを押したときに初期値が与えられる |
3 | 地面にいる時とジャンプ中で移動ロジックが切り替わる |
それぞれメリットデメリットがあると思うが、個人的に単純に放物線を描くジャンプはつまらないので3の物理挙動を無視したジャンプを作りたかった。
その中でも参考記事のH◯L研ジャンプが「高さ」「持続時間」「sin波の軌道のゆがみ」の調整が柔軟にでき、理想のジャンプが作りやすそうだったためUnity3Dで動くものを作った。
前提
- キーボードのXキーを押してジャンプする
- 接地中かどうかの判定方法がある(CharacterControllerのisGroundedでもいいはず)
- 重力加速度はOFF
とりあえず動くコード
適当に3Dモデルのゲームオブジェクトにアタッチすれば動くはず。
using System.Collections; using System.Collections.Generic; using System; using UnityEngine; public class MyJumpController : MonoBehaviour { bool isJumping = false; float t = 0f; //経過時間 ( 0.0 -> 1.0 ) Vector3 nextPos; //次に設定される座標 Vector3 firstPos; //動作開始した座標 Vector3 targetPos; //目標位置 float height = 1f; // ジャンプの高さ float distortion = 1f; // 曲線のゆがみ private void Start() { gr = GetComponent<MyGroundCheck>(); // CharacterControllerのisGroundedでもいい } void Update() { if(isJumping) { Jump(); return; } if (Input.GetKeyDown(KeyCode.X)) { isJumping = true; firstPos = transform.position; } } void Jump() { nextPos = transform.position; t += Time.deltaTime; float pow = (float)Math.Pow(1.0 - Math.Sin(Math.PI * t), distortion); nextPos.y = firstPos.y + (1.0f - pow) * height; transform.position = nextPos; if (gr.isGrounded) { t = 0f; isJumping = false; } } }
結果
着地をさせたかったのでジャンプの終了判定をt>1.0からisGroundedに無理やり変えた。
そのため同じ高さ~高いところへの着地はこれでいいが、崖からジャンプした時などはsin波を描いてしまう。
ユーザーからの操作の介入がない、敵キャラクターなどの動きではこのようなカーブの計算式で十分だったりします。
とのことなのでユースケースに合わせたジャンプ手法を採用しよう。