代码伪装成变量不存在

时间:2019-01-11 00:56:39

标签: c# unity3d

基本上,我需要对音频剪辑的长度进行一次检查,然后将其存储在变量中,以用作代码在继续销毁游戏对象之前应等待的时间。

我已经尝试了许多不同的事情,例如将其带到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;

如果(播放计时器<= 0)

应该能够看到:

float playtimer = aSource.clip.length;

相反,他们假装它甚至不存在,并且脚本因此而无法编译。

3 个答案:

答案 0 :(得分:1)

playtimer变量定义更高一级,以便在两个地方都可以看到它。

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

playtimer -= Time.deltaTime;

答案 1 :(得分:0)

您要在if范围内声明playtimer,因此在您致电时不存在     playtimer-= Time.deltaTime;

这样看,当lengthset不为false时,您还没有声明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的值,则可能需要将其添加为实例变量(即,将所有其他变量放在最前面)。如果这样做,请确保从方法逻辑中删除声明。

答案 2 :(得分:0)

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