[Request]Collision shapes for CapsuleComponent in ACharacter

Hi, we are making not human-like characters, for example you can look at screenshot.
It has not human body proportions, but ACharacter class have CapsuleComponent which can have spherical or cylindrical shape. But we need to use cube shape with scales in x,y,z.
For example collison shown on screenshot not cover all character body, and character always stacking in coners, when it trying to move behind wall.

It would be cool if you can set shape of CapsuleComponent for character.

Tnx

And screenshot:

Zak did you discussed other collision shapes and what is discussion result? Will it be added in short time, maybe next beta release?

Also, i have additional look when i suddenly found in one of udn answers that UE4 API with some code classes uploaded on FTP.

So, my new ideas are next: (will use Rama write style :slight_smile: )

1. The best and the simplest way for all developers

Epic games add blueprintable function SetShape(shape), where shape is box, cylinder, sphere, pyramid maybe. And movement will use shape and extent. (also with rotation)

2. Also it is extend of 1. - CapsuleComponentName

Just to override CapsuleComponentName with UShapeComponent with shape you wish like:
PCIP.SetDefaultSubobjectClass(ACharacter::CapsuleComponentName

3. set UpdatedComponent

CharacterMovement->UpdatedComponent = CollisionBox; or
    CharacterMovement->SetUpdatedComponent(CollisionBox);

where CollisionBox is UShapeComponent subclass.

For now if you will try to set UpdatedComponent you will get:

[   ]LogCharacterMovement:Error: CharMoveComp owned by Default__SM_Enemy_Vehicle must update a capsule component

because:

void UCharacterMovementComponent::SetUpdatedComponent(UPrimitiveComponent* NewUpdatedComponent) 
{ 
 .......
 // check that UpdatedComponent is a Capsule 
        if (Cast(NewUpdatedComponent) == NULL) 
        { 
            UE_LOG(LogCharacterMovement, Error, TEXT("%s owned by %s must update a capsule component"), *GetName(), *GetNameSafe(NewUpdatedComponent->GetOwner())); 
            return; 
        } 

4. Try to write Custom movement component

Custom movement component sublcassed from UCharacterMovementComponent with other SetUpdatedComponent() or maybe some other functions which are virtual But i do not know yet which functions needs to be changed.

I have overrided

SetUpdatedComponent()

and it still returns me capsule component after i set other my own.

Yes, we are discussing it, but there is no timetable yet as to when we might make the change, if at all.

CharacterMovementComponent::SetUpdatedComponent() currently aborts if provided a non-capsule (as you pointed out with the code snippet). There is code in the movement logic that depends on it being a capsule, and that is the main reason for the restriction. To make it support more than just a capsule, there is a significant amount of work required to make those pieces of code more general.

For now I am going to make it more explicit that it only supports a capsule (probably hide the base SetUpdatedComponent function and expose only one taking a capsule), until we revisit it and have a different solution.

I will start up a discussion about whether we could possibly accept other shapes. CharacterMovementComponent currently only accepts vertical capsules as the collision component.

The issue with boxes is that rotation is tricky, since corners may pass through objects between the start and end locations, since sweeps only support initial and end rotations, not sweeps through changes in rotation.

You may be able to extend the CharacterMovementComponent code to sweep something other than a capsule (possibly override MoveUpdatedComponent()) and modify the hit results as a result, but I think you’ll still have issues with rotation since we don’t check collision when rotation changes (not necessary for vertical capsule).

A) You can override the capsule component with any subclass you want to define in a subclass’ PCIP.

B) If you’re using meshes like that, you could use Pawns instead of Characters, as you likely don’t need things like crouching and jumping behaviour that Character provides?

Tnx for answer, Luke.

I wish i have one base class for all my characters to not duplicate functionality.
So, i need to override the capsule component, but i am not sure how to do it right, can you explaine more please? What and where and how to do it?

