首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Unity3D中的“技术”

Unity3D中的“技术”
EN

Stack Overflow用户
提问于 2015-09-01 06:09:45
回答 1查看 312关注 0票数 0

我正在创建一个FPS,旨在成为一个基于高技能上限运动的观众电子竞技(相当大的嘴巴)。作为这个游戏基于运动的一部分,我想介绍一下Smash中的"teching“。这个动作会打破一个人的跌倒伤害和队列跳跃,但我真正感兴趣的是时机。

如果玩家即将落地,我该如何进行检测?

EN

回答 1

Stack Overflow用户

发布于 2015-09-09 00:24:10

在超级Smash Bros中,teching (breakfall)有三个步骤:

  1. 当你在半空中并处于损坏状态时,你处于一种称为“翻滚”的状态,你可以通过左右滑动模拟杆退出“翻滚”,如果你与任何表面相撞,并在几帧内击中LR,你将你的速度投影到一个平面上,并在持有模拟杆的方向上添加一个速度矢量(对于就地技术来说,速度矢量可以是中立的)。
  2. 在这段时间里,玩家进入“正在训练”状态,除非你关闭另一面墙或暂停,否则无法取消。

多个状态的想法:“落地”,“坠落”,"FastFall",“翻滚”,“技术”立即需要某种形式的Finite State Machine (隐式或显式)。有限状态机是一种设计模式,它可以简化或复杂化您的代码,这取决于您如何使用它们。在这种情况下,我建议通过几个脚本class GroundedBehaviour : Behaviour {}class FallBehaviour : Behaviour {}class TechBehaviour : Behaviour {}创建一个状态机。然后,可以在角色控制器中保留对活动Behavior的引用。请注意重复出现的Behavior部件,而不是MonoBehaviour。我建议研究一下从MonoBehaviourBehaviourComponent继承的区别,因为当您理解这些区别时,它将有助于简化您的代码。

构建状态机后,有四个主要考虑事项:

当玩家的速度在平面上的任意surfaces

  • projection之间发生碰撞时,
  1. 会给玩家增加一些速度,同时他们也会使用技术。

在没有多人游戏的情况下,输入处理可能是最简单的部分,但要知道,任何竞争对手的FPS都会有几个同步的客户端,而且您必须处理将player input发送到其他客户端的问题。

下一个问题是您提出的问题(如何检测玩家是否即将与地面相撞)。这就是与任意曲面碰撞的问题。最简单的解决方案是在FixedUpdate中使用下面这一行

代码语言:javascript
运行
复制
if(Physics.CapsuleCast(lowerPoint, upperPoint, radius, velocity.normalized,
                       out hitInfo, velocity.magnitude * Time.deltaTime))
{
    //use hitInfo.normal to tech
}

有了这段代码,您就有了“何时使用技术”部分,但仍然需要“如何使用技术”部分。

拼图的下一块是将玩家的速度投影到地面上,这是最容易的一块。您只需要一行代码:velocity = Vector3.ProjectOnPlane(velocity,hitInfo.normal);

最后一部分是将技术添加到投影速度上,这意味着你会得到类似这样的东西:

代码语言:javascript
运行
复制
velocity += TechVelAdder(input /*Vector2 from analog stick*/,
                         hitInfo.normal /*Vector3 from the CapsuleCast earlier*/);`

我已经处理过类似于针对任意墙的teching的代码,有很多方法可以做到这一点(其中很多我指的是无限的)。话虽如此,这里有两个很好的方法:

代码语言:javascript
运行
复制
Vector3 TechVelAdder1(Vector2 input, Vector3 normal) //this will always move the player in the direction of the input from a bird's eye view
{
    float techSpeed = 10f;
    float input3D = new Vector3(input.x, 0f, input.z);
    float direction = Vector3.ProjectOnPlane(input3D, normal).normalized;
    direction *= input.magnitude; //preserve magnitude if the player wanted to do an in spot tech
    return techSpeed*direction;
}

Vector3 TechVelAdder2(Vector2 input, Vector3 normal, Quaternion rotation) //this will make the player tech in the input direction relative to what they perceive as forward
{
    float techSpeed = 10f;
    float input3D = new Vector3(input.x,0f, input.y);
    float direction = Vector3.ProjectOnPlane(rotation*input3D, normal).normalized;
    direction *= input.magnitude;
    return techSpeed*direction;
}

如果rotation*input3D部分让您感到困惑,那也没什么,它只是意味着input3D向量应该相对于球员的旋转。那是什么意思?如果球员面朝右,他们想往前走,那就往右走。

祝你好运,希望这对你有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32320711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档