Установить местоположение актера в мире из математики положения мыши

Мои познания в математике, к сожалению, сильно удручают, но очень хочется разобраться в коде, которым я должен управлять Актером, перетаскивая его мышкой. Этот код также работает как способ размещения объекта в мире щелчком мыши по экрану.

Во-первых - код работает отлично, речь больше о векторной алгебре, чем о Unreal Engine. Я так запутался, что даже не знаю, как правильно назвать переменные, лол

Итак, вот код, который я преобразовал из одного из найденных мной примеров Blueprint, который реализует нужную мне функциональность:

    FVector WorldLocation;
    FVector WorldDirection;
    PlayerController->DeprojectMousePositionToWorld(WorldLocation, WorldDirection);

    // Have no idea how it works but it works! I really need to learn more about vector Algebra :(((
    float DistanceAboveGround = 200.0f;
    float NotSureWhyThisValue = -1.0f;
    float WhyThisOperation = WorldLocation.Z / WorldDirection.Z + DistanceAboveGround;

    FVector IsThisNewWorldDirection = WorldDirection * WhyThisOperation * NotSureWhyThisValue;
    FVector ActorWorldLocation = WorldLocation + IsThisNewWorldDirection;            
    // end of "Have no idea how it works" code
    Capsule->SetWorldLocation(ActorWorldLocation);

Если кто-нибудь может объяснить мне, почему мне нужно выполнять эти операции, начиная с // Понятия не имею.. строка комментария? Если я смогу понять, как правильно называть «NotSureWhyThisValue», «WhatDoesItMean», «WhyThisOperation» и «IsThisNewWorldDirection?» это будет огромным улучшением для меня, хотя идеальным случаем было бы объяснить каждую строку...

Заранее спасибо!


person paxer    schedule 19.11.2019    source источник
comment
Предполагается ли это только для расчета значения высоты актера?   -  person Tagger5926    schedule 19.11.2019
comment
код работает, я использую его в Tick и могу перетаскивать своего актера с изменением положения мыши. Одна вещь может помочь понять сцену Unreal — это игра типа RTS, поэтому представьте себе Starcraft 3, и я создаю актера на карте щелчком мыши.   -  person paxer    schedule 19.11.2019


Ответы (1)


Это просто повторная реализация FMath::LinePlaneIntersection, который просто использует определенные сокращения, поскольку нормаль плоскости равна (0,0,1):

FVector WorldLocation;
FVector WorldDirection;
float DistanceAboveGround = 200.0f;

PlayerController->DeprojectMousePositionToWorld(WorldLocation, WorldDirection); 

FVector PlaneOrigin(0.0f, 0.0f, DistanceAboveGround);

FVector ActorWorldLocation = FMath::LinePlaneIntersection(
            WorldLocation,
            WorldLocation + WorldDirection,
            PlaneOrigin,
            FVector::UpVector);

Capsule->SetWorldLocation(ActorWorldLocation);

Посмотрите этот ответ Баса Смита здесь, если вы хотите лучше понять математику (скопировано ниже):

Vector3 Intersect(Vector3 planeP, Vector3 planeN, Vector3 rayP, Vector3 rayD)
{
    var d = Vector3.Dot(planeP, -planeN);
    var t = -( d 
            + rayP.z * planeN.z 
            + rayP.y * planeN.y 
            + rayP.x * planeN.x) 
          / (rayD.z * planeN.z 
            + rayD.y * planeN.y 
            + rayD.x * planeN.x);
    return rayP + t * rayD;
}

По сути, WhyThisOperation оказывается -t, затем оно умножается на -1, чтобы получить t, затем оно умножается на WorldDirection (rayD) и добавляется к WorldPosition (rayP), чтобы получить точку пересечения.

person Ruzihm    schedule 19.11.2019
comment
это выглядит намного чище, спасибо! Один вопрос, зачем нам тут WorldLocation + WorldDirection? - person paxer; 19.11.2019
comment
@paxer Я отредактировал свой вопрос, чтобы лучше объяснить код, который вы дали. В моем коде вам нужно иметь вторую точку на линии для этой функции, а добавление начала координат и направления дает вам еще одну точку на линии :) - person Ruzihm; 19.11.2019