更新 这不是我遇到的主要问题。查看this question
我在 unity 中做了一个多人游戏,我想知道对手玩家何时死亡 (bool oppdead)。
如果我运行我的代码,对手玩家死了,我会得到日志“opp player is dead”,但是我的 onGUI 没有被执行。我做错了什么吗?我所有其他 bool 的工作都很完美..
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;
}
}
最佳答案
(一)你面临的问题很简单,不要为“Inspector variables”设置默认值(即,当你有“public”时)。 Explanation.
IF(见下文)您需要一个 Inspector 变量,您根本无法这样做:
public int example = 3;
你必须这样做
public int example;
进一步了解您的具体案例 Emanuel。你需要尝试两件事。 (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”,但谁知道有多少游戏对象以及哪些游戏对象附加并运行了该组件;任何事情都可能改变值(value)。出于这个原因,请选择私有(private)。
下一个问题是,正如您所说,无法正确调试多人游戏,因为很难访问开发消息。 您必须解决这个问题,我会告诉您如何解决。
点击GameObject、UI、Canvas,选择“scale with screen size”
在此点击 GameObject、UI、Text。将其定位在左上角。提示,一定要这样选择这两项:
- 一定要命名文本项“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 系统。
让我们知道会发生什么,尤其是当您更改为“私有(private)”时。
我提醒您,如果您实际上将它用作公共(public)变量并从其他地方更改它,那么您就完全浪费了每个人的时间,因为您没有显示执行此操作的代码: )
提醒您,无论出于何种原因,您不得将其设为“Inspector”变量。
请告诉我们最新消息!
关于c# - 即使调用更改时 bool 仍然为 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37469767/