I understand that I can use a static mesh. I just set this up for simplicity here. I also am aware of how to setup collisions on a static mesh. I appreciate it though.
Let me try to explain a bit more of my issue. It has to do with movement and how that ties into collisions.
So let me eplain why I cannot use a scene component as the root component of my pawn.
SetActorLocation seems to be the way to move an actor. Under the hood it calls move component on the root component
bool AActor::SetActorLocation(const FVector& NewLocation, bool bSweep, FHitResult* OutSweepHitResult, ETeleportType Teleport)
{
if (RootComponent)
{
const FVector Delta = NewLocation - GetActorLocation();
return RootComponent->MoveComponent(Delta, GetActorQuat(), bSweep, OutSweepHitResult, MOVECOMP_NoFlags, Teleport);
}
else if (OutSweepHitResult)
{
*OutSweepHitResult = FHitResult();
}
return false;
}
And here is move component, check out this comment in the @param bSweep
“Only the root component is swept and checked for blocking. child components move without sweeping”
/**
* Tries to move the component by a movement vector (Delta) and sets rotation to NewRotation.
* Assumes that the component's current location is valid and that the component does fit in its current Location.
* Dispatches blocking hit notifications (if bSweep is true), and calls UpdateOverlaps() after movement to update overlap state.
*
* @note This simply calls the virtual MoveComponentImpl() which can be overridden to implement custom behavior.
* @note The overload taking rotation as an FQuat is slightly faster than the version using FRotator (which will be converted to an FQuat)..
* @param Delta The desired location change in world space.
* @param NewRotation The new desired rotation in world space.
* @param bSweep Whether we sweep to the destination location, triggering overlaps along the way and stopping short of the target if blocked by something.
* Only the root component is swept and checked for blocking collision, child components move without sweeping. If collision is off, this has no effect.
* @param Teleport Whether we teleport the physics state (if physics collision is enabled for this object).
* If TeleportPhysics, physics velocity for this object is unchanged (so ragdoll parts are not affected by change in location).
* If None, physics velocity is updated based on the change in position (affecting ragdoll parts).
* If CCD is on and not teleporting, this will affect objects along the entire swept volume.
* @param Hit Optional output describing the blocking hit that stopped the move, if any.
* @param MoveFlags Flags controlling behavior of the move. @see EMoveComponentFlags
* @param Teleport Determines whether to teleport the physics body or not. Teleporting will maintain constant velocity and avoid collisions along the path
* @return True if some movement occurred, false if no movement occurred.
*/
bool MoveComponent( const FVector& Delta, const FQuat& NewRotation, bool bSweep, FHitResult* Hit=NULL, EMoveComponentFlags MoveFlags = MOVECOMP_NoFlags, ETeleportType Teleport = ETeleportType::None);
And here is the issue. If your scene component is your root component it “has no rendering or collision capabilities.”
/**
* A SceneComponent has a transform and supports attachment, but has no rendering or collision capabilities.
* Useful as a 'dummy' component in the hierarchy to offset others.
* @see [Scene Components](https://docs.unrealengine.com/latest/INT/Programming/UnrealArchitecture/Actors/Components/index.html#scenecomponents)
*/
UCLASS(ClassGroup=(Utility, Common), BlueprintType, hideCategories=(Trigger, PhysicsVolume), meta=(BlueprintSpawnableComponent, IgnoreCategoryKeywordsInSubclasses, ShortTooltip="A Scene Component is a component that has a scene transform and can be attached to other scene components."), MinimalAPI)
class USceneComponent : public UActorComponent
It’s child class Primitive component does
/**
* PrimitiveComponents are SceneComponents that contain or generate some sort of geometry, generally to be rendered or used as collision data.
* There are several subclasses for the various types of geometry, but the most common by far are the ShapeComponents (Capsule, Sphere, Box), StaticMeshComponent, and SkeletalMeshComponent.
* ShapeComponents generate geometry that is used for collision detection but are not rendered, while StaticMeshComponents and SkeletalMeshComponents contain pre-built geometry that is rendered, but can also be used for collision detection.
*/
UCLASS(abstract, HideCategories=(Mobility, VirtualTexture), ShowCategories=(PhysicsVolume), MinimalAPI)
class UPrimitiveComponent : public USceneComponent, public INavRelevantInterface, public IInterface_AsyncCompilation, public IPhysicsComponent
public:
/**
* Begin tracking an overlap interaction with the component specified.
* @param OtherComp - The component of the other actor that this component is now overlapping
* @param bDoNotifies - True to dispatch appropriate begin/end overlap notifications when these events occur.
* @see [Overlap Events](https://docs.unrealengine.com/InteractiveExperiences/Physics/Collision/Overview#overlapandgenerateoverlapevents)
*/
ENGINE_API void BeginComponentOverlap(const FOverlapInfo& OtherOverlap, bool bDoNotifies);
So when you move your pawn with a scene component as the root it stops all it’s children from sweeping and then only sweeps the root which in this case does not have that functionality, so… you have just removed collisions on move… great.
So why not just use the box collision as the root of a pawn if the character capsule does not work…
That’s what my pictures were trying to show. The collision box does not fit my mesh because the center of my mesh sits back a little.
So if I move my mesh back like this to fit into the collision box it now has it’s pivot is to far forward so it rotates awkwardly.
So I can’t use the Box as the root because it messes with my origin and I can’t use my scene component as my root because it negates collisions.
So I thought what if I make the scene component the root and then call move component directly on the box component child with everything else parented to it. Well that worked, but I am only moving my box component and it’s children relative to it’s parent. It’s parent the root component does not move. So anything calling GetActorLocation() will get the actors root location 0,0,0 in this case while I have moved the children components to say 1524,500,0
So I am at a loss and that is why I was asking. Does anyone have experience making a custom solution to this problem and if so, did it work? or did it mess up other systems later on down the line?
Thanks for responding
I’m open to explain further if that is needed.