2015-05-07 4 views
0

Я пытаюсь вызвать метод AddFuel из другого сценария, но я не получаю ошибки, но мое топливо не обновляется, пользовательский интерфейс для видов топлива, за исключением того, что он отображает полное топливо (даже если топливо не должно быть полным), но как только я трачу топливо, топливо возвращается к тому, что было за вычетом топлива, которое я потратил.Неправильные методы вызова? C#

Как я могу решить эту проблему?

RefuelPickup Script

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

PlayerController Script

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

UIController Script

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 Script

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() { 

    } 
} 
+0

Комментарии не предназначены для расширенного обсуждения; этот разговор был [перемещен в чат] (http://chat.stackoverflow.com/rooms/77194/discussion-on-question-by-schmoopy-calling-methods-incorrectly-c). – Taryn

ответ

0

На вашем скрипте RefuelPickup вы создаете экземпляр нового компонента PlayerController каждый раз, когда вызывается метод Collect(). Когда создается новый PlayerController, какова стартовая ценность свойства топлива?

Посмотрев на свой код, я предполагаю, что PlayerController начнет с максимального количества топлива. Это объясняет, почему значение ползунка UIFuel всегда задано на новом сборе топлива. Каждый раз, когда вы вызываете сбор Создать новый экземпляр PlayerController, и UIFuel обновляется, чтобы отобразить полную стоимость топлива.

Если метод, используемый для расходования топлива, также используется в сценарии PlayerController, возможно, вы всегда вызываете метод расходования одного и того же экземпляра PlayerController, возможно, первый из них установлен, тем самым устанавливая значение ползунка UIFuel до значения, которое оно было до того, как кто-либо соберет минус затраченное значение.

Если это то, что происходит, следует избегать создания нового PlayerController каждый раз, когда вызывается метод Collect(). Вместо этого, попробовать что-то вроде этого на вашем RefuelPickup сценарий:

private PlayerController playerController; 

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

я должен был сделать много догадок, но я надеюсь, что это помогает :)

1

Линия

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

создает новый PlayerController и присоединяет его. Итак, если вы соберете 20 раз, вы получите 20 PlayerControllers, прикрепленных к вашему gameObject. Я предполагаю, что вы прикрепили один PlayerController раньше, и вы хотите получить ссылку на него вместо создания нового. Это особенно плохо, если все 20 будут конкурировать, чтобы установить значение ползунка, указывающего, сколько топлива осталось. Если да, то используйте вместо этого:

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

Всякий раз, когда вы используете GetComponent, вы можете проверить, является ли нуль объект возвращается, и иметь дело с этим. Таким образом, вы можете следить за ним с

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

Это похоже на ответ Габриэля Коутиньо, но здесь я сохранил ваше использование PlayerController в качестве локальной переменной. Кроме того, я использовал GetComponent. Использование GetComponent может привести к небольшому результативному результату, поэтому вы не хотите называть это много раз каждое обновление. (Вы можете использовать публичное или частное поле, чтобы использовать GetComponent только один раз.) Однако, если вы уже подключили один PlayerController, скажите в редакторе, где вы также установили начальное количество топлива, вы хотите использовать его, а не создать секунду, потому что у вас еще нет ссылки на него. Вы хотите, чтобы не было двух Игроков с различными идеями о том, сколько топлива осталось конкурирующим, чтобы установить значение индикатора топлива.

Смежные вопросы