How To Create A Sticky Character?

i want to make a game like “Katamari” or The One Im About To Talk About “The Wonderful End Of The World”
TWEOTW is a 3rd person arcade katamari clone where you play as an marionette here’s a trailer to get the point: The Wonderful End of the World - Trailer - YouTube
the point is i want to remake the game but i don’t know how to make things stick and not the level
help?

Generally how to get things to stick to your character is by attaching the things you want to stick with AttachComponent.

I would do it in three steps:

  • On Collision find out if the colliding object should stick e.g. by checking for a tag, or a type or the colliding object beeing physically simulated)
  • Find the point you want to stick it to
  • Stick it to the character by attaching it

Looks then something like this:

Did that with this code:
StickyComponent.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "StickyComponent.generated.h"


class USkeletalMeshComponent;
class UCapsuleComponent;

UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class ANSWERHUBANSWERS_API UStickyComponent : public UActorComponent
{
	GENERATED_BODY()

public:	
	// Sets default values for this component's properties
	UStickyComponent();

protected:
	// Called when the game starts
	virtual void BeginPlay() override;

	UFUNCTION()
	void OnActorHit(AActor* SelfActor, AActor* OtherActor, FVector NormalImpulse, const FHitResult& Hit);
	bool CanStick(AActor* actor) const;
	FVector GetAttachLocation() const;
	FName GetClosestBone(const FVector& LocationInQuestion) const;

	UPROPERTY()
	USkeletalMeshComponent* OwnerSkeletalMesh;

	UPROPERTY()
	UCapsuleComponent* OwnerCapsule;
};

StickyComponent.cpp

#include "StickyComponent.h"
#include "GameFramework/Character.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/CapsuleComponent.h"

UStickyComponent::UStickyComponent()
{
	PrimaryComponentTick.bCanEverTick = false;
}

void UStickyComponent::BeginPlay()
{
	Super::BeginPlay();

	auto* OwnerAsCharacter = Cast<ACharacter>(GetOwner());

	OwnerSkeletalMesh = OwnerAsCharacter->GetMesh();
	OwnerCapsule = OwnerAsCharacter->GetCapsuleComponent();

	// Register component to receive actor hit (collision) events
	OwnerAsCharacter->OnActorHit.AddDynamic(this, &UStickyComponent::OnActorHit);
}

void UStickyComponent::OnActorHit(AActor* SelfActor, AActor* OtherActor, FVector NormalImpulse, const FHitResult& Hit)
{
	if (CanStick(OtherActor))
	{
		auto* Owner = GetOwner();

		OwnerCapsule->IgnoreActorWhenMoving(OtherActor, true);

		auto* rootAsPrimitive = Cast<UPrimitiveComponent>(OtherActor->GetRootComponent());
		if (rootAsPrimitive)
		{
			rootAsPrimitive->SetSimulatePhysics(false);
		}


		auto AttachLocation =  GetAttachLocation();
		OtherActor->SetActorLocation(AttachLocation);
		FName BoneNameToAttachTo = GetClosestBone(AttachLocation);
		FAttachmentTransformRules AttachmentRules{EAttachmentRule::KeepWorld, true};
		OtherActor->AttachToComponent(OwnerSkeletalMesh, AttachmentRules, BoneNameToAttachTo);
	}
}

// Find out if hit object can stick 
// As an example I used a tag to identify any stickable objects
bool UStickyComponent::CanStick(AActor* actor) const
{
	return actor->ActorHasTag("StickAble");
}

// Find the location to attach your object to
// As an example I get a random point on the skeletal mesh
FVector UStickyComponent::GetAttachLocation() const
{
	FCollisionQueryParams Params;
	FHitResult Hit;

	FVector EndPoint = OwnerCapsule->GetComponentLocation();
	FVector RandomStart = EndPoint + FMath::VRand() * OwnerCapsule->GetScaledCapsuleHalfHeight();

	if (OwnerSkeletalMesh->LineTraceComponent(Hit, RandomStart, EndPoint, Params))
	{
		return Hit.ImpactPoint;
	}

	return EndPoint;
}

// Since I wanted to attach to the skeletal mesh
// I also wanted that the object animates with the skeletal mesh
// to achieve this i need to attach the object to the closest bone 
// to my attach location
FName UStickyComponent::GetClosestBone(const FVector& LocationInQuestion) const
{
	TArray<FName> BoneNames;
	OwnerSkeletalMesh->GetBoneNames(BoneNames);

	FName ClosestBoneName = NAME_None;
	float ClosestSquaredDistance = -1.0f;
	for (const auto& BoneName : BoneNames)
	{
		auto BoneLocation = OwnerSkeletalMesh->GetBoneLocation(BoneName);
		float SquaredDistance = FVector::DistSquared(BoneLocation, LocationInQuestion);
		if ((ClosestSquaredDistance < 0.0f) || (SquaredDistance < ClosestSquaredDistance))
		{
			ClosestSquaredDistance = SquaredDistance;
			ClosestBoneName = BoneName;
		}
	}

	return ClosestBoneName;
}

Made a small example on GitHub:
[GitHub Repo][2]