- Home /
How do I keep track of projectile owners in a networked game?
I've got a networked multiplayer game going using the M2H examples as the starting point. Everything is working fine except that I have to use instantiated projectiles instead of raycasting (they are slow-moving missiles and things), so I'm trying to figure out how to determine which player fired the projectile that hits another player.
I've tried setting variables on scripts on the projectiles and everything else I can think of, but nothing seems to work. The method that's gotten me the closest is to have the player that fires the projectile rename it. Then the player it hits can use OnCollisionEnter(hit : Collision) to read the name and do the appropriate calculations.
I currently have this in a script on the player firing the projectile:
var projectile : Transform;
function FireMissile () {
var missile = Network.Instantiate(projectile, launcher.position, launcher.rotation, 0);
missile.name = "myFancyMissile";
}
Unfortunately, this works great, but only for the player that is also the server. None of the other players' missile names change and I can't figure out why. I've got a network view and so on on the prefab, and they work just fine otherwise. They just don't get the name change.
I'm not tied to this approach. It's just the one that's gotten me the closest, so I'm open to other suggestions.
Send the name change through RPC and all will be well.
While you're doing that you can also set the missile's owner in a variable and solve your problem altogether.
Thanks for the help. That makes sense, but I'm having trouble getting it set up right. I've changed it to this:
function Fire$$anonymous$$issile () { var missile = Network.Instantiate(projectile, launcher.position, launcher.rotation, 0);
networkView.RPC("Change$$anonymous$$issileName", RPC$$anonymous$$ode.All, missile);
}
@RPC function Change$$anonymous$$issileName(myBullet : GameObject){ missile.name = "myFancy$$anonymous$$issile"; }
I don't get any errors compiling, but when I fire the missile I get this:
Sending RPC failed because 'Change$$anonymous$$issileName' parameter 0 (UnityEngine.GameObject) is not supported. UnityEngine.NetworkView:RPC(String, RPC$$anonymous$$ode, Object[])
I've tried changing "GameObject" to String and Transform but get similar errors. Have I got the basic setup correct and just syntax problems, or do I need to set it up differently?
RPCs don't support many parameter types. Transform and GameObject for example aren't supported. Send only the string, put the RPC on the missile and have it change it's own name. That should work.
Hmm, it's still not happy. The code on the player is now this (shooterName is the string of the player's name from player prefs):
networkView.RPC("Change$$anonymous$$issileName", RPC$$anonymous$$ode.All, shooterName);
And this is now in the script on the missile: @RPC function Change$$anonymous$$issileName(my$$anonymous$$issile : String){ this.name = my$$anonymous$$issile; }
I now get this error (Rig_01 is the player and $$anonymous$$issile_NetworkShoot is the script on the player controlling the firing):
RPC call failed because the function 'Change$$anonymous$$issileName' does not exist in the any script attached to'Rig_01' UnityEngine.NetworkView:RPC(String, RPC$$anonymous$$ode, Object[]) $$anonymous$$issile_NetworkShoot:Fire$$anonymous$$issile() (at Assets/Scripts/Weapons/$$anonymous$$issile_NetworkShoot.js:49)
I know this may be asking a lot, but an actual code snippet example would probably make it a lot clearer.
So no answer to this?
It's such a basic requirement for most network shooting games that I can't believe there isn't a decent solution. I've looked here, I've searched the forums, and even the Unify Wiki with no results. And of course the Unity examples and documentation are so basic as to be completely useless in any real-world situation.
It's funny how the lack of a few lines of code can stop an entire project dead in it's tracks. I'll keep trying because something has to work, but it's getting awefully frustrating constantly trying to re-invent the wheel. I don't know what to do at this point, but if I ever do get an answer, I'll definitely be writing a tutorial so that no one else has to go through this again.
Answer by asafsitner · Jan 05, 2012 at 07:44 AM
Let's try a few approaches. First, try putting the entire rpc call on the missile, i.e:
function Awake()
{
networkView.RPC("ChangeMissileName", RPCMode.All, shooterName);
}
@RPC
function ChangeMissileName(myMissile : String)
{
this.name = myMissile;
}
If that doesn't work, try instantiating the missile in an rpc instead of Network.Instantiate
(player script):
var missileViewId = Network.AllocateViewID();
networkView.RPC("FireMissile", RPCMode.AllBuffered, missileViewId, missileName);
@rpc
function FireMissile(mName : string, viewId : NetworkViewID)
{
var missile = Instantiate(projectile, launcher.position, launcher.rotation) as Transform;
var nView : NetworkView;
nView = missile.GetComponent(NetworkView);
nView.viewID = viewID;
missile.name = mName;
}
Naturally you'll want to separate missile fire and missile death RPC's to different network groups for better management through networkView.group
too
Thanks. It's getting close. The first method didn't quite work. I could get it to assign a fixed name to the projectile, but I couldn't figure out a way for it to get the player name of the particular player that fired it. It would just assign a random name no matter which player was firing.
The second is much closer, though. It, for the most part, works. Here's the revised RPC code (I really hate that you can only paste code into a new answer and not in a reply...):
@RPC function Fire$$anonymous$$issile(myViewId : NetworkViewID, mName : String){ Debug.Log("$$anonymous$$issile Stats: " + myViewId + " " + mName);
var missile = Instantiate(missile, launcher.position, launcher.rotation) as Transform;
//Debug.Log("missile name: " + missile.name);
var nView : NetworkView;
nView = missile.GetComponent(NetworkView); // <Line 86
Debug.Log("nView: " + nView);
nView.viewID = myViewId;
missile.name = mName;
missile.rigidbody.velocity = rig.rigidbody.velocity;
missile.rigidbody.AddRelativeForce (Vector3.forward * force);
}
The only problem now is that I get this error:
NullReferenceException: Object reference not set to an instance of an object $$anonymous$$issile_NetworkShoot.Fire$$anonymous$$issile (NetworkViewID myViewId, System.String mName) (at Assets/Scripts/Weapons/$$anonymous$$issile_NetworkShoot.js:86) UnityEngine.NetworkView:RPC(String, RPC$$anonymous$$ode, Object[])
The weird thing is that the missile actually does get instantiated and the name does get changed. I also get a correct AllocatedID from the first Debug.log. The problem appears to be that nothing seems to work after that except for "missile.name = mName;". I say that because I'm assu$$anonymous$$g that if that line wasn't working, the name of the instantiation would just stay at the default, and I can clearly see the change in the Hierarchy. I don't know enough to know if "nView.viewID" is the number that's supposed to be assigned to the network View attached to the missile, or if this is a completely different number. "myViewId" increments in the debug statement, but I noticed that the ID of the network view on all the missiles stays at 0, if that helps any.
Anyway, "missile.rigidbody.velocity..." and "missile.rigidbody.AddRelativeForce..." do nothing, and if I uncomment "//Debug.Log("missile name: " + missile.name);", it never prints anything.
Hope that's not too confusing. I really appreciate the help.
Okay, so not working even quite as well as I thought. It is assigning a different name to each players' missile now, but it seems to be randomly picking someone name and then sticking with it. The na$$anonymous$$g is consistent, but not necessarily the right player. I'm getting the name by reading a variable I set in each players' playerpref when they start the game. I don't know if that helps or makes it more confusing, but there it is :)
Your answer
Follow this Question
Related Questions
Problem making a Network projectile Instantiate. 0 Answers
Multiplayer projectiles 0 Answers
Projectile over network problem 1 Answer