x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

USpringArmComponent lag vars not abiding origin shifting (proto-fix included)

G'day,

It seems that if you use bEnableCameraLag == true with the spring arm component, the internal state variables "PreviousDesiredLoc" and "PreviousArmOrigin" are not updated when the world origin shifts. The effect of this is a very unpleasant location snapping effect every time the world origin is reset, because the component tries to interpolate from what is now a very wrong previous location.

I was able to address this locally by subclassing the component and adding something like this:

 void UMySpringArmComponent::ApplyWorldOffset(const FVector& offset, bool bWorldShift)
 {
    Super::ApplyWorldOffset(offset, bWorldShift);
    PreviousDesiredLoc += offset;
    PreviousArmOrigin  += offset;
 }

Following that, the interpolated movement remains smooth on origin rebasing. I believe the original component should do this though; I can't think of any conceivable reason you'd want the weird behavior it exhibits now. I imagine it's a simple matter of hoisting the above code into the USpringArmComponent.

(Separately but relatedly, the TemporalAA has some origin rebasing artifacts, which I haven't investigated yet).

Other details: UE 4.8.3 on Linux

Product Version: UE 4.8
Tags:
more ▼

asked Aug 21 '15 at 07:05 PM in Bug Reports

avatar image

pvz2015
106 4 7 10

avatar image Doug E ♦♦ STAFF Aug 24 '15 at 07:01 PM

Hey pvz2015-

I'm not sure what you mean by shifting the world origin. Can you provide further explanation of the issue and/or detailed steps I could follow to reproduce the problem on my end?

Cheers

Doug Wilson

avatar image pvz2015 Aug 24 '15 at 11:55 PM

Hi Doug,

Sure, I'll try. The high level topic is as described here. I have a FVector holding my observer location, and when that drifts too far from the world origin, I reset the origin as follows:

    // New location, but ignore Z axis
    if (FMath::Abs(location.X) > OriginRebaseThreshold || FMath::Abs(location.Y) > OriginRebaseThreshold)
       GetWorld()->SetNewWorldOrigin(FIntVector(location.X, location.Y, 0.0f) + GetWorld()->OriginLocation);

This works as expected: the ApplyWorldOffset() virtual method is called on various objects, with the new origin set close to the viewpoint. In principle, I don't think there should be a visually observable effect from this. A number of UE4 provided classes are overloading this method to do various internal housekeeping: for instance, USceneComponent::ApplyWorldOffset updates bounding box positions and whatnot.

The USpringArmComponent has not only its primary location to worry about, but some internal hysteresis variables for smoothing the camera location from wherever it just was, to wherever you are asking it to be. Those variables are not being updated. You probably wouldn't notice if you updated the observer location and the world origin at once, but if you set the world origin and the spring arm is "tensioned" so to speak, it jumps abruptly as the smoothing goes wonky.

I'm brand new to UE4, and it's very possible I have missed something important! But this fixes the weird spring arm behavior for me, and other UE4 classes are updating their own internal state similarly.

Thanks for looking into this! If there's anything else I can do to help, let me know. I can privately send you the APlayerController subclass which encountered this, though it wouldn't compile straight away since it has tentacles into some of my other code.

avatar image pvz2015 Aug 25 '15 at 12:11 AM

BTW, if you want to try to repro it without my code, you might:

(1) Set up a spring arm attached to an object you can drive around with the keyboard via PIE. It's essential that the spring arm have bEnableCameraLag = true.

(2) While actively driving the spring arm around - it's essential it's actively going through the interpolation code around SpringArmComponent:101 - set the world origin to a spot around 100m away via SetNewWorldOrigin(). You should see the camera do some weird things, because the internal state variables above are not getting updated when the origin is shifted. The spring arm tries to interpolate from a spot in the old world reference frame.

avatar image Doug E ♦♦ STAFF Aug 25 '15 at 07:05 PM

Hey pvz2015-

Where are you using the SetNewWorldOrigin() function? Is this being called in the same class that you setup your sprint arm component? When you say to set the world origin 100m away, are you referring to 100m away from the default world origin or from the location of the actor with the spring arm component? If possible could you include the code where you have your spring arm component set up for reference?

Cheers

Doug Wilson

avatar image pvz2015 Aug 25 '15 at 11:24 PM

Hi Doug,

I'm calling SetNewWorldOrigin from with a derived class of APlayerController, from a timer function called every half second (and then only if the camera has moved far from the origin). Though I believe the misbehavior is identical if it call it from the Tick() function.

When I say "100m away", I just mean 100m away from where the origin was previously. The absolute location doesn't matter: what matters is that it moves some distance from where it was, which causes the spring arm state variables to go stale. Similarly, the absolute distance isn't important: 10km would also show the problem.

And sure, I'll include the code I think you're talking about. If this isn't what you meant let me know and I'll try again. This happens in a derived class from APawn, in its constructor:

    SpringArm     = CreateDefaultSubobject<UMySpringArmComponent>(TEXT("CameraRigSpringArm"));
    RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("CameraRigRoot"));
 
    SpringArm->AttachTo(RootComponent);
       
    SpringArm->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, 0.0f), FRotator(-50.0f, 0.0f, 0.0f));
    SpringArm->bAbsoluteRotation        = true;
    SpringArm->TargetArmLength          = 2000.0f;
    SpringArm->bEnableCameraLag         = true;
    SpringArm->bEnableCameraRotationLag = true;
    SpringArm->bDoCollisionTest         = false;
    SpringArm->bInheritPitch            = false;
    SpringArm->bInheritRoll             = false;
    SpringArm->bInheritYaw              = true;
    SpringArm->CameraLagSpeed           = 5.0f;
    SpringArm->CameraRotationLagSpeed   = 16.0f;
    SpringArm->CameraLagMaxDistance     = 10000.0f;


