Как правильно организовать расположение отображаемой плоскости?

У меня есть видео, которое вы можете посмотреть здесь: <a href="https://www.youtube.com/watch?v=b-4EydkdnAc" rel="nofollow">тык</a>. <br/> <br/> Мне нужно, чтобы плоскость отображения (белый квадрат) правильно размещалась между двумя точками при клике на объект. Вот код инструмента: <br/> <br/> 

<pre><code class="lua">TOOL.Category = "Koshmarov"
TOOL.Name = "Plane Tool"
TOOL.Command = nil
TOOL.ConfigName = ""

if SERVER then return end

local function DrawPlaneBetweenPoints(point1, point2, ent, hitnormal)
    local dff = (point2 - point1) 
    local normal =  hitnormal:Angle() 

    cam.Start3D2D(ent:LocalToWorld(point1), ent:LocalToWorldAngles(normal), 1)
        surface.DrawRect( 0, 0, dff:Length(), 10 )
    cam.End3D2D()
end

function TOOL:LeftClick( trace )
    if not IsValid(trace.Entity) then return end
    local ent = trace.Entity
   
    if not self.point1 then
        print("point1 set")
        self.point1 = trace.Entity:WorldToLocal(trace.HitPos)
        self.hitnormal = trace.HitNormal
    else
        print("point2 set")
        self.point2 = trace.Entity:WorldToLocal(trace.HitPos)

        hook.Add("PostDrawOpaqueRenderables", "DrawPlane", function()
            render.SetColorMaterial()
            DrawPlaneBetweenPoints(self.point1, self.point2, ent, self.hitnormal)
        end)
    end
end
</code></pre>
  • 31 августа 2024 г. 8:44
Ответы на вопрос 2
Ваш код уже содержит основу для реализации инструмента, который рисует плоскость между двумя точками, однако есть несколько моментов, которые нужно скорректировать, чтобы плоскость отображалась правильно и располагалась между двумя точками. Давайте немного изменим ваш код:

1. Убедитесь, что вы правильно вычисляете среднюю точку между `point1` и `point2`.
2. Используйте правильный вектор нормали для ориентации плоскости.
3. Разместите плоскость таким образом, чтобы она корректно отображалась между этими двумя точками.

Вот пример того, как можно улучшить ваш код:

```lua
TOOL.Category = "Koshmarov"
TOOL.Name = "Plane Tool"
TOOL.Command = nil
TOOL.ConfigName = ""

if SERVER then return end

local function DrawPlaneBetweenPoints(point1, point2, ent, normal)
    local midPoint = (point1 + point2) / 2  -- Вычисляем среднюю точку
    local dff = (point2 - point1):Length() -- Длина между точками

    -- Рассчитаем угол, чтобы плоскость ориентировалась правильно
    local angle = normal:Angle()
    cam.Start3D2D(ent:LocalToWorld(midPoint), ent:LocalToWorldAngles(angle), 1)
        -- Учитываем ширину плоскости (например, 10)
        surface.DrawRect(-dff / 2, -5, dff, 10)
    cam.End3D2D()
end

function TOOL:LeftClick(trace)
    if not IsValid(trace.Entity) then return end
    local ent = trace.Entity
   
    if not self.point1 then
        print("point1 set")
        self.point1 = trace.Entity:WorldToLocal(trace.HitPos)
        self.hitnormal = trace.HitNormal
    else
        print("point2 set")
        self.point2 = trace.Entity:WorldToLocal(trace.HitPos)

        -- Удалим старый хук, если он существует
        if self.drawHook then
            hook.Remove("PostDrawOpaqueRenderables", self.drawHook)
        end

        -- Создаём новый уникальный хук
        self.drawHook = "DrawPlane"
        hook.Add("PostDrawOpaqueRenderables", self.drawHook, function()
            render.SetColorMaterial()
            DrawPlaneBetweenPoints(self.point1, self.point2, ent, self.hitnormal)
        end)

        -- Сбрасываем точки для следующего использования
        self.point1, self.point2, self.hitnormal = nil, nil, nil
    end
end
```

### Ключевые изменения:
1. **Средняя точка**: Мы вычислили среднюю точку между `point1` и `point2` для правильного расположения плоскости.
2. **Ориентация плоскости**: Плоскость теперь ориентируется по нормали пути к объекту.
3. **Очистка хуков**: Мы удалили старый хук перед добавлением нового, чтобы избежать конфликтов.
4. **Сброс переменных**: В конце метода `LeftClick` сбрасываем `point1`, `point2` и `hitnormal` для следующего использования.

Теперь вы можете кликнуть на объект дважды, чтобы установить две точки, и плоскость между ними будет отображаться правильно.
Предположу, что вызов ent:LocalToWorldAngles(normal) приводит к неправильным результатам. 
Попробуйте перевести HitNormal в локальный для объекта угол, а затем использовать этот угол каждый раз.
Для тестов поможет выводить в консоль (можно включить показ поверх экрана через developer 1 ) и вращать объект осторожно.

Обратите внимание, что LeftClick вызывается и на сервере и на клиенте (если это не cl_init.lua файл)
У игры есть Discord с отдельным каналом для вопросов по Lua.
Похожие вопросы