
- 作者: 吉谷幹人,布留川英一,一條貴彰,西森丈俊,藤岡裕吾,室星亮太,車谷勇人,湊新平,土屋つかさ,黒河優介,中村優一,牙竜,コポコポ,かせ,hataken,monmoko,佐藤英一
- 出版社/メーカー: ボーンデジタル
- 発売日: 2018/05/01
- メディア: 大型本
- この商品を含むブログを見る
序文
『UNITYゲーム プログラミング・バイブル』6日目?
昨日は全然頭が回らず更新できませんでした…。
進捗
(学習時間:2.5時間)
コード実装部分
\180715UnityGameProgrammingBible\Assets\Unity_Bible\03_Char_Control\Script\BasicCharCont.cs
(コメント書いた)
(ENTRY No.03)
using UnityEngine; using System.Collections; public class BasicCharCont : MonoBehaviour { private float walkSpeed = 2.0f; // 歩行速度 private float runSpeed = 4.0f; // 走行速度 private Vector3 movement; // 移動するベクター private float gravity = 20.0f; // キャラへの重力 private float speedSmoothing = 10.0f; // 回頭するときの滑らかさ private float rotateSpeed = 500.0f; // 回頭の速度 private float runAfterSeconds = 0.1f; // 走り終わったとき止まるまでの時間(秒) // 動くべき方向 private Vector3 moveDirection = Vector3.zero; // カレント移動方向 private float verticalSpeed = 0.0f; // カレント垂直方向速度 private float moveSpeed = 0.0f; // カレント水平方向速度 private CollisionFlags collisionFlags; // controller.Move が返すコリジョンフラグ:キャラが何かにぶつかったとき使用 private float walkTimeStart = 0.0f; // 歩き始める速度 // Use this for initialization void Start () { // 動くべき方向(向いている方向)をワールド座標でセットする moveDirection = transform.TransformDirection(Vector3.forward); // キャラの移動方向をキャラの向いている方向にセットする } // Update is called once per frame void Update () { // カメラのtransformコンポーネントを取得 Transform cameraTransform = Camera.main.transform; // カメラの向いている方向を得る // カメラから見た前方方向を取得して、ワールド座標に変換する Vector3 forward = cameraTransform.TransformDirection(Vector3.forward); // camera の x-z 平面から forward ベクターを求める // キャラクターは水平移動のみなのでY方向は無視する forward.y = 0; // Y方向は無視:キャラは水平面しか移動しないため // カメラ前方方向変数を正規化する forward = forward.normalized; // 方向を正規化する // forward方向から時計回りに45度方向がright(これも正規化されている) Vector3 right = new Vector3(forward.z, 0, -forward.x); // 右方向ベクターは常にforwardに直交 // 垂直方向への入力値 float v = Input.GetAxisRaw("Vertical"); // マウスもしくはコントローラスティックの垂直方向の値 // 水平方向への入力値 float h = Input.GetAxisRaw("Horizontal"); // マウスもしくはコントローラスティックの水平方向の値 // 左右の入力は水平方向(X軸)の移動に対応し // 上下の入力は奥行方向(Z軸)の以上に対応する // 入力された移動方向を計算する Vector3 targetDirection = h * right + v * forward; // カメラと連動した進行方向を計算:視点の向きが前方方向 // キャラクターが接地しているとき if ((collisionFlags & CollisionFlags.CollidedBelow) != 0) // キャラは接地しているか?:宙に浮いていないとき { // 移動入力キーが入っているとき if (targetDirection != Vector3.zero) // キャラは順方向を向いていないか?:つまり回頭している場合 { // このフレームで動くべき方法を計算する(向きは計算していないことに注意) // 現在の移動速度が遅いとき(1.8f以下)は // walkSpeed : 2.0f if (moveSpeed < walkSpeed * 0.9) // ゆっくり移動か? { Debug.Log("即時ターン"); // 即座に移動方向を変更する moveDirection = targetDirection.normalized; // 止まっているときは即時ターン } // 有働速度が早いときは else // 移動しているときはスムースにターン { // スムーズにターン Debug.Log("スムーズターン"); // 移動方向を自然に変更する // Mathf.Deg2Radは度数からラジアン角に変換するらしい moveDirection = Vector3.RotateTowards(moveDirection, targetDirection, rotateSpeed * Mathf.Deg2Rad * Time.deltaTime, 1000); // 正規化処理 moveDirection = moveDirection.normalized; } } // フレームを考慮した向くスピード // speedSmoothing:10.0f float curSmooth = speedSmoothing * Time.deltaTime; // 向きをスムースに変更 // 移動速度を1f以上にしない float targetSpeed = Mathf.Min(targetDirection.magnitude, 1.0f); // 最低限のスピードを設定 // 歩く速度と走る速度の切り替え:最初は歩いてで時間がたつと走る // あるき始めてから0.1f(runAfterSeconds)経ったところで走り始める if (Time.time - runAfterSeconds > walkTimeStart) targetSpeed *= runSpeed; else targetSpeed *= walkSpeed; // 移動速度をなめらかに変化させる moveSpeed = Mathf.Lerp(moveSpeed, targetSpeed, curSmooth); // Animatorコンポーネントを取得する Animator animator = GetComponent<Animator>(); // Animator コンポーネントを得る // spdパラメータにmoveSpeedをセットする animator.SetFloat("spd", moveSpeed); // Animator に移動速度のパラメータを渡す // fallパラメータをfalseにする animator.SetBool("fall", false); // Animator に落下フラグのパラメータを渡す:落下していない // moveSpeedが0.6以下なら if (moveSpeed < walkSpeed * 0.3) // まだ歩きはじめ walkTimeStart = Time.time; // その時間を保存しておく verticalSpeed = 0.0f; // 垂直方向の速度をゼロに設定 } else // 宙に浮いている { // 重力を考慮した落下速度を設定 verticalSpeed -= gravity * Time.deltaTime; // 重力を適応 if (verticalSpeed < -4.0) // 落ちる速度が一定を超えたら { Animator animator = GetComponent<Animator>(); // Animator コンポーネントを得る animator.SetBool("fall", true); // Animator に落下フラグのパラメータを渡す:落下している } } // 移動量を計算する movement = moveDirection * moveSpeed + new Vector3(0, verticalSpeed, 0); // キャラの移動量を計算 movement *= Time.deltaTime; // CharacterControllerコンポーネントを取得 CharacterController controller = GetComponent<CharacterController>(); // キャラクターコントローラコンポーネントを取得 // キャラクターを動かす(戻り値は衝突判定) collisionFlags = controller.Move(movement); // キャラを移動をキャラクターコントローラに伝える // キャラクターが設置しているとき if ((collisionFlags & CollisionFlags.CollidedBelow) != 0) // 宙に浮いていない場合 { // 向きを変える transform.rotation = Quaternion.LookRotation(moveDirection); // 移動方向に回頭:浮いていると回頭しない } } }
実行結果
(ENTRY No.04)
センスがないわー
感想
ENTRY No.03のスクリプトの解読とENTRY No.04のTerrain(テレイン)の操作。
No.03はスクリプトの解読までやったけど、そこまでやるといつまでも終わらなくなりそうなので、やっぱり書籍の内容を重視して進めていくことにしよう。
勉強にはなるんだろうけど…。
しかし、このスクリプトすごく細かい動作まで制御してるねぇ。
こういうやつこそコンポーネントひとつでえいやっ!っていい感じに実装してくれたらいいのに。
いまだに学習のペースがつかめないなぁ。
カロリーメイトください。
BGM
MASTER LOW / PEQUU
www.youtube.com なんでこんな再生されてんだ?と思ったら最近逮まったらしい
NG集(おまけ)
www.youtube.com
No.4のサンプルは最新版のUnityだと落下する模様。
本当に互換性悪いんだねぇ。