Hello,
I am trying to implement a custom character movement component for my video game framework plugin that I’m developing for Unreal Engine. I am trying to hide all of the walking, jumping, crouching, flying, and swimming options, as I want to provide my own system for customizing these values.
The reason is that along with this custom component I am also implementing a prone system and a blocking system, both of which will have speed modifiers applied to them that I need to allow the developer to edit.
If I was to just add the values and not even bother trying to at least make the panel look good, however, then these values may look out-of-place. For example, Max Walk Speed Crouched would be in its normal spot, but if I add “Max Walk Speed Prone” and “Max Walk Speed Blocking”, those will end up all the way at the bottom of the list, which just looks funny and like it was slopped together. Additionally, if I wanted to use ratios instead of a hard CROUCH, PRONE, BLOCK, etc., value, that wouldn’t work either - again, it would look out-of-place.
As such (I hope this has been clear so far XD), I am looking for a way to do one (or several/all) of a few things:
- Remove the details panel for the component entirely
- Remove the “Walking”, “Flying”, “Swimming”, etc., categories from the details panel entirely
- Insert properties between existing ones declared in the parent header file
All of these, by the way, without modifying source code.
Solutions I have already tried that did not work:
- I have tried to use the
HideCategories
tag on my component’s UCLASS() setting as shown below:
.h file
// Copyright Rapidfire Computer Entertainment. All rights reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "CF_CharacterMovement.generated.h"
//=============================================================================
/**
* This custom Character Movement Component handles movement logic for the associated character owner.
* It supports various movement modes that you will likely need or use for your game.
*
* Networking is fully implemented, with server-client correction and prediction included, as per the default component.
*
*/
UCLASS(hidecategories=("CharacterMovement: Walking|CharacterMovement: Jumping"))
class CONNIPTIONFRAMEWORK_API UCF_CharacterMovement : public UCharacterMovementComponent
{
GENERATED_BODY()
UCF_CharacterMovement(const FObjectInitializer& ObjectInitializer);
};
The issue here is that it outright refuses to work. I did fix the “Jumping” category, by the way, to “Character Movement: Jumping / Falling” instead of “CharacterMovement: Jumping”, but it still doesn’t work.
Below are the header files and the constructors for both my Custom Movement Component and my Custom Character Class. Character class header is a decent chunk so I will only include constructor for that, but if you need to see the header, don’t hesitate to ask.
.h (component)
// Copyright Rapidfire Computer Entertainment. All rights reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "CF_CharacterMovement.generated.h"
//=============================================================================
/**
* This custom Character Movement Component handles movement logic for the associated character owner.
* It supports various movement modes that you will likely need or use for your game.
*
* Networking is fully implemented, with server-client correction and prediction included, as per the default component.
*
*/
UCLASS(hidecategories=("CharacterMovement: Walking|CharacterMovement: Jumping"))
class CONNIPTIONFRAMEWORK_API UCF_CharacterMovement : public UCharacterMovementComponent
{
GENERATED_BODY()
UCF_CharacterMovement(const FObjectInitializer& ObjectInitializer);
};
.cpp (component, constructor only)
// Copyright Rapidfire Computer Entertainment. All rights reserved.
#include "CF_CharacterMovement.h"
UCF_CharacterMovement::UCF_CharacterMovement(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) // Visual studio spits out an error regarding the "Super" thing, don't worry about it.
{
// Set all of this by default!
// Hide our movement speed properties, because we don't need them here. We'll be setting all of that in our character class.
// Basic movement capabilities.
NavAgentProps.bCanCrouch = true;// Crouching is used in almost every game so why would this be disabled by default? Come on Epic!
NavAgentProps.bCanJump = true; // Same as crouching but this one's actually enabled by default, good stuff.
NavAgentProps.bCanSwim = true; // Same as the jumping/crouching but a little less common it seems.
NavAgentProps.bCanFly = true; // May use this for a more efficient parkour system so it's important to consider!
NavAgentProps.bCanWalk = true; // No-brainer, why wouldn't you be able to walk?
// Ground movement controls.
SetCrouchedHalfHeight(44.0f);
SetWalkableFloorAngle(45.0f);
MaxWalkSpeed = 400.0f;
MaxWalkSpeedCrouched = 230.0f;
bCanWalkOffLedgesWhenCrouching = true;
// Jump controls.
JumpZVelocity = 330.0f;
AirControl = 0.24f;
// Swim controls.
MaxSwimSpeed = 240.0f;
OutofWaterZ = 352.0f;
// Fly controls, even though we really don't use these.
MaxFlySpeed = 400.0f;
// Custom movement controls.
MaxCustomMovementSpeed = 400.0f;
// Rotation controls.
RotationRate = FRotator(0.0f, 470.0f, 0.0f);
// Nav mesh controls.
bProjectNavMeshWalking = true;
bProjectNavMeshOnBothWorldChannels = true;
// Optimization controls.
bUpdateOnlyIfRendered = true;
bAutoUpdateTickRegistration = true;
}
.cpp (character, constructor only)
// Copyright Rapidfire Computer Entertainment. All rights reserved.
#include "GameFramework/SpringArmComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/CapsuleComponent.h"
#include "Kismet/KismetSystemLibrary.h"
#include "EngineUtils.h"
#include "Camera/CameraComponent.h"
#include "Animation/AnimMontage.h"
#include "CF_CharacterMovement.h"
#include "CF_Character.h"
// Sets default values
ACF_Character::ACF_Character(const FObjectInitializer& ObjectInitializer)
// Override the movement component, because we're going to be using our own that has completely different default data.
: Super(ObjectInitializer.SetDefaultSubobjectClass<UCF_CharacterMovement>(ACharacter::CharacterMovementComponentName))
{
// Brute force the actor tick off. We don't need it, period. That's what we use timers for.
PrimaryActorTick.bCanEverTick = false;
PrimaryActorTick.bStartWithTickEnabled = false;
PrimaryActorTick.bAllowTickOnDedicatedServer = false;
PrimaryActorTick.bTickEvenWhenPaused = false;
// Set up default properties for the character mesh.
GetMesh()->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, -90.0f), FRotator(0.0f, -90.0f, 0.0f), false);
// Disable tick on all of our components. Seemingly even the movement component works without the tick function...
TArray<UActorComponent*> ComponentsArray;
GetComponents(ComponentsArray);
for (UActorComponent* UActorComponent : ComponentsArray)
{
UActorComponent->PrimaryComponentTick.bCanEverTick = false;
UActorComponent->PrimaryComponentTick.bStartWithTickEnabled = false;
UActorComponent->PrimaryComponentTick.bAllowTickOnDedicatedServer = false;
UActorComponent->PrimaryComponentTick.bTickEvenWhenPaused = false;
}
}
I know this was a LOT but I tried to provide a huge amount of information to make things easier for the community. I really appreciate any and all help, thanks in advance!