Cách hiệu quả nhất để chuyển đổi Vector3 sang Vector2


11

Cách hiệu quả nhất và nhanh nhất để chuyển đổi Vector3 thành Vector2 là gì?

Vật đúc:

Vector2 vector2 = (Vector2)vector3;

Đang khởi tạo Vector2 mới:

Vector2 vector2 = new Vector2(vector3.x, vector3.y);

Hoặc có một phương pháp khác mà tôi không biết?


10
Các loại hoạt động cấu trúc này sẽ không bao giờ là nút cổ chai xác định hiệu suất trong trò chơi của bạn, vì vậy thay vì bị sa lầy vào các tối ưu hóa vi mô như thế này, tôi khuyên bạn chỉ nên sử dụng bất kỳ cách nào rõ ràng hơn để hiểu trong bối cảnh bạn đang sử dụng nó ;)
DMGregory

1
@DMGregory: Tất nhiên, trừ khi OP đã thực hiện phân tích hiệu suất và, có lẽ do quyền anh, thực sự có điều này trong một vòng lặp lồng nhau gây ra vấn đề về hiệu suất. Ví dụ, một vòng lặp lồng nhau như vậy có thể là một triển khai A-star hoặc Dijkstra.
Pieter Geerkens

4
@PieterGeerkens Hội chợ, nhưng nếu OP đã thực hiện phân tích hiệu suất, họ đã thử cả hai cách và sẽ có số trên cả hai. ;) Từ việc xem quỹ đạo của một số người dùng Unity mới (bao gồm cả bản thân tôi), tôi khá tự tin rằng trong trường hợp này là tối ưu hóa vi mô, vì vậy tôi muốn đưa ra cảnh báo mạnh mẽ (nếu có thể nói quá) chống lại nó. Cách đó nằm ở hàng tuần hoặc hàng tháng điều chỉnh mã và băn khoăn về sự tối ưu theo những cách không làm cho trò chơi của chúng tôi trở nên tốt hơn.
DMGregory

Câu trả lời:


12
Vector3 v3 = Vector3.one;
Vector2 v2 = v3;

Vector3 có thể được chuyển đổi hoàn toàn thành Vector2 (z bị loại bỏ).

http://docs.unity3d.com/ScriptReference/Vector2-operator_Vector3.html

Nếu bạn phải thực hiện nhiều chuyển đổi, bạn có thể phải thay đổi cách bạn sử dụng các vectơ của mình. Thực hiện hai bài kiểm tra và thời gian để xem cái nào phù hợp với bạn.

CẬP NHẬT VỚI KIỂM TRA: Vì bạn đã hỏi ai là người nhanh nhất tôi đã tạo một bài kiểm tra chạy 10000000 chuyển đổi của mỗi bài trong Unity. Có vẻ như phiên bản Khởi tạo là nhanh nhất trong trường hợp này. NHƯNG, bạn nên luôn luôn sử dụng một trong những phù hợp với bối cảnh của riêng bạn, vì vậy tôi khuyên bạn nên chạy thử nghiệm của riêng bạn trong trò chơi của bạn.

TestConvertByOperation 10000000 phiên bản: 0.2714049s

TestConvertByCasting 10000000 phiên bản: 0.286027s

TestConvertByInitializing 10000000 phiên bản: 0.1458781s

using UnityEngine;

public class TestVector3Conversion : MonoBehaviour
{

    readonly int iterations = 10000000;
    Vector3 testVector = new Vector3(3f, 14f, 42f);

    void Start()
    {
        Debug.Log(string.Format("TestConvertByOperation {0} instances: {1}s", iterations, TestConvertByOperation()));
        Debug.Log(string.Format("TestConvertByCasting {0} instances: {1}s", iterations, TestConvertByCasting()));
        Debug.Log(string.Format("TestConvertByInitializing {0} instances: {1}s", iterations, TestConvertByInitializing()));
    }

    float TestConvertByOperation()
    {
        var timeStart = Time.realtimeSinceStartup;

        for (int i = 0; i < iterations; i++)
        {
            Vector2 v2 = testVector;
        }

        return Time.realtimeSinceStartup - timeStart;
    }

    float TestConvertByCasting()
    {
        var timeStart = Time.realtimeSinceStartup;

        for (int i = 0; i < iterations; i++)
        {
            Vector2 v2 = (Vector2)testVector;
        }

        return Time.realtimeSinceStartup - timeStart;
    }

    float TestConvertByInitializing()
    {
        var timeStart = Time.realtimeSinceStartup;

        for (int i = 0; i < iterations; i++)
        {
            Vector2 v2 = new Vector2(testVector.x, testVector.y);
        }

        return Time.realtimeSinceStartup - timeStart;
    }

}

1
Họ được ngầm đúc. Điều này được thực hiện bằng cách xác định các toán tử chuyển đổi mới . Trớ trêu thay Unity vi phạm '... nếu việc chuyển đổi được đảm bảo không gây mất dữ liệu.' phần.
Hd vk

1
Cập nhật câu trả lời của tôi với một ví dụ mã để kiểm tra các phương pháp khác nhau. Hãy cho tôi biết cái nào nhanh hơn trong trường hợp của bạn.
Mattias

1
Các kết quả thay đổi một chút trong bản dựng phát hành / không gỡ lỗi hoặc khi dữ liệu Vector2 có vòng đời bên ngoài vòng lặp for (giúp trình biên dịch không thực hiện một số loại tối ưu hóa nhất định). Tôi nhận được mức chênh lệch từ 110 đến 151 mili giây, hoặc chênh lệch tối đa khoảng 4 nano giây mỗi lần chuyển nhượng. Vì vậy, trừ khi chúng ta thực hiện điều này hàng trăm nghìn lần mỗi khung hình, đây có lẽ không phải là vấn đề đáng lo ngại, ngay cả khi có sự khác biệt có thể đo lường được trong một ví dụ tổng hợp như thế này.
DMGregory

1
@DMGregory Đồng ý. Đó là lý do tại sao luôn luôn nên chạy thử nghiệm hiệu năng trong ngữ cảnh chính xác, với dữ liệu thực.
Mattias

1
Vấn đề với chuyển đổi ngầm ylà lên. Khi chuyển đổi a Vector3thành a Vector2, bạn hầu như luôn muốn xz, không xy.
Kevin Krumwiede

6

Cả Vector2Vector3 đều là một cấu trúc trong công cụ Unity, vì vậy việc tạo cái này từ cái kia chỉ đơn giản liên quan đến việc phân bổ bộ lưu trữ trên ngăn xếp (trừ khi đích là thuộc tính của một đối tượng lớp , cho phép bỏ qua bước đầu tiên này) và sao chép hai giá trị thành phần. Cả hai cơ chế bạn cung cấp phải được biên dịch thành chính xác mã IL này.

Nếu bạn gặp phải vấn đề về hiệu năng với chuyển đổi loại này thì có lẽ bạn có vấn đề về quyền anh , với cấu trúc được chuyển đổi và sau đó từ một đối tượng lớp . Trong trường hợp đó, bạn nên điều tra xem liệu khi nào và khi nào, quyền anh có thể tránh được trong các phần quan trọng về hiệu suất của mã của bạn.


0

Từ thử nghiệm của tôi, cách tốt nhất để làm điều đó là tự mình gán giá trị của nó.

Vector2 vector2;
vector2.x = vector3.x;
vector2.y = vector3.y;

Đây là kết quả của tôi mà tôi mở rộng từ Mattias.

TestConvertByOperation 10000000 phiên bản: 0.3220527s

TestConvertByCasting 10000000 phiên bản: 0.3226218s

TestConvertByInitializing 10000000 phiên bản: 0.1916729s

TestConvertByManualAssign 10000000 phiên bản: 0.09500527s

using UnityEngine;

namespace myTest
{
    public class test: MonoBehaviour 
    {
        readonly int iterations = 10000000;
        Vector3 testVector = new Vector3(3f, 14f, 42f);

        void Start()
        {
            Debug.Log(string.Format("TestConvertByOperation {0} instances: {1}s", iterations, TestConvertByOperation()));
            Debug.Log(string.Format("TestConvertByCasting {0} instances: {1}s", iterations, TestConvertByCasting()));
            Debug.Log(string.Format("TestConvertByInitializing {0} instances: {1}s", iterations, TestConvertByInitializing()));
            Debug.Log(string.Format("TestConvertByManualAssign {0} instances: {1}s", iterations, TestConvertByManualAssign()));
        }

        float TestConvertByOperation()
        {
            var timeStart = Time.realtimeSinceStartup;
            Vector2 v2;
            for (int i = 0; i < iterations; i++)
            {
                v2 = testVector;
            }

            return Time.realtimeSinceStartup - timeStart;
        }

        float TestConvertByCasting()
        {
            var timeStart = Time.realtimeSinceStartup;
            Vector2 v2;
            for (int i = 0; i < iterations; i++)
            {
                v2 = (Vector2)testVector;
            }

            return Time.realtimeSinceStartup - timeStart;
        }

        float TestConvertByInitializing()
        {
            var timeStart = Time.realtimeSinceStartup;
            Vector2 v2;
            for (int i = 0; i < iterations; i++)
            {
                v2 = new Vector2(testVector.x, testVector.y);
            }

            return Time.realtimeSinceStartup - timeStart;
        }
        float TestConvertByManualAssign()
        {
            var timeStart = Time.realtimeSinceStartup;
            Vector2 v2;
            for (int i = 0; i < iterations; i++)
            {
                v2.x = testVector.x;
                v2.y = testVector.y;
            }

            return Time.realtimeSinceStartup - timeStart;
        }
    }
}

Xin lưu ý, tôi kiểm tra nó với phiên bản thống nhất 5.6.5

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.