错误帮助 - UnityException:声明变量时不允许调用此函数

时间:2015-08-05 14:01:22

标签: c# unity3d

我收到以下运行时错误...

“UnityException:声明变量时不允许调用此函数。 没有变量声明后将其移动到行。 如果您正在使用C#,请不要在构造函数或字段初始值设定项中使用此函数,而是将初始化移至Awake或Start函数。“

堆栈跟踪:

UnityEngine.GameObject..ctor () (at C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineGameObje‌​ctBindings.gen.cs:419)
BallManager..ctor ()
ArcadeBallManager..ctor ()
UnityEngine.GameObject:AddComponent()
BasicGame:Start() (at Assets/BasicGame.cs:106)

这似乎发生在我使用exampleObject.AddComponent<aType>()exampleObject.GetComponent<aType>()

的脚本中

我已经尝试了很多解决方法,首先将代码行移动到Awake()和Start Functions()(如错误日志中所示)。

我尝试使用不同的访问修饰符在本地,全局声明变量,此外我在声明后使用了即时vs延迟赋值。

我还尝试了其他帖子中的各种其他“修复”,包括重新启动Unity以及重新创建脚本等。

我正在想我是否正在遭受与此相关的某种基本知识差距。

我不是在寻找代码修复程序,我希望了解发生了什么,所以如果有人理解这个错误,请问它们是否可以解释它。

其他可能很重要的细节...... 我正在尝试根据游戏类型动态选择管理系统,例如classicManager,specialManager,baseManager。 管理类共享基类。我打算使用多态来解决基类...请参阅下面的伪示例

if(gameType == specialManager)
{
   manager = exampleObj.AddComponent<ClassicManager>() as baseManager;
} 

非常感谢任何帮助。

新增Arx代码。

using UnityEngine;
using System.Collections;
using System;

public class BasicGame : MonoBehaviour {

    public GameObject ball_manager_obj;
    //public BallManager ball_manager_script;// = BallManager();
    // Can Be : "NumBallClasic"  or "NumballArcade" etc.

    //TEST...

    public ArcadeBallManager arcd;
    public ClassicNumBallManager clsc;


    //...TEST END

    public string game_type = "Arcade";

    public int seconds_left;
    public int minutes_left;

    public int game_length_mins = 2;

    public string game_time_string = "";

    public bool game_over = false;
    public bool game_paused = false;

    public int score = 0;

    public float ball_interval_min = 0.2f;
    public float ball_interval_max = 0.6f;
    public float ball_interval = 0.5f;

    public float ball_check_interval = 0.1f;


    public Camera the_cam;

    public GameObject wall_container;
    public WallScript wall_script;

    public GameObject end_zone_container;
    public EndZoneScript end_zone_script;

    public Color lerp_colour_a = Color.white;
    public Color lerp_colour_b = new Color(0.2f,0.6f,0.8f,1.0f);
    public Color intended_colour = Color.white;
    public Color prev_colour = Color.white;

