うにty生活

UnityChanを生活させたい

キャラクターの動かし方を見直してみた #15

#2020/8/16に更新

 

どうもラブヘイトです

2018年もとうとうあと何日か、というところです

正直今やっと好きなことができています

この時間を大切にしていきたい

 

今回は過去の記事で変なところを見直してみました

 

◆現在の状況

 

tubakihimelovehate.hatenablog.com

 

 

tubakihimelovehate.hatenablog.com

 

これらの記事で、最終的には3つのキャラクター移動方法から、

RigidBody+Colider+Transform移動 ということに決定しました

 

実際はこのように動かしている状況です

public class UnityChanControl : MonoBehaviour {

//速さ
    public float speed = 3f;
 
//方向転換スピード
public float rotateSpeed = 200f;
 

void Start()
    {
    }

void FixedUpdate()
{

float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");

        
Vector3 velocity = new Vector3(0, 0, v);

        // キャラクターのローカル空間での方向に変換
        velocity = transform.TransformDirection(velocity);

        // キャラクターの移動
        transform.localPosition += velocity * speed *pulusSpeed* Time.fixedDeltaTime;

        // キャラクターの回転
        transform.Rotate(0, h * rotateSpeed * Time.fixedDeltaTime, 0);

 このスクリプトとRigidBody・ColliderをUnityちゃんにアタッチしています

 

これでもかなり自然なのですが(変なところと言ったらムーンウォークしてしまうくらいです)

 

ある日TwitterをみているとRigidBodyに関するリファレンスがあり、みていると

RigidBody中にTransform移動させるものではない」と書かれてあり

やべ・・・ってなったのが今回の経緯です

 

なので、移動方法を再検討していきます!

 

◆以前の条件

前回の記事で設定した、実現していきたいUnityちゃんの移動方法の条件はこちら

1,人として自然

2,壁を通り抜けない

3,階段を登れる

 

この3つでしたが、もう2つ条件を追加します

4,自然な重力のかかり方

 5 ,TransformとRigidBodyを一緒に使わない   ←今回の課題

 

 

新、移動方法はRigidBodyに力を加えて実現させていきます

 

 

◆RigidBodyに力を加える

まずは共通部分から

 

public class UnityChanControl : MonoBehaviour {

//速さ
    public float speed = 3f;
 
 
//方向転換スピード
public float rotateSpeed = 200f;

public Rigidbody rigid;



void Start()
    {
rigid = GetComponent<Rigidbody>();
    }

void FixedUpdate()
{

    float h = Input.GetAxis("Horizontal");
    float v = Input.GetAxis("Vertical");

        
    Vector3 velocity = new Vector3(0, 0, v);
 

      // キャラクターのローカル空間での方向に変換
      velocity = transform.TransformDirection(velocity);

  //この間に移動処理
 
    // キャラクターの回転
        transform.Rotate(0, h * rotateSpeed * Time.fixedDeltaTime, 0);
 
 
    }
}

上のコードは共通部分で、入力された値をもとに移動できるコードを書いていきます

 

色々試してみました

・今までの移動方法(Transform):RigidBodyと共存できないため非推奨

transform.localPosition += velocity * speed *pulusSpeed* Time.fixedDeltaTime;

 

・RigidBody.AddForce:失敗 勝手に動く

rigid.AddForce(transform.position+velocity*speed*Time.deltaTime);

 

・RigidBody.AddForceAtPosition:失敗 歩けるが滑っていく

rigid.AddForceAtPosition(velocity*10,transform.position);

そもそもAddForceは速度にどんどん足されていくので、人間の動きではない

 

・RigidBody.velocity:失敗 勝手に動く(制御しても明後日の方向に飛んでいく)

rigid.velocity = transform.position*0.1f;

 

・RigidBody.position:成功 Transformと同じ動作が確認できた

階段も登れて、重力も自然

rigid.position = transform.position+velocity*speed*Time.deltaTime;

 

・RigidBody.MovePosition( ):成功 Transformと同じ動作確認 階段・重力ok

rigid.MovePosition(transform.position+velocity*speed*Time.deltaTime);

 

最後ふたつは同じ意味ですがMovePositionは、RigidBodyのisKinematicの値によって

動き方が変わります

falseの時は空間移動trueの時は瞬間移動になります

 

isKinematicは物理演算の有効(false),無効(true)を切り替えます

いつもと逆なので気をつけてください

なのでここがtrueになっている時は別にTransformで移動させても良いのです

 

例えばキャラクターがワープして、遠くの違う場所に行くときなどは

isKinematicを一時的にtrueにしてTransformで一気に動かすというのが可能です

 

 

 

◆比較

以前の移動方法と比較してみます

f:id:tubakihimeLoveHate:20181205214252g:plain

Before(Transform)

f:id:tubakihimeLoveHate:20181205214349g:plain

After(RigidBody.position)


同じ動作になりました!

 

最後に気になるのは方向転換はTransformでいいのか?ということですね

今の所変な動きはしていないのでそのままにしておきます、、、w

 

 本当はisKinematicの活用や、CharacterControllerとかでも動かそうと検証していたのですが

案外簡単に見つかってしまったので簡潔にこれだけ書くことにしました

 

◆最後に

今回の記事では文字サイズを大きくしたり、枠をつけて見たりと

ブログ自体も見やすくしました!

 

これからも少しづつ試行錯誤しながら個性と読みやすさを調和させていきます!

ではまた