Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
0
Question by AggroBird · Oct 10, 2013 at 09:49 PM · multiplayernetworkdestroy

Network RPC buffer issue

Hello Unitypeople,

I have been struggeling with an issue in Unity's Network system for a long time now that I cannot seem to fix.

I have specially created a stripped down version of my project to demonstrate the issue, which can be downloaded here.

The following project consists of a "game" in which one server and multiple clients can engage in a battle of cube instantiation. These cubes are to represent actual game elements such as player characters and projectiles. Note that clients Instantiate their own objects to make sure that the movement of these objects runs smooth on their side, and smooth with prediction and interpolation on other sides.

The issue that I am facing is when I have a server and one client, and a second client connects, that last client can see loads of objects that should have been destroyed. I suspect that the Instantiation of that object remains in the RPC buffer even though I have tried to remove it.

I give the cubes a red color by default on start, to mark these as cubes that are unowned by any network player. Then, once OnSerializeNetworkView() is called, that would imply that someone somewhere wrote into the stream because he owns the cube, which makes the cube turn green. Cubes that remain red don't have any owner and should be destroyed.

In order to reproduce the issue:

It is rather simple to reproduce the issue. All you have to do is start the "game" three times. Start one as server, and one as client. Let them have their cube-war for aproximatically 10 seconds, and then use the third game to connect aswell. That client will have loads of unowned red cubes that shouldnt be there. This can be done from editor aswell as from standalone builds.

The entire project consists of two scripts, a game controller that manages the network and the cubes, and a cube script that synchronizes its data through the network stream.

I would be really happy if someone spots the problem of what I am doing wrong, because I am almost 100% certain that I have understood Unity's documentation of Networking, and I am unable to find what is causing the issue.

Here be code:

 using UnityEngine;
 
 public class GameController : MonoBehaviour
 {
     private static GameController s_main = null;
     public static GameController main
     {
         get
         {
             if (!s_main)
                 return null;
             return s_main;
         }
     }
     private void Awake()
     {
         //Ensure that only one GameController is active in the game, and destroy duplicates when returning to menu scene
         if (s_main == null)
         {
             s_main = this;
 
             //Make the GameController persistant
             GameObject.DontDestroyOnLoad(gameObject);
         }
         else
         {
             GameObject.Destroy(gameObject);
         }
     }
 
     private float cubeTimer = 0;
 
 
     private void Update()
     {
         //Exit application
         if (Input.GetKeyDown(KeyCode.Escape))
             Application.Quit();
 
         //Return if we are not in the game scene
         if (Application.loadedLevel != 1)
             return;
 
         //Return when we are not connected
         if (Network.peerType != NetworkPeerType.Server && Network.peerType != NetworkPeerType.Client)
             return;
 
         //Create a cube every tenth of a second
         cubeTimer -= Time.deltaTime;
         while (cubeTimer <= 0)
         {
             cubeTimer += 0.1f;
             Network.Instantiate(Resources.Load("NetworkCube"), new Vector3(Random.Range(-5f, 5f), Random.Range(-5f, 5f), 0), Quaternion.identity, 0);
         }
     }
 
     private void OnGUI()
     {
         //Connect/disconnect GUI
         if (Network.peerType != NetworkPeerType.Disconnected)
         {
             if (Network.isServer)
             {
                 GUI.Box(new Rect(50, 50, 120, 30), "Playing as server");
                 if (GUI.Button(new Rect(180, 50, 120, 30), "Disconnect"))
                     Disconnect();
             }
             else if (Network.isClient)
             {
                 GUI.Box(new Rect(50, 50, 120, 30), "Playing as client");
                 if (GUI.Button(new Rect(180, 50, 120, 30), "Disconnect"))
                     Disconnect();
             }
         }
         else
         {
             if (GUI.Button(new Rect(50, 50, 120, 30), "Start as server"))
                 Network.InitializeServer(32, 2302, false);
             else if (GUI.Button(new Rect(180, 50, 120, 30), "Start as client"))
                 Network.Connect("127.0.0.1", 2302);
         }
     }
 
 
     private void OnServerInitialized()
     {
         //Force clients to load the following level upon connecting
         networkView.RPC("ClientLoadLevel", RPCMode.OthersBuffered);
         Application.LoadLevel(1);
     }
 
     private void OnPlayerDisconnected(NetworkPlayer player)
     {
         //When a player disconnects, destroy his objects
         Network.RemoveRPCs(player, 0);
         Network.DestroyPlayerObjects(player);
     }
 
     private void OnDisconnectedFromServer()
     {
         //Return to the menu on disconnect
         if (Application.loadedLevel != 0)
             Application.LoadLevel(0);
     }
 
 
     [RPC]
     private void ClientLoadLevel()
     {
         //Stop the message queue and load the game level
         Network.isMessageQueueRunning = false;
         Network.SetLevelPrefix(1);
         Application.LoadLevel(1);
     }
 
     private void OnLevelWasLoaded(int level)
     {
         //Resume the message queue upon loading the game scene
         Network.isMessageQueueRunning = true;
     }
 
     internal static void Disconnect()
     {
         //Disconnect from the server
         Network.Disconnect();
 
         //Return to the menu if neccesairy
         if (Application.loadedLevel != 0)
             Application.LoadLevel(0);
     }
 }

