プログラム研究 備忘録

java,C#,Unity等の備忘録です。経済理論も少し。

Character Controllerメモ2

目的地の座標変数を用意する。

目的地に向かって移動させるには、目的地方向1フレーム分の移動量を求めて、

現在地に加算すればいい。

 

1フレーム分の移動量は方向と速度さえ分かればよい。//方向×速度×1フレーム時間

 

よって、速度と方向を掛け合わせたベクトルを求める。

移動を繰り返す。

目的地に近づいたら移動終了。

 

覚え書き、誤字の可能性アリ。

using UnityEngine;
using System.Collections;

// キャラクターを移動させる。
// Chapter3
public class CharacterMove : MonoBehaviour {
// 重力値.
const float GravityPower = 9.8f;
// 目的地についたとみなす停止距離.
const float StoppingDistance = 0.6f;

// 現在の移動速度.
Vector3 velocity = Vector3.zero;
// キャラクターコントローラーのキャッシュ.
CharacterController characterController;
// 到着したか(到着した true/到着していない false)
public bool arrived = false;

// 向きを強制的に指示するか.
bool forceRotate = false;

// 強制的に向かせたい方向.
Vector3 forceRotateDirection;

// 目的地.
public Vector3 destination;

// 移動速度.
public float walkSpeed = 6.0f;

// 回転速度.
public float rotationSpeed = 360.0f;



// Use this for initialization
void Start () {
characterController = GetComponent<CharacterController>();
destination = transform.position;
}

// Update is called once per frame
void Update () {

// 移動速度velocityを更新する
if (characterController.isGrounded) {
// 水平面での移動を考えるのでXZのみ扱う.
Vector3 destinationXZ = destination;
destinationXZ.y = transform.position.y;// 高さを目的地と現在地を同じにしておく.

//********* ここからXZのみで考える. ********
// 目的地までの距離と方角を求める.
Vector3 direction = (destinationXZ - transform.position).normalized;
float distance = Vector3.Distance(transform.position,destinationXZ);

// 現在の速度を退避.
Vector3 currentVelocity = velocity;

// 目的地にちかづいたら到着..
if (arrived || distance < StoppingDistance)
arrived = true;


// 移動速度を求める.
if (arrived)
velocity = Vector3.zero;
else
velocity = direction * walkSpeed;


// スムーズに補間.
velocity = Vector3.Lerp(currentVelocity, velocity,Mathf.Min (Time.deltaTime * 5.0f ,1.0f));
velocity.y = 0;


if (!forceRotate) {
// 向きを行きたい方向に向ける.
if (velocity.magnitude > 0.1f && !arrived) { // 移動してなかったら向きは更新しない.
Quaternion characterTargetRotation = Quaternion.LookRotation(direction);
transform.rotation = Quaternion.RotateTowards(transform.rotation,characterTargetRotation,rotationSpeed * Time.deltaTime);
}
} else {
// 強制向き指定.
Quaternion characterTargetRotation = Quaternion.LookRotation(forceRotateDirection);
transform.rotation = Quaternion.RotateTowards(transform.rotation,characterTargetRotation,rotationSpeed * Time.deltaTime);
}

}

// 重力.
velocity += Vector3.down * GravityPower * Time.deltaTime;

// 接地していたら思いっきり地面に押し付ける.
// (UnityのCharactorControllerの特性のため)
Vector3 snapGround = Vector3.zero;
if (characterController.isGrounded)
snapGround = Vector3.down;

// CharacterControllerを使って動かす.
characterController.Move(velocity * Time.deltaTime+snapGround);

if (characterController.velocity.magnitude < 0.1f)
arrived = true;

// 強制的に向きを変えるを解除.
if (forceRotate && Vector3.Dot(transform.forward,forceRotateDirection) > 0.99f)
forceRotate = false;


}

// 目的地を設定する.引数destinationは目的地.
public void SetDestination(Vector3 destination)
{
arrived = false;
this.destination = destination;
}

// 指定した向きを向かせる.
public void SetDirection(Vector3 direction)
{
forceRotateDirection = direction;
forceRotateDirection.y = 0;
forceRotateDirection.Normalize();
forceRotate = true;
}

// 移動をやめる.
public void StopMove()
{
destination = transform.position; // 現在地点を目的地にしてしまう.
}

// 目的地に到着したかを調べる. true 到着した/ false 到着していない.
public bool Arrived()
{
return arrived;
}


}