Announcement

Collapse
No announcement yet.

Ok, I'm curious. Is this undefined behavior?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Ok, I'm curious. Is this undefined behavior?

    I'm not sure whether I should post this here or in the Blueprint section. Please let me know if I should post it there instead.

    My characters use planar movement. By default, movement is assumed to be perpendicular to the ground normal. I find it useful to use a public 2D vector to describe movement factors for the horizontal and vertical axes. From BP, relaying movement factors becomes a matter of doing the following:



    This is a trivial piece of BP code, yet it does not work for both axes simultaneously. Individually, yes, the components are updated properly, but if I run both, it only works "sometimes". Sometimes only one axis will work, seemingly at random, sometimes both work and movement proceeds as planned, but changing the Blueprint anywhere else seems to affect this section. For instance, I changed a print call and it stopped working.

    I wrote two C++ functions to set the factors individually, and they work as intended. I expected the Blueprint code above to be its equivalent, but apparently it isn't.

    This suggests a race condition to me. What am I missing?

    #2
    Some old code of mine (twin-stick aiming). AimDir_X and AimDir_Y are separate axis bindings for gamepad stick X/Y. Both bind to the same function, and you can ignore the input value and just "read" the current axis values.

    Does mean it get's processed twice per-frame, but I can live with that (simple to add a bypass to that).

    Alternatively, you can skip binding and just read the axis values on tick - just make sure it's an early tick.

    Code:
    void AECGame_BaseOrb::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
    {
        Super::SetupPlayerInputComponent(PlayerInputComponent);
    
        PlayerInputComponent->BindAxis(TEXT("AimDir_X"), this, &AECGame_BaseOrb::OnAimInput);
        PlayerInputComponent->BindAxis(TEXT("AimDir_Y"), this, &AECGame_BaseOrb::OnAimInput);
    }
    
    void AECGame_BaseOrb::OnAimInput(const float Val)
    {
        FVector RawAimVector = FVector::ZeroVector;
        RawAimVector.Y = GetInputAxisValue(TEXT("AimDir_X"));
        RawAimVector.X = GetInputAxisValue(TEXT("AimDir_Y"));
    
        if ((RawAimVector.X == 0.f && RawAimVector.Y == 0.f))
        {
            AimMagnitude = 0.f;
            return;
        }
    
        AimMagnitude = FMath::Min(1.f, FMath::Square(RawAimVector.X) + FMath::Square(RawAimVector.Y));
    
        // Set Controller Yaw Rotation to match.
        // Pass in a Z value to force Roll to Zero
        const FRotator NewControlRotation = FRotationMatrix::MakeFromXZ(RawAimVector, FVector::UpVector).Rotator();
        if (GetController())
        {
            GetController()->SetControlRotation(NewControlRotation);
        }
    }
    Last edited by TheJamsh; 11-20-2019, 06:12 AM.

    Comment

    Working...
    X