Update
Added “static friction lock” functionality which prevents vehicle from sliding on slope. Tried couple of different approaches and one which spawns a breakable physics constraint finally works. I don’t remember who exactly suggested it first, I think it was [MENTION=252207]Black Phoenix[/MENTION].
With generous help of @0lento made a small function that allows to set physics constraint as breakable, programmatically from BP. For some reason setters are not exposed to BP and it wasn’t trivial on how to apply new settings, just setting their values does nothing.
For now, most of the implementation is in BP and two vehicles have this feature: 4WheeledVehicle and LightTankTraceWheelsWithAnimBP (T-26 in the main level).
I’ll use BP of tank highlight changes which where made:
Friction component’s physics update now returns a boolean to indicate if static friction was achieved during calculations, while wheels/tracks weren’t rotating. Points which achieved such state are counted.
Then we check if all or more than 80% of all friction points have achieved such state and advance a simple timer to make sure that lock is not engaged immediately but takes a second or two:
In case if not enough points achieved static state, like if user pressed on throttle and wheels started to spin, then we destroy constraint if it was already made:
If we pass timer check then constraint can be made, but first we calculate a sum of all friction limits on points. Friction limit is a normal force multiplied by static friction coefficient, if more than this amount of force is applied to an object then object should start to move. So we need our locking constraint to be breakable and use total friction limit as breakable force threshold:
When constraint is broken on PhysX level it gets deactivated but UE4 component stays alive. Which means we need to track OnConstraintBroken event and destroy component. For this reason, creation of constraint had to be moved into CustomEvent, so we can bind some logic to OnConstraintBroken.
New constraint component is added when CreateStaticLock custom event is called:
Custom function is used to set constraint as breakable and logic to destroy constraint when it gets broken is added:
The end result is rather simple, if you posses 4WheeledVehicle or LightTankTraceWheelsWithAnimBP, after enabling debug mode (Shift+Alt+D) you will see on-screen messages when lock is activated or destroyed:
Applying larger enough force, as a result of colliding into vehicle, will automatically break constraint. In my tests, constraint was broken at the instant of collision so you don’t even notice that constraint was even there.
In case of tank I had to set logic to check if 80% percent of friction points are in static case because with many wheels and not equal distribution of weight, some points can stay in kinematic case just because they don’t support enough weight. Raising static friction coefficient can solve this too, but it has a direct effect on vehicle handling. In this case, lowering amount of contacts that need to be in static state is a better compromise.
Unrelated change - switched suspension of LightTankTraceWheelsWithAnimBP to use sweep shapes and it restored it mobility, it can drive over all obstacles again.
Latest version of MMT Content is on github and new version of MMT Plugin will be uploaded shortly.
@MagnusAnder let me know how this fix works for you. It's quite possible that I've missed some test cases.