Unityでオブジェクトを動かして自由に動かす方法を初心者向けに解説します。いくつかのモバイルソリューションの説明

I.はじめに

Unity のゲーム開発において、動きは非常に重要な部分であり、動きの感触がゲームの成否を左右しますが、優れたモバイル感はゲームに非常に快適な体験をもたらすことは間違いありません。Unity には、Transform を使用する、Rigidbody を使用する、CharacterController を使用する、NavMesh ナビゲーション システムを使用するなど、さまざまな移動方法があります。もちろん、初心者にとって、最も一般的な移動ソリューションは、Transform と Rigidbody の 2 つのコンポーネントを使用することです。したがって、この記事では、これら 2 つのモバイル ソリューションを分析して説明します。

知らせ!次のコードはすべて 2D シーンであり、3D にも同じことが当てはまります。

2. 変身

TransformコンポーネントはGameObjectの位置(Position)、サイズ(Scale)、回転(Rotation)などを操作できるGameObjectの変形コンポーネントです。したがって、Transform コンポーネントを使用してオブジェクトを移動することは非常に良い選択です。以下に、Transform コンポーネントを通じて実現されるいくつかの移動方法と、対応するシナリオを示します。

1.翻訳

Transform の Translate 関数を使用して、GameObject のローカル座標系で変換します。変位ベクトルをパラメータとして渡して、移動の方向と距離を指定できます。

[SerializeField] private float moveSpeed;
    private void Update()
    {
        //自动向右移动
        transform.Translate(Vector2.right * moveSpeed * Time.deltaTime);
    }
//物体沿向量指向方向移动
//Vector2.right 向右移动向量,也可以写成自己定义的
//moveSpeed 移动速度,通常为float型

Translate メソッドは、ゲーム内のオブジェクトを移動するために使用でき、平面上でボックスを自動的に移動させるなど、単純な移動方法に適しています。

2.向かって進む

Transform の MoveTowards 関数を使用して、ターゲットの位置に直接移動します。現在位置、目標位置、移動速度を入力して、移動速度を制御し、目標位置に到達することができます。

MoveTowards関数に対応するパラメータは3つ(現在位置、目標位置、移動速度)で、最初の2つはVector型、最後の1つは整数なども記述できるfloat型です。

例: オブジェクトを (5, 5) の位置に移動します。

    [SerializeField] private float moveSpeed;
    private void Update()
    {
        transform.position = Vector2.MoveTowards(transform.position,new Vector2(5,5),moveSpeed);
    }

3.レルプ

Transform の Lerp 機能を使用すると、滑らかな補間動作を実現できます。開始位置、ターゲット位置、および補間スケールを渡して、動きのトランジション効果を制御できます。

Lerp 関数に対応する 3 つのパラメータは (現在位置、目標位置、補間スケール) で、最初の 2 つは Vector 型、最後の 1 つは float 型 = type、補間スケールの範囲は [0, 1] です。 0 の場合、オブジェクトは移動しません。 lerp が 1 の場合、オブジェクトは目標位置に直接移動します。 lerp 値が大きいほど、オブジェクトはより速く移動します。

例: オブジェクトを (5, 5) に移動します。

[SerializeField] private float moveSpeed;
[SerializeField] private float lerp;
private void Update()
{
    transform.position = Vector3.Lerp(transform.position, new Vector2(5,5), lerp); 
}

次に、Lerp 関数の動作原理を説明します。

補間係数 lerp は基本的に、オブジェクトの現在位置からターゲット位置までのオブジェクトの各移動の距離の比率です。オブジェクトの各移動後、次の移動距離はリセットされますが、比率は変わりません。つまり、オブジェクトは目標点に向かって移動しますが、1回あたりの移動距離は短くなります。とても複雑に聞こえますよね?この原理を図を使って説明しましょう。

 赤の縦線が1回目の移動位置なので移動距離はL1=S1*lerp、青の縦線が2回目の移動位置なので移動距離はL2=となります。 S2*lerp.同様に、L3=S3*lerp. 図からわかるように、物体が1回に移動する距離は短くなりますが、現在位置から目標位置までの距離に対する1回の移動距離の割合は変わりません。また、lerp 値が大きいほど 1 回の移動距離が大きく、つまり速度が速く、逆に lerp 値が小さいほど単語の移動距離が小さくなることもわかります。最後に、Lerp 関数では、オブジェクトが移動する距離は常に現在位置から目標位置までの距離 * lerp であることを見つけるのは難しくありません。つまり、オブジェクトは決して目標位置に到達することはできません。ただし、目標位置に無限に近づくだけです。したがって、オブジェクトが目標位置に到達するためには、オブジェクトの目標位置からの距離が一定値未満の場合に、オブジェクトの位置が目標位置になるという if 条件を追加できます。

if (Vector2.Distance(transform.position, new Vector2(5, 5))<0.1f)
{
     transform.position = new Vector2(5, 5);
}

