コード例 #1
0
/** Sets the current ball possessor */
void AMagicBattleSoccerBall::SetPossessor(AMagicBattleSoccerCharacter* Player)
{
    if (Role < ROLE_Authority)
    {
        // Safety check. Only authority entities should drive the ball.
    }
    else
    {
        // We only allow a possession change if the ball is being unpossessed or the player is not one we're ignoring
        if (nullptr == Player || (CanPossessBall(Player) && (PossessorToIgnore != Player)))
        {
            AMagicBattleSoccerCharacter *OldPossessor = Possessor;

            // Assign the new possessor
            Possessor = Player;

            // Handle cases when the ball had a possessor in the previous frame
            if (nullptr != OldPossessor)
            {
                // Assign the last possessor
                LastPossessor = OldPossessor;
                // Assign the possessor to ignore
                PossessorToIgnore = OldPossessor;
            }

            // Toggle physics
            UPrimitiveComponent *Root = Cast<UPrimitiveComponent>(GetRootComponent());
            if (nullptr != Possessor)
            {
                Possessor->StopWeaponFire(Possessor->PrimaryWeapon);
                Possessor->StopWeaponFire(Possessor->SecondaryWeapon);
                Root->PutRigidBodyToSleep();
                Root->SetSimulatePhysics(false);
                Root->SetEnableGravity(false);
                SetActorEnableCollision(false);
                MoveWithPossessor();
            }
            else
            {
                Root->SetSimulatePhysics(true);
                Root->SetEnableGravity(true);
                SetActorEnableCollision(true);
                Root->PutRigidBodyToSleep();
            }
        }

        // Force the orientation to be replicated at the same time the possessor is replicated
        UPrimitiveComponent *Root = Cast<UPrimitiveComponent>(GetRootComponent());
        ServerPhysicsState.pos = GetActorLocation();
        ServerPhysicsState.rot = GetActorRotation();
        ServerPhysicsState.vel = Root->GetComponentVelocity();
        ServerPhysicsState.timestamp = AMagicBattleSoccerPlayerController::GetLocalTime();
    }
}
コード例 #2
0
void AMagicBattleSoccerBall::Tick(float DeltaSeconds)
{
    Super::Tick(DeltaSeconds);

    if (nullptr != Possessor)
    {
        // If the ball is possessed by a player, then the ball should move as a function
        // of the possessor
        MoveWithPossessor();
    }
    else
    {
        // No possessor. The ball is freely moving.
        if (Role < ROLE_Authority)
        {
            // Clients should update its local position based on where it is on the server
            ClientSimulateFreeMovingBall();
        }
        else
        {
            // Update the charging value
            if (GetVelocity().SizeSquared() > 1.f)
            {
                IsCharging = false;
            }

            // Servers should simulate the ball physics freely and replicate the orientation
            UPrimitiveComponent *Root = Cast<UPrimitiveComponent>(GetRootComponent());
            ServerPhysicsState.pos = GetActorLocation();
            ServerPhysicsState.rot = GetActorRotation();
            ServerPhysicsState.vel = Root->GetComponentVelocity();
            ServerPhysicsState.timestamp = AMagicBattleSoccerPlayerController::GetLocalTime();

            // Servers should also test the distance from the old possessor and reset it
            if (nullptr != PossessorToIgnore)
            {
                if (!PossessorToIgnore->IsAlive())
                {
                    PossessorToIgnore = nullptr;
                }
                else
                {
                    FVector2D PossessorLoc(PossessorToIgnore->GetActorLocation());
                    FVector2D BallLoc(GetActorLocation());
                    float d = FVector2D::DistSquared(PossessorLoc, BallLoc);
                    if (d > 14000)
                    {
                        PossessorToIgnore = nullptr;
                    }
                }
            }
        }
    }
}