调用方法不正确? C#

时间:2015-05-07 09:28:34

标签: c# methods unity3d

我试图从另一个脚本调用AddFuel方法,但我没有得到任何错误,但我的燃料不会更新,燃料类更新的UI除了它显示全部燃料(即使燃料不应该&#t; t但是,只要我消耗燃料,燃料就会恢复到我消耗的燃料量。

我该如何解决这个问题?

RefuelPickup脚本

void Collect()
{
    PlayerController playerController =gameObject.AddComponent<PlayerController>();
    float addFuel = .5f;
    playerController.AddFuel(addFuel);
}

PlayerController脚本

public void AddFuel(float value)
{
    fuel += value;
    UIController.SetFuel(fuel);
}

UIController脚本

using UnityEngine;
using System.Collections;

public class UIController : MonoBehaviour {

    private static UIController Instance { get; set; }

    public UIRemaining remaining;
    public UIFuel fuel;
    public UIGameOver gameOver;
    public UITimer timer;

    /// <summary>
    /// Update the UI to show the new number of remaining goals.
    /// </summary>
    /// <param name="value">The number of goals remaining.</param>
    public static void SetRemaining(int value)
    {
        Instance.remaining.SetValue(value);
    }

    /// <summary>
    /// Set the current value of the fuel bar
    /// </summary>
    /// <param name="value">A normalised value between 0 and 1, with 0 being empty and 1 being full.</param>
    public static void SetFuel(float value)
    {
        Instance.fuel.SetValue (value);
    }

    /// <summary>
    /// Update the game timer to display a new value
    /// </summary>
    /// <param name="gameTime">The time, in seconds, to display in the UI</param>
    public static void SetTime(float gameTime)
    {
        Instance.timer.SetTime(gameTime);
    }

    /// <summary>
    /// Display the game over screen with a custom message. This will not show any time information.
    /// </summary>
    /// <param name="message">The message to display on the game over screen.</param>
    public static void GameOver(string message)
    {
        Instance.gameOver.Show (message);
    }

    /// <summary>
    /// Display the game over screen with a custom message and time information.
    /// </summary>
    /// <param name="message">The message to display on the game over screen.</param>
    /// <param name="time">The last time, in seconds, played in this level</param>
    /// <param name="bestTime">The best time, in seconds, played in this level</param>
    /// <param name="isNewHighscore">True if the best time is a new highscore, otherwise false.</param>
    public static void GameOver(string message, float time, float bestTime, bool isNewHighscore)
    {
        Instance.gameOver.Show (message, time, bestTime, isNewHighscore);
    }

    public static void LoadUI()
    {
        if (Instance == null) {
            Application.LoadLevelAdditive("UI");
        }
    }

    void Awake()
    {
        Instance = this;
    }

    void OnDestroy()
    {
        Instance = null;
    }

    // Use this for initialization
    void Start () {
    }
}

UIFuel脚本

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class UIFuel : MonoBehaviour {

    public Slider slider;

    public void SetValue (float value)
    {
        slider.value = value;
    }

    // Use this for initialization
    void Start () {

    }
}

2 个答案:

答案 0 :(得分:1)

该行

PlayerController playerController=gameObject.AddComponent<PlayerController>();

创建一个新的PlayerController并附加它。所以,如果你收集了20次,你最终会将20个PlayerControllers附加到你的gameObject上。我的猜测是你先前附加了一个PlayerController,并且想要获得它的引用而不是创建一个新的。如果所有20个竞争对手设置指示剩余燃料量的滑块值,则这尤其糟糕。如果是这样,请改用:

PlayerController playerController=gameObject.GetComponent<PlayerController>();

每当使用GetComponent时,您可能想要测试返回的对象是否为null,并处理它。所以,你可以用

来跟进
if (playerController == null)
{
    playerController = gameObject.AddComponent<PlayerController>();
}

这类似于Gabriel Coutinho的回答,但在这里我保留了你对playerController作为局部变量的使用。另外,我使用了GetComponent。使用GetComponent可以带来轻微的性能损失,因此您不希望每次更新都会调用很多次。 (您可以使用公共或私有字段,以便只使用一次GetComponent。)但是,如果您已经连接了一个PlayerController,比如在您也设置了初始燃料量的编辑器中,您想要使用那个,并且不要因为你还没有引用它而创建第二个。您希望避免让两个PlayerController对燃料指示器的价值设置燃料指示器的剩余燃料有不同的想法。

答案 1 :(得分:0)

在RefuelPickup脚本上,每次调用Collect()方法时都会实例化一个新的PlayerController组件。当一个新的PlayerController被实例化时,燃料属性的起始值是多少?

通过查看您的代码,我的猜测是PlayerController以最大值的燃料开始。这可以解释为什么在新的燃料收集时UIFuel滑块值总是设置为满。每次调用Collect时,都会创建一个新的PlayerController实例,并更新UIFuel以显示完整的燃料值。

如果用于消耗燃料的方法也在PlayerController脚本上,那么你可能总是调用同一个PlayerController实例的spend方法,可能是第一个实例化的方法,因此将UIFuel滑块值设置为在任何收集减去消费价值之前的价值。

如果发生了这种情况,那么每次调用Collect()方法时都要避免创建新的PlayerController。相反,在RefuelPickup脚本上尝试这样的事情:

private PlayerController playerController;

void Collect()
{
    if(playerController == null)
    {
        PlayerController playerController = gameObject.AddComponent<PlayerController>();
    }
    playerController.AddFuel(.5f);
}

我必须做出很多猜测,但我希望这会有所帮助:)