Hi all,
I have been working on developing some additions to the Unity runtime which will allow bounding boxes to work with Unity's physics engine (Physx, but hopefully later Box2D). Hopefully Nate will be able to pop this work into the official runtimes after further testing. So here is a breakdown of it...
[Jump animation + physics interaction]
What has been implemented so far...
Bounding Boxes are created individually as mesh colliders at a default size/rotation/position relative to a child GameObject representing their parent bone. This GameObject's local transform is then updated relative to the root GameObject each frame, so the collider's geometry/vertices don't have to be updated each frame, allowing the overhead to be minimal. Colliders are enabled/disabled at runtime based on the animation. Collider geometry is checked each time you run the game, so you can be sure any changes you make in the Spine Editor will be reflected in game.
If bounding boxes are not present, then the impact on the runtime performance is minimal. A single boolean is checked each frame. If not enabled nothing happens
The GameObjects which house the Bounding Box colliders are persisted even if you disable Bounding Boxes, remove a Bounding Box from your animation, etc. Instead the colliders are simply disabled and the GameObjects are no longer updated. This is so that you can attach scripts to the GameObjects and not have to worry about losing information associated with those scripts (variables you have set and so on). You can then decide what to do with those scripts before deleting the unwanted GameObjects for yourself from the heirarchy.
It is very simple to toggle on/off all Bounding Box collisions. Yous simply disable/enable a script which sits on the root GameObject next to SkeletonComponent.cs/SkeletonAnimation.cs called SkeletonCollisions.cs. Easy peasy
. You can also override (turn off) individual Bounding Box colliders if you would also like to do so.
A Rigidbody is attached to the root GameObject, allowing for all of the Bounding Boxes to form one large collider. Collision scripts can be attached to the root and still detect which Bounding Box collider actually intersected. This also means that Bounding Boxes which intersect other Bounding Boxes of the same animation will not trigger collisions. However, one can attach Rigidbodies to the child colliders to allow collision scripts to be associated with those colliders only and this is required to mix trigger and non-trigger Bounding Boxes, as well as allow for triggers to provide information on with Bounding Box was triggered in the collection of Bounding Boxes forming the collider (not present when using Triggers
).
Good news aside though, there are a few issues associated with the implementation
Issues...
Currently, you can specify concave Bounding Boxes in the Spine Editor, and rightly so. However, in Unity (and most physics engines) concave colliders will not collide with other concave colliders. Therefore, I have started trying to look into Optimal Convex Decompositions and how I can go about breaking down concave Bounding Boxes into multiple convex polgons, which will sum up to represent the initial concave shape.
Carrying on from 4. above, the introduction of individual Rigidbodies per Bounding Box creates issues. They introduce more overhead (more Rigidbodies) as well as allow Bounding Boxes which intersect other Bounding Boxes of the same animation to trigger/collide with each other. This could be overcome by modifying the layer collision matrix so certain layers can't collide in Unity and specifying different layers for the Bounding Boxes in an animation. However, you only have 30 or so layers to fiddle with and you don't want to end up with two different skeletons not colliding/triggering through trying to avoid self collision.
The Bounding Boxes are created using Mesh Colliders. These are the most expensive physics collider in Unity, and may well destroy the speed of mobile games for example. It may be better to try and approximate the Bounding Boxes with a collection of Box Collider primitives, which are much faster for physics computations. However writing an algorithm to do this is going to be tricky. See the image below which touches on this.
I'm looking into automating the approximation as best I can with an algorithm, but for now will probably just provide an option for the user to create n number of Box Colliders in child GameObjects to approximate the Bounding Box shape and position/rotate/scale them by hand. This will obviously be optional to the existing Mesh Colliders created and will disable those mesh colliders while enabled. The parent bone GameObject will be transformed as necessary every frame, and the child Box colliders will automatically inherit the new scale/position/rotation so the overhead should still be minimal.
- Finally, you have to provide a depth for the Mesh Colliders created otherwise Unity throws a wobbly. This means that you cannot have a depth of zero
. This is not configurable just yet, but will be very shortly. I am pretty sure this won't become an issue with the introduction of Box2D.
And so...
Hopefully support for Box2D, when implemented in Unity, will be simpler to add than stooopid PhysX. Box2D is obviously more suited to what I imagine most Spine users will need (being 2D and all). However it is always good to provide support for both, as some people (like me) may need 3D physics in their game.
Anyway, I'm not going to make the code available right now, and instead I will be sending it to Nate for review when finished and hopefully integration into the Git Repository.
If anyone has any thoughts or suggestions then post them here and we can all have a chat about how to continue and improve this. Spine is awesome, so lets support these guys and help them make it even better!
Rob