- Home /
NetworkView does exist!
Hey guys, I have been chasing this problem for a few days now. In fact there is a post of mine on the forums where I blame Network.Destroy for all my troubles. The truth of the matter is that I didn't fully understand it as it didn't rear its head every time I expected it too. When you write code, you expect it to work or not to work. Anyway on to the problem...
I build ships, ships can build projectiles to shoot at other ships. When I start a server for the first minute everything is fine. However, I have noticed that I reach a point after this first minute where I start encountering "NetworkView doesn't exist". If it is a Client created object, these errors appear on the Server, similarly, if it is server owned these messages appear on the client.
View ID AllocatedID: 54 not found during lookup. Strange behaviour may occur
Received state update for view id' AllocatedID: 54' but the NetworkView doesn't exist
By enabling Network debugging to full have determined that this happens once my Client VeiwIDs enter into the 50+ plus range. I'm getting the impression that my server thinks after 60 seconds "okay this guy needs some view IDs to pool from, here you go" - but none of them work from this point forward. Actually they throw that particular error but often they also leave an objects state unchanged on one system. It doesn't seem to matter how I allocate them either. I have projectiles manually allocated, and ships instantiated with Network.Instantiate. I did this to draw a comparison.
Some code then, right when my ships receive a target they call the following:
function fireWarhead(go : GameObject)
{
if(armNuke)
{
targetEnemy = go;
if(networkView.isMine)
{
var viewID = Network.AllocateViewID();
networkView.RPC("SpawnNuke", RPCMode.All, viewID);
}
}
armNuke = false;
}
@RPC
function SpawnNuke (viewID : NetworkViewID)
{
// Instantate the prefab locally
newNuke = Instantiate(nuke, transform.position, transform.rotation);
var nView : NetworkView;
nView = newNuke.GetComponent(NetworkView);
nView.viewID = viewID;
if(networkView.isMine)
{
newNuke.GetComponent(homingMissile).setTarget(targetEnemy); //position is in sync on owner
}
}
Any ideas, suggestions or abuse? The fault is undoubtedly mine, however given that the earliest allocated viewIDs seem fine with both parties - it looks a lot like unity's network handler is dropping the ball.
Just a tip don't use \> to format your code, ins$$anonymous$$d indent it four spaces or one tab before pasting it or highlight it and click the code button
Answer by whydoidoit · Jun 16, 2012 at 12:24 PM
Right this might be it: in SpawnNuke you are checking if networkView.isMine rather than checking if nView.isMine. That just might be confusing things depending on what this script is attached to.
No, it's ok the way he has it ;) A NetworkView actually doesn't have an owner, just the NetworkViewID has an owner. Since the new instantiated object doesn't have a ViewID assigned yet, you can't even test who owns the object. The SpawnNuke RPC has to be executed by all players to actually create the object. The passed ViewID can tell you who owns the object (or the viewID to be more precise), but that's irrelevant for creating the object. Everyone has to create it. If someone wouldn't create it and of course doesn't assign the NetworkViewID to a NetworkView, that would cause that error since this client would receive updates for this NetworkViewID, but there is no object with that ID on this client.
I can remember there was a quite annoying issue with RPCs. RPC$$anonymous$$ode.All works fine, but (at least that was the behaviour in the past) when it's executed on the server, the RPC isn't called on the server itself. The server couldn't send a message to itself. I'm not sure if that has been fixed.
The usual workaround was to check if you're the server and send an RPC.Others and additionally invoke the RPC function manually.
I'm sorry :D After i've reformated the code i saw what you've ment...
Yes, in this case you might want to check the passed ViewID rather than the NetworkView of the executing script.
Btw: @avalongames: To which object is that script attached to? To your ship?
And again, the error you've mentioned always occures when the owner of a ViewID is sending updates on his object, but another player doesn't have an object with that ID. The reason could be:
The other player destroyed the object locally.
The other player hasn't instantiated the object at all.
You know this beats my last day job, I'm trying to figure out how to control nuclear weapons rather than seeing how much money someone spent on cornflakes in the last month...
Thank you for your feedback both of you. Sorry about the sloppy layout of my code, I had to do this with an iPhone as I'm away this weekend. This script is called on the ship which is instantiated earlier with Network.instantiate. The networkView.is$$anonymous$$ine check I've put in is to make sure that only the owner can create nukes.
I agree with you about the errors Bunny 83. I kill my ships and nukes by sending RPC calls ending in Destroy(gameObject). However, this call first goes to the server so it can destroy it's version first before it calls RPC.Others on the clients. A top down approach which to me makes sense and does work for ~60 secs. The problems arrive after my viewIDs change from 1,2,3... to 50,51,52 on the opposite system. As a side note I read that RPC.Server can't be called on the server but I thought RPC.All can be called on the server and work.
From what you have said, and from my own guess work I think that A) the viewIDs are not the same despite everything currently telling me that they are (I've checked client logs). B) weirdly the Destroy(gameObject) is happening in such a way that it thinks the RPC call is arriving after the event. I need to explore these two further situations further. I am very grateful for the input it's very frustrating.
I am fairly sure these methods only get called once for each object. Hence the use of NetworkView.is$$anonymous$$ine. Oh and I think I'm okay to call NetworkView.is$$anonymous$$ine in the last script as the owner has a target and position is sync'd. If I solve this I'll post back with the answer. There is other code I'm not showing here, didn't want to bog people down but maybe I'll post that too.
$$anonymous$$y point with the networkView was that it makes more sense to test if you own the thing that controls the nuke, rather than the ship you are currently executing your code on. It just feels wrong, but it is probably ok. Surely you need to own the thing that has the ho$$anonymous$$g missile components?
Next - my NetworkViewIDs for any dynamically instantiated object always start at 50. Only my scene objects that are fixed have network view ids below 50. So I'm kinda surprised you aren't seeing the same thing.
Per @Bunny83 - are you sure you can't destroy your stuff on every copy of the game, rather than destroying on one and sending an RPC to destroy on the others?
Is your Server also a player in this? RPC$$anonymous$$ode.All will call all connected players including the Server. RPC$$anonymous$$ode.Server will not call the server if it is issued on the server.
Your answer
Follow this Question
Related Questions
RPC not being called 1 Answer
Network.Instantiate dont instantiate object 0 Answers
Networking between projects: how to send ViewIDs? 1 Answer
NetworkView Component state update 2 Answers
ViewId is different in Unity editor than it is stand-alone 0 Answers