Sword Mechanics for VR

A playable demo of this project can be downloaded here.  You’ll need a SteamVR-compatible setup with tracked controllers.


The lack of force feedback in VR systems is an interesting limitation when it comes to game design.

Many real-world interactions that VR games might like to incorporate only work because your hands don’t always move exactly the way you want them to. Everything from not being able to stick your hand through a table, to having trouble moving around a heavy object, or perhaps contests of strength against other people – all of it results in, and “works” because of, external forces causing things to not go exactly the way we’d like.

Bonk.

For VR, simulating these things directly would require force feedback on a scale that just isn’t available yet, and would also probably be hard to do safely, given that a force-feedback device that could stop someone’s arm would necessarily be stronger than said arm.

The only actually solid things that game developers have to work with are the controllers, and the floor. This allows for some suspension of disbelief – mostly holding and using small, lightweight objects that don’t really run into other things – but for much larger objects, the usual “parent/glue the object to the controller” approach might result in comedy.

I wanted to spend some time working around this problem. I eventually settled on doing something with swords, because:

  • Swords are heavy-ish (~3.5 to 4.5 lbs, roughly 3 or 4 times heavier than Vive controllers). You shouldn’t be able to wave a big one around like an inflatable toy, but they’re still light enough to hold in one hand.
  • Swords are kinda big – one could easily run into / clip through things, and if force is applied somewhere along the blade, there could be a big lever arm against the player’s hand.
  • Swords not following the controller 1:1 would be a necessary component in any “accurate” VR swordplay, against AI or other players.

I figure that if something could make a sword in VR “feel good,” then a very similar something could work well in a more general case.

Current VR Sword Solutions

In most VR games featuring swords or other melee weapons, the weapon follows the player’s controller 1:1. This can result in some comedy, and – since flailing your sword around like a hamster on caffeine is a legitimate strategy – is a bit immersion-breaking if you don’t play on an honor system.


To be fair, if you were strong enough to move a sword this fast and slice through any obstacle like it’s nothing, this would absolutely be a legitimate strategy.

Vanishing Realms has a “block” mechanic – both you, and NPCs, can block sword swings with their own swords or shields. If you block an opponent’s sword with your sword (or a shield), their swing animation stops in a satisfying way – but the same doesn’t apply for your blade. Enemies can “block” your sword, but it just turns transparent / harmless for a bit and continues on its way, still attached to your controller. This works for gameplay, but is a bit unsatisfying.

Another method is to simply make it so whatever sword-like thing you’re holding will never be stopped by another object at all, and instead try to encourage reasonable movement via other mechanics. In Beat Saber, for example, your (royalty-free) lightsabers pass right through everything, but you must cut targets in a specific direction; in Fruit Ninja VR and ZenBlade, you get more points for smooth sweeps that slice multiple fruits, and in the latter, you need to align the sharp edge of your blade with your swing. Several other games that incorporate sword or melee combat (Space Pirate Trainer, Raw Data, Sairento VR, …) work similarly – nothing actually stops your weightless weapon, even if it helps to swing your controller “reasonably.”

Other games – like GORN and Blade & Sorcery – disconnect your controller from the weapon in-game, simulating weight by making heavy objects lag behind the controller if you move too quickly. This does prevent senseless flailing, at the cost of some sense of control for the player, but is easy enough to learn.

Of course, there are probably more and better examples out there.

A Possibly Better Target

In my opinion, a good sword implementation needs to:

  • Not pass through impenetrable things
  • Stop other swords, and be stopped by other swords, no matter what the tracked controller is actually doing
  • Remain under the player’s control
  • Encourage reasonable motion / discourage flailing

There’s a bit of a contradiction in that list – it’s hard to keep a sword strictly “under the player’s control” if it can’t pass through objects in the scene. Some sort of compromise will be needed between accuracy and allowing the player to feel in control.

A New Solution: Springs. Lots of springs.

Instead of the “traditional” method of parenting a sword to a tracked controller and disabling most of its physics, we:

  • Attach an invisible, mass-less, empty “wrist” object to the controller via the normal parent-to-object method
  • Attach the sword to said wrist object with a flexible physics joint, with:
    • Rotational spring/dampers keeping the sword aligned with the wrist
    • Linear spring/dampers holding the sword at the wrist position
  • Leave all rigidbody physics and colliders enabled on the sword

