如何使播放器在地形上平稳滑动


11

图

我正在制作一个等距游戏。当玩家尝试对角地走进墙壁时,我希望他们在墙壁上顺畅地滑动,因此将使用合法的移动部分,并丢弃法线方向的任何东西。墙壁可以是任何角度,而不仅仅是垂直或水平,并且播放器可以360度运动。

我觉得自己快到了,但是我无法把最后一块放到位。

更新:大家好消息!我有工作。但是...我有些困惑,我应该规范什么,不应该规范什么。法线只需要是一个单位向量,对吗?但是然后我将其与输入混合在一起,因此我将其标准化了-我错了吗?

顺便说一句,我还发现我需要将播放器朝法线方向推1个像素,这样它们才不会卡在东西上-效果很好。

Answers:


13

只需将运动向量投影到法线平面上,然后从运动向量中减去结果即可。

Vector undesiredMotion = normal * (dotProduct(input, normal));
Vector desiredMotion = input - undesiredMotion;

反正就是这样。尽管在您的可爱图中,输入似乎远离墙壁,所以我有些困惑。


抱歉,他应该在那儿的一堵垂直墙前。可怕的图画
伊恩

1
我对点积感到困惑。点积不是标量吗?
伊恩

1
是的,但是您将其乘以法线(向量)即可获得不希望有的运动的向量。向量(x,y,z)乘以标量s可得到向量(sx,sy,sz)。
克里斯·豪

完成后,更改变量以希望与图表匹配。:)
克里斯·豪

@Iain我真的在试图了解如何使用此答案,但我似乎无法掌握它。当我创建此确切的代码时,我得到的desiredMotion结果确实很奇怪。你有没有做这个工作?
测试

1

虽然直接删除法线方向上的运动分量很简单,但它可能适合您的游戏玩法来旋转运动矢量。例如,在第三人称动作游戏中,可能容易挂在墙壁和其他边界上,因此您可以对玩家的意图做出一些猜测。

// assume that 'normal' is unit length
Vector GetDesired(Vector input, Vector normal) {
   // tune this to get where you stop when you're running into the wall,
   // vs. bouncing off of it
   static float k_runningIntoWallThreshold = cos(DEG2RAD(45));

   // tune this to "fudge" the "push away" from the wall
   static float k_bounceFudge = 1.1f;

   // normalize input, but keep track of original size
   float inputLength = input.GetLength();
   input.Scale(1.0f / inputLength);

   float dot = DotProduct(input, normal);

   if (dot < 0)
   {
      // we're not running into the wall
      return input;
   }
   else if (dot < k_runningIntoWallThreshold)
   {
      Vector intoWall = normal.Scale(dot);
      intoWall.Scale(k_bounceFudge);

      Vector alongWall = (input - intoWall).Normalize();
      alongWall.Scale(inputLength);

      return alongWall;
   }
   else
   {
      // we ran "straight into the wall"
      return Vector(0, 0, 0);
   }
}

真好 但是,如果按虚假因素进行缩放,是否会使您沿着墙碰撞而不是沿着墙滑动,还是只是进行调整?
克里斯·豪

我的想法是,您对其进行了调整以使其看起来不错;当然,如果太大,它看起来就像在弹跳,但如果它足够细微,它只会阻止您挂在表面的轻微弯曲上。
dash-tom-bang 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.