[Unity] Character Controller メモ(非エンジニア)
Character Controller
オブジェクトの移動と衝突判定を行えるComponent
プロパティ
Slope Limit 登ることができる傾斜角の限界値 値以上の傾斜は登れない
ただし傾斜角値以上でも着地はできるのでジャンプを使えば登れてしまう
Step Offset 登ることができる段差の高さ 値を大きくすると以下のエラーが発生する可能性がある (Height + Radius * 2)より小さい値にすればよい
Step Offset must be less or equal to <scaled Height> + <scaled Radius> * 2
Skin Width 接地面までの距離 値が大きいとオブジェクトが浮いているように見える その時はこの値を小さくするか CenterのYで位置を上にずらすと良い
Min Move Distance 移動値の切り捨て この値以下の移動値を無視する
Center 当たり判定の中心位置 (0,0,0)はAddComponentされているオブジェクトの原点位置
原点位置が足元の場合、Heightの半分の値をYに入れれば接地面が足元にくる HeightがRadiusより小さい場合はRadiusと同じ値をYに入れれば接地面が足元にくる
Radius 当たり判定の半径
Height 当たり判定の高さ Radiusより小さい値にすると無視される
以下公式マニュアルの引用
移動する
以下のScriptをCharacterControllerをつけているオブジェクトにAddComponentする
AddComponentできない時はScriptのクラス名とファイル名が同じになっているか確認する
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SampleScript : MonoBehaviour // クラス名はファイル名と同じにする
{
//CharacterController型の変数の宣言
private CharacterController _CharaCon;
//移動値用の変数の宣言 vectro3型はxyzの3つの値を持てる
private Vector3 _MoveDirection = Vector3.zero;
void Start()
{
// AddComponentされているCharacterControllerを取得して_CharaConに代入
_CharaCon = this.GetComponent<CharacterController>();
}
void Update()
{
//--------------------
// 落下の処理
//--------------------
// 地面に接地している時
if (_CharaCon.isGrounded){
// Yの移動値(落下速度)を戻す
if(_MoveDirection.y < -0.1f){
_MoveDirection.y = -0.1f;
}
}
// 地面から離れている時
else if (!_CharaCon.isGrounded){
// Yの移動値(落下速度)がー5以上の時
if(_MoveDirection.y > -5){
// Yの移動値(落下速度)の加算
_MoveDirection.y -= 0.5f;
}
// ↑キーを押していない時
if (!Input.GetKey(KeyCode.UpArrow)){
// 移動値の反映
_CharaCon.Move(_MoveDirection * Time.deltaTime);
}
}
//--------------------
// 移動の処理
//--------------------
// ↑キーを押している時
if (Input.GetKey(KeyCode.UpArrow))
{
// 移動速度の値
float speed = 1;
// オブジェクトの向きと移動速度を掛けて変数へ代入
Vector3 velocity = this.transform.rotation * new Vector3(0, 0, speed);
// 移動値を代入
_MoveDirection = new Vector3 (velocity.x, _MoveDirection.y, velocity.z);
// 移動値の反映
_CharaCon.Move(_MoveDirection * Time.deltaTime);
// 移動値のリセット
_MoveDirection.x = 0;
_MoveDirection.z = 0;
}
//--------------------
// オブジェクトの回転の処理
//--------------------
//→キーが押されていて←キーが押されていない時
if (Input.GetKey(KeyCode.RightArrow) && !Input.GetKey(KeyCode.LeftArrow)){
// オブジェクトの回転
this.transform.Rotate(Vector3.up, 5.0f);
}
//←キーが押されていて→キーが押されていない時
else if (Input.GetKey(KeyCode.LeftArrow) && !Input.GetKey(KeyCode.RightArrow)){
// オブジェクトの回転
this.transform.Rotate(Vector3.up, -5.0f);
}
//--------------------
// ジャンプの処理
//--------------------
// 地面に接地している時
if(_CharaCon.isGrounded)
{
// Jキーを押した時
if(Input.GetKeyDown(KeyCode.J)){
// Yの移動値にジャンプの値を代入
_MoveDirection.y = 8.0f;
// ↑キーを押していない時
if (!Input.GetKey(KeyCode.UpArrow)){
// 移動値の反映
_CharaCon.Move(_MoveDirection * Time.deltaTime);
}
}
}
}
}
Scriptの補足説明
private CharacterController _CharaCon;
_CharaConという名前の変数をCharacterController型で宣言
private Vector3 _MoveDirection = Vector3.zero;
_MoveDirectionという名前の変数をVector3型で宣言
Vector3.zeroはnew Vector3(0,0,0)と同義
_CharaCon = this.GetComponent<CharacterController>();
オブジェクトにAddComponentされているCharacterControllerを取得して
変数_CharaConに代入
this.はこのScriptがAddComponentされているオブジェクトを指定している
_CharaCon.isGrounded
変数_CharaConに入っているCharacterControllerが接地しているかを取得
接地していれば true 接地していなければ false
_MoveDirection.y = -0.1f;
_MoveDirectionのYの値に-0.1を代入
整数でない値のときは基本的にfをつける(floatのf)
接地後に落下速度をリセットしている
リセットしないとジャンプせずに床から落下した場合に最速状態で落下する
_MoveDirection.y -= 0.5f;
上記は_MoveDirection.y = _MoveDirection.y - 0.5f;と同義
落下速度をどんどん速くしていっている
Input.GetKey(KeyCode.UpArrow)
上キーを押しているかを取得
押している場合は true 押していなければ false
if文で先頭に!をつけるとfalseかどうかチェックする
Input.GetKey(KeyCode.○○) ○○を押している時
Input.GetKeyDown(KeyCode.○○) ○○を押した時
Input.GetKeyUp(KeyCode.○○) ○○を離した時
UnityはInput ManagerからInput Systemに移行しようとしているので数年後のバージョンは上記のInput.GetKeyはよろしくないかもしれない
_CharaCon.Move(_MoveDirection * Time.deltaTime);
CharacterControllerに移動値を反映する
この処理がないとCharacterControllerは動かない
Time.deltaTimeについては以下を参考にしてみてください
Vector3 velocity = this.transform.rotation * new Vector3(0, 0, speed);
オブジェクトの角度に移動用の値を掛けて変数に代入している
この場合はZ軸を正面としている X軸が正面の場合はXのところにspeedを入れる
_MoveDirection.x = 0;
_MoveDirection.z = 0;
移動値のリセット
移動値をそのままにしておくと移動し続ける事になる
例えば、移動を止めた後にジャンプを行うとY移動値の反映とともにXZの移動値も反映されてしまうので移動が終わったら移動値のリセットを行わなければならない
ここでは移動値の反映の直後にリセットを行なっている
this.transform.Rotate(Vector3.up, 2.5f);
オブジェクトの現在の角度に任意の角度を加算する
Vector3.upはオブジェクトの上面を指し
どの面を指定するかで回転軸が変わる
Vector3.forward 正面
Vector3.back 背面
Vector3.up 上面
Vector3.down 下面
Vector3.right 右面
Vector3.left 左面
CharacterControllerのプロパティの値を変更
無闇に変更するものではないが一応変更可能
特にMin Move Distanceを移動値以上にすると動かなくなるので注意
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SampleScript2 : MonoBehaviour // クラス名はファイル名と同じにする
{
//CharacterController型の変数の宣言
private CharacterController _CharaCon;
void Start()
{
// AddComponentされているCharacterControllerを取得して_CharaConに代入
_CharaCon = this.GetComponent<CharacterController>();
// Slope Limit
_CharaCon.slopeLimit = 50;
// Step Offset
_CharaCon.stepOffset = 0.5f;
// Skin Width
_CharaCon.skinWidth = 0.1f;
// Min Mouse Distance
_CharaCon.minMoveDistance = 0.01f;
// Center
_CharaCon.center = new Vector3(0, 0.5f, 0);
// Radius
_CharaCon.radius = 0.5f;
// Height
_CharaCon.height = 0.5f;
}
}
CharacterControllerのOn/Off
Offにすることはまずないが一応できる
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SampleScript3 : MonoBehaviour // クラス名はファイル名と同じにする
{
//CharacterController型の変数の宣言
private CharacterController _CharaCon;
void Start()
{
// AddComponentされているCharacterControllerを取得して_CharaConに代入
_CharaCon = this.GetComponent<CharacterController>();
}
void Update()
{
// Sキーを押した時かつCharacterControllerがOnの時
if(Input.GetKeyDown(KeyCode.S) && _CharaCon.enabled){
// CharacterControllerをOffにする
_CharaCon.enabled = false;
}
// Sキーを押した時かつCharacterControllerがOffの時
else if(Input.GetKeyDown(KeyCode.S) && !_CharaCon.enabled){
// CharacterControllerをOnにする
_CharaCon.enabled = true;
}
}
}
勉強中ですので説明が間違っている可能性があります自分でも調べて確認してみてください
この記事が気に入ったらサポートをしてみませんか?