Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 11 Next capture
2021 2022 2023
1 capture
11 Jun 22 - 11 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by dsull · Jul 10, 2015 at 01:36 PM · c#unity 5networkingmultiplayer-networking

Multiple NetworkBehaviours with the same SyncVar hook not working

This is going to be a lot of text, scroll down to

I'm trying to place 2 of the same of the same script onto a single object.

PlayerPrefab scripts/behaviours

alt text

The script is set up to sync the position/rotation/networktimestamp of the "Transform Sync". Here I'm using the basic FirstPersonController renamed PlayerPrefab and the camera renamed PlayerCamera. There is also a capsule on it and an object attached to the camera so that I can see where they are and so that I can see the rotation of the PlayerPrefab and the PlayerCamera

PlayerPrefab in the editor

alt text

Here's what it looks like in the inspector. The Capsule and the LocalRotationPositionArms are just meshes with no colliders, no funny business on them.

So the script I wrote should sync the Transform of the PlayerPrefab itself, and also sync the Transform of the PlayerCamera object.

The Problem

It appears only one script, the later script, is being given information. Both scripts are working side by side for the clients connecting to the host. The functionality I tried to implement falls apart.

Code

The code I have looks like this. A single instance of the script appears to work fine for me.

StringNetworkBehaviour

 using UnityEngine;
 using UnityEngine.Networking;
 using System.Collections;
 public abstract class StringNetworkBehaviour : NetworkBehaviour {
 
     [SyncVar (hook = "SyncMessage")]
     private string Message = string.Empty;
 
     protected StringSerializable MessageModel { get; set; }
 
     protected virtual void FixedUpdate()
     {
         this.TransmitMessage ();
     }
 
     public virtual bool TransmitCondition()
     {
         return this.isLocalPlayer;
     }
 
     public virtual StringSerializable GetStringSerializable()
     {
         return this.MessageModel;
     }
 
     public virtual void SendNext(StringSerializable messageModel)
     {
         this.MessageModel = messageModel;
     }
 
     public string GetLastRecievedMessage(){
         return this.Message;
     }
 
     [Command]
     protected virtual void Cmd_TrasmitMessageFromClientToServer(string message)
     {
         this.Message = message;
     }
 
     [ClientCallback]
     protected virtual void TransmitMessage()
     {
         if(this.TransmitCondition())
         {
             StringSerializable message = this.GetStringSerializable();
             if(message != null)
             {
                 this.Cmd_TrasmitMessageFromClientToServer(message.SerializeToString());
             }
         }
     }
 
     [Client]
     protected virtual void SyncMessage(string message)
     {
         this.Message = message;
     }
 }

StringSerializable

 using UnityEngine;
 using System.Collections;
 public interface StringSerializable  {
     string SerializeToString();
     void DeSerializeFromString(string serialized);
 }

NetworkSyncPositionRotation

 using UnityEngine;
 using UnityEngine.Networking;
 using System.Collections;
 
 [NetworkSettings (channel = 0, sendInterval = 0.1f)]
 public class NetworkSyncPositionRotation : StringNetworkBehaviour {
 
     [Tooltip("This transform will be synced. Defaults to the object's tranform.")]
     public Transform TransformSync;
     [Tooltip("Each time the position and rotation are Lerped, the amount it lerps will be this percentage towards the target.")]
     public float LerpRate = 10f;
     [Tooltip("If set to true, the local position and rotation will be synced instead of the world position and rotation.")]
     public bool UseLocalPositionAndRotation = false;
 
     void Awake()
     {
         if (this.TransformSync == null) {
             this.TransformSync = this.transform;
         }
     }
 
     void Update () 
     {
         if (this.isLocalPlayer) 
         {
             int time = NetworkTransport.GetNetworkTimestamp ();
             StringSerializable message = null;
             if(!this.UseLocalPositionAndRotation)
             {
                 message = new PositionRotationMessageModel (this.TransformSync.position, this.TransformSync.rotation, time);
             } else {
                 message = new PositionRotationMessageModel (this.TransformSync.localPosition, this.TransformSync.localRotation, time);
             }
             this.SendNext (message);
         } 
         else 
         {
             
             this.LerpPositionRotation ();
         }
     }
 
     void LerpPositionRotation()
     {
         if (!string.IsNullOrEmpty (message)) 
         {
             var model = PositionRotationMessageModel.BuildFrom(message);
 
             if(!this.UseLocalPositionAndRotation)
             {
                 this.TransformSync.position = Vector3.Lerp (this.TransformSync.position, model.Position, LerpRate * Time.deltaTime);
                 this.TransformSync.rotation = Quaternion.Lerp (this.TransformSync.rotation, model.Rotation, LerpRate * Time.deltaTime);
             }
             else 
             {
                 this.TransformSync.localPosition = Vector3.Lerp (this.TransformSync.localPosition, model.Position, LerpRate * Time.deltaTime);
                 this.TransformSync.localRotation = Quaternion.Lerp (this.TransformSync.localRotation, model.Rotation, LerpRate * Time.deltaTime);
             }
         }
     }
 
     public override bool TransmitCondition()
     {
         return this.isLocalPlayer;
     }
 }

