Unity NetworkTransform, force update every Frame?
On a purposed LAN setup, I want Unity's NetworkTransform
to simply send every single frame. (Mode is "Sync Transform", not rigidbody, etc.)
I'm wondering how to do this .. if you just set the send rate to 0.00001 will it in fact do it every frame that the object is moving?
(The Inspector interface only allows up to 29Hz, simply set it in code if you want smaller values.)
I was also thinking something like on a script......
void Update() { .. SetDirtyBit( ? ); }
would that do it?
(And, what do you use as a bitmask there?)
It really takes forever to determine this sort of thing experimentally. Obviously Unity's doco is a joke. And I couldn't google anyone who'd already figured it. Any experience in this?
Secondly...
Further information. We did some experiments and indeed if you set it to a very small value, it does seem to sync the NetworkTransform
every single frame.
(Of course, it doesn't bother sending if it has not moved, as @Programmer points out below.)
H O W E V E R this does not produce smooth results for kinematic objects or camera positions. I don't know why; it has to do with the Update loop and exactly when the change takes place. But what you get is a "very fine jitter".
Thirdly...
I did an experiment, simply using Commands and Rpcs, to send some information every frame (actually from one client to another).
I specifically used a purpose solo ethernet network and the apps do little or nothing other than send the info every frame (ie "manually" just using Command/Rpc), ie on Update().
In fact, it still drops many frames, it's often not sent. (Let's say, it misses 10 or 20 in 10 seconds worth.)
Good grief!
Do not bother doing this if you need some info sent "every frame", say on a LAN system.
unity3d unity3d-unet
|
show 1 more comment
On a purposed LAN setup, I want Unity's NetworkTransform
to simply send every single frame. (Mode is "Sync Transform", not rigidbody, etc.)
I'm wondering how to do this .. if you just set the send rate to 0.00001 will it in fact do it every frame that the object is moving?
(The Inspector interface only allows up to 29Hz, simply set it in code if you want smaller values.)
I was also thinking something like on a script......
void Update() { .. SetDirtyBit( ? ); }
would that do it?
(And, what do you use as a bitmask there?)
It really takes forever to determine this sort of thing experimentally. Obviously Unity's doco is a joke. And I couldn't google anyone who'd already figured it. Any experience in this?
Secondly...
Further information. We did some experiments and indeed if you set it to a very small value, it does seem to sync the NetworkTransform
every single frame.
(Of course, it doesn't bother sending if it has not moved, as @Programmer points out below.)
H O W E V E R this does not produce smooth results for kinematic objects or camera positions. I don't know why; it has to do with the Update loop and exactly when the change takes place. But what you get is a "very fine jitter".
Thirdly...
I did an experiment, simply using Commands and Rpcs, to send some information every frame (actually from one client to another).
I specifically used a purpose solo ethernet network and the apps do little or nothing other than send the info every frame (ie "manually" just using Command/Rpc), ie on Update().
In fact, it still drops many frames, it's often not sent. (Let's say, it misses 10 or 20 in 10 seconds worth.)
Good grief!
Do not bother doing this if you need some info sent "every frame", say on a LAN system.
unity3d unity3d-unet
Afaik NetworkTransform also tries to a certain limit to predict movements if using RigidBody .. maybe that causes the jitter? For me the NetworkTransform never worked well and I ended up writing a custom one with Commands, Rpcs and interpolation of the position. forum.unity.com/threads/network-transform-lags.334718
– derHugo
Nov 14 '18 at 6:42
1
(Right, I was not using RigidBody. Yes, their system is trash; this is more of a curiosity investigation :) )
– Fattie
Nov 14 '18 at 6:54
Yeah thats why they start over
– derHugo
Nov 14 '18 at 6:58
ah I did not know that @derHugo . I heard it from you first! Geesh ... yet another attempt by Unity at networking :/
– Fattie
Nov 14 '18 at 7:01
yeah we all hope that will be a better one .. so far we ended up writing our complete own networking using very low level socket connections (after allc#
is stillc
;) )
– derHugo
Nov 14 '18 at 7:03
|
show 1 more comment
On a purposed LAN setup, I want Unity's NetworkTransform
to simply send every single frame. (Mode is "Sync Transform", not rigidbody, etc.)
I'm wondering how to do this .. if you just set the send rate to 0.00001 will it in fact do it every frame that the object is moving?
(The Inspector interface only allows up to 29Hz, simply set it in code if you want smaller values.)
I was also thinking something like on a script......
void Update() { .. SetDirtyBit( ? ); }
would that do it?
(And, what do you use as a bitmask there?)
It really takes forever to determine this sort of thing experimentally. Obviously Unity's doco is a joke. And I couldn't google anyone who'd already figured it. Any experience in this?
Secondly...
Further information. We did some experiments and indeed if you set it to a very small value, it does seem to sync the NetworkTransform
every single frame.
(Of course, it doesn't bother sending if it has not moved, as @Programmer points out below.)
H O W E V E R this does not produce smooth results for kinematic objects or camera positions. I don't know why; it has to do with the Update loop and exactly when the change takes place. But what you get is a "very fine jitter".
Thirdly...
I did an experiment, simply using Commands and Rpcs, to send some information every frame (actually from one client to another).
I specifically used a purpose solo ethernet network and the apps do little or nothing other than send the info every frame (ie "manually" just using Command/Rpc), ie on Update().
In fact, it still drops many frames, it's often not sent. (Let's say, it misses 10 or 20 in 10 seconds worth.)
Good grief!
Do not bother doing this if you need some info sent "every frame", say on a LAN system.
unity3d unity3d-unet
On a purposed LAN setup, I want Unity's NetworkTransform
to simply send every single frame. (Mode is "Sync Transform", not rigidbody, etc.)
I'm wondering how to do this .. if you just set the send rate to 0.00001 will it in fact do it every frame that the object is moving?
(The Inspector interface only allows up to 29Hz, simply set it in code if you want smaller values.)
I was also thinking something like on a script......
void Update() { .. SetDirtyBit( ? ); }
would that do it?
(And, what do you use as a bitmask there?)
It really takes forever to determine this sort of thing experimentally. Obviously Unity's doco is a joke. And I couldn't google anyone who'd already figured it. Any experience in this?
Secondly...
Further information. We did some experiments and indeed if you set it to a very small value, it does seem to sync the NetworkTransform
every single frame.
(Of course, it doesn't bother sending if it has not moved, as @Programmer points out below.)
H O W E V E R this does not produce smooth results for kinematic objects or camera positions. I don't know why; it has to do with the Update loop and exactly when the change takes place. But what you get is a "very fine jitter".
Thirdly...
I did an experiment, simply using Commands and Rpcs, to send some information every frame (actually from one client to another).
I specifically used a purpose solo ethernet network and the apps do little or nothing other than send the info every frame (ie "manually" just using Command/Rpc), ie on Update().
In fact, it still drops many frames, it's often not sent. (Let's say, it misses 10 or 20 in 10 seconds worth.)
Good grief!
Do not bother doing this if you need some info sent "every frame", say on a LAN system.
unity3d unity3d-unet
unity3d unity3d-unet
edited Nov 14 '18 at 7:06
Fattie
asked Nov 13 '18 at 16:48
FattieFattie
20.1k31199437
20.1k31199437
Afaik NetworkTransform also tries to a certain limit to predict movements if using RigidBody .. maybe that causes the jitter? For me the NetworkTransform never worked well and I ended up writing a custom one with Commands, Rpcs and interpolation of the position. forum.unity.com/threads/network-transform-lags.334718
– derHugo
Nov 14 '18 at 6:42
1
(Right, I was not using RigidBody. Yes, their system is trash; this is more of a curiosity investigation :) )
– Fattie
Nov 14 '18 at 6:54
Yeah thats why they start over
– derHugo
Nov 14 '18 at 6:58
ah I did not know that @derHugo . I heard it from you first! Geesh ... yet another attempt by Unity at networking :/
– Fattie
Nov 14 '18 at 7:01
yeah we all hope that will be a better one .. so far we ended up writing our complete own networking using very low level socket connections (after allc#
is stillc
;) )
– derHugo
Nov 14 '18 at 7:03
|
show 1 more comment
Afaik NetworkTransform also tries to a certain limit to predict movements if using RigidBody .. maybe that causes the jitter? For me the NetworkTransform never worked well and I ended up writing a custom one with Commands, Rpcs and interpolation of the position. forum.unity.com/threads/network-transform-lags.334718
– derHugo
Nov 14 '18 at 6:42
1
(Right, I was not using RigidBody. Yes, their system is trash; this is more of a curiosity investigation :) )
– Fattie
Nov 14 '18 at 6:54
Yeah thats why they start over
– derHugo
Nov 14 '18 at 6:58
ah I did not know that @derHugo . I heard it from you first! Geesh ... yet another attempt by Unity at networking :/
– Fattie
Nov 14 '18 at 7:01
yeah we all hope that will be a better one .. so far we ended up writing our complete own networking using very low level socket connections (after allc#
is stillc
;) )
– derHugo
Nov 14 '18 at 7:03
Afaik NetworkTransform also tries to a certain limit to predict movements if using RigidBody .. maybe that causes the jitter? For me the NetworkTransform never worked well and I ended up writing a custom one with Commands, Rpcs and interpolation of the position. forum.unity.com/threads/network-transform-lags.334718
– derHugo
Nov 14 '18 at 6:42
Afaik NetworkTransform also tries to a certain limit to predict movements if using RigidBody .. maybe that causes the jitter? For me the NetworkTransform never worked well and I ended up writing a custom one with Commands, Rpcs and interpolation of the position. forum.unity.com/threads/network-transform-lags.334718
– derHugo
Nov 14 '18 at 6:42
1
1
(Right, I was not using RigidBody. Yes, their system is trash; this is more of a curiosity investigation :) )
– Fattie
Nov 14 '18 at 6:54
(Right, I was not using RigidBody. Yes, their system is trash; this is more of a curiosity investigation :) )
– Fattie
Nov 14 '18 at 6:54
Yeah thats why they start over
– derHugo
Nov 14 '18 at 6:58
Yeah thats why they start over
– derHugo
Nov 14 '18 at 6:58
ah I did not know that @derHugo . I heard it from you first! Geesh ... yet another attempt by Unity at networking :/
– Fattie
Nov 14 '18 at 7:01
ah I did not know that @derHugo . I heard it from you first! Geesh ... yet another attempt by Unity at networking :/
– Fattie
Nov 14 '18 at 7:01
yeah we all hope that will be a better one .. so far we ended up writing our complete own networking using very low level socket connections (after all
c#
is still c
;) )– derHugo
Nov 14 '18 at 7:03
yeah we all hope that will be a better one .. so far we ended up writing our complete own networking using very low level socket connections (after all
c#
is still c
;) )– derHugo
Nov 14 '18 at 7:03
|
show 1 more comment
2 Answers
2
active
oldest
votes
In the Unity Docs It says
If sendInterval is zero, updates will be sent at the end of the frame when dirty bits are set for that script. Note that setting the value of a SyncVar will automatically set dirty bits.
So you could use your own script using NetworkSettings
using UnityEngine.Networking;
[NetworkSettings(channel = 1, sendInterval = 0.0f)]
class MyScript : NetworkBehaviour
{
[SyncVar]
int value;
}
However SyncVar
only works Server -> Client.
But you can use SetDirtyBit to manually set the behaviour dirty.
Or you probably could also use InvokeSyncEvent to synchronize some values directly.
Here I found a bit more information on Dirty bits.
I really did not know aboutNetworkSettings
, orInvokeSyncEvent
! I believe though those are not forNetworkTransform
, only SyncVars ?? IDK
– Fattie
Nov 14 '18 at 3:14
Never tried it but it is also possible that if you call a Command in Update it might really be send every frame while sendInterval only applies to the SyncVar. I'm not sure on this. In general you would have to write your own custom NetworkTransform script e.g. using a combination of [SyncVar] and Command (Might be something like this but there are other examples, too). Unfortunately the whole Unity docs concentrates on Server -> Client syncronisation...
– derHugo
Nov 14 '18 at 4:48
add a comment |
if you just set the send rate to 0.00001 will it in fact do it every
frame that the object is moving?
Yes, but when the Object's transform is not moving or rotating, it's not updated over the network regardless of the value of NetworkTransform.sendInterval
.
I was also thinking something like on a script......
void Update() { .. SetDirtyBit( ? ); }
Yes. You need to call SetDirtyBit
every frame if you need the network update to be sent for the object.
And, what do you use as a bitmask there?
The SetDirtyBit
function is technically the function version of the SyncVar
attribute. The argument is not really documented that much but if SyncVar
marked variable is changed, its dirty mask is changed to 1
. This also means that you should pass 1
to the SetDirtyBit
function if you want network update to be sent for the object.
You should also use it from a function marked with the [Command]
attribute instead of directly from the Update
function. Something like below:
void Update()
{
if (isLocalPlayer)
{
CmdUpdateTransform();
}
}
[Command]
void CmdUpdateTransform()
{
SetDirtyBit(1u);
}
While Unity claims you can update the transform by simply using the SetDirtyBit
function. I don't think this is true. The statement is missing lots of information. You will need OnSerialize
to serialize and send the data and OnDeserialize
to receive and de-serialize it. The SetDirtyBit
function is simply used to determine which data to send. It's used to reduce bandwidth issues that comes from using uNET.
The code below shows what the use of SetDirtyBit
should look like. It might need few changes to work on your side.
public class Example : NetworkBehaviour
{
private const uint SEND_POSITION = 1u;
private const uint SEND_ROTATION = 2u;
private const uint SEND_SCALE = 3u;
void Update()
{
uint dirtyBit = syncVarDirtyBits;
dirtyBit |= SEND_POSITION;
dirtyBit |= SEND_ROTATION;
dirtyBit |= SEND_SCALE;
if (isLocalPlayer)
{
CmdUpdateTransform(dirtyBit);
}
}
[Command]
void CmdUpdateTransform(uint dirtyBit)
{
SetDirtyBit(dirtyBit);
}
public override bool OnSerialize(NetworkWriter writer, bool initialState)
{
if ((this.syncVarDirtyBits & SEND_POSITION) != 0u)
{
writer.Write(this.transform.position);
}
if ((this.syncVarDirtyBits & SEND_ROTATION) != 0u)
{
writer.Write(this.transform.rotation);
}
if ((this.syncVarDirtyBits & SEND_SCALE) != 0u)
{
writer.Write(this.transform.localScale);
}
return true;
}
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
if ((this.syncVarDirtyBits & SEND_POSITION) != 0u)
{
Vector3 pos = reader.ReadVector3();
}
if ((this.syncVarDirtyBits & SEND_ROTATION) != 0u)
{
Quaternion rot = reader.ReadQuaternion();
}
if ((this.syncVarDirtyBits & SEND_SCALE) != 0u)
{
Vector3 scale = reader.ReadVector3();
}
}
}
Good one. So to summarize, (1) it seems thatSetDirtyBit
is actually only relevant to SyncVars? It does not work forNetworkTransform
?
– Fattie
Nov 14 '18 at 3:15
SetDirtyBit is the manual way of sending data instead of using SyncVar which will automatically do that for you when you make a variable with the SyncVars attribute. SetDirtyBit is not related to NetworkTransform. You can use it to send any type of data over the network. I think that the documentation is not clear on this. Calling SetDirtyBit will cause Unity to call OnSerialize() and OnDeserialize() and there you can add the custom data to send like the example in my answer. For example,you can send the position, rotation and scale of the object.
– Programmer
Nov 14 '18 at 5:15
The good side of using it is that you can decide when to update the variable unlikeSyncVar
which simply updates based on the send rate. This is really important when it comes to bandwidth management. Imaging having ~12 variables for each 12 player you want to update over the network and they are marked asSyncVar
, they will be updating at whatever the send rate is set to. You can't control when to stop them from updating over the network. WithSetDirtyBit
, you can and it saves bandwidth and processing time.
– Programmer
Nov 14 '18 at 5:21
1
Ah ok. So SetDirtyBit does not relate to NetworkTransform, and it does not relate to SyncVars ! It's just "a way to send info (using the Serialize functions)". Is that about right??! Thanks! :)
– Fattie
Nov 14 '18 at 5:25
Yes, that's correct and I think the doc is saying that if you want to update the transform manually, you should setsendInterval
to0
, call SetDirtyBits then use OnSerialize() and OnDeserialize() to send the transform information. They left that last part out.
– Programmer
Nov 14 '18 at 5:30
|
show 14 more comments
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53285808%2funity-networktransform-force-update-every-frame%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
In the Unity Docs It says
If sendInterval is zero, updates will be sent at the end of the frame when dirty bits are set for that script. Note that setting the value of a SyncVar will automatically set dirty bits.
So you could use your own script using NetworkSettings
using UnityEngine.Networking;
[NetworkSettings(channel = 1, sendInterval = 0.0f)]
class MyScript : NetworkBehaviour
{
[SyncVar]
int value;
}
However SyncVar
only works Server -> Client.
But you can use SetDirtyBit to manually set the behaviour dirty.
Or you probably could also use InvokeSyncEvent to synchronize some values directly.
Here I found a bit more information on Dirty bits.
I really did not know aboutNetworkSettings
, orInvokeSyncEvent
! I believe though those are not forNetworkTransform
, only SyncVars ?? IDK
– Fattie
Nov 14 '18 at 3:14
Never tried it but it is also possible that if you call a Command in Update it might really be send every frame while sendInterval only applies to the SyncVar. I'm not sure on this. In general you would have to write your own custom NetworkTransform script e.g. using a combination of [SyncVar] and Command (Might be something like this but there are other examples, too). Unfortunately the whole Unity docs concentrates on Server -> Client syncronisation...
– derHugo
Nov 14 '18 at 4:48
add a comment |
In the Unity Docs It says
If sendInterval is zero, updates will be sent at the end of the frame when dirty bits are set for that script. Note that setting the value of a SyncVar will automatically set dirty bits.
So you could use your own script using NetworkSettings
using UnityEngine.Networking;
[NetworkSettings(channel = 1, sendInterval = 0.0f)]
class MyScript : NetworkBehaviour
{
[SyncVar]
int value;
}
However SyncVar
only works Server -> Client.
But you can use SetDirtyBit to manually set the behaviour dirty.
Or you probably could also use InvokeSyncEvent to synchronize some values directly.
Here I found a bit more information on Dirty bits.
I really did not know aboutNetworkSettings
, orInvokeSyncEvent
! I believe though those are not forNetworkTransform
, only SyncVars ?? IDK
– Fattie
Nov 14 '18 at 3:14
Never tried it but it is also possible that if you call a Command in Update it might really be send every frame while sendInterval only applies to the SyncVar. I'm not sure on this. In general you would have to write your own custom NetworkTransform script e.g. using a combination of [SyncVar] and Command (Might be something like this but there are other examples, too). Unfortunately the whole Unity docs concentrates on Server -> Client syncronisation...
– derHugo
Nov 14 '18 at 4:48
add a comment |
In the Unity Docs It says
If sendInterval is zero, updates will be sent at the end of the frame when dirty bits are set for that script. Note that setting the value of a SyncVar will automatically set dirty bits.
So you could use your own script using NetworkSettings
using UnityEngine.Networking;
[NetworkSettings(channel = 1, sendInterval = 0.0f)]
class MyScript : NetworkBehaviour
{
[SyncVar]
int value;
}
However SyncVar
only works Server -> Client.
But you can use SetDirtyBit to manually set the behaviour dirty.
Or you probably could also use InvokeSyncEvent to synchronize some values directly.
Here I found a bit more information on Dirty bits.
In the Unity Docs It says
If sendInterval is zero, updates will be sent at the end of the frame when dirty bits are set for that script. Note that setting the value of a SyncVar will automatically set dirty bits.
So you could use your own script using NetworkSettings
using UnityEngine.Networking;
[NetworkSettings(channel = 1, sendInterval = 0.0f)]
class MyScript : NetworkBehaviour
{
[SyncVar]
int value;
}
However SyncVar
only works Server -> Client.
But you can use SetDirtyBit to manually set the behaviour dirty.
Or you probably could also use InvokeSyncEvent to synchronize some values directly.
Here I found a bit more information on Dirty bits.
edited Nov 13 '18 at 21:00
answered Nov 13 '18 at 18:32
derHugoderHugo
5,11421029
5,11421029
I really did not know aboutNetworkSettings
, orInvokeSyncEvent
! I believe though those are not forNetworkTransform
, only SyncVars ?? IDK
– Fattie
Nov 14 '18 at 3:14
Never tried it but it is also possible that if you call a Command in Update it might really be send every frame while sendInterval only applies to the SyncVar. I'm not sure on this. In general you would have to write your own custom NetworkTransform script e.g. using a combination of [SyncVar] and Command (Might be something like this but there are other examples, too). Unfortunately the whole Unity docs concentrates on Server -> Client syncronisation...
– derHugo
Nov 14 '18 at 4:48
add a comment |
I really did not know aboutNetworkSettings
, orInvokeSyncEvent
! I believe though those are not forNetworkTransform
, only SyncVars ?? IDK
– Fattie
Nov 14 '18 at 3:14
Never tried it but it is also possible that if you call a Command in Update it might really be send every frame while sendInterval only applies to the SyncVar. I'm not sure on this. In general you would have to write your own custom NetworkTransform script e.g. using a combination of [SyncVar] and Command (Might be something like this but there are other examples, too). Unfortunately the whole Unity docs concentrates on Server -> Client syncronisation...
– derHugo
Nov 14 '18 at 4:48
I really did not know about
NetworkSettings
, or InvokeSyncEvent
! I believe though those are not for NetworkTransform
, only SyncVars ?? IDK– Fattie
Nov 14 '18 at 3:14
I really did not know about
NetworkSettings
, or InvokeSyncEvent
! I believe though those are not for NetworkTransform
, only SyncVars ?? IDK– Fattie
Nov 14 '18 at 3:14
Never tried it but it is also possible that if you call a Command in Update it might really be send every frame while sendInterval only applies to the SyncVar. I'm not sure on this. In general you would have to write your own custom NetworkTransform script e.g. using a combination of [SyncVar] and Command (Might be something like this but there are other examples, too). Unfortunately the whole Unity docs concentrates on Server -> Client syncronisation...
– derHugo
Nov 14 '18 at 4:48
Never tried it but it is also possible that if you call a Command in Update it might really be send every frame while sendInterval only applies to the SyncVar. I'm not sure on this. In general you would have to write your own custom NetworkTransform script e.g. using a combination of [SyncVar] and Command (Might be something like this but there are other examples, too). Unfortunately the whole Unity docs concentrates on Server -> Client syncronisation...
– derHugo
Nov 14 '18 at 4:48
add a comment |
if you just set the send rate to 0.00001 will it in fact do it every
frame that the object is moving?
Yes, but when the Object's transform is not moving or rotating, it's not updated over the network regardless of the value of NetworkTransform.sendInterval
.
I was also thinking something like on a script......
void Update() { .. SetDirtyBit( ? ); }
Yes. You need to call SetDirtyBit
every frame if you need the network update to be sent for the object.
And, what do you use as a bitmask there?
The SetDirtyBit
function is technically the function version of the SyncVar
attribute. The argument is not really documented that much but if SyncVar
marked variable is changed, its dirty mask is changed to 1
. This also means that you should pass 1
to the SetDirtyBit
function if you want network update to be sent for the object.
You should also use it from a function marked with the [Command]
attribute instead of directly from the Update
function. Something like below:
void Update()
{
if (isLocalPlayer)
{
CmdUpdateTransform();
}
}
[Command]
void CmdUpdateTransform()
{
SetDirtyBit(1u);
}
While Unity claims you can update the transform by simply using the SetDirtyBit
function. I don't think this is true. The statement is missing lots of information. You will need OnSerialize
to serialize and send the data and OnDeserialize
to receive and de-serialize it. The SetDirtyBit
function is simply used to determine which data to send. It's used to reduce bandwidth issues that comes from using uNET.
The code below shows what the use of SetDirtyBit
should look like. It might need few changes to work on your side.
public class Example : NetworkBehaviour
{
private const uint SEND_POSITION = 1u;
private const uint SEND_ROTATION = 2u;
private const uint SEND_SCALE = 3u;
void Update()
{
uint dirtyBit = syncVarDirtyBits;
dirtyBit |= SEND_POSITION;
dirtyBit |= SEND_ROTATION;
dirtyBit |= SEND_SCALE;
if (isLocalPlayer)
{
CmdUpdateTransform(dirtyBit);
}
}
[Command]
void CmdUpdateTransform(uint dirtyBit)
{
SetDirtyBit(dirtyBit);
}
public override bool OnSerialize(NetworkWriter writer, bool initialState)
{
if ((this.syncVarDirtyBits & SEND_POSITION) != 0u)
{
writer.Write(this.transform.position);
}
if ((this.syncVarDirtyBits & SEND_ROTATION) != 0u)
{
writer.Write(this.transform.rotation);
}
if ((this.syncVarDirtyBits & SEND_SCALE) != 0u)
{
writer.Write(this.transform.localScale);
}
return true;
}
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
if ((this.syncVarDirtyBits & SEND_POSITION) != 0u)
{
Vector3 pos = reader.ReadVector3();
}
if ((this.syncVarDirtyBits & SEND_ROTATION) != 0u)
{
Quaternion rot = reader.ReadQuaternion();
}
if ((this.syncVarDirtyBits & SEND_SCALE) != 0u)
{
Vector3 scale = reader.ReadVector3();
}
}
}
Good one. So to summarize, (1) it seems thatSetDirtyBit
is actually only relevant to SyncVars? It does not work forNetworkTransform
?
– Fattie
Nov 14 '18 at 3:15
SetDirtyBit is the manual way of sending data instead of using SyncVar which will automatically do that for you when you make a variable with the SyncVars attribute. SetDirtyBit is not related to NetworkTransform. You can use it to send any type of data over the network. I think that the documentation is not clear on this. Calling SetDirtyBit will cause Unity to call OnSerialize() and OnDeserialize() and there you can add the custom data to send like the example in my answer. For example,you can send the position, rotation and scale of the object.
– Programmer
Nov 14 '18 at 5:15
The good side of using it is that you can decide when to update the variable unlikeSyncVar
which simply updates based on the send rate. This is really important when it comes to bandwidth management. Imaging having ~12 variables for each 12 player you want to update over the network and they are marked asSyncVar
, they will be updating at whatever the send rate is set to. You can't control when to stop them from updating over the network. WithSetDirtyBit
, you can and it saves bandwidth and processing time.
– Programmer
Nov 14 '18 at 5:21
1
Ah ok. So SetDirtyBit does not relate to NetworkTransform, and it does not relate to SyncVars ! It's just "a way to send info (using the Serialize functions)". Is that about right??! Thanks! :)
– Fattie
Nov 14 '18 at 5:25
Yes, that's correct and I think the doc is saying that if you want to update the transform manually, you should setsendInterval
to0
, call SetDirtyBits then use OnSerialize() and OnDeserialize() to send the transform information. They left that last part out.
– Programmer
Nov 14 '18 at 5:30
|
show 14 more comments
if you just set the send rate to 0.00001 will it in fact do it every
frame that the object is moving?
Yes, but when the Object's transform is not moving or rotating, it's not updated over the network regardless of the value of NetworkTransform.sendInterval
.
I was also thinking something like on a script......
void Update() { .. SetDirtyBit( ? ); }
Yes. You need to call SetDirtyBit
every frame if you need the network update to be sent for the object.
And, what do you use as a bitmask there?
The SetDirtyBit
function is technically the function version of the SyncVar
attribute. The argument is not really documented that much but if SyncVar
marked variable is changed, its dirty mask is changed to 1
. This also means that you should pass 1
to the SetDirtyBit
function if you want network update to be sent for the object.
You should also use it from a function marked with the [Command]
attribute instead of directly from the Update
function. Something like below:
void Update()
{
if (isLocalPlayer)
{
CmdUpdateTransform();
}
}
[Command]
void CmdUpdateTransform()
{
SetDirtyBit(1u);
}
While Unity claims you can update the transform by simply using the SetDirtyBit
function. I don't think this is true. The statement is missing lots of information. You will need OnSerialize
to serialize and send the data and OnDeserialize
to receive and de-serialize it. The SetDirtyBit
function is simply used to determine which data to send. It's used to reduce bandwidth issues that comes from using uNET.
The code below shows what the use of SetDirtyBit
should look like. It might need few changes to work on your side.
public class Example : NetworkBehaviour
{
private const uint SEND_POSITION = 1u;
private const uint SEND_ROTATION = 2u;
private const uint SEND_SCALE = 3u;
void Update()
{
uint dirtyBit = syncVarDirtyBits;
dirtyBit |= SEND_POSITION;
dirtyBit |= SEND_ROTATION;
dirtyBit |= SEND_SCALE;
if (isLocalPlayer)
{
CmdUpdateTransform(dirtyBit);
}
}
[Command]
void CmdUpdateTransform(uint dirtyBit)
{
SetDirtyBit(dirtyBit);
}
public override bool OnSerialize(NetworkWriter writer, bool initialState)
{
if ((this.syncVarDirtyBits & SEND_POSITION) != 0u)
{
writer.Write(this.transform.position);
}
if ((this.syncVarDirtyBits & SEND_ROTATION) != 0u)
{
writer.Write(this.transform.rotation);
}
if ((this.syncVarDirtyBits & SEND_SCALE) != 0u)
{
writer.Write(this.transform.localScale);
}
return true;
}
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
if ((this.syncVarDirtyBits & SEND_POSITION) != 0u)
{
Vector3 pos = reader.ReadVector3();
}
if ((this.syncVarDirtyBits & SEND_ROTATION) != 0u)
{
Quaternion rot = reader.ReadQuaternion();
}
if ((this.syncVarDirtyBits & SEND_SCALE) != 0u)
{
Vector3 scale = reader.ReadVector3();
}
}
}
Good one. So to summarize, (1) it seems thatSetDirtyBit
is actually only relevant to SyncVars? It does not work forNetworkTransform
?
– Fattie
Nov 14 '18 at 3:15
SetDirtyBit is the manual way of sending data instead of using SyncVar which will automatically do that for you when you make a variable with the SyncVars attribute. SetDirtyBit is not related to NetworkTransform. You can use it to send any type of data over the network. I think that the documentation is not clear on this. Calling SetDirtyBit will cause Unity to call OnSerialize() and OnDeserialize() and there you can add the custom data to send like the example in my answer. For example,you can send the position, rotation and scale of the object.
– Programmer
Nov 14 '18 at 5:15
The good side of using it is that you can decide when to update the variable unlikeSyncVar
which simply updates based on the send rate. This is really important when it comes to bandwidth management. Imaging having ~12 variables for each 12 player you want to update over the network and they are marked asSyncVar
, they will be updating at whatever the send rate is set to. You can't control when to stop them from updating over the network. WithSetDirtyBit
, you can and it saves bandwidth and processing time.
– Programmer
Nov 14 '18 at 5:21
1
Ah ok. So SetDirtyBit does not relate to NetworkTransform, and it does not relate to SyncVars ! It's just "a way to send info (using the Serialize functions)". Is that about right??! Thanks! :)
– Fattie
Nov 14 '18 at 5:25
Yes, that's correct and I think the doc is saying that if you want to update the transform manually, you should setsendInterval
to0
, call SetDirtyBits then use OnSerialize() and OnDeserialize() to send the transform information. They left that last part out.
– Programmer
Nov 14 '18 at 5:30
|
show 14 more comments
if you just set the send rate to 0.00001 will it in fact do it every
frame that the object is moving?
Yes, but when the Object's transform is not moving or rotating, it's not updated over the network regardless of the value of NetworkTransform.sendInterval
.
I was also thinking something like on a script......
void Update() { .. SetDirtyBit( ? ); }
Yes. You need to call SetDirtyBit
every frame if you need the network update to be sent for the object.
And, what do you use as a bitmask there?
The SetDirtyBit
function is technically the function version of the SyncVar
attribute. The argument is not really documented that much but if SyncVar
marked variable is changed, its dirty mask is changed to 1
. This also means that you should pass 1
to the SetDirtyBit
function if you want network update to be sent for the object.
You should also use it from a function marked with the [Command]
attribute instead of directly from the Update
function. Something like below:
void Update()
{
if (isLocalPlayer)
{
CmdUpdateTransform();
}
}
[Command]
void CmdUpdateTransform()
{
SetDirtyBit(1u);
}
While Unity claims you can update the transform by simply using the SetDirtyBit
function. I don't think this is true. The statement is missing lots of information. You will need OnSerialize
to serialize and send the data and OnDeserialize
to receive and de-serialize it. The SetDirtyBit
function is simply used to determine which data to send. It's used to reduce bandwidth issues that comes from using uNET.
The code below shows what the use of SetDirtyBit
should look like. It might need few changes to work on your side.
public class Example : NetworkBehaviour
{
private const uint SEND_POSITION = 1u;
private const uint SEND_ROTATION = 2u;
private const uint SEND_SCALE = 3u;
void Update()
{
uint dirtyBit = syncVarDirtyBits;
dirtyBit |= SEND_POSITION;
dirtyBit |= SEND_ROTATION;
dirtyBit |= SEND_SCALE;
if (isLocalPlayer)
{
CmdUpdateTransform(dirtyBit);
}
}
[Command]
void CmdUpdateTransform(uint dirtyBit)
{
SetDirtyBit(dirtyBit);
}
public override bool OnSerialize(NetworkWriter writer, bool initialState)
{
if ((this.syncVarDirtyBits & SEND_POSITION) != 0u)
{
writer.Write(this.transform.position);
}
if ((this.syncVarDirtyBits & SEND_ROTATION) != 0u)
{
writer.Write(this.transform.rotation);
}
if ((this.syncVarDirtyBits & SEND_SCALE) != 0u)
{
writer.Write(this.transform.localScale);
}
return true;
}
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
if ((this.syncVarDirtyBits & SEND_POSITION) != 0u)
{
Vector3 pos = reader.ReadVector3();
}
if ((this.syncVarDirtyBits & SEND_ROTATION) != 0u)
{
Quaternion rot = reader.ReadQuaternion();
}
if ((this.syncVarDirtyBits & SEND_SCALE) != 0u)
{
Vector3 scale = reader.ReadVector3();
}
}
}
if you just set the send rate to 0.00001 will it in fact do it every
frame that the object is moving?
Yes, but when the Object's transform is not moving or rotating, it's not updated over the network regardless of the value of NetworkTransform.sendInterval
.
I was also thinking something like on a script......
void Update() { .. SetDirtyBit( ? ); }
Yes. You need to call SetDirtyBit
every frame if you need the network update to be sent for the object.
And, what do you use as a bitmask there?
The SetDirtyBit
function is technically the function version of the SyncVar
attribute. The argument is not really documented that much but if SyncVar
marked variable is changed, its dirty mask is changed to 1
. This also means that you should pass 1
to the SetDirtyBit
function if you want network update to be sent for the object.
You should also use it from a function marked with the [Command]
attribute instead of directly from the Update
function. Something like below:
void Update()
{
if (isLocalPlayer)
{
CmdUpdateTransform();
}
}
[Command]
void CmdUpdateTransform()
{
SetDirtyBit(1u);
}
While Unity claims you can update the transform by simply using the SetDirtyBit
function. I don't think this is true. The statement is missing lots of information. You will need OnSerialize
to serialize and send the data and OnDeserialize
to receive and de-serialize it. The SetDirtyBit
function is simply used to determine which data to send. It's used to reduce bandwidth issues that comes from using uNET.
The code below shows what the use of SetDirtyBit
should look like. It might need few changes to work on your side.
public class Example : NetworkBehaviour
{
private const uint SEND_POSITION = 1u;
private const uint SEND_ROTATION = 2u;
private const uint SEND_SCALE = 3u;
void Update()
{
uint dirtyBit = syncVarDirtyBits;
dirtyBit |= SEND_POSITION;
dirtyBit |= SEND_ROTATION;
dirtyBit |= SEND_SCALE;
if (isLocalPlayer)
{
CmdUpdateTransform(dirtyBit);
}
}
[Command]
void CmdUpdateTransform(uint dirtyBit)
{
SetDirtyBit(dirtyBit);
}
public override bool OnSerialize(NetworkWriter writer, bool initialState)
{
if ((this.syncVarDirtyBits & SEND_POSITION) != 0u)
{
writer.Write(this.transform.position);
}
if ((this.syncVarDirtyBits & SEND_ROTATION) != 0u)
{
writer.Write(this.transform.rotation);
}
if ((this.syncVarDirtyBits & SEND_SCALE) != 0u)
{
writer.Write(this.transform.localScale);
}
return true;
}
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
if ((this.syncVarDirtyBits & SEND_POSITION) != 0u)
{
Vector3 pos = reader.ReadVector3();
}
if ((this.syncVarDirtyBits & SEND_ROTATION) != 0u)
{
Quaternion rot = reader.ReadQuaternion();
}
if ((this.syncVarDirtyBits & SEND_SCALE) != 0u)
{
Vector3 scale = reader.ReadVector3();
}
}
}
edited Nov 14 '18 at 5:57
answered Nov 13 '18 at 21:55
ProgrammerProgrammer
76.1k1085148
76.1k1085148
Good one. So to summarize, (1) it seems thatSetDirtyBit
is actually only relevant to SyncVars? It does not work forNetworkTransform
?
– Fattie
Nov 14 '18 at 3:15
SetDirtyBit is the manual way of sending data instead of using SyncVar which will automatically do that for you when you make a variable with the SyncVars attribute. SetDirtyBit is not related to NetworkTransform. You can use it to send any type of data over the network. I think that the documentation is not clear on this. Calling SetDirtyBit will cause Unity to call OnSerialize() and OnDeserialize() and there you can add the custom data to send like the example in my answer. For example,you can send the position, rotation and scale of the object.
– Programmer
Nov 14 '18 at 5:15
The good side of using it is that you can decide when to update the variable unlikeSyncVar
which simply updates based on the send rate. This is really important when it comes to bandwidth management. Imaging having ~12 variables for each 12 player you want to update over the network and they are marked asSyncVar
, they will be updating at whatever the send rate is set to. You can't control when to stop them from updating over the network. WithSetDirtyBit
, you can and it saves bandwidth and processing time.
– Programmer
Nov 14 '18 at 5:21
1
Ah ok. So SetDirtyBit does not relate to NetworkTransform, and it does not relate to SyncVars ! It's just "a way to send info (using the Serialize functions)". Is that about right??! Thanks! :)
– Fattie
Nov 14 '18 at 5:25
Yes, that's correct and I think the doc is saying that if you want to update the transform manually, you should setsendInterval
to0
, call SetDirtyBits then use OnSerialize() and OnDeserialize() to send the transform information. They left that last part out.
– Programmer
Nov 14 '18 at 5:30
|
show 14 more comments
Good one. So to summarize, (1) it seems thatSetDirtyBit
is actually only relevant to SyncVars? It does not work forNetworkTransform
?
– Fattie
Nov 14 '18 at 3:15
SetDirtyBit is the manual way of sending data instead of using SyncVar which will automatically do that for you when you make a variable with the SyncVars attribute. SetDirtyBit is not related to NetworkTransform. You can use it to send any type of data over the network. I think that the documentation is not clear on this. Calling SetDirtyBit will cause Unity to call OnSerialize() and OnDeserialize() and there you can add the custom data to send like the example in my answer. For example,you can send the position, rotation and scale of the object.
– Programmer
Nov 14 '18 at 5:15
The good side of using it is that you can decide when to update the variable unlikeSyncVar
which simply updates based on the send rate. This is really important when it comes to bandwidth management. Imaging having ~12 variables for each 12 player you want to update over the network and they are marked asSyncVar
, they will be updating at whatever the send rate is set to. You can't control when to stop them from updating over the network. WithSetDirtyBit
, you can and it saves bandwidth and processing time.
– Programmer
Nov 14 '18 at 5:21
1
Ah ok. So SetDirtyBit does not relate to NetworkTransform, and it does not relate to SyncVars ! It's just "a way to send info (using the Serialize functions)". Is that about right??! Thanks! :)
– Fattie
Nov 14 '18 at 5:25
Yes, that's correct and I think the doc is saying that if you want to update the transform manually, you should setsendInterval
to0
, call SetDirtyBits then use OnSerialize() and OnDeserialize() to send the transform information. They left that last part out.
– Programmer
Nov 14 '18 at 5:30
Good one. So to summarize, (1) it seems that
SetDirtyBit
is actually only relevant to SyncVars? It does not work for NetworkTransform
?– Fattie
Nov 14 '18 at 3:15
Good one. So to summarize, (1) it seems that
SetDirtyBit
is actually only relevant to SyncVars? It does not work for NetworkTransform
?– Fattie
Nov 14 '18 at 3:15
SetDirtyBit is the manual way of sending data instead of using SyncVar which will automatically do that for you when you make a variable with the SyncVars attribute. SetDirtyBit is not related to NetworkTransform. You can use it to send any type of data over the network. I think that the documentation is not clear on this. Calling SetDirtyBit will cause Unity to call OnSerialize() and OnDeserialize() and there you can add the custom data to send like the example in my answer. For example,you can send the position, rotation and scale of the object.
– Programmer
Nov 14 '18 at 5:15
SetDirtyBit is the manual way of sending data instead of using SyncVar which will automatically do that for you when you make a variable with the SyncVars attribute. SetDirtyBit is not related to NetworkTransform. You can use it to send any type of data over the network. I think that the documentation is not clear on this. Calling SetDirtyBit will cause Unity to call OnSerialize() and OnDeserialize() and there you can add the custom data to send like the example in my answer. For example,you can send the position, rotation and scale of the object.
– Programmer
Nov 14 '18 at 5:15
The good side of using it is that you can decide when to update the variable unlike
SyncVar
which simply updates based on the send rate. This is really important when it comes to bandwidth management. Imaging having ~12 variables for each 12 player you want to update over the network and they are marked as SyncVar
, they will be updating at whatever the send rate is set to. You can't control when to stop them from updating over the network. With SetDirtyBit
, you can and it saves bandwidth and processing time.– Programmer
Nov 14 '18 at 5:21
The good side of using it is that you can decide when to update the variable unlike
SyncVar
which simply updates based on the send rate. This is really important when it comes to bandwidth management. Imaging having ~12 variables for each 12 player you want to update over the network and they are marked as SyncVar
, they will be updating at whatever the send rate is set to. You can't control when to stop them from updating over the network. With SetDirtyBit
, you can and it saves bandwidth and processing time.– Programmer
Nov 14 '18 at 5:21
1
1
Ah ok. So SetDirtyBit does not relate to NetworkTransform, and it does not relate to SyncVars ! It's just "a way to send info (using the Serialize functions)". Is that about right??! Thanks! :)
– Fattie
Nov 14 '18 at 5:25
Ah ok. So SetDirtyBit does not relate to NetworkTransform, and it does not relate to SyncVars ! It's just "a way to send info (using the Serialize functions)". Is that about right??! Thanks! :)
– Fattie
Nov 14 '18 at 5:25
Yes, that's correct and I think the doc is saying that if you want to update the transform manually, you should set
sendInterval
to 0
, call SetDirtyBits then use OnSerialize() and OnDeserialize() to send the transform information. They left that last part out.– Programmer
Nov 14 '18 at 5:30
Yes, that's correct and I think the doc is saying that if you want to update the transform manually, you should set
sendInterval
to 0
, call SetDirtyBits then use OnSerialize() and OnDeserialize() to send the transform information. They left that last part out.– Programmer
Nov 14 '18 at 5:30
|
show 14 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53285808%2funity-networktransform-force-update-every-frame%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Afaik NetworkTransform also tries to a certain limit to predict movements if using RigidBody .. maybe that causes the jitter? For me the NetworkTransform never worked well and I ended up writing a custom one with Commands, Rpcs and interpolation of the position. forum.unity.com/threads/network-transform-lags.334718
– derHugo
Nov 14 '18 at 6:42
1
(Right, I was not using RigidBody. Yes, their system is trash; this is more of a curiosity investigation :) )
– Fattie
Nov 14 '18 at 6:54
Yeah thats why they start over
– derHugo
Nov 14 '18 at 6:58
ah I did not know that @derHugo . I heard it from you first! Geesh ... yet another attempt by Unity at networking :/
– Fattie
Nov 14 '18 at 7:01
yeah we all hope that will be a better one .. so far we ended up writing our complete own networking using very low level socket connections (after all
c#
is stillc
;) )– derHugo
Nov 14 '18 at 7:03