KActor Replication
How it works
The code is based on the replication technique found in KCar. Every tick, the server checks the location, linear and angular velocity of the actor, and if it differs much from when the last replication occured or if more time than MaxNetUpdateInterval has elapsed, the state of the actor on the server will be stored in a variable that is replicated to clients. On recieving the new state, the actor on the client will apply the new state to itself.
Note that RemoteRole is set to ROLE_SimulatedProxy, bNetNotify is set to true (so that PostNetReceive is called on the client) and the KarmaParams property bClientOnly is set to false (so Karma is simulated on the server as well as the client).
The code
class LawDogsKActor extends KActor placeable; var() float MaxNetUpdateInterval; var float NextNetUpdateTime; var KRigidBodyState KState, KRepState; var bool bNewKState; var int StateCount, LastStateCount; replication { unreliable if(Role == ROLE_Authority) KRepState, StateCount; } function Tick(float Delta) { PackState(); } //Pack current state to be replicated function PackState() { local bool bChanged; if(!KIsAwake()) return; KGetRigidBodyState(KState); bChanged = Level.TimeSeconds > NextNetUpdateTime; bChanged = bChanged || VSize(KRBVecToVector(KState.Position) - KRBVecToVector(KRepState.Position)) > 5; bChanged = bChanged || VSize(KRBVecToVector(KState.LinVel) - KRBVecToVector(KRepState.LinVel)) > 1; bChanged = bChanged || VSize(KRBVecToVector(KState.AngVel) - KRBVecToVector(KRepState.AngVel)) > 1; if(bChanged) { NextNetUpdateTime = Level.TimeSeconds + MaxNetUpdateInterval; KRepState = KState; StateCount++; } else return; } //New state recieved. simulated event PostNetReceive() { if(StateCount == LastStateCount) return; } //Apply new state. simulated event bool KUpdateState(out KRigidBodyState newState) { //This should never get called on the server - but just in case! if(Role == ROLE_Authority || StateCount == LastStateCount) return false; //Apply received data as new position of actor. newState = KRepState; StateCount = LastStateCount; return true; } defaultproperties { MaxNetUpdateInterval=0.5 StaticMesh=StaticMesh'MiscPhysicsMeshes.Barrels.Barrel' Begin Object Class=KarmaParams Name=KarmaParams0 KMass=0.5 bHighDetailOnly=False bKAllowRotate=True KFriction=0.2 KRestitution=0.5 KImpactThreshold=1000.0 bClientOnly=False Name="KarmaParams0" End Object KParams=KarmaParams'KarmaParams0' RemoteRole=ROLE_SimulatedProxy bNetNotify=True }
Related Topics
Foxpaw: I think this page could be called something else.. KActor is just a class that you can use to make karma physics objects.. kind of like staticmeshactor. Any actor can have a static mesh, and any actor can use Karma physics.. so I think this should have a more general name seeing as this applies to more than just KActors.
Kaoh: Yeah but the replication technique is special for karma actors. Its not needed for other actors, So I feel it applies.
Foxpaw: What I'm saying is, KActor is just a class that happens to use Karma physics. There are many karma actors that aren't KActors, so I think a more general name would be better.