diff --git a/Unreal/Plugins/PS_Ballistics/Binaries/Win64/UnrealEditor-EasyBallistics.dll b/Unreal/Plugins/PS_Ballistics/Binaries/Win64/UnrealEditor-EasyBallistics.dll index 8ca448f..cb25160 100644 Binary files a/Unreal/Plugins/PS_Ballistics/Binaries/Win64/UnrealEditor-EasyBallistics.dll and b/Unreal/Plugins/PS_Ballistics/Binaries/Win64/UnrealEditor-EasyBallistics.dll differ diff --git a/Unreal/Plugins/PS_Ballistics/Binaries/Win64/UnrealEditor-EasyBallistics.pdb b/Unreal/Plugins/PS_Ballistics/Binaries/Win64/UnrealEditor-EasyBallistics.pdb index 0d0ccd4..17f72c9 100644 Binary files a/Unreal/Plugins/PS_Ballistics/Binaries/Win64/UnrealEditor-EasyBallistics.pdb and b/Unreal/Plugins/PS_Ballistics/Binaries/Win64/UnrealEditor-EasyBallistics.pdb differ diff --git a/Unreal/Plugins/PS_Ballistics/Source/EasyBallistics/Private/BarrelEvents.cpp b/Unreal/Plugins/PS_Ballistics/Source/EasyBallistics/Private/BarrelEvents.cpp index 540d5cf..0c855b6 100644 --- a/Unreal/Plugins/PS_Ballistics/Source/EasyBallistics/Private/BarrelEvents.cpp +++ b/Unreal/Plugins/PS_Ballistics/Source/EasyBallistics/Private/BarrelEvents.cpp @@ -14,7 +14,7 @@ void UEBBarrel::SpawnBulletEventMulticast_Implementation(FVector Start, FVector } void UEBBarrel::Shoot(bool Trigger, int nextFireID) { - if (ClientSideAim && GetOwner()->GetRemoteRole() == ROLE_Authority && Trigger) { + if (ClientSideAim && GetOwner()->GetLocalRole() == ROLE_AutonomousProxy && Trigger) { Aim = GetComponentTransform().GetUnitAxis(EAxis::X); Location = GetComponentTransform().GetLocation(); nextFireEventID = nextFireID; diff --git a/Unreal/Plugins/PS_Ballistics/Source/EasyBallistics/Private/EBBarrel.cpp b/Unreal/Plugins/PS_Ballistics/Source/EasyBallistics/Private/EBBarrel.cpp index 0fcb7b6..dcd06e3 100644 --- a/Unreal/Plugins/PS_Ballistics/Source/EasyBallistics/Private/EBBarrel.cpp +++ b/Unreal/Plugins/PS_Ballistics/Source/EasyBallistics/Private/EBBarrel.cpp @@ -53,7 +53,8 @@ void UEBBarrel::TickComponent(float DeltaTime, ELevelTick TickType, FActorCompon UpdateTransformHistory(); if (ClientSideAim){ - if (GetOwner()->GetRemoteRole()==ROLE_Authority){ + const ENetRole LocalRole = GetOwner()->GetLocalRole(); + if (LocalRole == ROLE_AutonomousProxy){ TimeSinceAimUpdate += DeltaTime; if (TimeSinceAimUpdate >= 1.0f / ClientAimUpdateFrequency) { @@ -62,7 +63,7 @@ void UEBBarrel::TickComponent(float DeltaTime, ELevelTick TickType, FActorCompon ClientAim(UGameplayStatics::RebaseLocalOriginOntoZero(GetWorld(),Location), Aim); TimeSinceAimUpdate = FMath::Fmod(TimeSinceAimUpdate, 1.0f / ClientAimUpdateFrequency); }; - }else{ + }else if (LocalRole == ROLE_Authority){ if (!RemoteAimReceived) { ComputeAntiRecoilTransform(); } @@ -74,6 +75,7 @@ void UEBBarrel::TickComponent(float DeltaTime, ELevelTick TickType, FActorCompon } } } + // ROLE_SimulatedProxy: observer, aim comes from replicated transform — nothing to do } else { ComputeAntiRecoilTransform(); diff --git a/Unreal/Plugins/PS_Ballistics/Source/EasyBallistics/Public/EBBarrel.h b/Unreal/Plugins/PS_Ballistics/Source/EasyBallistics/Public/EBBarrel.h index 057e3f9..5b7aec1 100644 --- a/Unreal/Plugins/PS_Ballistics/Source/EasyBallistics/Public/EBBarrel.h +++ b/Unreal/Plugins/PS_Ballistics/Source/EasyBallistics/Public/EBBarrel.h @@ -226,8 +226,8 @@ public: bool ReplicateShotFiredEvents = true; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Replication", meta = (ToolTip = "When true, the owning client computes the barrel aim position/direction locally and sends it to the server via RPC. The server uses the client's aim to spawn the bullet. Essential for VR/tracked controllers where the server cannot know the exact barrel orientation. When false, the server uses the barrel component's replicated transform.")) bool ClientSideAim=false; - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Replication", meta = (ToolTip = "How often (Hz) the client sends aim updates to the server when ClientSideAim is true. Higher values = more accurate server-side aim at the cost of bandwidth. 15 Hz is a good default. Only relevant when ClientSideAim is enabled.", EditCondition = "ClientSideAim", ClampMin = "1")) - float ClientAimUpdateFrequency = 15.0f; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Replication", meta = (ToolTip = "How often (Hz) the owning client sends aim updates to the server when ClientSideAim is true. Higher values = more accurate server-side aim at the cost of bandwidth. 60 Hz matches typical VR tracking rates. Only relevant when ClientSideAim is enabled. Only the owning client sends these updates (observers skip the RPC).", EditCondition = "ClientSideAim", ClampMin = "1")) + float ClientAimUpdateFrequency = 60.0f; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Replication", meta = (ToolTip = "Maximum allowed distance (UU/cm) between the client-reported aim position and the server's barrel position. Acts as an anti-cheat clamp: if the client aim is further than this, the server clamps it. 200 = 2 meters. Set higher if the tracker has large offsets from the replicated barrel position.", EditCondition = "ClientSideAim", ClampMin = "0")) float ClientAimDistanceLimit = 200.0f;