Ok so, here is the problem.
I am doing a multiplayer 2D game using UNET.
I have a script that kind of helps a player select an avatar to play with. The avatars are listed as a scrollview of buttons. These buttons invoke the function setAvatar(int id)
that sets a player's avatar passing in an ID as argument. The function just sets the player's avatar using ID as index in a list of avatars.
Now the problem is this player is a prefab which is instantiated at the start of the playscene for Player A and Player B. So the setAvatar(int sprid)
function assumes I am referring to the prefab whenever I use "gameObject"
So, I decided to store the local gameObject in a temporary variable.
Here's the full code,
public class Player2DController : NetworkBehaviour // Attached to player prefab
{
public float moveForce = 2;
Rigidbody2D myBody;
Transform mainCamera;
Shooting shscript;
int i;
public Transform joystick;
GameObject temp;
public Sprite[] spr;
void Start ()
{
if (!isLocalPlayer)
{
Destroy (this);
return;
}
temp = gameObject; // storing local gameobject in temp
joystick = GameObject.Find ("MobileJoystick").transform;
shscript = GetComponent<Shooting> ();
mainCamera = Camera.main.transform;
RotateCamera ();
myBody = GetComponent<Rigidbody2D> ();
if (isClient)
{
i = -1;
}
if (isServer)
{
i = 1;
}
}
public void RotateCamera()
{
if (isClient)
{
mainCamera.rotation = Quaternion.Euler (new Vector3 (0f, 0f, 180f));
}
if (isServer)
{
mainCamera.rotation = Quaternion.Euler (new Vector3 (0f, 0f, 0f));
}
}
void FixedUpdate ()
{
if (PauseMenu.isOn)
{
return;
}
Vector2 moveVec = new Vector2(CrossPlatformInputManager.GetAxis("Horizontal"),CrossPlatformInputManager.GetAxis("Vertical"))* moveForce;
myBody.AddForce (moveVec * i);
if (CrossPlatformInputManager.GetButton("Shoot"))
{
shscript.CmdFire ();
}
}
public void setAvatar(int id) // called through the buttons in the avatar list
{
temp.GetComponent<SpriteRenderer> ().sprite = spr [id];//null pointer exception
}
}
This code doesn't work. I get a null pointer exception on temp
variable saying it is not assigned. But how can this be? I clearly assign it to active gameObject in Start()
method. The only reason I can think of why this is happening is that since the button acts on the player prefab, it creates a separate instance of the script for the player prefab that doesn't get executed. So, when it invokes setAvatar()
, it has a temp which is not initialized.
So that's the whole problem. Since this didn't work, I tried renaming the players as clientPlayer
and serverPlayer
and then accessing them using GameObject.Find(name).GetComponent<SpriteRenderer>().sprite
. But this had no effect and no errors. I have no idea why.
So any ideas on how to go about this?
temp
on the spawned instance, but the buttons are callingsetAvatar
on the prefab — these two instances of the object each have their own copy of that variable, so setting one doesn't influence the other. You can change that by making thetemp
variablestatic
(shared between instances), but it may be neater and more scalable to introduce something like a PlayerManager script the buttons can talk to instead. \$\endgroup\$