Я только начинаю изучать LUA, и у меня возникла проблема, которую я не знаю, как «правильно» решить.
Когда я передаю Defold vmath.vector3 своей функции, кажется, что он передается по ссылке и поэтому изменяется.
Если я умножу его на что-нибудь, это будет решено.
Есть ли другой более правильный способ решить эту проблему? Я не хочу изменять исходный вектор, который передаю в качестве аргумента.
function M.get_nearest_tile(x, y)
if y then -- if we've got 2 inputs, use x & y
x = math.floor(x / M.TILE_SIZE)
y = math.floor(y / M.TILE_SIZE)
return x, y
else -- if we've only got 1 input, use as vector
local vec = x * 1 -- multiplying by 1 to avoid modifying the real vector
vec.x = math.floor(vec.x / M.TILE_SIZE)
vec.y = math.floor(vec.y / M.TILE_SIZE)
return vec.x, vec.y
end
end
Ах, извините, я чувствую себя глупо. Я думал, что это из математики. Это от "vmath", который используется Defold (игровой движок).
Согласно документам, вы можете скопировать вектор с помощью local new = vmath.vector3(old)defold.com/ref/vmath/#vmath.vector3:v1
Вау ... Я действительно обманул себя на этот раз ... Я думал, что у меня, вероятно, будет такая же проблема с таблицей, поэтому я сказал себе, что это проблема с LUA в целом, и не стал проверять их документы ... , Я думаю, это настоящий ответ, хотя то, что я спрашивал, было неправильным с самого начала. Мне нужно попробовать, что произойдет, если я сделаю то же самое со столом.
Что касается вашего исходного вопроса, вы не можете «выключить» передачу по ссылке. Если что-то реализовано как ссылочный тип, оно будет передано как таковое. Копирование таблиц в Lua нетривиально, потому что это действительно зависит от того, как и какую часть содержимого вы хотите скопировать (рекурсивный, метатаблицы и т. д.).
Понятно, спасибо вам большое за объяснение!
Нитпик: Это Lua, а не LUA.
Вы получите такой же результат при прохождении стола. Как упоминал выше Генри Менке, скопировать таблицу Lua нетривиально.

У вас уже есть решение в вашей ветке else: вам нужно будет создать копию ваших векторов, прежде чем применять к ним операции «изменения».
Что касается других вариантов, возможно, удастся найти способ использовать прокси-таблицы, но это будет намного сложнее, чем просто создание копии.
Поскольку вы возвращаете x и y как два значения, вы можете реализовать обе ветви одинаково, не изменяя никаких таблиц:
function M.get_nearest_tile(x, y)
local newX, newY
if y then -- if we've got 2 inputs, use x & y
newX = math.floor(x / M.TILE_SIZE)
newY = math.floor(y / M.TILE_SIZE)
else -- if we've only got 1 input, use as vector
newX = math.floor(x.x / M.TILE_SIZE)
newY = math.floor(x.y / M.TILE_SIZE)
end
return newX, newY
end
У вас есть повторяющееся объявление x и y, хотя синтаксически оно не неверно, оно не будет работать должным образом.
@dualed: Понял. Фиксированный.
Я искал очевидное решение, не связанное с Defold.
Defold предоставляет ряд специальных структур данных, которые очень полезны при разработке игр:
Все вышеперечисленное используется игровым движком Defold, но вы найдете такие же структуры данных и в других игровых движках.
У приведенных выше структур данных есть одна общая черта: они относятся к Lua-типу userdata.
print(type(vmath.vector3())) -- "userdata"
Пользовательские данные всегда передаются по ссылке, поэтому вы видите описанное вами поведение. Однако Defold предоставляет способы делать копии:
local copy = vmath.vector3(original) -- copy the vector3 'original'
local copy = vmath.vector4(original) -- copy the vector4 'original'
local copy = vmath.quat(original) -- copy the quaternion 'original'
local copy = vmath.matrix4(original) -- copy the matrix4 'original'
Откуда взялся
vector3? Это Роблокс или что-то в этом роде?