例如一把武器(AWeapon)在平时是模拟物理的,在被角色(ABlasterCharacter)携带时需要取消模拟物理,附着在角色身上移动。
void AWeapon::BeginPlay()
{
Super::BeginPlay();
if (HasAuthority())
{
SetReplicates(true);
_mesh->SetIsReplicated(true);
_mesh->SetSimulatePhysics(true);
}
else
{
_mesh->SetSimulatePhysics(false);
}
}
携带武器
当角色要携带这把武器时,该武器必须取消模拟物理_mesh->SetSimulatePhysics(false)
。然后角色调用SetOwner(this)
将该武器的NetConnection与自己绑定,最后调用AttachActor(_weapon, GetMesh())
将武器附加在骨骼socket上。
void AWeapon::OnPickUp()
{
_mesh->SetSimulatePhysics(false);
}
void ABlasterCharacter::PickUp()
{
_weapon->OnPickUp();
// 装备该武器
const USkeletalMeshSocket* rightHandSocket = GetMesh()->GetSocketByName(FName("RightHandSocket"));
if (rightHandSocket)
{
_weapon->SetOwner(this);
rightHandSocket->AttachActor(_weapon, GetMesh());
}
// 调用服务端RPC
if (!HasAuthority())
{
Server_PickUp();
}
}
void ABlasterCharacter::Server_PickUp_Implementation()
{
PickUp();
}
丢弃武器
当角色丢弃这把武器时,反向执行逻辑即可。角色调用DetachFromActor(rules)
将武器从骨骼socket上分离,然后调用_weapon->SetOwner(nullptr)
将该武器的NetConnection与自己解绑。最后将武器的模拟物理重新启用:_mesh->SetSimulatePhysics(true)
。
void ABlasterCharacter::Drop()
{
if (_weapon)
{
// 丢弃当前武器
FDetachmentTransformRules rules(EDetachmentRule::KeepWorld, EDetachmentRule::KeepWorld, EDetachmentRule::KeepWorld, true);
_weapon->DetachFromActor(rules);
_weapon->SetOwner(nullptr);
_weapon->OnDrop();
}
// 调用服务端RPC
if (!HasAuthority())
{
Server_Drop();
}
}
void ABlasterCharacter::Server_Drop_Implementation()
{
Drop();
}
void AWeapon::OnDrop()
{
_mesh->SetSimulatePhysics(true);
}