    public bool is_set_up = false;
    // Use this for initialization
    void Start() 
    {

        the_cam = GameObject.Find ("Main Camera").GetComponent<Camera> ();
        the_cam.backgroundColor = intended_colour;
        //this.gameObject.transform.localScale = (new Vector3(the_cam.rect.width, the_cam.rect.height,0));

        ball_manager_obj = new GameObject ();
        ball_manager_obj.transform.SetParent (this.gameObject.transform);
        ball_manager_obj.name = "BallManagerObj";

        wall_container = new GameObject ();
        wall_container.name = "WallContainer";
        wall_container.transform.SetParent (this.gameObject.transform);
        wall_container.AddComponent<WallScript>();
        wall_script = wall_container.GetComponent<WallScript> ();
        wall_script.createWalls ();

        end_zone_container = new GameObject ();
        end_zone_container.name = "EndZoneContainer";
        end_zone_container.transform.SetParent (this.gameObject.transform);
        end_zone_container.AddComponent<EndZoneScript> ();
        end_zone_script = end_zone_container.GetComponent<EndZoneScript> ();
        end_zone_script.createEndZone ();

        setGameType (game_type); //<<<<--TO BE SET SET VIA USER Eventually

        //chooseBallManager(ball_manager_obj, ball_manager_script);

        if(game_type == "NumBallClasic")
        {

            seconds_left = 0;
            minutes_left = game_length_mins;
            game_time_string = ("" + game_length_mins + ":00");

            BallManager ball_manager_script =      ((BallManager)ball_manager_obj.AddComponent<ClassicNumBallManager>());
            //return b_man;

        }
        if(game_type == "Arcade")
        {

            seconds_left = 0;
            minutes_left = game_length_mins;
            game_time_string = ("" + game_length_mins + ":00");

            if(ball_manager_obj != null)
            {

                BallManager ball_manager_script = (BallManager)ball_manager_obj.gameObject.AddComponent<ArcadeBallManager>();
            }
            else
            {
                ball_manager_obj = new GameObject ();
                BallManager ball_manager_script = (BallManager)ball_manager_obj.gameObject.AddComponent<ArcadeBallManager>();
                //ball_manager_script =  ball_manager_obj.GetComponent<ArcadeBallManager>();
            }


            //ArcadeBallManager nu_b_man = new ArcadeBallManager();
            //BallManager b_man = nu_b_man as BallManager;

            //return b_man;

        }
        else
        {
            seconds_left = 0;
            minutes_left = game_length_mins;

            game_time_string = ("" + game_length_mins + ":00");

            BallManager ball_manager_script =  ((BallManager)ball_manager_obj.AddComponent<ArcadeBallManager>());

            //BallManager b_man = new ArcadeBallManager() as BallManager;
            //return b_man;

        }


    }

为31eee384添加新代码: (注意,课程几乎没有触及 - 获取精灵只是返回一个新的精灵用于测试目的atm)

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

public class ArcadeBallManager : BallManager {


    // Use this for initialization
    void Start () 
    {


    }

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


    }


    public override Sprite getActiveSprite (string b_type)
    {
        //SendActiveSprite
        Sprite spr = new Sprite();

        return spr;
    }
}

1 个答案:

答案 0 :(得分:0)

简而言之......

检查,检查并再次检查!

如果您没有发现问题,请重复上述步骤。

问题是31eee384指出的...... 深埋在我的基础课程中,有一行看起来像:

GameObject obj = new GameObject();

修复此错误只是在函数内初始化GameObject,例如

GameObject obj;

...

public void aFunc()
{
    obj = new GameObject();
}

注意:错误显示为“...而是将初始化移至唤醒或启动功能”。 - 这不适用于这个特殊情况。继续阅读以了解更多信息。

虽然正确和基本的答案如上所述,但我会解释导致我这种令人沮丧的简单错误的情况,因为其他人也犯了同样的错误......

之前的方法,我遇到了类似于上面的代码产生的空引用错误。 我最初在Start()函数中初始化GameObject,但无法弄清楚为什么我收到了null引用异常。 作为一个解决方法,我在我正在使用它的函数之外初始化了GameObject,如下所示(并在顶部提到)......

GameObject obj = new GameObject();

这条线在我的代码中被遗忘了,并且被遗忘了,因为修复似乎有效,直到我遇到“......在声明变量时不允许调用此函数”错误。

简单的空引用错误&amp; “...而不是将初始化移动到唤醒或启动功能”的问题。 ...

Start()函数没有在基类中触发,因为扩展它的类也使用了Start()函数。 HEAD SLAP MOMENT

完整修复:

1)确保只在函数内初始化对象。

2)确保您初始化的函数实际在基类中运行。

在我的情况下,我将基类中的Start()函数的名称更改为InitBase()。然后我从扩展类中调用它。

希望这会有所帮助:)