PositionRotationMessageModel

 using UnityEngine;
 using System.Collections;
 
 public class PositionRotationMessageModel : StringSerializable  
 {
     public Vector3 Position {get;set;}
     public Quaternion Rotation {get;set;}
     public int TimeStamp {get;set;}
 
     public PositionRotationMessageModel()
     {
     }
 
     public PositionRotationMessageModel(Vector3 pos, Quaternion rot, int timeStamp)
     {
         this.Position = pos;
         this.Rotation = rot;
         this.TimeStamp = timeStamp;
     }
     
     public static PositionRotationMessageModel BuildFrom(string serialized)
     {
         var obj = new PositionRotationMessageModel ();
         obj.DeSerializeFromString (serialized);
         return obj;
     }
     
     public string SerializeToString()
     {
         string message = string.Empty;
         message += this.Position.x + "\t" + this.Position.y + "\t" + this.Position.z;
         message += "\t";
         message += this.Rotation.x + "\t" + this.Rotation.y + "\t" + this.Rotation.z + "\t" + this.Rotation.w;
         message += "\t";
         message += this.TimeStamp;
         return message;
     }
     
     public void DeSerializeFromString(string serialized)
     {
         string[] split = serialized.Split ('\t');
         this.Position = new Vector3 (float.Parse (split [0]), float.Parse (split [1]), float.Parse (split [2]));
         this.Rotation = new Quaternion (float.Parse (split [3]), float.Parse (split [4]), float.Parse (split [5]), float.Parse (split [6]));
         this.TimeStamp = int.Parse(split [7]);
     }
 }
 

NetworkSetupPlayerControl

 using UnityEngine;
 using UnityEngine.Networking;
 using System.Collections;
 
 public class NetworkSetupPlayerControl : NetworkBehaviour 
 {
     [Tooltip("The camera that this player object controls.")]
     public Camera PlayerCamera;
     [Tooltip("The audio listener that this player object controls.")]
     public AudioListener PlayerAudioListener;
     
     public override void OnStartLocalPlayer ()
     {
         GameObject.Find("Scene Camera").SetActive(false);
         this.PlayerCamera.enabled = true;
         this.PlayerAudioListener.enabled = true;
         this.GetComponent<UnityStandardAssets.Characters.FirstPerson.FirstPersonController>().enabled = true;
         this.transform.position = new Vector3 (0, 3, 0);
     }
 }
 

 

The general idea is that I wanted to make a simple way to send lots of information using a string. The problem is that placing two of my NetworkSyncPositionRotation scripts on the same object seems to break it. I'm concerned that if I extend anything else off of StringNetworkBehaviour that it'll also break, since I believe it's breaking at the hook.

My goal was to create a simple to extend way to deal with Unity's networking so I wouldn't have to write too much to create my scripts. That's why all the syncing logic is in StringNetworkBehaviour and my NetworkSyncPositionRotation just builds and serializes a message and sets it to be sent then forgets about it.

Question

Is the behaviour that's breaking my script intentional? Or am I overlooking something? Can it be fixed?

Notes

The behaviour seems to function perfectly as I intended for the client who is Hosting locally. All the clients can see the host perfectly as he is supposed to be displayed. The host and the clients see all the non hosts as messed up. Not sure why that's going on.

networking.png (33.0 kB)
playersetup.png (2.8 kB)
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image BigHandInSky · Sep 29, 2016 at 09:45 AM 0
Share

Commenting to add that I'm receiving the exact same issue with a similar Transform-syncing script,

For now I'm using the Unity NetworkTransform / NetworkTransformChild combo ins$$anonymous$$d for the time being, where looking into the Child's scripting here seems like an index is needed in the network message transmitting the sync values?

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Ferur · Aug 29, 2015 at 01:56 PM

hi, i am not 100% sure, but i don't think the virtual FixedUpdate() is ever called from Unity because its not in the derived class, so you never actually Transmit the message. I guess because the host is using the same scene for the server and the local client changing the message there is enough to get it onto the server and it gets sent to the clients through the syncVar.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image dsull · Aug 29, 2015 at 03:19 PM 0
Share

FixedUpdate is being called from the class StringNetworkBehaviour

avatar image Ferur · Aug 30, 2015 at 01:40 PM 0
Share

Yes, FixedUpdate is in StringNetworkBehaviour, but you only use the derived class on your Gameobject. I havent tested it myself, thats why i said i am not 100% sure, but in this thread the answer from Peter $$anonymous$$ suggests that Unity will not call FixedUpdate if its only in the base class. So reimplementing the method in your derived class might fix it.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Can I see how many bytes are being sent by a particular SyncVar variable? 1 Answer

Two or more players in tank using mirror 1 Answer

This is giving an error for the other client and cannot hit other client. 1 Answer

Can I use Rpc Calls and Commands on the same object? 0 Answers

Remote database for leaderboard 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges