Який найефективніший і найшвидший спосіб перетворити Vector3 в Vector2?
Кастинг:
Vector2 vector2 = (Vector2)vector3;
Ініціалізація нового Vector2:
Vector2 vector2 = new Vector2(vector3.x, vector3.y);
Або є інший метод, про який я не знаю?
Який найефективніший і найшвидший спосіб перетворити Vector3 в Vector2?
Кастинг:
Vector2 vector2 = (Vector2)vector3;
Ініціалізація нового Vector2:
Vector2 vector2 = new Vector2(vector3.x, vector3.y);
Або є інший метод, про який я не знаю?
Відповіді:
Vector3 v3 = Vector3.one;
Vector2 v2 = v3;
Vector3s можна неявно перетворити на Vector2 (z відкидається).
http://docs.unity3d.com/ScriptReference/Vector2-operator_Vector3.html
Якщо вам доведеться зробити багато перетворень, можливо, доведеться змінити спосіб використання своїх векторів. Зробіть два тести і приділіть їм час, щоб побачити, який з них працює.
ОНОВЛЕННЯ З ТЕСТОВАМИ: Оскільки ви запитали, який з них найшвидший, я створив тест із виконанням 10000000 перетворень кожної в Unity. Здається, що в цьому випадку версія ініціалізації є найшвидшою. Але, ви завжди повинні використовувати той, який відповідає вашому власному контексту, тому я раджу вам запустити власні тести у своїй грі.
10000000 екземплярів TestConvertByOperation: 0,2714049s
TestConvertByCasting 10000000 екземплярів: 0,286027s
TestConvertByІніціалізація 10000000 екземплярів: 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;
}
}
y
вгору. Перетворюючи a Vector3
в a Vector2
, ви майже завжди хочете, x
а z
, не, x
і y
.
І Vector2, і Vector3 є структурою в двигуні Unity, тому створення одного з іншого просто передбачає виділення сховища в стеку (якщо призначення не є атрибутом об’єкта класу , який дозволив би пропустити цей перший крок) і копіювання двох компонентних значень. Обидва механізми, які ви надаєте, повинні бути складені саме до цього ІЛ-коду.
Якщо ви стикаєтеся з проблемою продуктивності при перетворенні цього типу, то, ймовірно, виникла проблема з боксом : структура перетворюється на об'єкт класу, а потім на нього . У такому випадку слід дослідити, чи можна, коли і як уникнути боксу в критичних для продуктивності частинах вашого коду.
З мого тесту, найкращий спосіб зробити це вручну призначити його значення самостійно.
Vector2 vector2;
vector2.x = vector3.x;
vector2.y = vector3.y;
Це мій результат, який я поширюю від Маттіаса.
10000000 екземплярів TestConvertByOperation: 0,3220527s
TestConvertByCasting 10000000 екземплярів: 0,3226218s
TestConvertByІніціалізація 10000000 екземплярів: 0,1916729
10000000 екземплярів: 0.09500527s. TestConvertByManualAssign
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;
}
}
}
Зверніть увагу, я перевіряю його у версії 5.6.5