- Home /
Non-MonoBehaviour class exists in scene, constantly calling itself
Here's the code:
class PlayerHUD {
function get score() : AUVTextWriter { return myScore; }
function get coin() : AUVTextWriter { return myCoin; }
function get health() : StatBar { return myHealth; }
function get shield() : StatBar { return myShield; }
function get transform() : Transform { return tx; }
private var tx : Transform;
private var myBase : AnimatedUV;
private var myHealth: StatBar;
private var myShield: StatBar;
private var myScore : AUVTextWriter;
private var myCoin : AUVTextWriter;
static var nhuds : int;
function PlayerHUD() { Debug.Log(nhuds++ + " huds"); }
function PlayerHUDZ() {
var auv : AnimatedUV;
var pos : Vector3;
tx = new GameObject("Player HUD").transform;
var basePos : Vector3 = tx.position;
myBase = GameObject.Instantiate(HUD.instance.base, basePos, Quaternion.identity).GetComponent.<AnimatedUV>();
auv = GameObject.Instantiate(HUD.instance.coin, basePos+myBase.PixelOffset(HUD.instance.coinOffset.x,HUD.instance.coinOffset.y), Quaternion.identity).GetComponent.<AnimatedUV>();
myBase.transform.parent = auv.transform.parent = tx;
auv = GameObject.Instantiate(HUD.instance.score,basePos+myBase.PixelOffset(HUD.instance.scoreOffset.x,HUD.instance.scoreOffset.y), Quaternion.identity).GetComponent.<AnimatedUV>();
auv.transform.parent = tx;
myHealth = new StatBar( tx, Vector3.up + myBase.PixelOffset( HUD.instance.barOffsetHealth.x, HUD.instance.barOffsetHealth.y ) );
myShield = new StatBar( tx, Vector3.up + myBase.PixelOffset( HUD.instance.barOffsetShield.x, HUD.instance.barOffsetShield.y ) );
}
}
In a certain scene, whenever I compile (that is, every time I save a script file and then go back to Unity), it creates 26 of these PlayerHUD objects in the editor (as evidenced by the constructor counter). If I alter the constructor to accept an argument (thus removing the default constructor), there are no errors reported and the new constructor isn't called.
The Debug trace isn't helpful - it lists only the line in the constructor. Is there an extended trace option to try to find what's making these, or is there a way to find and destroy these 'ghost' objects?
Adding 'extends $$anonymous$$onoBehaviour' also stops the constant constructor calls.
The constructor is called even in a new, empty scene with no objects.
Removing this var from another script:
class Player {
@HideInInspector var hud : PlayerHUD;
}
Causes the constructor to stop being called.
In an empty scene.
Were you able to solve the problem? I'm not a unityscript user but I'm still curious.
Nope. I'm using the dummy constructor, but any time I implement the default constructor in this one particular class it creates 26 instances of itself whenever scripts are compiled.
Answer by Democre · Nov 27, 2012 at 06:56 PM
My guess is that you have several prefabs with members of type PlayerHUD.
If it is a member of a script attached to a prefab or in scene game object, then the constructor will get called to access its default values at unforeseen times (play state changes, compilation, asset import, periodically as needed, etc...)
Do not use such a constructor for creating or instantiating any objects, but only for initialization of data values. Instead make a method named "Instantiate" or something that you can call when the containing gameObject Awakes or Starts.
I can understand that for public variables, I just don't get why it would call constructors on hidden or private variables. It was the prefab object - removing the prefab stopped the constructor calls. Oh well, problem... circumvented, thanks. :)
Answer by Shrandis · Nov 23, 2012 at 08:45 AM
As far as I know, in UnityScript if you don't specify a base class for your class, MonoBehavior is assumed while in C# System.Object is assumed.
Since your UnityScript class inherits from MonoBehavior(because you didn't specify a base class), the default constructor is called at the editor when the compiling is completed.
From Unity Script Reference:
Never initialize any values in the constructor or variable initializers in a MonoBehaviour script. Instead use Awake or Start for this purpose. Unity automatically invokes the constructor even when in edit mode. This usually happens directly after compilation of a script because the constructor needs to be invoked in order to retrieve default variable values. Not only will the constructor be called at unforeseen times, it might also be called for prefabs or inactive game objects.
That's only if you don't declare a class. Declaring the class... I suppose /usually/ forces it to inherit from exactly what you tell it to and nothing else. Thanks for the try though. I'll look into replicating this with some typecasting shenanigans.