【问题标题】:Set Actor world location from mouse position math从鼠标位置数学设置 Actor 世界位置
【发布时间】:2020-03-14 10:39:37
【问题描述】:

不幸的是,我的数学知识非常令人沮丧,但我真的很想了解我必须通过用鼠标拖动来控制 Actor 的代码。此代码还可以用作通过在屏幕上单击鼠标将对象放置在世界中的方式。

首先 - 代码运行良好,这是更多关于向量代数而不是虚幻引擎的问题。我很迷茫,我什至不知道如何正确命名变量 lol

所以,这是我从我发现的一个蓝图示例转换而来的代码,它实现了我需要的功能:

    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”?这对我来说将是一个巨大的进步,完美的情况是解释每一行......

提前致谢!

【问题讨论】:

  • 这只是为了计算演员的身高值吗?
  • 代码有效,我在 Tick 中使用它,并且可以随着鼠标位置的变化拖动我的演员。有一件事可能有助于理解虚幻场景——它是一种 RTS 类型的游戏,所以想象一下星际争霸 3,我通过鼠标点击在地图上生成了一个演员。

标签: c++ linear-algebra unreal-engine4 game-development vectormath


【解决方案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);

See this answer by Bas Smit here如果你想更好地理解数学(复制如下):

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) 获取交点。

【讨论】:

  • 这看起来干净多了,谢谢!一个问题为什么我们需要在这里“WorldLocation + WorldDirection”?
  • @paxer 我编辑了我的问题以更好地解释您提供的代码。在我的代码中,您需要在该函数的线上有第二个点,并添加原点和方向会在线上为您提供另一个点:)
猜你喜欢
  • 2011-03-06
  • 1970-01-01
  • 1970-01-01
  • 2019-02-07
  • 1970-01-01
  • 2018-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多