【问题标题】:How to create a slippery floor effect如何打造滑地效果
【发布时间】:2015-04-21 17:05:52
【问题描述】:

我正在制作一个简单的 2D 平台游戏,我遇到了让我的角色在冰冷的地面上滑倒的问题。

创建 2D 物理材质适用于墙壁,但玩家在地面上时似乎不会滑动,即使摩擦力为 0,所以我正在尝试通过代码而不是物理材质来完成。

// Colliding with ICE
void OnCollisionEnter2D(Collision2D col)
{
    if (col.gameObject.tag == "ICE") 
    {
        TouchingIce = true;
    }
}

void OnCollisionStay2D(Collision2D col)
{
    if (col.gameObject.tag == "ICE") 
    {
        TouchingIce = true;
    }
}

(我知道检测结冰的地面没有问题,因为我可以在检查器中看到 TouchingIce Bool 按预期变为真和假。)

然后在更新中:

if (TouchingIce) {
    iceMovement = true;
} else 
{
    iceMovement = false; 
}

最后在fixedUpdate中:

if (iceMovement) 
{
    // this is where I'm stuck
}

当玩家在固定更新中停在正常地面上时,我的动作是这样的

float move = Input.GetAxis("Horizontal"); // moving along horizontal Axis
anim.SetFloat ("Speed", Mathf.Abs (move));
if (grounded) 
{
    rb2d.velocity = new Vector2 (move * maxSpeed, rb2d.velocity.y);
}

如果您需要查看我的其余代码,请告诉我,我将发布其余部分。

【问题讨论】:

  • 您可能希望将此迁移到 game development stack exchange
  • 谢谢你,我真的不知道有一个专门用于游戏开发的堆栈页面,我会确保我以后发布到那里:)

标签: c# unity3d


【解决方案1】:

控制你速度的线是:

rb2d.velocity = new Vector2 (move * maxSpeed, rb2d.velocity.y);

水平速度的 100% 由水平输入轴设置。 你需要一种不同的方式来处理这个问题。

当 TouchingIce 为真时,您必须保留上次更新的速度,这意味着,如果玩家全速前进,到达冰面并释放控制,他们将继续以与上次更新相同的速度。

然后将“移动”值视为加速度而不是实际速度。

试试这个:(伪代码)

if(TouchingIce){
  // Apply input as a force instead of setting velocity directly.
  rb2d.AddForce(new Vector2 (move * maxSpeed, rb2d.velocity.y));
}else{
  // Set Velocity Directly
  rb2d.velocity = new Vector2 (move * maxSpeed, rb2d.velocity.y);
}

您可能会发现您需要为玩家跳过冰面时添加一些逻辑,因为您有空气转向功能。

【讨论】:

  • 感谢您的回复,我尝试过加力,但他似乎以正常速度行走...我明白您说这只是伪代码,但您写它的方式是我的方式写的很真实,谢谢你的回复
  • 尝试减少你添加的力量。像 MaxSpeed*0.05f 那应该可以。还要确保没有在其他任何地方设置 rb23D.Velciocity。
  • 它会起作用的。为了您的理解,请查看使用 addForce 与速度对比的统一答案线程:answers.unity3d.com/questions/619186/… 在大多数平台游戏中,您需要设置速度。但是当你保存动量时,比如在冰上时,你可能想要使用力量。
  • 对不起,我已经离开了一段时间,我使用了你的想法,发现是的,速度是在其他地方设置的,并且随着正确,我现在终于在玩家走路时得到一个滑动动作冰感谢使用 AddForce... 但我发现播放器会突然停止四分之一而不是继续,你知道有什么其他方法可以解决这个问题吗?顺便说一句,我的代码很简单 if (iceMovement && TouchingIce) { rb2d.AddForce(new Vector2(move * maxSpeed, 0)); }
  • 我看到您正在将运动的 y 分量设置为零。如果玩家缓慢地向后漂移,并且没有与冰物体碰撞,那么touchingIce 将是错误的。或者第二个对撞机也可以将touchingIce设置为false。顺便说一句 - 如果这确实回答了原始问题,请点击答案上的接受。
【解决方案2】:

冰的诀窍在于,由于它的摩擦力要低得多,它上面的物体比在正常地面上更好地保持动量,所以你希望操纵杆的运动与小加速度相关,而不是直接与速度相关。

我怀疑您可以保留一个变量 oldVelocity 来保持当前速度。然后每次更新,而不是将您的速度更改为等于您的 (move * maxSpeed),只需将 (move * maxSpeed * someSmallFactor) 添加到您的 oldVelocity。调整 someSmallFactor 以适应您尝试模拟的动作。

(当然,在此之后您还必须做一些其他工作,限制您的最高速度,可能会在操纵杆居中时增加摩擦力以减慢玩家的速度等)

【讨论】:

  • 我在这里看到了你的逻辑,谢谢你的回复,我明白你的意思但是我如何将我当前的速度存储到一个变量中,然后在需要时添加到它,我只看过的教程告诉我我编写代码的方式。会是类似于私有vector2 curVel的东西吗? curVel = rb2d.velocity = new Vector2 (move * maxSpeed, rb2d.velocity.y); ....事实上,现在我已经写了两个 '=' 符号 init 看起来很不对。
猜你喜欢
  • 2013-10-22
  • 1970-01-01
  • 2015-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-14
  • 2021-11-18
相关资源
最近更新 更多