Where "UMySpringArmComponent" is the derivation I made to include my fix above, but you can replace it with the stock spring arm to show the trouble.

I do have a spring arm feature request too, but I'll put that in another reply to avoid conflating it with this topic :).

avatar image Adam Davis STAFF Aug 28 '15 at 03:02 PM

Hi pvz2015,

Do you have a sample project this is occurring in? I'd be happy to take a look and see what may be occurring.

avatar image pvz2015 Aug 28 '15 at 06:30 PM

Hi Adam,

Over the w/e perhaps I can come up with an example project by trimming down the full project I have. Shouldn't be too hard.

I have an adequate workaround (from my post at the top of this thread), so it isn't a big problem for me. I just thought you might want to roll a similar fix into the main engine, if you end up believing it's a real bug once you see it yourself locally. I'll try to get you an example project soon...

avatar image pvz2015 Aug 31 '15 at 02:19 AM

Adam,

I have a test project that shows this. How do I give it to you?

avatar image Adam Davis STAFF Aug 31 '15 at 02:36 PM

Hi pvz2015,

You can send it to me either here by posting the .zip or in a private message on the forums.

avatar image pvz2015 Sep 01 '15 at 12:26 AM

Alrighty. I'm quite new to UE4 and not entirely clear on what subset of the project to package up, so I took a SWAG at it, and if you need something else, I'll try again.

There's a file README-SpringArmPossibleBug.txt included which explains the situation. Line endings are Linux form for both code and the readme.

link text

springarmtest.zip (377.6 kB)
avatar image pvz2015 Sep 01 '15 at 11:28 PM

Hi Doug,

Is there other documentation for the spring arm than the reference entry here? I looked there and didn't see anything about origin rebasing or ApplyWorldOffset. It's a bit on the terse side.

Anyway, I know I can fix it by overriding that method, but I was thinking that generally the other internal UE4 classes seem to handle rebasing their own state, rather than leaving it up to custom derivations that might not even have visibility into or knowledge of their internal state. Arguably, the spring arm ought to do the same. As a user of the spring arm, I didn't even know about those variables until I went to debug the problem. I'm fine either way, but from an API perspective I think it's better, and might save other new users similar head-scratching.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

Hi pvz2015,

I've entered this into our system as a feature request, UE-21057, to be considered by our development staff.

more ▼

answered Sep 14 '15 at 03:56 PM

avatar image pvz2015 Sep 14 '15 at 11:25 PM

Cool.

...

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

Hey pvz2015-

I can see the jump you mention when moving the actor in game. Overriding the ApplyWorldOffset as you've done in your spring arm component is what needs to be done to correct this in custom classes as stated in the documentation. Doing the same thing in a custom camera class could help eliminate the jump/hitch more.

more ▼

answered Sep 01 '15 at 06:32 PM

avatar image pvz2015 Sep 01 '15 at 11:29 PM

Hi Doug,

Is there other documentation for the spring arm than the reference entry here? I looked there and didn't see anything about origin rebasing or ApplyWorldOffset. It's a bit on the terse side.

Anyway, I know I can fix it by overriding that method, but I was thinking that generally the other internal UE4 classes seem to handle rebasing their own state, rather than leaving it up to custom derivations that might not even have visibility into or knowledge of their internal state. Arguably, the spring arm ought to do the same. As a user of the spring arm, I didn't even know about those variables until I went to debug the problem. I'm fine either way, but from an API perspective I think it's better, and might save other new users similar head-scratching. Also, I think an argument could be made that origin rebasing should be as seamless as possible.

Anyway, thanks.

avatar image Adam Davis STAFF Sep 09 '15 at 07:11 PM

Hi pvz2015,

I am still looking into this. I'll post here when I have additional information.

avatar image pvz2015 Sep 09 '15 at 11:11 PM

Okay, great.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question