概要
UnityでRigidbodyとColliderを用いたキャラクターの操作を実装します。
テンプレ的に6パターン作ってみました。
移動方法その1
まずはふつうの移動。
Locomotion1.csというC#スクリプトを作成し、操作したいキャラクターにアタッチします。
Rigidbodyで重力を付け、Colliderで衝突と着地判定しています。
十字キーで前後左右移動
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Locomotion1 : MonoBehaviour {
public float speed = 3f;
public float jumpSpeed = 3f;
private Rigidbody rb;
private float h, v;
private Vector3 moveDirection = Vector3.zero;
void Start() {
//Rigidbodyを取得し,回転しないように固定
rb = GetComponent<Rigidbody>();
rb.constraints = RigidbodyConstraints.FreezeRotation;
}
void Update() {
h = Input.GetAxis ("Horizontal");
v = Input.GetAxis ("Vertical");
if (h != 0 || v != 0) {
moveDirection = speed * new Vector3 (h, 0, v);
moveDirection = transform.TransformDirection (moveDirection);
rb.velocity = moveDirection;
}
if (Input.GetButtonDown ("Jump")) {
rb.velocity = new Vector3 (rb.velocity.x, 5, rb.velocity.z);
}
}
}
移動方法その2
こちらはLocomotion1.csの操作方法をすこし変更したものです。
Locomotion2.csというC#スクリプトを作成し、操作したいキャラクターにアタッチします。
十字キーで前後移動
マウスで回転と視点移動
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Locomotion2 : MonoBehaviour {
public float speed = 3f;
public float jumpSpeed = 3f;
public float rotateSpeed = 3.0F;
public float camRotSpeed = 5.0f;
private float lookUpAngle;
private Rigidbody rb;
private float h, v;
private float mX, mY;
private Vector3 moveDirection = Vector3.zero;
void Start() {
//Rigidbodyを取得し,回転しないように固定
rb = GetComponent<Rigidbody>();
rb.constraints = RigidbodyConstraints.FreezeRotation;
}
void Update() {
h = Input.GetAxis ("Horizontal");
v = Input.GetAxis ("Vertical");
mX = Input.GetAxis ("Mouse X");
mY = Input.GetAxis ("Mouse Y");
//カメラのみ上下に回転させる,180-140=60より上下60度まで見ることができる
lookUpAngle = Camera.main.transform.eulerAngles.x - 180 + camRotSpeed * mY;
if (Mathf.Abs (lookUpAngle) > 140)
Camera.main.transform.Rotate (new Vector3 (camRotSpeed * mY, 0, 0));
gameObject.transform.Rotate (new Vector3 (0, rotateSpeed * mX, 0));
if (h != 0 || v != 0) {
moveDirection = speed * new Vector3 (h, 0, v);
moveDirection = transform.TransformDirection (moveDirection);
rb.velocity = moveDirection;
}
if (Input.GetButtonDown ("Jump")) {
rb.velocity = new Vector3 (rb.velocity.x, 5, rb.velocity.z);
}
}
}
移動方法その3
今度はRayを使って着地判定します。
Locomotion3.csというC#スクリプトを作成し、操作したいキャラクターにアタッチします。
Rigidbodyで重力を付け、Colliderで衝突。
地面に向けて直線のRayを飛ばし着地判定しています。
台の上に乗ったときに端で着地判定ができずにフリーズしてしまうことがあります。
十字キーで前後左右移動
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Locomotion3 : MonoBehaviour {
public float speed = 3f;
public float jumpSpeed = 3f;
private Rigidbody rb;
private float h, v;
private Vector3 moveDirection = Vector3.zero;
private bool isGrounded = false;
void Start() {
rb = GetComponent<Rigidbody>();
rb.constraints = RigidbodyConstraints.FreezeRotation;
}
void Update() {
h = Input.GetAxis ("Horizontal");
v = Input.GetAxis ("Vertical");
//足元から下へ向けてRayを発射し,着地判定をする
isGrounded = Physics.Raycast (gameObject.transform.position + 0.1f * gameObject.transform.up, -gameObject.transform.up, 0.15f);
//デバッグ用にシーンにRayを表示する
Debug.DrawRay (gameObject.transform.position + 0.1f * gameObject.transform.up, -0.15f*gameObject.transform.up, Color.blue);
if (isGrounded || Mathf.Abs (rb.velocity.y) < 0.01f) {
if (h != 0 || v != 0) {
moveDirection = speed * new Vector3 (h, 0, v);
moveDirection = transform.TransformDirection (moveDirection);
rb.velocity = moveDirection;
}
if (Input.GetButtonDown ("Jump")) {
rb.velocity = new Vector3 (rb.velocity.x, 5, rb.velocity.z);
}
}
}
}
移動方法その4
操作方法3にマウス操作を追加します。
Locomotion4.csというC#スクリプトを作成し、操作したいキャラクターにアタッチします。
Rigidbodyで重力を付け、Colliderで衝突。
地面に向けて直線のRayを飛ばし着地判定しています。
やはり台の上に乗ったときに端で着地判定ができずにフリーズしてしまうことがあります。
十字キーで前後左右移動
マウスで回転と視点移動
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Locomotion4 : MonoBehaviour {
public float speed = 3f;
public float jumpSpeed = 3f;
public float rotateSpeed = 1.5f;
public float camRotSpeed = 3.5f;
private float lookUpAngle;
private Rigidbody rb;
private float h, v;
private float mX, mY;
private Vector3 moveDirection = Vector3.zero;
private bool isGrounded = false;
void Start() {
rb = GetComponent<Rigidbody>();
rb.constraints = RigidbodyConstraints.FreezeRotation;
}
void Update() {
h = Input.GetAxis ("Horizontal");
v = Input.GetAxis ("Vertical");
mX = Input.GetAxis ("Mouse X");
mY = Input.GetAxis ("Mouse Y");
//カメラのみ上下に回転させる,180-140=60より上下60度まで見ることができる
lookUpAngle = Camera.main.transform.eulerAngles.x - 180 + camRotSpeed * mY;
if (Mathf.Abs (lookUpAngle) > 140)
Camera.main.transform.Rotate (new Vector3 (camRotSpeed * mY, 0, 0));
//足元から下へ向けてRayを発射し,着地判定をする
isGrounded = Physics.Raycast (gameObject.transform.position + 0.1f * gameObject.transform.up, -gameObject.transform.up, 0.15f);
//デバッグ用にシーンにRayを表示する
Debug.DrawRay (gameObject.transform.position + 0.1f * gameObject.transform.up, -0.15f*gameObject.transform.up, Color.blue);
if (isGrounded || Mathf.Abs (rb.velocity.y) &l 0.01f) {
gameObject.transform.Rotate (new Vector3 (0, rotateSpeed * mX, 0));
if (h != 0 || v != 0) {
moveDirection = speed * new Vector3 (h, 0, v);
moveDirection = transform.TransformDirection (moveDirection);
rb.velocity = moveDirection;
}
if (Input.GetButtonDown ("Jump")) {
rb.velocity = new Vector3 (rb.velocity.x, 5, rb.velocity.z);
}
}
}
}
移動方法その5
今度は球状のRayを使って着地判定します。
Locomotion5.csというC#スクリプトを作成し、操作したいキャラクターにアタッチします。
Rigidbodyで重力を付け、Colliderで衝突。
地面に向けて球状のRayを飛ばし着地判定しています。
おそらく最もきれいに着地判定が可能。
十字キーで前後左右移動
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Locomotion5 : MonoBehaviour {
public float speed = 3f;
public float jumpSpeed = 3f;
private Rigidbody rb;
private float h, v;
private Vector3 moveDirection = Vector3.zero;
private bool isGrounded = false;
private Ray ray;
void Start() {
rb = GetComponent<Rigidbody>();
rb.constraints = RigidbodyConstraints.FreezeRotation;
}
void Update() {
h = Input.GetAxis ("Horizontal");
v = Input.GetAxis ("Vertical");
//足元から下へ向けて球状のRayを発射し,着地判定をする
//rayで中心と方向を指定,SphereCastで球の半径と,球を飛ばす距離を指定
ray = new Ray(gameObject.transform.position+0.18f*gameObject.transform.up, -gameObject.transform.up);
isGrounded = Physics.SphereCast (ray, 0.13f, 0.08f);
//着地判定の範囲をシーンに示す
Debug.DrawRay (gameObject.transform.position+0.2f*gameObject.transform.up, -0.22f*gameObject.transform.up);
if (isGrounded) {
if (h != 0 || v != 0) {
moveDirection = speed * new Vector3 (h, 0, v);
moveDirection = transform.TransformDirection (moveDirection);
rb.velocity = moveDirection;
}
if (Input.GetButtonDown ("Jump")) {
rb.velocity = new Vector3 (rb.velocity.x, 5, rb.velocity.z);
}
}
}
}
移動方法その6
移動方法その5にマウス操作を追加します。
Locomotion6.csというC#スクリプトを作成し、操作したいキャラクターにアタッチします。
十字キーで前後左右移動
マウス操作で回転と視点移動
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Locomotion6 : MonoBehaviour {
public float speed = 3f;
public float jumpSpeed = 3f;
public float rotateSpeed = 1.5f;
public float camRotSpeed = 3.5f;
private float lookUpAngle;
private Rigidbody rb;
private float h, v;
private float mX, mY;
private Vector3 moveDirection = Vector3.zero;
private bool isGrounded = false;
private Ray ray;
void Start() {
rb = GetComponent<Rigidbody>();
rb.constraints = RigidbodyConstraints.FreezeRotation;
}
void Update() {
h = Input.GetAxis ("Horizontal");
v = Input.GetAxis ("Vertical");
mX = Input.GetAxis ("Mouse X");
mY = Input.GetAxis ("Mouse Y");
//カメラのみ上下に回転させる,180-140=60より上下60度まで見ることができる
lookUpAngle = Camera.main.transform.eulerAngles.x - 180 + camRotSpeed * mY;
if (Mathf.Abs (lookUpAngle) > 140)
Camera.main.transform.Rotate (new Vector3 (camRotSpeed * mY, 0, 0));
//足元から下へ向けて球状のRayを発射し,着地判定をする
//rayで中心と方向を指定,SphereCastで球の半径と,球を飛ばす距離を指定
ray = new Ray(gameObject.transform.position+0.18f*gameObject.transform.up, -gameObject.transform.up);
isGrounded = Physics.SphereCast (ray, 0.13f, 0.08f);
//着地判定の範囲をシーンに示す
Debug.DrawRay (gameObject.transform.position+0.2f*gameObject.transform.up, -0.22f*gameObject.transform.up);
if (isGrounded) {
gameObject.transform.Rotate (new Vector3 (0, rotateSpeed * mX, 0));
if (h != 0 || v != 0) {
moveDirection = speed * new Vector3 (h, 0, v);
moveDirection = transform.TransformDirection (moveDirection);
rb.velocity = moveDirection;
}
if (Input.GetButtonDown ("Jump")) {
rb.velocity = new Vector3 (rb.velocity.x, 5, rb.velocity.z);
}
}
}
}