Just checked this out and looking good great work - ābutā I have a little problem when using the āPluginā.
I can install and activate the plugin fine, when I select the Tegcar in the Default Pawn Class and then press play the game/engine instantly crashes and restarts ??
Any ideas ?
++Update - Fixed, recompiled to the version I was running 4.10
Iāve started working on a component based approach for my custom tanks. To handle physics sub-stepping Iām building a scaffolding where I have a āphysics controllerā component which is responsible for gathering all physics related interactions and applying forces to necessary bodies. The rest of components, such as suspension, wheel, engine and etc. are left to be implemented in blueprints (they can be done in c++ but itās not necessary). After reading some post here and there and see that blueprint functions can be called from C++, so this part is fine. The one part that is missing is getting a proper transform and velocities during sub-stepping from blueprints. Do you know if itās possible to access FBodyInstance of the static mesh component from blueprints?
The whole logic with components is rather simple. Letās say we have a c++ component VMK_PhysicsController (child of USceneComponent) and c++ interface VMK_PhysicsUpdate. In addition to this, we have a custom blueprint component VMK_Suspension which implements VMK_PhysicsUpdate interface. The idea is that VMK_Suspension never calls anything like AddForce() by itself, it has all code to calculate amount of force and location of application but never calls AddForce by itself. This is the role of VMK_PhysicsController, which uses VMK_PhysicsUpdate interface to run component specific physics calculation code and getās something like [ForceVector, ForceLocation, ComponentRefereceToApplyPhysicsTo] structure in return. Pseudo code looks like this:
struct sRemoteForce{ //structure which holds results of custom physics calculations
FVector ForceVector;
FVector ForceLocation;
SceneComponent ComponentReference;
}
// VMK_PhysicsUpdate Interface
GetForceToApply(){ //method which needs to be implemented by VMK_Suspension component in blueprint
return sRemoteForce;
}
//in VMK_Suspension blueprint component we have something like this
[Implements VMK_PhysicsUpdate]
GetForceToApply(){
FVector ForceToApply = ForwardVector * GetSpringLength() * SpringStiffnes;
FVector LocationToApply = GetWorldLocation();
SceneComponent ComponentToApplyTo = (SceneComponent) ChassisComponentReference;
return [ForceToApply, LocationToApply, ComponentToApplyTo]
}
//finally VMK_PhysicsController just iterates over all components which implement VMK_PhysicsUpdate interface
UpdatePhysics(){
VMK_BaseComponent] VMK_Components = GetComponentsWhichImplementInterface(VMK_PhysicsUpdate);
For each VMK_Components{
sRemoteForce remoteForce = VMK_Components.item->GetForceToApply(); //this is where component specific physics code done in blueprints is executed
remoteForce.ComponentReference.AddForceAtLocation(remoteForce.ForceVector, remoteForce.ForceLocation);
}
}
When VMK_Suspension executes GetSpringLength() method it obviously needs a āsub-stepping safeā transform of some other components, for this purpose FBodyInstance transform can be used. I donāt think I can access it directly from blueprints but perhaps I can add few methods into VMK_PhysicsUpdate C++ component which can do that for me.
Iāve also been wanting to make my custom vehicle movement component with options for addons such as turbo , variable valve technology , etc (ended up doing sounds lol)
When you access mesh component from blueprint, you already have same transform as BodyInstance as itās synced for each Tick. The reason why you need to use BodyInstance in substepping is because you need the data more often than once per Tick.
Also as substepping is running on a separate thread, you canāt easily access individual substeps from blueprints so youād still need to do those physics calculations on the c++ side and just feed necessary parameters from blueprints. You can for example calculate and apply all the forces and velocities on c++ side and bring them over your BP if you need those values to do something there, just donāt try to do it the other way around.
As a side note, I know you said the code you posted was pseudocode, but if you run it using custom physics delegate (to run it on each substep), set bAllowSubstepping to false (optional parameter on AddForce and AddForceAtLocation). Ori also mentioned this briefly here: Physics Sub-Stepping - Announcements - Epic Developer Community Forums
edit-> I reread what you wrote and you said you could execute BP from c++ (which I wasnāt even aware that was possible). To be honest, even if possible I wouldnāt consider it as it makes very little sense to do CPU intensive things on BPs when you already use both.
Completely agree regarding performance, but practically I see a lot of cases where physicsā math in components is relatively simple. Something like an air drag component is just 1/2V^2RoSDs, which fits into a single math expression and so much easy for people to build in BP without touching C++. Thatās kind of the point of design - to have just a few components written in C++ and the rest keep in BP as long as performance impact is negligible.
I donāt even know if it will work Iāve just found few post like this: https://answers.unrealengine.com/questions/214147/grand-unified-cblueprint-cast-interface-explanatio.html which explain how BP code can be called from C++.
I guess the easiest way for BP code, executed from C++, to see FBodyInstance transform is by adding few methods into C++ based components which would retrieve FBodyInstance from SceneComponent reference and pass it to BP. I mean itās not really passing transforms, itās more like, letās say we want to find a distance between two arbitrary components.
//Normally in BP we would do it like this:
VectorLength(Comp1.GetWorldLocation() - Comp2.GetWorldLocation())
//But here we would take a bit more complicated rout, which potentially works with sub-stepping:
Comp1Pos = VMK_PhysicsController.GetLocationByReference(Comp1);
Comp2Pos = VMK_PhysicsController.GetLocationByReference(Comp2);
VectorLength(Comp1.GetWorldLocation() - Comp2.GetWorldLocation());
//where VMK_PhysicsController.GetLocationByReference() would do something like this:
GetLocationByReference(ReferenceComponent){
RefComp = Find component by reference(ReferenceComponent); //
RefLocation = RefComp.FBodyInstance.Transform.Location();
return RefLocation;
}
I do get what you are after here for trying to stick with BP, I just donāt know if itās that easy to get working. This would make even more sense in the future as BP speed will improve after epic gets their BP to C++ conversion tool done (my guess would be 4.13+).
The issue we have is not just calling BP from c++, itās also about substepping running on that other thread. I actually forgot about this but Iāve done BP events that fire from c++ side in the past, I just donāt think it would work with substepping. You can read more about this from here: A new, community-hosted Unreal Engine Wiki - Announcements - Epic Developer Community Forums
Well, the good news is that I actually tried this now and it actually works! You still canāt handle anything but physics on your substep event but itās ok for this purpose Bad news is that it only seems to work for actor/pawn/player controller, at least I couldnāt make it work for example on actor component but I may have missed something. Iāll try few other things and post some code snippets for this later on.
Unzip it somewhere, right click the .uproject and generate Visual Studio project files. After that, launch from VS and you should see a similar example I gave earlier, except this time itās done almost completely on blueprints. Itās bit hacky and it still needs some rigidbody at the root of the Pawn but you get the idea. Pawn is currently only thing implemented on c++ and itās then inherited to BP.
You probably could do it on actor component if you figure out how to send the physics tick event from there. Pawn doesnāt calculate any forces in any way, it just creates the event and passes things like AddSubstepForce and GetSubstepTransform. Do note that you can use regular AddImpulse directly from BP as it executes only once. You need to call those AddSubstepForces manually because you canāt pass that false-flag to a regular AddForce on BPs (regular AddForce would send additional AddForces to physx on each substep that would carry on until next tick starts).
Basically what my example does is that it adds that custom physics delegate to that root rigidbody and when the custom physics gets executed, it triggers Physics Tick event which you can then use from BP side. Hereās a screenshot of it:
Just remember to do all debug draws and actual mesh movements on regular tick, only deal with physics on physics tick. Even line trace debug setting will make Unreal Editor crash!
edit-> cleaned up the project a little, updated project link.
As an additional note, breakpoints on sub-stepped part of the BP graph seemed to freeze my Unreal Editor, so thatās probably out of the question as well.
Looking through the code. If I understand correctly, the only reason you need to bind delegate inside of the pawn is to know when sub-step physics update starts using itās root body and from that point you can call AddForce() and etc. on any component of your pawn. The only limitation of this setup Iām aware of is that components which you can build in BP canāt receive events, but this is easy to overcome by receiving event in Pawn and then just calling something like MyComponent->UpdatePhysics() function in a loop for all components.
This is really cool! So there is no need in any sort of āphysics controllerā component, all what is needed is a custom pawn class and being careful to call sub-step specific AddForce() and GetTransform() in components logic. Iām going to try it when I get home!
Sounds about right. That example calls custom physics delegate when actual sub-stepping occurs for the Primitive Component (any mesh or shape will do) which you have on the Pawnās root. Code is bit messy because I added additional calls for adding forces / reading transforms from other attached components than the one in root, so thereās lots of duplicates. You can clean those away if you donāt need that kind of functionality, I just put everything I could think would be useful there. The functions that are used for the root component are bit more efficient as they cache the main BodyInstance and Transform which get used often (saves reusing getters all over again on same physics tick).
BP on that extended example is also a bit of a mess as I just kept building it from scratch to suit this kind of workflow better. Basically I tried to build it so, that thereās a BP struct array which contains all the live data you need / can access from each suspension element. That way you can read the ray traced position, on ground bool, hit normal etc on regular tick from there and for each wheel. That extended example also contains some changes to functions on c++ side, I cleaned it up little more to follow the way epic has done the same things so I recommend to take a look at that instead of the first example.
I usually donāt comment the code that much, but I guess some explanations could help if things are not obvious. Thereās usually a separate c++ function for calling the same thing for Root/Pawn vs component like AddSubstepPawnForce vs AddSubstepForce (I donāt like the naming convention I made in the middle of the night so you could want to rethink those). Anyway brief explanation for each:
These three work only on physics tick as they carry on the force only until next sub-stepping occurs:
AddSubstepForce - Adds Force.
AddSubstepForceAtLocation - Adds force at Location which is presented in world space.
AddSubstepTorque - Adds Torque.
These two can be used everywhere:
GetSubstepTransfrom - Get transform straight from BodyIntance so itās up-to-date even on sub-steps.
GetSubstepLocationWithOffset - Get offsetted location in world space using BodyInstance. Offset is in local space so you can use components Relative Location for it. Useful for getting components location in world space without any math on BP side as you canāt use components own function calls for this (as they are updated only once per Tick).
BodyInstance getter is only for internal c++ use as you canāt expose BodyInstance to the blueprints as is.
That setting is only meant to be used if you use substepping and apply AddForce from regular Ticks (that boolean also defaults to true). As AddForce only carries the force until next physics step, it needs to handle it bit differently in case where you call it only on regular Tick but still have more physics steps. Without substepping your physics step is same a regular tick on most cases.
I know it sounds the opposite, but itās been in the engine before we could do custom physics delegates on each substep. This whole approach is bit of a hack in my opinion as physics engine interface on UE4 hasnāt been designed for this kind of a use. Thatās also the reason why we have variables like this that donāt make much sense at first.
Ah I see now . Iām working on a Kit for the marketplace and applying forces each tick + sub-stepping enabled is doing the trick without any performance drop (40 AI-driven vehicles 60fps).
From my experience it helps only with collision and physics constraints, anything you calculate yourself in Tick() gets very little benefit from sub-stepping. The whole point is to do calculations of your forces INSIDE of each sub-step.
To see if your setup benefits from sub-stepping lower your fps artificially and see if it still behaves normally. Something like dampener in suspension calculation, can heavily dependent on delta time and when you tweak it to work nicely at 60 fps donāt be surprised if you get completely different behavior at 30 fps. By doing calculation inside of the sub-step you guarantee that your physics update has more or less the same frequency, regardless of how many FPS you get from rendering.
Im using an old pc for that , and all is working great at 25 fps.
One other tip , instead of using tick , you can use a looping timer with 0.008 interval.
If you plan to sell that kit, you need to make sure it actually works well for all kinds of hardware or youāll have lots of disappointed customers.
edit-> seems like I misunderstood your comment, sorry about that. Apparently you do actually test this using two different computers. Iād still check it would work even at 10fps, just in case.
Issue is not being able to do enough calculations, you can loop through as many calculation rounds as you want even on regular tick or timer or whatever is your way of doing it. Issue is that you donāt get real-time data back from physics engine unless you get access to those physics steps directly. Unreal by default updates physics scene to regular objects only once per Tick, so even if you do ask for component locations from BP faster than regular Tick occurs, you can only read the value that was synced to that component on previous Tick.
You can do it from console using āt.maxfps 20.0ā.
Iāve tried timer for tanks, it doesnāt really work because AddForce() is not executed immediately. Actors/pawns tick before physics, all calls to changing physics state of the components is processed after the tick.