環境:Unity 2019.2.13f1
せっかくなのでキャラクターをジャンプさせてみました。
まずはアニメーションの遷移から。アニメーションはジャンプする瞬間、ジャンプ中、着地の3つを用意する。Animatorはこのような構造にする。bool型でIsJumpingとIsLandingのフラグをつくる。
BlendTree(歩きモーション)からJumpまでの遷移のConditionをIsJumping、trueに設定。Has Exit Timeは外す。
JumpingからLandingの遷移のConditionのIsLandingをtrueに設定。Has Exit Timeは外す。
PlayerのGameObjectにRigidBodyとCapsule Colliderを追加する。RigidbodyのFreeze RotationのXとZにチェックを入れて倒れないようにする。
プレイヤー動作のコードは以下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControllerJump : MonoBehaviour
{
GameObject camera; // 外部のオブジェクトを参照する
float moveSpeed = 2.0f;
float rotationSpeed = 360.0f;
Animator animator;
Rigidbody rigidbody;
bool isJump;
public float jumpPower = 5.0f;
// Start is called before the first frame update
void Start()
{
camera = GameObject.FindGameObjectWithTag("MainCamera");
animator = this.GetComponentInChildren();
rigidbody = this.GetComponent();
// 全体の重力を変更する
Physics.gravity = new Vector3(0, -5.0f, 0);
}
// Update is called once per frame
void Update()
{
// ゲームパッドの左スティックのベクトルを取得する
Vector3 direction = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
// 他のオブジェクトのスクリプトを読み込む(スクリプトはクラス扱い)
CameraController cameraScript = camera.GetComponent();
// カメラのY軸角度から回転行列を生成する
Quaternion rot = Quaternion.Euler(0, cameraScript.cameraRotation.y * Mathf.Rad2Deg + 90, 0);
// 逆行列を生成する
Matrix4x4 m = Matrix4x4.TRS(Vector3.zero, rot, Vector3.one);
Matrix4x4 inv = m.inverse;
// 回転行列をかけたベクトルに変換する
direction = inv.MultiplyVector(direction);
if (direction.magnitude > 0.001f)
{
// Slerpは球面線形補間、Vector3.Angleは二点間の角度(degree)を返す
Vector3 forward = Vector3.Slerp(this.transform.forward, direction, rotationSpeed * Time.deltaTime / Vector3.Angle(this.transform.forward, direction));
// ベクトル方向へ向かせる
transform.LookAt(this.transform.position + forward);
}
// 座標移動させる
transform.position += direction * moveSpeed * Time.deltaTime;
// アニメーターコントローラへ値を渡す
animator.SetFloat("Blend", direction.magnitude);
if (Input.GetButtonDown("Jump") && isJump == false)
{
isJump = true;
animator.SetBool("IsJumping", true);
animator.SetBool("IsLanding", false);
rigidbody.velocity += Vector3.up * jumpPower;
}
}
void OnCollisionEnter(Collision other)
{
isJump = false;
animator.SetBool("IsJumping", false);
animator.SetBool("IsLanding", true);
}
}