【问题标题】:Unity3D: How to show GUI.box if condition is true?Unity3D:如果条件为真,如何显示 GUI.box?
【发布时间】:2013-02-11 07:07:41
【问题描述】:

我正在使用 C# 在 Unity3D 中制作游戏。我正在使用 GUI.box 为小怪显示一个健康栏,但我只想在有目标时显示 GUI.box。

这是我目前的代码。

public GameObject target;
public bool existsTarget;

// Use this for initialization
void Start()
{

PlayerAttack pa = (PlayerAttack)GetComponent("PlayerAttack");
target = pa.target;

existsTarget = false;
}

// Update is called once per frame
void Update()
{

if(target != null)
existsTarget = true;
else
existsTarget = false;


}

void OnGUI()
{
if(existsTarget)
        GUI.Box(new Rect(500, 10, healthBarLength, 20), curHealth + "/" + maxHealth);
    else   {
       GUI.Box(new Rect(Screen.width, 10, healthBarLength, 20), curHealth + "/" + maxHealth);
   }

不幸的是,这根本没有显示任何健康条。关于为什么的任何想法?

应大众需求在此处发布脚本。

public class Targetting : MonoBehaviour {
public List<Transform> targets;
public List<Transform> items;
public GameObject TheSelectedTarget {get; set;}
private Transform selectedTarget;
private Transform selectedItem;
private Transform myTransform;

// Use this for initialization
void Start () {
    targets = new List<Transform>();
    items = new List<Transform>();

    selectedTarget = null;
    selectedItem = null;
    myTransform = transform;
    TheSelectedTarget = null;

    addAllEnemies();
    addAllItems();
}

//adds all targets to a list
private void addAllEnemies() {

    GameObject[] go = GameObject.FindGameObjectsWithTag("Enemy");

    foreach(GameObject enemy in go){
        addTarget(enemy.transform);
    }

}

//adds a target
private void addTarget(Transform enemy) {

    targets.Add(enemy);
}

//sorts target by distance
private void sortTargets() {

    targets.Sort(delegate(Transform t1, Transform t2) {
        return Vector3.Distance(t1.position, myTransform.position).CompareTo(Vector3.Distance(t2.position, myTransform.position));
    });
}

//targets an enemy
private void targetEnemy() {

    addAllEnemies();

    if(selectedTarget == null) {
        sortTargets();
        selectedTarget = targets[0];
    } else {
        int index = targets.IndexOf(selectedTarget);

        if(index < targets.Count -1) {
            index++;

        } else {
            index = 0;

        } 
        deselectTarget();
        selectedTarget = targets[index];
}
    selectTarget();
    targets.Clear();
    }
//selects a specific target, and colors it red
public void selectTarget() {

    selectedTarget.renderer.material.color = Color.red;

    PlayerAttack pa = (PlayerAttack)GetComponent("PlayerAttack");
    pa.target = selectedTarget.gameObject;

    TheSelectedTarget = pa.target;
}

//deselects the current selected target, and colors i grey
private void deselectTarget() {
    selectedTarget.renderer.material.color = Color.gray;
    selectedTarget = null;
}

//adds all items to a list
void addAllItems() {

GameObject[] go = GameObject.FindGameObjectsWithTag("Book");

foreach(GameObject book in go){
    addItem(book.transform);
}

}

'

....然后脚本继续,但与此无关...

'          public class EnemyHealth : MonoBehaviour
          {
            public string enemyName;
              public int maxHealth = 100;
              public int curHealth = 100;
              public float healthBarLength;
              public GameObject target;
          public bool existsTarget;
          public AudioSource dying;

    // Use this for initialization
    void Start()
{
    //enemyName = this.enemyName;
    healthBarLength = Screen.width / 3;

    existsTarget = false;
}

// Update is called once per frame
void Update()
{
    adjustCurHealth(0);

    Targetting ta = (Targetting)GetComponent("Targetting");
    target = ta.TheSelectedTarget;
    Debug.Log (target);

    if(target != null)
        existsTarget = true;
    else {
        existsTarget = false;   
    }

}

void OnGUI()
{
    if(existsTarget)
        GUI.Box(new Rect(500, 10, healthBarLength, 20), curHealth + "/" + maxHealth);
    else   {
       GUI.Box(new Rect(Screen.width, 10, healthBarLength, 20), curHealth + "/" + maxHealth);
   }
}

public void adjustCurHealth(int adj)
{
    curHealth += adj;

    if (curHealth < 0)
        curHealth = 0;

    if (curHealth > 100)
        curHealth = 100;

    if (maxHealth < 0)
        maxHealth = 1;

    if(curHealth == 0)
    {
        //dying.Play ();
        GameObject.Destroy(gameObject);
    }

    healthBarLength = (Screen.width / 3) * (curHealth / (float)maxHealth);
}

}

【问题讨论】:

  • 再次检查您的盒子的位置参数。我猜你是在告诉它不在屏幕上,或者长度为 0。
  • 我也认为位置参数是这里的问题,尝试在原点使用更大的(200x50),看看会发生什么。顺便说一句,在OnGUI() 中检查条件target != null 不是更容易吗?请记住,每帧可能会多次调用此方法。
  • 感谢 cmets!我不认为这是位置参数,因为如果我简单地去掉 if 条件,GUI.box 会显示得非常好。起初我确保 GUI.box 正确显示,但后来我一直看到所有小怪的健康栏,这当然不是很好 -.- 我的第一次尝试是在 OnGUI() 中设置条件,但是没用,所以我认为它没有在每一帧上更新,所以我把它移到了 Update()。现在又试了一次,还是不行。
  • 我认为我们需要查看PlayerAttack 脚本才能确切知道发生了什么......
  • @user1776119 如果您取消条件,您将绘制 2 个独立的框。您的第二个框开始在屏幕边缘绘制,除非 healthBarLength 为负数,否则不会显示,但负的 Rect 长度会导致框不正确。我在没有条件的情况下运行了您的代码,并且只绘制了第一个框,但这是有道理的,它是在 x=500 处绘制的。

标签: c# user-interface unity3d


【解决方案1】:

除了 Start() 方法之外,您是否曾在任何地方设置目标?如果 PlayerAttack.Target 在开始时不为空,您显示的代码只会显示 GUI.box。尝试将此代码移至 Update() 方法。

PlayerAttack pa = (PlayerAttack)GetComponent("PlayerAttack");
target = pa.target;

编辑:

检查目标是否为空,这可能是问题所在。

target = pa.target;
Debug.Log(target);

这将作为任何 GameObject 打印到日志中,或者为 null。如果为空,则没有目标。

【讨论】:

  • PlayerAttack 脚本是否附加到您尝试从中获取它的同一组件?
  • 不,不是。刚刚附上它,但这也没有用:(
  • 如果您通过 AddComponent 附加了它,您必须能够使用 GetComponent 方法将其取回。
  • 我只是把它拖到了游戏对象上。这是一个相当小的游戏,所以:P 那我还需要做些什么吗?
  • @user1776119: 所以对象有 2 个脚本?检查检查器,它必须显示你的对象有一个 PlayerAttack 脚本和另一个(我不知道名字)你正在调用 GetComponent
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-14
  • 2014-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-08
  • 1970-01-01
相关资源
最近更新 更多