I can’t tell you how to write your capsule component (that’s up to you of course), but I can tell you how to override it:

  1. Create a subclass of Character (e.g. MyCharacter) for your players / pawns.

  2. In it’s PCIP, you need to do something like this:
    AMyCharacter::AMyCharacter(const class FPostConstructInitializeProperties& PCIP)
    : Super( PCIP.SetDefaultSubobjectClass(ACharacter::CapsuleComponentName)
    {
    }

This will override the original CapsuleComponent type with the one you have defined. Note that CapsuleComponentName is a variable inside ACharacter, not something you create.

You can also do the same with the mesh or movement components if you need to.

tnx
I do not understand how CapsuleComponentName will override CapsuleComponent type i have defined?
What and where set as CapsuleComponentName? UBoxComponent?
sorry, really hard to understand, especially when you do not see parent class code…

first i have tried to do after your first answer:

	Components.Empty();
	CapsuleComponent->DestroyComponent();

	Components.Add(CharacterMovement);

	BoxCollision = PCIP.CreateDefaultSubobject(this, TEXT("MeshBox"));
	BoxCollision->SetComponentTickEnabled(true);
	BoxCollision->SetCollisionResponseToChannel(COLLISION_PROJECTILE, ECR_Block);
	BoxCollision->SetCollisionResponseToChannel(COLLISION_WEAPON, ECR_Ignore);
	BoxCollision->bCanEverAffectNavigation = true;
	RootComponent = BoxCollision;
	Components.Add(BoxCollision);
	Components.Add(Mesh);

	CharacterMovement->UpdatedComponent = BoxCollision;

But Rocket crashed every time i try to spawn actor of this class.

You don’t destroy the component or create a new default subobject, the code I’ve given you is a PCIP definition, not the content of the class.

/** Name of the CapsuleComponent. */
static FName CapsuleComponentName;

This is a variable in ACharacter that lets you override CapsuleComponent with a different class. In the PCIP you call SetDefaultSubobjectClass, and pass it this variable which holds the name of the CapsuleComponent.

Looking at the above, it looks like this forum software can’t handle the syntax. It should look like this (sorry for the confusion):

AMyCharacter::AMyCharacter(const class FPostConstructInitializeProperties& PCIP)
	: Super( PCIP.SetDefaultSubobjectClass(ACharacter::CapsuleComponentName)
{
}

tnx for fast answers.

when i am trying to do like you wrote i get editor crash error at run.

my classes:

UCLASS(abstract)
class ASM_Character : public ACharacter

UCLASS(Blueprintable)
class ASM_Enemy : public ASM_Character

and constructor in class ASM_Enemy

ASM_Enemy::ASM_Enemy(const class FPostConstructInitializeProperties& PCIP) : Super( PCIP.SetDefaultSubobjectClass(ACharacter::CapsuleComponentName) )
{
}

Look like i can not override CapsuleComponentName with UBoxComponent and only can with UCapsuleComponent subclass

Also i have tried to make my own class:

#pragma once

#include "SM_CollisionComponent.generated.h"

UCLASS()
class USM_CollisionComponent : public UCapsuleComponent
{
	GENERATED_UCLASS_BODY()

public:		
	void SetShape();
	
};

and then tried to:

ASM_Enemy::ASM_Enemy(const class FPostConstructInitializeProperties& PCIP) : Super( PCIP.SetDefaultSubobjectClass(ACharacter::CapsuleComponentName) )
{
}

But it did not compiled with many linking functions errors.
And also i really can not imagine what i will do with my class to have it looks similar to box collision shape

If it is possible, i wish to request the simple shape set function for character, it would be nice, because sometimes it is too hard to write something if you do not know how it works, and how it was done in parent classes, and also not all characters are humans or wheeled vehicle, so collision shape for character can be different than cylinder, it can be sphere, cylinder and box.

I have posted thread on forum, maybe some one will help me with this component http://forums.epicgames.com/threads/982247-Help-with-custom-UCapsuleComponent-Writing-own-subclass-to-have-box-collision-shape?p=31783335#post31783335

Since this is somewhat relative to my future interests, I had a go at creating a new pawn type & movement comp that uses box component.

Got the very basics working, though it doesn’t detect rotation penetration unless you are moving as well as rotating… but I’m sure that’s fixable.

Also, the movement component is NOT based the character movement component, so replication would need to be reimplemented.

If you are interested, its on the drop box:

/KrisRigby/Boxy.7z

#A Hybrid Solution

I recommend a hybrid solution that works great for me for my Large Big New Surprise units (forum post on this soon)

#Step 1

Set the collision capsule so its bottom is at the appropriate spot so that the character will collide with terrain at the right height, this is the main role of collision capsule, for landscape and basing.

#Step 2

Disable the capsule collision with pawns via the BP properties of your character

#Step 3

Enable collision for the skeletal mesh of your Character, and set it to physics, making sure collision with pawn is enabled (use custom)

#Step 4

Make physics asset for your Character that is tailored to your unsual body shape


#Summary

Use the capsule only for collision with ground, and replicating basing on platforms,

and use mesh physics asset for the more-important-to-be-precise collision with players and other things

#Not Yet Investigated

I’ve not yet determined how best to handle collisions of this hybrid solution with world geometry that is not on the ground, a good radius for the capsule might be enough

or the physics asset might just work happily for this as is, not sure yet!

#No C++

There is no c++ involved in this solution

Rama