Добавлен , опубликован
Способ реализации:
Lua
Версия Warcraft:
Автор этой наработки PT153, а не я. Но делал он её по доброте душевной для меня, а я делюсь со всеми.
3 Функции:
CreateEffectLighting3D
MoveEffectLighting3D
DestroyEffectLighting3D
Позволяют создать, передвинуть или уничтожить молнию сделанную, из чего угодно, из снарядов, из пеонов, из рыцарей, из цепей
Но зачем же?? есть же стандартные молнии ко ко ко, чем они не устраивают?
Да всем, вы видели этот импорт видели, ну так я напомню
Наработка хорошая, молния красивая, привет Феникс, но что проще Контрс+Контрв или же мучения связанные с импортом и настройкой slk?
Весь код
do
	Vector = {}
	Vector.__index = Vector
end


function Vector:new(x, y, z)
	local v = {x = x, y = y, z = z}
	setmetatable(v, self)
	return v
end

function Vector:copy()
	return Vector:new(self.x, self.y, self.z)
end

function Vector:dot(other)
	return self.x * other.x + self.y * other.y + self.z * other.z
end

function Vector:length()
	return math.sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
end

function Vector:length2d()
	return math.sqrt(self.x * self.x + self.y * self.y)
end

function Vector:__mul(num)
	return Vector:new(self.x * num, self.y * num, self.z * num)
end

function Vector:__div(num)
	return Vector:new(self.x / num, self.y / num, self.z / num)
end

function Vector:__div(num)
	return Vector:new(self.x / num, self.y / num, self.z / num)
end

function Vector:normalize(clone)
	if clone then
		return self / self:length()
	end
	local l = self:length()
	self.x = self.x / l
	self.y = self.y / l
	self.z = self.z / l
	return self
end

function Vector:angleBetween(other)
	return math.acos(self:dot(other) / other:length() / self:length())
end

function Vector:yaw()
	return math.atan(self.y, self.x)
end

function Vector:pitch()
	return math.atan(self.z, self:length2d())
end

function CreateEffectLighting3D(x1, y1, z1, x2, y2, z2, step, effModel,length)
	local vector = Vector:new(x2 - x1, y2 - y1, z2 - z1)
	local normalized = vector:normalize(true)
	local chainCount = math.floor(vector:length() / step)
	local pitch = vector:pitch()
	local yaw = vector:yaw()
	local eff = {}
	if not length then
		length=chainCount
	end
	
	if length <1 then
		print("ОШИБКА, СЛИШКОМ МАЛО ЭЛЕМЕНТОВ МЕЖДУ ТОЧКАМИ, ЗАДАЙТЕ ЧИСЛО ВРУЧНУЮ length")
		length=100
	end

	for i = 1, length do
		if i<=chainCount then
			eff[i] = AddSpecialEffect(effModel, 0, 0)
			local v = normalized * (step * i)
			BlzSetSpecialEffectPosition(eff[i], x1 + v.x, y1 + v.y, z1 + v.z)
			BlzSetSpecialEffectPitch(eff[i], -pitch)
			BlzSetSpecialEffectYaw(eff[i], yaw)
		else
			eff[i] = AddSpecialEffect(effModel, OutPoint, OutPoint)
		end
	end
	return eff
end

function MoveEffectLighting3D(x1, y1, z1, x2, y2, z2, step, eff,length,isUnit)
	local vector = Vector:new(x2 - x1, y2 - y1, z2 - z1)
	local normalized = vector:normalize(true)
	local chainCount = math.floor(vector:length() / step)
	local pitch = vector:pitch()
	local yaw = vector:yaw()
	if not length then
		length=#eff
	end
	if isUnit then
		pitch=pitch-math.rad(90)
	end

	for i = 1, length do
		local v = normalized * (step * i)
		if i<=chainCount then
			local z = z1 + v.z
			BlzSetSpecialEffectPosition(eff[i], x1 + v.x, y1 + v.y, z)
			BlzSetSpecialEffectPitch(eff[i], -pitch)
			BlzSetSpecialEffectYaw(eff[i], yaw)
		else
			BlzSetSpecialEffectPosition(eff[i], OutPoint, OutPoint, 0)
		end

	end
	return pitch