And cube:

 using UnityEngine;
 
 public class NetworkCube : MonoBehaviour
 {
     private Vector3 orbitPoint;
     private float angle;
     private float lifeTime = 1f;
 
 
     private void Start()
     {
         if (networkView.isMine)
         {
             orbitPoint = transform.position;
             angle = Random.Range(60f, 120f);
             transform.Translate(0, 1, 0);
 
             //Set the color to red to mark this as an invalid object
             renderer.material.color = Color.green;
         }
         else
         {
             //Set the color to red to mark this as an invalid object
             renderer.material.color = Color.red;
         }
     }
     
     private void Update()
     {
         if (networkView.isMine)
         {
             //Rotate the cube around a point
             transform.position = orbitPoint;
             transform.Rotate(0, 0, -angle * Time.deltaTime);
             transform.Translate(0, 1, 0);
 
             //Destroy after one second
             lifeTime -= Time.deltaTime;
             if (lifeTime <= 0)
                 NetworkDestroy();
         }
     }
 
     private void NetworkDestroy()
     {
         //Remove RPC calls related to this object
         Network.RemoveRPCs(networkView.viewID);
 
         //Destroy this object over network
         Network.Destroy(networkView.viewID);
     }
 
     private void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
     {
         if (stream.isWriting)
         {
             //Set the color to green once the owner of this cube has started streaming/receiving
             //Cubes that are not owned by anyone will not turn green
             renderer.material.color = Color.green;
 
             //Stream the cube position/rotation
             Vector3 position = transform.position;
             Quaternion rotation = transform.rotation;
             stream.Serialize(ref position);
             stream.Serialize(ref rotation);
         }
         else
         {
             //Set the color to green once the owner of this cube has started streaming/receiving
             //Cubes that are not owned by anyone will not turn green
             renderer.material.color = Color.green;
     
             //Receive the cube position/rotation
             Vector3 position = transform.position;
             Quaternion rotation = transform.rotation;
             stream.Serialize(ref position);
             stream.Serialize(ref rotation);
             transform.position = position;
             transform.rotation = rotation;
         }
     }
 }
 

Kind regards, Romenski

Comment
Add comment
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

0 Replies

· Add your reply
  • Sort: 

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

15 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Set unity process as server and client? 0 Answers

How can I delete or destroy an instance of an object IN A MULTIPLAYER GAME?. 2 Answers

Network Game - all players respond to same input 0 Answers

How to apply damage to raycast hitten object's Networkview? 2 Answers

Player not deleting on server exit 1 Answer


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