想做到不论是下蹲还是站立,在装备了武器按下右键后,角色状态从持枪状态进入瞄准状态。还是先看输入绑定。
1 2 3 4
| EnhancedInputComponent->BindAction(IA_AimingPressed, ETriggerEvent::Triggered, this, &ABlasterCharacter::InputAimingPressed);
EnhancedInputComponent->BindAction(IA_AimingReleased, ETriggerEvent::Triggered, this, &ABlasterCharacter::InputAimingReleased);
|
我这里设置的是右键长按瞄准,松开恢复。此处增强输入对应设置如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| void ABlasterCharacter::InputAimingPressed(const FInputActionValue& InputValue) { if (CombatComp) { CombatComp->SetAiming(true); } }
void ABlasterCharacter::InputAimingReleased(const FInputActionValue& InputValue) { if (CombatComp) { CombatComp->SetAiming(false); } }
|
对了,UE一直有个bug,UE有时候创建组件后拿到的是空,需要重命名组件,这bug已知从4.27贯穿到5.20,不知道什么时候修,我在这里把Combat变量命名改为CombatComp。

在Combat组件中,去设置角色当前的状态是否在瞄准,同时将bAiming设为属性同步。这样在SetAiming中先写bAiming = bIsAiming;是为了让本地直接进入瞄准状态,不然需要等Client调用ServerSetAiming在Server上执行后,bAiming再属性同步回客户端才能进入瞄准状态,这样体验很差,所以可以提前本地执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void UCombatComponent::SetAiming(bool bIsAiming) { bAiming = bIsAiming; ServerSetAiming(bAiming); } void UCombatComponent::ServerSetAiming_Implementation(bool bIsAiming) { bAiming = bIsAiming; } void UCombatComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const { Super::GetLifetimeReplicatedProps(OutLifetimeProps); DOREPLIFETIME(UCombatComponent, bAiming); }
|
这样玩家长按鼠标右键,背后的关于控制瞄准的变量逻辑就执行好了,此时需要暴露给动画蓝图,让动画蓝图播放相应的瞄准动画。这里在角色类的public里写一个获取是否正在瞄准的变量。
1 2 3 4
| bool ABlasterCharacter::IsAiming() { return (CombatComp && CombatComp->bAiming); }
|
同时在角色动画实例cpp中添加是否在瞄准变量。
1 2 3 4 5 6 7 8 9 10
| UPROPERTY(BlueprintReadOnly, Category = Anim, meta = (AllowPrivateAccess = "true")) bool bAiming; void UBlasterAnimInstance::NativeUpdateAnimation(float DeltaTime) { Super::NativeUpdateAnimation(DeltaTime); bAiming = BlasterCharacter->IsAiming(); }
|
这样子我们就能在动画蓝图中获取角色是否在瞄准了。最后在动画蓝图中选择合适的动画就可以了。

最后看一下效果:
下蹲持枪状态:

下蹲瞄准状态:
