1

UPDATE this is not the main problem I had. check out this question

I've made a little multiplayer game in unity, and I want to know, when the opponent player is dead (bool oppdead).

If I run my code, and the opponent player dies, I do get the Log "opp player is dead", but my onGUI isnt beeing executed. Have I done something wrong? all my other bool's work perfectly..

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using GooglePlayGames.BasicApi.Multiplayer;
using UnityEngine.UI;
using System;

public class BirdMovementMP : MonoBehaviour, MPLobbyListener
{



    public GameObject opponentPrefab;
    public Rigidbody2D oppPlane;

    private bool _multiplayerReady;
    private string _myParticipantId;

    public bool oppdead = false;

    public float flapSpeed = 100f;
    public float forwardSpeed = 1f;

    bool didFlap = false;

    Animator animator;

    public bool dead = false;
    float deathCooldown;


    public Rigidbody2D plane;

    public Button buttonImage;


    public GUISkin replay;
    public GUISkin home;

    void SetupMultiplayerGame()
    {
        MultiplayerController.Instance.lobbyListener = this;

        // 1
        _myParticipantId = MultiplayerController.Instance.GetMyParticipantId();
        // 2
        List<Participant> allPlayers = MultiplayerController.Instance.GetAllPlayers();
        _opponentScripts = new Dictionary<string, OpponentPlane>(allPlayers.Count - 1);
        for (int i = 0; i < allPlayers.Count; i++)
        {
            string nextParticipantId = allPlayers[i].ParticipantId;
            Debug.Log("Setting up car for " + nextParticipantId);
            // 3
            if (nextParticipantId == _myParticipantId)
            {
                // 4
                //rigidbody2D.GetComponent<BirdMovementMP>().SetCarChoice(i + 1, true);
               // myCar.transform.position = carStartPoint;
            }
            else
            {
                // 5
               /* GameObject OpponentPlane = (Instantiate(opponentPrefab, carStartPoint, Quaternion.identity) as GameObject);
                OpponentPlane opponentScript = OpponentPlane.GetComponent<OpponentPlane>();
                opponentScript.SetCarNumber(i + 1);
                // 6
                _opponentScripts[nextParticipantId] = opponentScript;*/
            }
        }
        // 7

        _multiplayerReady = true;

    }

    public void UpdatePlane(string senderId, float x, float y, float z, bool death)
    {

        MultiplayerController.Instance.GetMyParticipantId();

        // OpponentPlane opponent = _opponentScripts[senderId];
        if (death)
        {
            Debug.Log("opp Player is dead");

            oppdead = true;

        }
        if (opponentPrefab != null)
            {

            opponentPrefab.transform.position = new Vector3(x, y, 0);
            opponentPrefab.transform.rotation = Quaternion.Euler(0, 0, z);
                Debug.Log("setting opp  pos new");

            }
        if (opponentPrefab == null)
        {
               // Debug.Log("oppo is gleich null");
            opponentPrefab = GameObject.Find("Opponent");

            opponentPrefab.transform.position = new Vector3(x, y, 0);
                opponentPrefab.transform.rotation = Quaternion.Euler(0, 0, z);

            }


    }

    void doMultiplayerUpdate()
    {


        MultiplayerController.Instance.SendMyUpdate(plane.transform.position.x,
                                            plane.transform.position.y,
                                            plane.transform.rotation.eulerAngles.z,
                                            dead);

     //   Debug.Log("Im at position:" + plane.transform.position.x + "x" + plane.transform.position.x + "y");




    }

    // Use this for initialization
    void Start()
    {
        if(opponentPrefab == null)
        {
            opponentPrefab = GameObject.Find("Opponent");

        }

        animator = transform.GetComponentInChildren<Animator>();
        Time.timeScale = 0;

        if (animator == null)
        {
            Debug.LogError("Didn't find animator!");
        }
    }
    void OnGUI()
    {
        if (oppdead)
        {
            GUI.skin.label.fontSize = Screen.height / 20;
            GUI.Label(new Rect(Screen.height / 2, Screen.height / 2, Screen.height / 2, Screen.height / 2), "   other is deadddd ");

        }
        if (dead)
        {

            //Menu Button
            GUI.skin = null;
            GUI.skin = home;
            if (GUI.Button(new Rect(10, Screen.height / 2, Screen.height / 4, Screen.height / 4), ""))
            {
                Application.LoadLevel("home");
            }

        }

    }


    // Do Graphic & Input updates here
    void Update()
    {



        doMultiplayerUpdate();
        if (dead)
        {
            deathCooldown -= Time.deltaTime;





        }
        else
        {


            if (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0))
            {
                didFlap = true;
            }
        }
    }


    // Do physics engine updates here
    void FixedUpdate()
    {

        if (dead)
            return;

        plane.AddForce(Vector2.right * forwardSpeed);

        if (didFlap)
        {
            plane.AddForce(Vector2.up * flapSpeed);
            animator.SetTrigger("DoFlap");


            didFlap = false;
        }

        if (plane.velocity.y > 0)
        {
            transform.rotation = Quaternion.Euler(0, 0, 0);
        }
        else
        {
            float angle = Mathf.Lerp(0, -90, (-plane.velocity.y / 3f));
            transform.rotation = Quaternion.Euler(0, 0, angle);
        }
    }

    void OnCollisionEnter2D(Collision2D collision)
    {


        animator.SetTrigger("Death");
        dead = true;
        deathCooldown = 0.5f;
    }


}
Community
  • 1
  • 1