And that’s it! This way, the sword can still interact with / collide with the environment, deflecting if it strikes an object, and pushing harder against it the more it’s deflected.

I was looking forward to coding up a 6DoF spring like this… until I found Unity’s built-in ConfigurableJoint, which does everything I just said and more. It’s probably for the best, but I couldn’t help feeling a little disappointed. Here’s the settings used.

They aren’t joking when they call it “configurable.”

Note that the linear spring force is much, much stronger than the torsion spring force. This makes the sword deflect in angle a lot easier than deflecting in position, causing the tip to “drag” along obstacles – which felt a lot better, IMO.

Stoppable force, meet immovable object.

SteamVR Interaction Implementation

I wanted to take advantage of the very polished Interaction System from The Lab that now comes with the SteamVR Unity plugin, for all of its very polished UI highlighting. Some customization was needed.

The sword itself is a rigidbody with an Interactable component, so the blade will highlight when the player hovers a hand over it. However, when it’s picked up, instead of attaching itself to the controller, a script on the sword will:

  • Instantiate a new SwordWrist object, which is a prefab empty object containing a mostly set-up ConfigurableJoint
  • Attach the sword to the SwordWrist’s ConfigurableJoint
  • Attach the SwordWrist to the hand

Then, in an OnAttachedFromHand callback, the SwordWrist aligns itself with the hand. The visible effect is that the player can grab a sword from any point or angle, and the spring snaps the sword into position.

When the weapon is detached from the hand, the SwordWrist is deleted – removing the joint, and causing the sword (which has been simulated as a proper physics object this whole time) to separate and/or be thrown freely.

Sword-Sword Collision & Strength

Since the sword isn’t anything special in a Unity physics sense – just a rigidbody with a collider on a spring – I whipped up a target dummy and stuck a sword + wrist on it, just to see what would happen if I struck it with another sword.

Some physics timestep & collision tuning later – turns out, Unity does not handle collisions between fast-moving smallish meshes well by default – we have a sword that can deflect blows!

Springy.

While playing around with this, I noticed this use of springs seemed to be almost simulating strength, in a way. For example, if I used the hilt of my sword to push against the tip of another sword, I could deflect it easily, since my “spring” had leverage over the other one; the opposite is true when trying to strike at the hilt of a sword using the tip of mine.

Strength & Endurance

While fiddling around with settings, I observed that the spring constant made for a good “strength” analog; in a contest between two swords, the one with the higher spring constant will usually “win” and push the weaker spring out of the way.

Allowing a sword to deflect on a spring solves the clipping-through-things problem, but it doesn’t model the weight of the sword, or the effort it would take to constantly push on things. However, since strength can be modeled by spring constant – what if the wielder’s “strength” drops as they expend more and more effort?

The idea is that each swordsman would have a pool of “energy,” which recovers over time, but would be drained by things that would require application of force, like:

  • Rotational deflection of the sword (applies spring force)
  • Linear deflection of the sword (applies spring force)
  • Rotational acceleration of the sword
  • Linear acceleration of the sword
  • Gameplay- or stat-related buffs/debuffs (i.e. weaken if hurt)

So, if the player pushes hard against a wall, rapidly strikes at an opponent, or flops their wrist around like a fish out of water, they might rapidly find themselves unable to defend against a stronger strike – or outright not be able to move their weapon as quickly or accurately.

The same goes when attacking or defending against a sword strike. Defending with leverage or other advantage over an attacker causes them to lose strength more quickly than a defender; attacking a weakened opponent means they’re less likely to successfully block.

Demo AI

This strength/endurance system adds a tactical element to swordplay. For example, if a player is defending against an aggressive opponent, dodging strikes or carefully blocking might result in the player gaining a significant strength advantage over a tired attacker.

While a multiplayer version of this system might be very interesting, it also sounds like a massive pain to get working properly with all the precise physics needed. So, I made a couple of simple bots to try things out locally.

The first is a defensive bot, which tries to block strikes by placing the hilt of its sword perpendicular to the tip of the players’, attempting to gain leverage over the attacker:

And a more aggressive bot, which randomly swings through the air in front:

Amusingly, since the defensive bot blocks the nearest sword regardless of holder, I can put a pair of these together and make them duel each other. Fun to watch.

Bit one-sided, really.

Demo Download

A playable demo of this project can be downloaded here. You will need a SteamVR-compatible system with a headset and tracked controllers to play.

About the Author