Character Customization Via Morphs + Dynamic Collision?

Is this possible in UE5? From what I’ve researched, it seems like you can’t alter Physics Assets at run time.

In my use case, I have a physically animated character with a Physics Asset built up of primarily spheres. Adding character customization to this via morphs is fine, but then how would I update their collision shape to accommodate morphs like body weight etc?

Is there a recognized or known solution to this problem?

You don’t.
Its not a problem anyone cares about.

And you are overthinking it.

A character doesn’t need collisions that accurate.

And when you do something stupid like making them accurate, you realize pretty quick that you just prevented your player base from passing through a door because their fat ■■■ hits it.

Customization generally affects bones set to stretch, not morphs.
Morphs are generally reserved for runtime needs.
Think getting buff or fat while you play more than customizing the way you look in a character creation section.
The bone scale will generally affect linked capsules providing some changes to a phat asset - which are also pointless.

You test hits against specific meshes, not against a phat asset…

Thanks for the response, due to the nature of my project, the problem I described is exactly what I need. It’s not over thinking. In my current project, collision accuracy is a major factor in the end result. I don’t think you can get the level of quality in character customization that I’m targeting with simple bone scaling. It would look beyond subpar.

Perhaps if I created an entirely new rig with bones specifically for customization and limb scaling. But that’s not an avenue I can go down due to an already existing rig we rely on.

I was able to create a system like this from scratch in Unity via custom code, but I’ve not had similar success in UE5 as I’m still getting acquainted with their systems.

So to my original question, is this possible in UE5? The simple requirement is the resizing of physics colliders at runtime.

#pragma once

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

enum class ECollisionShapes : uint8
	FKSphereElem  UMETA(DisplayName = "Sphere"),
	FKBoxElem UMETA(DisplayName = "Box"),
	FKSphylElem UMETA(DisplayName = "Sphyl"),
	FKConvexElem UMETA(DisplayName = "Convex"),
	FKTaperedCapsuleElem UMETA(DisplayName = "Tapered Capsule")

class YOUR_API UCustomizeFunctionLibrary : public UBlueprintFunctionLibrary
	static void SetCollider(USkeletalMeshComponent* Mesh, FName BoneName, ECollisionShapes Shape, float Radius, float Radius2, float Height, FTransform PassedInTransform, int32 PrimitiveIndex = 0);



#include "CustomizeFunctionLibrary.h"
#include "PhysicsEngine/PhysicsAsset.h"

void UCustomizeFunctionLibrary::SetCollider(USkeletalMeshComponent* Mesh, FName BoneName, ECollisionShapes Shape, float Radius, float Radius2, float Height, FTransform PassedInTransform, int32 PrimitiveIndex)
	UPhysicsAsset* PhysAsset = Mesh->GetPhysicsAsset();

	if (PhysAsset != nullptr) {

		bool bPassPACheck = false;
		bPassPACheck = (PhysAsset->BodySetupIndexMap.Find(BoneName) != nullptr);

		int32* boneIndex = PhysAsset->BodySetupIndexMap.Find(BoneName);

		if (bPassPACheck) {

			FKAggregateGeom aggGeo = Mesh->GetPhysicsAsset()->SkeletalBodySetups[*boneIndex].Get()->AggGeom;
			if (Shape == ECollisionShapes::FKSphylElem) {				
				if (aggGeo.SphylElems.IsValidIndex(PrimitiveIndex)) {
					aggGeo.SphylElems[PrimitiveIndex].Radius = Radius;

			if (Shape == ECollisionShapes::FKSphereElem) {
				if (aggGeo.SphereElems.IsValidIndex(PrimitiveIndex)) {
					aggGeo.SphereElems[PrimitiveIndex].Radius = Radius;

			if (Shape == ECollisionShapes::FKBoxElem) {					
				if (aggGeo.BoxElems.IsValidIndex(PrimitiveIndex)) {
			if (Shape == ECollisionShapes::FKConvexElem) {	
				if (aggGeo.ConvexElems.IsValidIndex(PrimitiveIndex)) {				

			if (Shape == ECollisionShapes::FKTaperedCapsuleElem) {
				if (aggGeo.TaperedCapsuleElems.IsValidIndex(PrimitiveIndex)) {
					aggGeo.TaperedCapsuleElems[PrimitiveIndex].Radius0 = Radius;
					aggGeo.TaperedCapsuleElems[PrimitiveIndex].Radius1 = Radius;
					aggGeo.TaperedCapsuleElems[PrimitiveIndex].Length = Height;

			Mesh->GetPhysicsAsset()->SkeletalBodySetups[*boneIndex].Get()->AggGeom = aggGeo;

The convex mesh would need more work but it is possible.
You would need to extract the passed in shape data, extract the vertex data from the render data and then reconstruct the mesh to the convex mesh.


If you would want to add and delete them dynamically you can access the array from the aggGeo index array element to remove parts, or to add just access the while array aggGeo.SpecificShape.Add()


FKSphylElem el;
el.Radius = 5;
el.Length = 10;

if collisions don’t register then maybe it would require
Mesh->UpdateBoneBodyMapping(); or Mesh->RecreatePhysicsState();

You can also use the physics asset override if the mesh is known. (Runtime phys asset swap)

Or you could just use the mesh for hits directly?