Emanuel Graf
  • 756
  • 17
  • 37
  • What happens when you put a breakpoint on the `if (oppdead)` line and step through the code? – Lews Therin May 26 '16 at 19:50
  • I always test it directly on the devices, because in unity itself, google multiplayer wont work, so I think I only have the logcat right? but when I putted a Debug.Log there, it didnt show up in logcat – Emanuel Graf May 26 '16 at 19:52
  • 2
    @EmanuelGraf you can still debug scripts [while they run on the device](http://docs.unity3d.com/Manual/AttachingMonoDevelopDebuggerToAnAndroidDevice.html) – Scott Chamberlain May 26 '16 at 19:56
  • Would probably be easier to do the UI with the 4.6+ UI stuff, not the IMGUI. – Gunnar B. May 26 '16 at 20:05
  • 1
    you absolutely CAN NOT use the "ancient" Unity gui system. It won't work. You must change to the ordinary "new" UI system. Click "add canvas" and then click "add button" (or whatever). (it is extremely easy.) – Fattie May 26 '16 at 20:42
  • Possible duplicate of [String.Split() Function mysteriously ignoring duplicates](http://stackoverflow.com/questions/34711899/string-split-function-mysteriously-ignoring-duplicates) – Fattie May 26 '16 at 20:42
  • sorry wrong link .... here .... http://stackoverflow.com/a/35166004/294884 – Fattie May 26 '16 at 20:44

1 Answers1

4

(One) problem you face is simple, DO NOT set a default value for "Inspector variables" (ie, when you have "public"). Explanation.

IF (see below) you need an Inspector variable, you simply cannot do this:

public int example = 3;

you must do this

public int example;

Further to your specific case Emanuel. You need to try two things. (A) there is absolutely no reason to have an Inspector variable here. Please change to this:

public bool oppdead = false;

change to

[System.NonSerialized] public bool oppdead = false;

It's one of those odd things in Unity. In practice there is very little reason to use "Inspector" variables other than in test projects. So when you need an ordinary, everyday public variable in c#, you have to declare it as

[System.NonSerialized] public

rather than just

public

So, you see this everywhere in Unity source files. So in the first case "A" try that.


In the second case and conversely.

One simple possibility is it is highly likely some other process is changing the variable, since, you have marked it public. You must change it to a local variable.

 private bool oppdead

Try this and see what happens.

Note that if you are an experienced programmer new to Unity, Unity can be incredibly confusing since, classes mean less than nothing in Unity; you may have a component that "changes oppdead" BUT who knows how many game objects and which ones have that component attached and running; anything could be changing the value. For this reason go with private.


The next issue is, as you say, it's impossible to debug multiplayer games properly as it's hard to access development messages. You must fix this problem, and I will show you how.

  • click GameObject, UI, Canvas, select "scale with screen size"

  • on that click GameObject, UI, Text. position it towards the top left. tip, be sure to choose these two items like this:

enter image description here

  • be sure to name the Text item "devText"

Use code roughly like this to display ongoing development messages:

public void devMessage(string m)
{
Text t = GameObject.Find("devText").GetComponent<Text>();
t.text = t.text +"\n" +m
}

(you can call it from any object.)

at the point where you "Debug.Log("opp Player is dead");", use the devMessage system instead.


Let us know what happens, particularly when you change to "private".

I remind you that if you are actually using it as a public variable and changing it from elsewhere, you have completely wasted everyone's time here as you don't show the code that is doing that :)

A reminder that you must not make it an "Inspector" variable, for any reason.

Pls let us know the latest!

Community
  • 1
  • 1
Fattie
  • 27,874
  • 70
  • 431
  • 719
  • Still go through this up to this day. Code doesn't work. Looks in the editor hours later and realize there is a different value there. Feel bad for new users as it will take them forever to find the problem. – Programmer May 27 '16 at 01:15
  • it will take them forever to tick the answer ;-) – Fattie May 27 '16 at 01:36
  • @Programmer - there's a challenge for you .. http://stackoverflow.com/questions/37473802/unity3d-ui-calculation-for-position-dragging-an-item – Fattie May 27 '16 at 02:20
  • worst part is when they don't reply to tell you if the answer worked or not. I will take a look at your question. – Programmer May 27 '16 at 05:10
  • @JoeBlow Thanks for this answer. Tried it, but didnt work. I do have a public variable with a default value, see `public bool dead = false;` and this one works perfectly – Emanuel Graf May 27 '16 at 11:41
  • HI @EmanuelGraf, in the first instance you MUST delete the default value in the code, on the "public" variable. (Secondly you can no longer use the "ancient" gui system, so the whole thing is a waste of your time.) I will put in some further suggestions. mfg. – Fattie May 27 '16 at 14:06
  • So I spent 10 mins including some more info, cheers @EmanuelGraf – Fattie May 27 '16 at 14:27
  • thank you very much @JoeBlow unluckily, setting the bool to private does not change anything. but as the rest of your answer is really improving my debug 'skills' I'm marking your answer as correct. – Emanuel Graf May 27 '16 at 14:48