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 MD_Reptile · May 15, 2013 at 11:09 AM · networkingmultiplayernetworkcoroutinecolor.lerp

Networked Coroutine DOESNT behave on client

I have a simple networking issue right now, where I have an authoritative server calling all the shots in a multiplayer game, and when the server calls an RPC (just a simple method to start a coroutine locally) the coroutine runs fine on the server (or in single player) but the client doesnt run the coroutine, even though debug shows the code reaches the same point on client and server!

Heres exactly what happens:

1) The server send out an update to a "planet" (gameobject/scripts running it) like this

 networkView.RPC("SendPlanetMessage", RPCMode.OthersBuffered, i, Teams[i], Units[i]); // update clients of this status

2) The RPC fires on the client, and performs the following

 [RPC]
     void SendPlanetMessage(int planetNumber, int team, int units)
     {
 //        Debug.Log("RPC: SendPlanetMessage - ID: " + networkView.viewID.ToString());
         // send all connected users the updates planetary info
         if(Teams[planetNumber] != team)
             SimpleSwitchColor(planetNumber, team);
         Teams[planetNumber] = team;
         Units[planetNumber] = units;
     }

3) This starts another method locally (client) "SimpleSwitchColor()" like below

 void SimpleSwitchColor(int planetNumber, int team)
     {
         Debug.Log("RPC: SimpleSwitchColor " + planetNumber + " to " + team);
         // use it like: networkView.RPC(SimpleSwitchColor(planetNumberString, someColor), RPCMode.AllBuffered);
         StartCoroutine(ChangePlanetColor(planetNumber, Planets[planetNumber].renderer.material.color, team, Time.time));
     }

4) Which in turn starts this Coroutine for "fading" the gameobjects color (works on server every time)

 IEnumerator ChangePlanetColor(int planetNumber, Color startColor, int endTeam, float startTime)
     {
         Debug.Log("Changing planet color");
         
         // change planet colors
         if(endTeam == 1)
         {
             while(Planets[planetNumber].renderer.material.color != GreenColor && Teams[planetNumber] == endTeam)
             {
                     Color lerpedColor = Color.Lerp(startColor, GreenColor, (Time.time - startTime) / 5);
                 Planets[planetNumber].renderer.material.color = lerpedColor;
                 yield return new WaitForSeconds(0.15f);
             }
         }
         if(endTeam == 2)
         {
             while(Planets[planetNumber].renderer.material.color != RedColor && Teams[planetNumber] == endTeam)
             {
                 Color lerpedColor = Color.Lerp(startColor, RedColor, (Time.time - startTime) / 5);
                 Planets[planetNumber].renderer.material.color = lerpedColor;
                 yield return new WaitForSeconds(0.15f);
             }
         }
         if(endTeam == 3)
         {
             while(Planets[planetNumber].renderer.material.color != BlueColor && Teams[planetNumber] == endTeam)
             {
                 Color lerpedColor = Color.Lerp(startColor, BlueColor, (Time.time - startTime) / 5);
                 Planets[planetNumber].renderer.material.color = lerpedColor;
                 yield return new WaitForSeconds(0.15f);
             }
         }
     }

Now, why in the world does it work just fine (locally) when called on server, yet even when its LOCALLY called (through the steps above) on the client, with correct vars, it does NOT change the color of the GO whatsoever... stays the default color...

Is this something strange about unity networking? the console debug entry shows me that the coroutine is getting the right information... maybe im a tired coffee filled coder who needs a break? Am I missing something obvious here?

A couple notes: the server ALSO calles SimpleSwitchColor() when doing this, just not from planet message... I am using Unity 3x latest... testing with both android and windows standalones, sometimes two builds, sometimes a build as server and editor as client, vice versa sometimes...

Comment
Add comment · Show 2
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 Kibsgaard · May 15, 2013 at 11:16 AM 0
Share

$$anonymous$$y guess would be that the array "Teams" is not populated correctly on the clients. How do you populate that array?

Edit: Also, does it work on the server if you use RPC$$anonymous$$ode.AllBuffered to switch the color?

avatar image MD_Reptile · May 16, 2013 at 05:26 PM 0
Share

It did work on the server as allbuffered (not on the client still), but I decided not to handle it that way because people write that they have problems with allbuffered calls, so I call it locally now on the server, and RPC on the clients. But see, if I just instantly change the color of the target object(again, with this exact RPC), its fine, works no problem, but by trying to implement this fade, is where the problem arises, it fades locally on the server, but then when im calling the coroutine to fade (locally, after RPC comes in) on the client, it doesnt fade! the $$anonymous$$ms are correctly set through checks by the server, sending messages to the client, and when debugging in the editor, I do see these numbers are being correctly set! So the problem has to be in the coroutine being called from outside (a rpc for a method to startcoroutine locally)... maybe this is a networking thing? your not supposed to startcoroutine from RPC call? im not directly calling the coroutines method, like I said, another method (the RPC) starts it...

and like, when im just directly switching colors, there is no coroutine, it just changes the color in the simpleswitchcolor()

Soooooooo, maybe somebody could tell me, how can I easily fade my objects color, and call it from the network, and perhaps an alternative would work better to my attempts above?

