3

序章

私は現在、GameObjectのポイントアンドクリックの動作を制御するスクリプト(UnityのC#スクリプト)を作成しようとしています。

本質的に、プレーヤーは、画面をクリックするだけで熱気球を制御します。これにより、オブジェクトは加速し始め、クリックの位置に向かって移動します。クリック位置の特定の距離にあるとき、熱気球は反対方向に加速し始め(したがって減速し)、クリックの位置で正確に完全に停止するはずです。

私はすでに完全に機能するコメント付きのスクリプト(この投稿の下部にあります)を作成しました。このスクリプトは、GameObjectを一定の速度でクリックの位置に向かって移動し、特定の距離内にあるとき、その時点で停止します。

また、加速しながらクリックの位置に向かって移動する、個別に完全に機能するスクリプトを作成しました(そのような小惑星を突き出す動作を取得します)。これは、投稿の下部にもあります。

問題

今私が直面している問題は、これら2つの動作を取り、それらを1つの動作スクリプトとして実装できる解決策を見つけるためにかなり長い間取り組んできたということです。つまり、熱気球は加速動作をします。また、ここにあるこの視覚的な例とまったく同じように、速度を落とし、目標位置で停止します。

視覚的な到着行動のデモンストレーション

質問

私の質問は次のようになります:

一定の速度だけでなく、方程式に加速度も含まれている場合、どのようにして到着動作を作成できますか?私はこの問題を調査し、自分自身の解決策を試してみましたが、私が行うことは何も期待どおりに機能していないようです。

スクリプトの添付ファイル

到着動作を伴う一定速度でのポイントアンドクリックの動き

using UnityEngine;
using System.Collections;

public class PlayerControl : MonoBehaviour 
{
    // Fields
    Transform cachedTransform;
    Vector3 currentMovementVector;
    Vector3 lastMovementVector;
    Vector3 currentPointToMoveTo;
    Vector3 velocity;
    int movementSpeed;

    Vector3 clickScreenPosition;
    Vector3 clickWorldPosition;

    float slowingDistance = 8.0f;

    Vector3 desiredVelocity;

    float maxSpeed = 1000.0f;

    // Use this for initialization
    void Start () 
    {
        cachedTransform = transform;
        currentMovementVector = new Vector3(0, 0);
        movementSpeed = 50;
        currentPointToMoveTo = new Vector3(0, 0);
        velocity = new Vector3(0, 0, 0);
    }

    // Update is called once per frame
    void Update () 
    {
        // Retrive left click input
        if (Input.GetMouseButtonDown(0))
        {
            // Retrive the click of the mouse in the game world
            clickScreenPosition = Input.mousePosition;

            clickWorldPosition = Camera.main.ScreenToWorldPoint(new      Vector3(clickScreenPosition.x, clickScreenPosition.y, 0));
            currentPointToMoveTo = clickWorldPosition;

            currentPointToMoveTo.z = 0;

            // Calculate the current vector between the player position and the click
            Vector3 currentPlayerPosition = cachedTransform.position;

            // Find the angle (in radians) between the two positions (player position and click position)
            float angle = Mathf.Atan2(clickWorldPosition.y - currentPlayerPosition.y, clickWorldPosition.x - currentPlayerPosition.x);

            // Find the distance between the two points
            float distance = Vector3.Distance(currentPlayerPosition, clickWorldPosition);

            // Calculate the components of the new movemevent vector
            float xComponent = Mathf.Cos(angle) * distance;
            float yComponent = Mathf.Sin(angle) * distance;

            // Create the new movement vector
            Vector3 newMovementVector = new Vector3(xComponent, yComponent, 0);
            newMovementVector.Normalize();

            currentMovementVector = newMovementVector;
        }

        float distanceToEndPoint = Vector3.Distance(cachedTransform.position, currentPointToMoveTo);

        Vector3 desiredVelocity = currentPointToMoveTo - cachedTransform.position;

        desiredVelocity.Normalize();

        if (distanceToEndPoint < slowingDistance)
        {
            desiredVelocity *= movementSpeed * distanceToEndPoint/slowingDistance;
        }
        else
        {
            desiredVelocity *= movementSpeed;
        }

        Vector3 force = (desiredVelocity - currentMovementVector);
        currentMovementVector += force;

        cachedTransform.position += currentMovementVector * Time.deltaTime;
    }
}

加速を使用してポイントアンドクリックの動きをしますが、到着動作はありません

using UnityEngine;
using System.Collections;

public class SimpleAcceleration : MonoBehaviour 
{
    Vector3 velocity;
    Vector3 currentMovementVector;

    Vector3 clickScreenPosition;
    Vector3 clickWorldPosition;

    Vector3 currentPointToMoveTo;
    Transform cachedTransform;

    float maxSpeed;

    // Use this for initialization
    void Start () 
    {
        velocity = Vector3.zero;
        currentMovementVector = Vector3.zero;
        cachedTransform = transform;
        maxSpeed = 100.0f;
    }

    // Update is called once per frame
    void Update () 
    {
        // Retrive left click input
        if (Input.GetMouseButtonDown(0))
        {
            // Retrive the click of the mouse in the game world
            clickScreenPosition = Input.mousePosition;

            clickWorldPosition = Camera.main.ScreenToWorldPoint(new Vector3(clickScreenPosition.x, clickScreenPosition.y, 0));
            currentPointToMoveTo = clickWorldPosition;

            // Reset the z position of the clicking point to 0
            currentPointToMoveTo.z = 0;

            // Calculate the current vector between the player position and the click
            Vector3 currentPlayerPosition = cachedTransform.position;

            // Find the angle (in radians) between the two positions (player position and click position)
            float angle = Mathf.Atan2(clickWorldPosition.y - currentPlayerPosition.y, clickWorldPosition.x - currentPlayerPosition.x);

            // Find the distance between the two points
            float distance = Vector3.Distance(currentPlayerPosition, clickWorldPosition);

            // Calculate the components of the new movemevent vector
            float xComponent = Mathf.Cos(angle) * distance;
            float yComponent = Mathf.Sin(angle) * distance;

            // Create the new movement vector
            Vector3 newMovementVector = new Vector3(xComponent, yComponent, 0);
            newMovementVector.Normalize();

            currentMovementVector = newMovementVector;
        }

        // Calculate velocity
        velocity += currentMovementVector * 2.0f * Time.deltaTime;

        // If the velocity is above the allowed limit, normalize it and keep it at a constant max speed when moving (instead of uniformly accelerating)
        if (velocity.magnitude >= (maxSpeed * Time.deltaTime))
        {
            velocity.Normalize();
            velocity *= maxSpeed * Time.deltaTime;
        }

        // Apply velocity to gameobject position
        cachedTransform.position += velocity;
    }
}
4

2 に答える 2

3

最初のスクリプトを調整します。

velocity2 番目のスクリプトのように、variable を導入します。movementSpeedこれをinに等しく設定し、その後Start()は使用しないでくださいmovementSpeedこれが完全に機能するまで先に進まないでください。

次に加速を導入します。

if (distanceToEndPoint < slowingDistance)
{
   velocity *= distanceToEndPoint/slowingDistance;
}
else
{
   velocity += direction * 2.0f * Time.deltaTime;
}
于 2012-06-04T21:11:51.047 に答える
3

モーションをどのように表示するかに応じて、等速方程式またはこれらの方程式のいずれかが必要になります。一定速度の方が簡単です。

例: 出発地と目的地の間の距離を 2 で割ります。その後、数学を使用して途中まで加速し、その後減速します。

于 2012-06-04T19:00:14.977 に答える