Weird comportment with my atempt of a physics based items equipment systeme

Hello there,

I have a bit of a probleme with my blueprints logic involving physic based actor. I have an item BP that a character can pick up. When he does, the item is attached to the player mesh and physics and collision are deactivated by a function and reactivated by another when the item is dropped.

Now the weird thing is that I observed two different results in this item comportment depending on if ‘‘simulate physics” is activated directly in the detail pannel or is activated in game.

If physics is enabled in detail panel, then when the item is picked and physics disabled by my function, the item stay in place, floating in the location where it has been transformed to, and don’t follow the player .

If physics is not enable from detail panel, the item can be picked, physics disabled by my function, follow the player is attach to. When I dropped it, physics is re-enable and nothing weird happens, the item comportment works has intended.

I don’t really understand why that is, and I need the object to have physics activated before player picks it.

I tryed something different by using the physics handle component, but its not really what I’m looking for, the point is to pass from an item in LVL that have physics and can be picked, attach to player as a “static object“ in a sens, and resimulate physics when dropped. Since it works when physics is not directly activated in detail panel, I have the feeling that I just missed something.

My DeactivePhysics function:

My ActivatePhysics function :

The part of my actor component managing spawning actor and attach it to character mesh by bone name :

I hope I gave enought precision, if not, feel free to ask. Any help would be greatly appreciated !

Hi there,

This is an interesting question for me also so thanks for it. Good observation, never encountered it before.

Edit :
Actually wrote a lot of suggestions before but editing now since I think replicated the issue and found reason. This happening because the actor’s RigidBody is not default root probably under a scene component. Make it root and think it will work.


to
image

Why happenns, after actor’s set simulated since its not the root, simulated object detaches not hierarcy wise but physics solver takes over. Actor is there root scene component there but they are ignored. When we stop simulating the physics ofcourse it doesn’t snaps back but stays where ever its in the world. If we get the root component and make sure their transforms are same and then we do whatever attachement / transform it will work.

Attach Simulated (false) component to Actors Root.

Or ofcourse you can just get Actor’s Component Simulated (false) and attach to your component too.

On deeper level there should be some kind of mismatch / desync maybe so I will make further investigation around it.

Hope this works and let me know.

Edit 2:

So I check and actually its what I suspected and here is the comment by Epic

// So the primitive component when you check the details panel bool calls this.
void UPrimitiveComponent::SetSimulatePhysics(bool bSimulate)
{
	BodyInstance.SetInstanceSimulatePhysics(bSimulate);
}

// This calls a core function found over here
	ENGINE_API void SetInstanceSimulatePhysics(bool bSimulate, bool bMaintainPhysicsBlending=false, bool bPreserveExistingAttachment = false);


// Comment by Epic basically saying we break / detach from parent if bPreserveExistingAttachment not set true.

	/** 
	 * @param bPreserveExistingAttachments If true then any existing attachment between the owning component and 
	 *        its parent will be preserved, even when switching to simulate (most likely useful for skeletal meshes
	 *        that are parented to a moveable component). If false then the owning component will be detached 
	 *        from its parent if this is the root body and it is being set to simulate.
	 */

// If we say true in the execution of it basically it will also carry the actor with it. This seems like a design choice which makes sense kinda. However this can be also exposed to designer atleast or with a special function. 

//So basically I did that without modifying the code created a BlueprintFunctionLibrary and wrapped this function.

MyPhysicsLibrary.h

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyPhysicsLibrary.generated.h"

/**
 * 
 */
UCLASS()
class VACUUMGUNPROTOTYPE_API UMyPhysicsLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
public:

	UFUNCTION(BlueprintCallable, Category = "Physics", meta=(DefaultToSelf="SimComponent", CompactNodeTitle="Custom Physics Simulate"))
	static void SetSimulatePhysicsWithAttachment(UPrimitiveComponent* SimComponent, bool bSimulate, bool bPreserveAttachment = true);
};

MyPhysicsLibrary.cpp

#include "MyPhysicsLibrary.h"
#include "Components/PrimitiveComponent.h"
#include "PhysicsEngine/BodyInstance.h"

void UMyPhysicsLibrary::SetSimulatePhysicsWithAttachment(UPrimitiveComponent* SimComponent, bool bSimulate, bool bPreserveAttachment)
{
	if (SimComponent)
	{
		if (FBodyInstance* BI = SimComponent->GetBodyInstance())
		{
			BI->SetInstanceSimulatePhysics(bSimulate, false, bPreserveAttachment);
		}
	}
}

Go inside the Actor, change nothing leave with parent scene component, didn’t check simulation true from details but used this function at begin play.

Detail : This should work as expected without creating this strange behaviour.

So if its really important for your case you can just create a C++ class from editor or IDE wrap this or directly copy paste .h .cpp with correct api and you can use this.