top of page
検索

【Unity】オンライン3Dゲーム -オブジェクト移動編-

  • uniteen
  • 2015年8月14日
  • 読了時間: 4分

やべぇ。Unity2ヶ月いじってなかった・・・。

せっかく教えてくださった友人に申し訳がたたないので、こっちもやっていきます笑

今私がやっていることの根源は、プログラミング初心者の私にプログラミングを教えてくれた

友人のおかげですからね。中学の時からの付き合いですが、またネトゲ一緒にやりたいすねw

まさかどっちとも作る側に立つ日が来るとは思いませんでしたがw

今回のメインは、動作のスクリプトの解説になります。

Slope Limit : 登れる勾配の角度

Step Offset : 登れる段差の高さ

Skin Width : 接触時にめり込む幅(推奨10%)

以下当たり判定の大きさを変える

今回のスクリプトは、wasd移動ではなく、目的地の座標を入力することで、

障害物などの要素を反映して、通り抜けなどすることなく、目的地に

自動でキャラクターが向かうスクリプトです、

【以下動作スクリプトの解説】

using UnityEngine; using System.Collections; // キャラクターを移動させる。 // Chapter3 public class CharacterMove : MonoBehaviour { // 重力値. const float GravityPower = 9.8f;

まあいい感じの数値を入れておいてください。

// 目的地についたとみなす停止距離. const float StoppingDistance = 0.6f;

目的地との距離が0.6以下になったら、加速をやめ、減速できるようにします。

// 現在の移動速度. 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);

下に落ちるのは、重力が働きますし、inspectorで登れる段差や角度も設定済みなので、

ひたすら平行移動に距離を動かしてくれればオッケーです。 // 目的地にちかづいたら到着.. if (arrived || distance < StoppingDistance) arrived = true; // 移動速度を求める. if (arrived) velocity = Vector3.zero; else velocity = direction * walkSpeed;

到着したら、加速度を0にします。 // 現在の速度を退避. Vector3 currentVelocity = velocity;

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

直前の速度をcurrentVelocityに一時保存、目的地と現在地の距離でLerpで補間しております。 velocityの定義がdirection、つまり残りの距離*歩行速度なので、ここで最大速度と、計算上の

最低速度のどちらか最小値を選択できるようにしております。

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); }

キャラクターの視点の移動にともない、体の向きを変えるメソッド

いきなりカクンと変わらないようにTowards関数で制御しています。 } // 重力. velocity += Vector3.down * GravityPower * Time.deltaTime;

時間の経過とともに、下に向かって加速させます。 // 接地していたら思いっきり地面に押し付ける. // (UnityのCharactorControllerの特性のため) Vector3 snapGround = Vector3.zero; if (characterController.isGrounded) snapGround = Vector3.down;

isGroundは接地を測定するメソッドです。

これ知らない時は、地面と接触した時で判定とってましたが、マジめんどうだった笑

そして、なぜ地面に思いっきり押し付けないといけないかというと、跳ねるからです笑

マリオ系のゲーム、下に移動する床の上ならこれいれないと、とんでもない挙動しますからねw // CharacterControllerを使って動かす. characterController.Move(velocity * Time.deltaTime+snapGround); if (characterController.velocity.magnitude < 0.1f) arrived = true;

速度ベクトルが0に近づけば、到着間近と判定する。 // 強制的に向きを変えるを解除. 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; } }

とりあえず、明日はYahooのテストなんで、勉強して一発で受かりたい・・・。

てかもうあのテストのためにお金を使いたくない・・・。

では。


 
 
 

Comments


  • Facebook Black Round
  • Google+ Black Round
  • Twitter Black Round
bottom of page