Код притворяется, будто переменная не существует - PullRequest
0 голосов
/ 11 января 2019

По сути, мне нужно выполнить однократную проверку длины аудиоклипа, а затем сохранить ее в переменной, чтобы использовать в качестве промежутка времени, в течение которого код должен ждать, прежде чем продолжить и уничтожить игровой объект.

Я пробовал множество разных вещей, например, вывод его за пределы оператора if и тому подобное, но каждая попытка приводила к тому, что этот код либо работал, но не так, как предполагалось, или просто отказывался компилироваться.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

 public class Fighting : MonoBehaviour
{

public int Team = 1; //Which team entity is on
public int Health = 100; //How much heath it has
public int MaxHealth = 100; //Maximum health cap
public int AttackDamage = 10; //Attack Damage to enemy entities
public int HealAmount = 0; //Amount it can heal friendly entities
public int DecayAmount = 1; //Amount of health lost over time (If over health cap)
public float DecayCooling = 1; //Seconds it takes for health to be lost over time (If over health cap)
public float DecayOriginal = 1; //Needs to be hidden and equal to DecayCooling
public float CoolDown = 2; //Seconds it takes until it can attack enemies again
public float original = 2; //Needs to be hidden and equal to CoolDown
public bool CoolingDown = false; //Is attack cooling Down?
public bool Decaying = false; //Is decaying cooling Down?
public bool Structure = false; //Is it a building?
public bool SelfHealing = false; //Can it heal itself?
public bool HealAll = false; //Can it heal every friendly unit in its radius?
public bool Garrisoning = false; //Can it garrison troops?
public bool Snap = false; //Do you wanna snap it?
public bool clipplayed = false;
public bool lengthset = false;
public AudioSource aSource;
//public AudioSource[] mSource;
public Component[] obj;

// Update is called once per frame
void Update()
{
    if (Snap == true || Health <= 0) //Snaps the entity if either is true
    {
        //Destroy(gameObject, .5f);
        obj = transform.parent.GetComponentsInChildren<MeshRenderer>();
        foreach (MeshRenderer rend in obj)
        {
            rend.enabled = false;
        }

        if (clipplayed == false)
        {
            aSource.Play();
            clipplayed = true;
        }

        bool playing = true;

        if (playing == false)
        {
            Destroy(transform.parent.gameObject);
        }

        if (playing == true)
        {
            if (lengthset == false)
            {
                float playtimer = aSource.clip.length;
                lengthset = true;
            }

            playtimer -= Time.deltaTime;

            if (playtimer <= 0)
            {
                playing = false;
            }

        }
    }

    if (Input.GetKey(KeyCode.N)) Instantiate(transform.parent.gameObject); //Debug tool to spawn another

    if (Health > MaxHealth && Decaying == false) //Checks to see if health should be decaying
    {
        Health -= DecayAmount;
        Decaying = true;
    }
    if (Decaying == true)
    {
        DecayCooling -= Time.deltaTime;
        if (DecayCooling <= 0)
        {
            Decaying = false;
            DecayCooling = DecayOriginal;
        }
    }
}

}

Эти строки кода:

playtimer - = Time.deltaTime;

if (playtimer <= 0) </p>

Должен быть в состоянии увидеть:

float playtimer = aSource.clip.length;

Вместо этого они делают вид, будто его даже не существует, и сценарий не будет компилироваться из-за него.

Ответы [ 3 ]

0 голосов
/ 11 января 2019

Вы объявляете playtimer в своей области if, поэтому он не существует, когда вы звоните playtimer - = Time.deltaTime;

Посмотрите на это так, что произойдет, если длина набора не ложна, вы еще не объявили бы playtimer:

if (lengthset == false)
{
    float playtimer = aSource.clip.length;
    lengthset = true;
}
playtimer -= Time.deltaTime;

Вместо этого объявите это вне области действия if:

float playtimer = 0;
if (lengthset == false)
{
    playtimer = aSource.clip.length;
    lengthset = true;
}
playtimer -= Time.deltaTime;

О, черт возьми, из вашего комментария: «Я построил код таким образом, чтобы он выполнялся только один раз, а не просто возвращал переменную к тому, что было снова и снова. Есть ли лучший способ выполнить мои намерения? ?».

Если вам нужно отслеживать значение playtimer между вызовами, то вы, вероятно, захотите добавить его в качестве переменной экземпляра (т. Е. Сверху всех остальных переменных). Обязательно удалите объявление из логики метода, если вы это сделаете.

0 голосов
/ 11 января 2019

В C # код во вложенной области видимости может видеть переменные, определенные вне области. Код за пределами области видимости не может видеть переменные, определенные внутри области видимости.

Поэтому следующее не будет работать:

{
    int a = 5;
}

Console.WriteLine(a); // can't see a because it's declaration is in the nested scope

но это будет работать:

int a = 0;

{
    a = 5;
}

Console.WriteLine(a); // can see a, its value is 5

В этом примере a объявляется вне двух вложенных областей, поэтому к ним могут обращаться оба:

{
    int a = 5;

    {
        a = 3;
    }

    {
        Console.WriteLine(a); // this will also work because a is declared outside the scope. Its value is 3.
    }
}

Если вам нужно, чтобы playTimer была одной и той же переменной (т. Е. Содержала одно и то же значение) между вызовами Update(), вам нужно переместить ее объявление за пределы Update() и в область уровня класса. Объем.

Например:

class Test
{
    float playTimer = 0;

    void Update()
    {
        Console.WriteLine(playTimer);
    }
}
0 голосов
/ 11 января 2019

Определите playtimer переменную на один уровень выше, чтобы увидеть ее в обоих местах.

float playtimer = 0;
if (lengthset == false)
{
    playtimer = aSource.clip.length;
    lengthset = true;
}

playtimer -= Time.deltaTime;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...