During my free time I enjoy practicing and prototyping Gameplay Mechanics, this way I can always be improving and seeing different challenges that can come up in this job. I enjoy taking high quality assets and putting things together, adding the design and code part of the equation to it - in these examples, I'm using one Paragon character (Sparrow) and a free model from the Mixamo website.

Unreal Sparrow
The Challenge I'm imposing to myself with this one is getting something that was made for a game, in this case, Paragon, and how I can adapt it to another type of game and putting all these things together. I always wanted to prototype a shooting mechanic with a bow, so I decided to use Sparrow to try this.
The Sparrow Gameplay Character has 4 main states: BowDown, BowAiming, FastShot and HeavyShot, with a simple difference between those.
- Bow Down: High velocity and no aiming capabilities
- Bow Aiming: Medium Velocity, can aim to prepare to shoot
- Fast Shot: Locks movements for a little while, shots for low damage
- Heavy Shot: Locks movement while charging bow, player has to release key to shot for higher damage
UENUM(BlueprintType) enum class EBowStatus : uint8 { EBS_BowDown UMETA(DisplayName = "BowDown"), EBS_BowAiming UMETA(DisplayName = "BowAiming"), EBS_FastShot UMETA(DisplayName = "FastShot"), EBS_HeavyShot UMETA(DisplayName = "HeavyShot"), EBS_MAX UMETA(DisplayName = "DefautMAX") };
void AThirdPersonShooterCharacter::MoveForward(float Value) { LastFrameUpValue = Value; MoveCharacterWithAxis(EAxis::X, Value); } void AThirdPersonShooterCharacter::MoveRight(float Value) { LastFrameRightValue = Value; MoveCharacterWithAxis(EAxis::Y, Value); } void AThirdPersonShooterCharacter::MoveCharacterWithAxis(EAxis::Type AxisType, float Value) { if (Controller != nullptr && Value != 0.0f) { const FRotator Rotation = Controller->GetControlRotation(); const FRotator YawRotation = FRotator(0.0f, Rotation.Yaw, 0.0f); const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(AxisType); AddMovementInput(Direction, Value); } } /* Set the Current Bow Status for the Player Character - The only reason this function is not FORCEINLINE is that we might want to execute some behavior when going to some states */ void AThirdPersonShooterCharacter::SetBowStatus(EBowStatus BowStatus) { if (BowStatus == EBowStatus::EBS_BowDown) { GetCharacterMovement()->MaxWalkSpeed = BowAimingPlayerVelocity; GetCharacterMovement()->bOrientRotationToMovement = true; GetCharacterMovement()->bUseControllerDesiredRotation = false; } else if (BowStatus == EBowStatus::EBS_BowAiming) { GetCharacterMovement()->MaxWalkSpeed = BowDownPlayerVelocity; GetCharacterMovement()->bOrientRotationToMovement = false; GetCharacterMovement()->bUseControllerDesiredRotation = true; } CurrentBowStatus = BowStatus; }

ARPG Demo
The point of this Demo is to challenge myself into making an Action RPG combat mechanic, Dark Souls and Bloodborne are games that I take as a reference for everything as a designer and developer, so trying and understanding what goes into that type of combat is something that takes me interest!
void AMainCharacter::Attack() { if (!bIsAttacking) { bIsAttacking = true; UAnimInstance* pAnimInstance = GetMesh()->GetAnimInstance(); if (pAnimInstance != nullptr && pCombatMontage != nullptr) { int32 Section = FMath::RandRange(0, 1); switch (Section) { case 0: pAnimInstance->Montage_Play(pCombatMontage, 1.5f); pAnimInstance->Montage_JumpToSection(FName("Attack_2"), pCombatMontage); break; case 1: pAnimInstance->Montage_Play(pCombatMontage, 2.0f); pAnimInstance->Montage_JumpToSection(FName("Attack_1"), pCombatMontage); break; default: break; } } } } void AMainCharacter::FinishedAttack() { bIsAttacking = false; if (bLeftMouseButtonDown) { Attack(); } }
void AWeapon::EquipWeaponIntoCharacter(AMainCharacter* CharacterToEquip) { if (CharacterToEquip != nullptr) { /** Ignoring the collision with the camera, so it doesn't affect the spring arm */ pWeaponSkeletalMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Camera, ECollisionResponse::ECR_Ignore); pWeaponSkeletalMesh->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Ignore); pWeaponSkeletalMesh->SetSimulatePhysics(false); const USkeletalMeshSocket* pRightHandSocket = CharacterToEquip->GetMesh()->GetSocketByName("RightHandSocket"); if (pRightHandSocket != nullptr) { pRightHandSocket->AttachActor(this, CharacterToEquip->GetMesh()); bRotate = false; AWeapon* CurrentlyEquippedWeapon = CharacterToEquip->GetEquippedWeapon(); if (CurrentlyEquippedWeapon != nullptr) { CurrentlyEquippedWeapon->Destroy(); } CharacterToEquip->SetEquippedWeapon(this); CharacterToEquip->SetActiveOverlappingItem(nullptr); } if (pOnEquipSound != nullptr) { UGameplayStatics::PlaySound2D(this, pOnEquipSound); } if (!bWeaponParticle) { pIdleParticlesComponent->Deactivate(); } } }