【问题标题】:bool stays false even when called to change即使调用更改,布尔值也保持为假
【发布时间】:2016-05-26 19:48:41
【问题描述】:

更新 这不是我遇到的主要问题。查看this question

我做了一个多人游戏,我想知道对方玩家什么时候死(bool oppdead)。

如果我运行我的代码,而对手玩家死了,我会得到日志“opp player is dead”,但我的 onGUI 没有被执行。我做错了什么吗?我所有其他布尔的工作都很完美..

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;
    }


}

【问题讨论】:

  • if (oppdead) 行设置断点并单步执行代码会发生什么?
  • 我总是直接在设备上测试它,因为在统一本身中,谷歌多人游戏无法工作,所以我认为我只有 logcat 对吗?但是当我在那里放一个 Debug.Log 时,它没有出现在 logcat 中
  • @EmanuelGraf 你仍然可以调试脚本while they run on the device
  • 用 4.6+ UI 的东西做 UI 可能会更容易,而不是 IMGUI。
  • 你绝对不能使用“古老”的 Unity gui 系统。它行不通。您必须更改为普通的“新” UI 系统。单击“添加画布”,然后单击“添加按钮”(或其他)。 (这非常容易。)

标签: c# unity3d


【解决方案1】:

(一个)你面临的问题很简单,不要为“Inspector variables”设置默认值(即,当你有“public”时)。 Explanation.

如果(见下文)你需要一个 Inspector 变量,你根本不能这样做:

public int example = 3;

你必须这样做

public int example;

关于您的具体情况,伊曼纽尔。你需要尝试两件事。 (A) 绝对没有理由在这里有一个 Inspector 变量。请改成这样:

public bool oppdead = false;

改成

[System.NonSerialized] public bool oppdead = false;

这是 Unity 中那些奇怪的事情之一。在实践中,除了在测试项目中之外,几乎没有理由使用“Inspector”变量。所以当你在c#中需要一个普通的、日常的public变量时,你必须将它声明为

[System.NonSerialized] public

而不仅仅是

public

因此,您在 Unity 源文件中随处可见。所以在第一种情况下,“A”尝试一下。


在第二种情况下,反之亦然。

一个简单的可能性是其他进程很可能正在更改变量,因为您已将其标记为公开。您必须将其更改为局部变量。

 private bool oppdead

试试这个,看看会发生什么。

请注意,如果您是一位经验丰富的 Unity 程序员新手,Unity 可能会令人难以置信的困惑,因为 类在 Unity 中意义不大;您可能有一个“更改 oppdead”的组件,但谁知道有多少游戏对象以及哪些游戏对象附加并运行了该组件;任何事情都可能改变价值。因此,请选择私人。


正如您所说,下一个问题是无法正确调试多人游戏,因为很难访问开发消息。 必须解决这个问题,我会告诉你怎么做。

  • 点击GameObject、UI、Canvas,选择“scale with screen size”

  • 点击游戏对象、UI、文本。将其放在左上角。提示,请务必像这样选择这两项:

  • 一定要命名文本项“devText”

使用大致这样的代码来显示正在进行的开发消息:

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

(你可以从任何对象调用它。)

在您“Debug.Log("opp Player is dead");”的地方,请改用 devMessage 系统。


让我们知道会发生什么,尤其是当您更改为“私人”时。

我提醒您,如果您实际上 将它用作一个公共变量并从其他地方更改它,那么您完全浪费了每个人的时间,因为您没有显示执行此操作的代码: )

提醒您不得出于任何原因将其设为“Inspector”变量。

请告诉我们最新消息!

【讨论】:

  • 直到今天仍在经历这一切。代码不起作用。几个小时后在编辑器中查看并意识到那里有不同的价值。为新用户感到难过,因为他们要花很长时间才能找到问题。
  • 他们将永远选择答案 ;-)
  • @Programmer - 你有一个挑战.. stackoverflow.com/questions/37473802/…
  • 最糟糕的是,他们没有回复告诉您答案是否有效。我会看看你的问题。
  • @JoeBlow 感谢您的回答。试过了,但没有用。我确实有一个具有默认值的公共变量,请参阅public bool dead = false;,这个工作完美
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-29
  • 1970-01-01
  • 1970-01-01
  • 2017-09-17
相关资源
最近更新 更多