上記は、Transform を使用してオブジェクトを移動するいくつかの方法です。もちろん、Transform コンポーネントを使用してオブジェクトを移動する方法はたくさんあります。自分で試してみることもできます。

もちろん、Transform コンポーネントを使用してオブジェクトを移動するときに小さなバグが発生することがあります。これについては Rigidbody で説明します。

3. リジッドボディ

Rigidbody は剛体コンポーネントであり、このコンポーネントでは物理の定義を使用してオブジェクトの移動などの操作を実行できます。さらに、これはプレーヤーの動きを制御するために最も一般的に使用されるコンポーネントでもあります。もちろん、剛体コンポーネントはゲームオブジェクトを動かすだけでなく、さまざまな操作を行いますが、ここでは移動の使用についてのみ説明します。

前述したように、Transform には小さなバグがあり、それはカビの貫通を引き起こす、つまり、オブジェクトが移動中に障害物に遭遇し、移動を続けると、障害物をすり抜けてしまうというものです。致命的なバグです。ただし、剛体コンポーネントを使用すると、このバグをうまく解決できます。ここで、いくつかの情報を確認したところ、大まかに言うと、Transform コンポーネントは位置の変更、つまり、位置の変更は一度に 1 つずつ発生し、毎回テレポート フラッシュに相当し、一定の位置に留まるということです。次回、次の位置にテレポートするとき、この場合、障害物を挟む際に、オブジェクトと障害物が非常に交差しやすくなり、衝突判定が異常となり、カビの侵入を引き起こし、剛体コンポーネントは非常に便利です。オブジェクトを引っ張って移動する場合、そのようなバグはありません。この側面に興味がある場合は、関連情報を確認してください。

Rigidbody コンポーネントが GameObject の動きをどのように制御するかを説明していきます。

1.アドフォース

AddForce 関数を使用して、剛体に力を加えてオブジェクトを移動します。移動したい方向に、その方向に力を加えます。

AddForce 関数のパラメーターは、AddForce (方向ベクトル * 力の大きさ) です。

[SerializeField] private float force;
private Rigidbody2D rigidbody2D;
private void Start()
{
    //获取挂载脚本的物体的刚体组件
    rigidbody2D = GetComponent<Rigidbody2D>();
}
private void Update()
{
    //向上施加一个大小为force的力
    rigidbody2D.AddForce(Vector2.up * force);
}

2.位置の移動

MovePosition 関数はオブジェクトの位置を直接設定できます。

MovePosition 関数のパラメータは MovePosition (位置 (tramsform.position など)) です。

以下のコードはオブジェクトが毎回右にフラッシュ/テレポートする速度の長さですが、この方法も金型破損の原因となりますのでご注意ください。

[SerializeField] private float speed;
private Rigidbody2D rigidbody2D;
private void Start()
{
    //获取挂载脚本的物体的刚体组件
    rigidbody2D = GetComponent<Rigidbody2D>();
}
private void Update()
{
    //向右移动,2D中为向右/前,X轴正方向
    rigidbody2D.MovePosition(transform.position + Vector3.right * speed * Time.deltaTime);
}

もちろん、ターゲット位置を直接塗りつぶして、指定したターゲット位置にオブジェクトをフラッシュさせることもできます。

[SerializeField] private Transform targetTransform;
private Rigidbody2D rigidbody2D;
private void Start()
{
    //获取挂载脚本的物体的刚体组件
    rigidbody2D = GetComponent<Rigidbody2D>();
}
private void Update()
{
    //传送到targetTransform的位置
    rigidbody2D.MovePosition(targetTransform.position);
}

3.速度

最初に説明することは、速度は関数ではなく、オブジェクトの速度であるパラメーターであるということです。

したがって、オブジェクトが移動しようとする方向に速度を加えることで、オブジェクトを指定された方向を超えて一定の速度で移動させることができます。

[SerializeField] private float moveSpeed_X;
[SerializeField] private float moveSpeed_Y;
private Rigidbody2D rigidbody2D;
private void Start()
{
    //获取挂载脚本的物体的刚体组件
    rigidbody2D = GetComponent<Rigidbody2D>();
}
private void Update()
{
    //水平方向
    float horizontal = Input.GetAxis("Horizontal");
    //竖直方向
    float vertical = Input.GetAxis("Vertical");
    rigidbody2D.velocity=new Vector2 (horizontal*moveSpeed_X*Time.deltaTime, vertical* moveSpeed_Y * Time.deltaTime);
    //也可以只改变x或y的值
    rigidbody2D.velocity = new Vector2(horizontal * moveSpeed_X * Time.deltaTime, rigidbody2D.velocity.y);
    rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, vertical * moveSpeed_Y * Time.deltaTime);
}

4. エンディング

上記はオブジェクトを移動するいくつかの簡単な方法です。もちろん、オブジェクトを移動する方法はたくさんあります。ここではほんの一部を紹介します。興味のある友達は詳しく見てみましょう。

おすすめ

転載: blog.csdn.net/qq_63486332/article/details/131953729