I have a class called Entity that has a name, health, level, and some other stats, and a single function called “attack” (which takes a single argument–an Entity). I’m making an RPG. Entity is off in a script somewhere. Entity is going to be used for both enemies and player characters.
In the script for my player character, I make him an Entity. In the script for my enemy character, I make him an Entity. He also has some GUI stuff, so I make a button above his head that, when clicked, will use the “attack” function of the player character Entity on him. Of course, to call the player’s Entity from his script, I must make it static.
Big problem, now. Making it static makes the game crash. Like, completely. Just adding the word static in front of “var jakob : Entity;” will turn a scene that worked into a scene that doesn’t, instantly. The game starts for about 2 milliseconds, the music begins to play, then Unity has to be force-closed.
class BattleEntity{
var Name : String;
var Health : int;
var maxHealth : int;
var Lvl : int;
var Str : int;
var Int : int;
var Def : int;
var MagDef : int;
var Agi : int;
function Attack(attackTarget : BattleEntity){
attackTarget.Health-=(Str+PlayerPrefs.GetInt("CG_CurrentWeaponATT",2))*Random.Range(2.5, 3.5);
}
}
This is kinda hard for me to tell why without seeing any code, but some questions.
Is the Entity object for both the player and the enemy a member of a class (like a Player class or Enemy class)? If so then you shouldn’t need to make it static to access it, just public, assuming that the Enemy class has a reference to the Player object. A combination of Gameobject.Find() and GetComponent() could give you the references you need to directly access it.
Do you have “Pause on Error” selected in the console? It may be possible that Unity is finding an error during runtime but keeps running in spite of it, and you never see it due to the forced shut down.
From what I have researched, JS doesn’t support static variables. That maybe wrong, but I’m no JS person. Here’s a possible workaround though.
I will be assuming the following things:
-That you are attempting to call the player’s Entity.Attack() from the enemy’s script.
-There is a Gameobject called “Enemy” that has the battle0001.js script in it.
-There is a Gameobject called “Player” that has the jakob.js script in it.
In battle0001.js script, add the following to the Start function:
var playerEntity : Entity = Gameobject.Find(“Player”).GetComponent(“Entity”);
In the spot you have the commented //jakob.jakobEnt.Attack(aron), place:
playerEntity.Attack(aron);
Assuming my syntax is correct, this could be a work around.
I could do this (right now I am not attaching the BattleEntity component to anything, didn’t think I need to), but I just wanted to clarify: Jscript DOES support static variables for all the builtin/mono types, at least in Unity. I have used them to great effect before.
BattleEntity shouldn’t need to be placed on anything. And interesting on the static thing. I’m not sure how Unity handles it, but having that Gameobject reference should allow it to work.
But doesn’t this just make playerEntity a clone of what jakobEnt is at that specific time? That’s not really an appropriate workaround. I guess I could update playerEntity every frame.
Whenever I use Find or GetComponent, it appears to be a direct reference than a copy. Again, this may be a functional different between C# and JS for these functions, but for me they’ve always been references.
If there is a major difference between the C# version and the JS version of Find and GetComponent, there is one other workaround I can think of that should not be language specific. Updating every frame with the Find and GetComponent is very processor expensive.
I will be assuming that:
-There is a Gameobject called “Player” that has the jakob.js script in it (and not in a child object.
In jakob.js, add the following function:
function Attack(BattleEntity enemy) {
jakobEnt.Attack(enemy);
}
In battle0001.js, add the variable:
var playerObj : GameObject;
Add to Start():
playerObj = GameObject.Find(“Player”);
In Update(), replace where you have the current call to Attack with:
playerObj.SendMessage(“Attack”, aron);
You can pass whole classes using the SendMessage function and it’s variates. Here’s a link to it if you haven’t seen this function before:
Additionally, with some modifications, could I not just attach BattleEntity.js as a component to both the “Jakob” and “Aron” gameobjects, set the proper values in their script or in the inspector, and then use GetComponent on that script?