or, somebody want to enlighten me in directly calling a coroutine with RPC? is that possible? like networkView.RPC(StartCoroutine(...?

If nobody knows what to try next, I'll hack out another way to get the client to just call these coroutines on itself, based on what the $$anonymous$$ms are set to from the server, rather than doing it this way.

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Bunny83 · May 16, 2013 at 06:29 PM

So what Debug.Logs are you actually seeing? Does SimpleSwitchColor get executed? Does the coroutine get started? What value has "endTeam" on the server / client? Why do you actually check if the "endTeam" is Teams[planetNumber] in the while loop? is it a termination condition? Also is there a reason why you want 6.666 color changes per second?

I would implement this coroutine like this:

 IEnumerator ChangePlanetColor(int planetNumber, int endTeam)
 {
     if (Teams[planetNumber] != endTeam)
         yield break;
     
     Material mat = Planets[planetNumber].renderer.material;
     Color startColor = mat.color;
     Color targetColor = Color.black;
     if (endTeam == 1)
         targetColor = GreenColor;
     else if (endTeam == 2)
         targetColor = RedColor;
     else if (endTeam == 3)
         targetColor = BlueColor;
     float t = 0;
     while(t < 1.0f)
     {
         t += Time.deltaTime / 5;
         mat.color = Color.Lerp(startColor, targetColor, t);
         yield return null;
     }
 }

I think that's a bit easier and more readable. Also a bit more effecient.

There's nothing wrong the way you call your coroutine. Just add some more debug logs to see what actually get's executed. Just to be sure: Are you sure that the GameObject and the script are activated / enabled? Coroutines won't run on disabled GameObjects / MonoBehaviours.

Comment
Add comment · Show 5 · 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 MD_Reptile · May 16, 2013 at 06:56 PM 0
Share

Ahh I will try this when I get back to it later.

endTeam was an int I used for the $$anonymous$$m it would change to, so 1 was green, 2 was red, and 3 was blue...silly way to handle it but most other parts of my script do it that way, to make easier networking methods sending ints across for $$anonymous$$m info...and I checked it stayed endTeam, because if this happened from two $$anonymous$$ms within the time it ran, they would flicker back and forth between the two $$anonymous$$m colors (coroutine fighting itself lol), and that stopped it from running if another $$anonymous$$m took over the "planet"

I didnt really intend to call it so frequently, I was trying to figure a good balance between speed of updating and speed of changing color, that seemed to work best haha. Your solution seems much better, I'll report back.

EDIT: @bunny83

I tried using your code, and on my client, I get as far as the first debug line, but no other debug lines come up...leads me to think my planets $$anonymous$$ms are incorrect, but the inspector (client running) seems to show good numbers being set (i update the planets $$anonymous$$ms about once a second from another RPC from server)

Here is what I had, again, only got to first debug line?

 IEnumerator ChangePlanetColor(int planetNumber, int endTeam)
     {
         Debug.Log("Starting color change: " + planetNumber + " to " + endTeam);
         if (Teams[planetNumber] != endTeam)
             yield break;
  
         $$anonymous$$aterial mat = Planets[planetNumber].renderer.material;
         Color startColor = mat.color;
         Color targetColor = Color.black;
         if (endTeam == 1)
         {
             targetColor = GreenColor;
             Debug.Log("SetColorGreen");
         }
         else if (endTeam == 2)
         {
             targetColor = RedColor;
             Debug.Log("SetColorRed");
         }
         else if (endTeam == 3)
         {
             targetColor = BlueColor;
             Debug.Log("SetColorBlue");
         }
         float t = 0;
         while(t < 1.0f)
         {
             t += Time.deltaTime / 5;
             mat.color = Color.Lerp(startColor, targetColor, t);
             Debug.Log("Step");
                yield return null;
         }
     }
avatar image Bunny83 · May 16, 2013 at 11:52 PM 1
Share

How about using a debug statement like this:

 Debug.Log("Planet: " + planetNumber + " endTeam: " + endTeam + " PlanetTeam: " + Teams[planetNumber]);
avatar image MD_Reptile · May 17, 2013 at 12:30 PM 0
Share

@bunny83 Awesome, it was that Teams[] was not being set in order before the coroutine ran, causing the coroutine to quit as soon as it starts. Good eye bunny, I would have been looking for that bug for a while on my own :D

I changed the RPC that updates the planets $$anonymous$$ms to occur before the RPC to start the coroutine, and works flawlessly for me now! $$anonymous$$akes a great fade effect from color to color for my game. Thumbs up, especially for the better method!

Bonus sneak peek:

http://img20.imageshack.us/img20/3566/spacecommanddevscene5.png

avatar image Bunny83 · May 17, 2013 at 04:28 PM 0
Share

This re$$anonymous$$ds me of NanoWar

avatar image MD_Reptile · May 17, 2013 at 10:06 PM 0
Share

its more so like GalCon which is my direct inspiration for this game, although $$anonymous$$e has unique features to both of these games :D

I am trying nano war right now tho, I do like that game! Hmmm... if(GalCon + NanoWar

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

Unity networking tutorial? 6 Answers

UNET AddPlayerForConnection with already existing player GameObject 0 Answers

Multiplayer objects isn't equals. 1 Answer

Can I add a network prefab at runtime? 1 Answer

how to sync a struct of numbers 0 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