end

function DestroyEffectLighting3D(eff)
	for i = 1, #eff do
		BlzSetSpecialEffectPosition(eff[i], OutPoint, OutPoint, 0)
		DestroyEffect(eff[i])
	end
end

Нюансы

  1. Молния возвращает типа данных "Таблица" при создании, если я не прав - поправьте меня
  2. Модель должна быть правильно настроена как и дефолтные снаряды, то есть смотреть слева направо, если проверять через Mdlvis
  3. Шаг между моделями задаётся через параметр step, рекомендуется использовать длину модели
  4. Число элементов создаётся с излишком, излишек указан вот тут for i = 1, 100 do, при шаге 50, это позволит создать запас для растягиваемой молнии до 5000, но можно просто использовать chainCount
Я не буду рисовать 3D чайники из пеонов, принцип работы полностью идентичен молниям, Но самое главное ради чего эта система создавалась - ради создания молний, которые не растягиваются при масштабировании
И конечно пентаграмма из пеонов
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
21
Наработка хорошая, молния красивая, привет Феникс, но что проще Контрс+Контрв или же мучения связанные с импортом и настройкой slk?
ну как бы чтобы что-то импортировать нужно ещё это где-то взять. импорт на деревьях не растёт. Нестандартных молний не так уж много, в отличии от моделек
33
Ну так я про что, это прям сильное расширение функционала
33
Vlod, цепь адмирала все видели, как сделаю что другое - сразу добавлю
27
Bergi_Bear, а дуговую молнию как сделать? тоже из частиц будет?
21
МрачныйВорон:
Bergi_Bear, а дуговую молнию как сделать? тоже из частиц будет?
Странный вопрос какой-то
33
Да, только думаю частиц надо в 4 раза больше, и надо полностью алгоритм построения менять
12
Если можно сделайте видео или гифку с демонстрацией
33
Пока что есть только это, обновил шапку ^^


Кстати рефордже такие молнии ещё и тени отбрасывают, даже не знал
Загруженные файлы
33

Обновление

Исправления ошибка лишних просчетов для молний фиксированной длины
Добавлены новые параметры:
MoveEffectLighting3D - добавлены необязательные параметры length и isUnit
length - избавляет нас от тяжелого получения размерности #eff в цикле на каждый тик, это повысило производительность примерно на 10%, если не указан, то ничего страшного, имеет смысл юзать на очень громоздких молниях более 100 элементов длинной
isUnit - собирался и ранее добавить его, опцию нужно применять, если эффект вертикальный, например, как юнит или здание
Хороший пример, пеон наклонён лицом вниз, ибо иначе находился бы в режиме стоя
код пример для вращения пеонов в пентаграмме
function CreatePentagram(xs,ys,distance,effModel)
	local PentaPoint={}
	local pa=360/5--72
	local eff={}
	for i=1,5 do
		PentaPoint[i]={x=0,y=0}
		PentaPoint[i].x,PentaPoint[i].y=MoveXY(xs,ys,distance,pa*i)
	end

	for i=1,5 do
		local k=i+2
		if k>5 then
			k=k-5
		end
		eff[i]=CreateEffectLighting3D(PentaPoint[i].x,PentaPoint[i].y,350,PentaPoint[k].x,PentaPoint[k].y,350,60,effModel)
		print(#eff[i])
	end
	local a=0

	TimerStart(CreateTimer(), TIMER_PERIOD, true, function()
		--pa=pa+2
		a=a+1
		for i=1,5 do
			PentaPoint[i]={x=0,y=0}
			PentaPoint[i].x,PentaPoint[i].y=MoveXY(xs,ys,distance,(pa*i)+a)
		end
		for i=1,5 do
			local k=i+2
			if k>5 then
				k=k-5
			end
			MoveEffectLighting3D(PentaPoint[i].x,PentaPoint[i].y,350,PentaPoint[k].x,PentaPoint[k].y,350,60,eff[i],#eff[i],true)
		end
	end)
end
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.