void ReplicateObject(float dt, SerializableObject obj, Actor actor, ObjectReplicator replicator, bool isOwner, bool isRelevant, ref NetMsgs.ReplicatedObjectData msg) { Perf.Begin("ActorReplicationChannel.ReplicateObject"); Assert.IsFalse((actor != null) ? actor.netTornOff : false); bool wroteAnything = false; // start on a byte boundary so we can restore the position to this point if we don't write any data. msg.archive.Flush(); msg = msg.MaybeSend(connection); var position = msg.archive.Position; bool relevancyChanged = true; CHECK_FLD(msg.archive); if (replicator == null) { replicator = obj.internal_GetReplicator(connection); } if (replicator == null) { replicator = new ObjectReplicator(this, obj, connection.world.InternalGetReplicatedFields(obj), isOwner); obj.internal_SetReplicator(connection, replicator); msg.archive.Write((ushort)obj.netID); CHECK_FLD(msg.archive); // actor has not been replicated yet msg.archive.WriteUnsignedBits(1, 1); msg.archive.WriteUnsignedBits(isRelevant ? 1 : 0, 1); msg.archive.WriteUnsignedBits(((actor != null) && (actor.internal_NetTearOff)) ? 1 : 0, 1); CHECK_FLD(msg.archive); msg.archive.Write((ushort)((obj.outer is SerializableObject) ? (obj.outer as SerializableObject).netID : 0)); msg.archive.Write(obj.classID); CHECK_FLD(msg.archive); replicator.FullSerialize(dt, msg.archive); SerializeCustomData(obj, msg.archive); wroteAnything = true; } else { relevancyChanged = replicator.wasRelevant != isRelevant; bool replicate = true; if ((dt >= 0f) && (actor != null) && !actor.internal_NetTearOff && !actor.internal_NetFlush && !relevancyChanged) { replicator.serializeDeltaTime += dt; if (replicator.serializeDeltaTime < actor.replicateRate) { replicate = false; } } if (replicate) { msg.archive.Write((ushort)obj.netID); CHECK_FLD(msg.archive); msg.archive.WriteUnsignedBits(0, 1); msg.archive.WriteUnsignedBits(isRelevant ? 1 : 0, 1); msg.archive.WriteUnsignedBits(((actor != null) && (actor.internal_NetTearOff)) ? 1 : 0, 1); CHECK_FLD(msg.archive); wroteAnything = replicator.DeltaSerialize(dt, msg.archive, (actor != null) && (actor.internal_NetFlush || relevancyChanged)); wroteAnything = SerializeCustomData(obj, msg.archive) || wroteAnything; } } if (wroteAnything || ((actor != null) && (actor.internal_NetFlush || relevancyChanged))) { CHECK_FLD(msg.archive); obj.SerializeSubobjects(this); } else { msg.archive.Position = position; msg.archive.Discard(); } replicator.wasRelevant = isRelevant; if ((actor != null) && actor.internal_NetTearOff) { obj.internal_SetReplicator(connection, null); } Perf.End(); }