- Home /
Variable not changing on real-time problem
Hello,
I have a very weird problem. I make a game where you control a spaceship and destroy comets. If a comet hits you, you lose one life.
The problem is that I have set a variable that holds the lives
var curLives : int;
but if a comet hits me it doesn't change. However, when I click the play button again to stop testing the game it goes to the number it was supposed to be as i was playing the game. In other words, if I have 5 lives at the beginning of the game and 3 comets hit me, when I stop playing the game, the variable on the inspector goes to 2.
This is really confusing.
I also have this line on the start function, so it sets the lives as another variable.
function Start() {
curLives = maxLives;
}
But it doesn't change....
here are my scripts. If anyone can help me :)
Js_Spaceship :
#pragma strict
var speed : int;
var missle : GameObject;
var spawner : GameObject;
private var canShoot : boolean = true;
var curLives : int;
var maxLives : int;
var livesObj1 : GameObject;
var livesObj2 : GameObject;
var livesObj3 : GameObject;
var livesObj4 : GameObject;
var livesObj5 : GameObject;
function Start () {
var curLives = maxLives;
}
function Update () {
transform.Translate(Input.GetAxis("Horizontal") * Time.deltaTime * speed,0,0);
if(transform.position.x >= 4)
{
transform.position.x = 4;
}
if(transform.position.x <= -4)
{
transform.position.x = -4;
}
Shoot();
//life calculations
Lifer ();
}
function Shoot () {
if(Input.GetKey(KeyCode.Space) && canShoot)
{
Instantiate(missle, spawner.transform.position, spawner.transform.rotation);
canShoot = false;
yield WaitForSeconds(0.5);
canShoot = true;
}
}
function Lifer () {
if(curLives == 5)
{
livesObj1.active = true;
livesObj2.active = true;
livesObj3.active = true;
livesObj4.active = true;
livesObj5.active = true;
}
if(curLives == 4)
{
livesObj1.active = true;
livesObj2.active = true;
livesObj3.active = true;
livesObj4.active = true;
livesObj5.active = false;
}
if(curLives == 3)
{
livesObj1.active = true;
livesObj2.active = true;
livesObj3.active = true;
livesObj4.active = false;
livesObj5.active = false;
}
if(curLives == 2)
{
livesObj1.active = true;
livesObj2.active = true;
livesObj3.active = false;
livesObj4.active = false;
livesObj5.active = false;
}
if(curLives == 1)
{
livesObj1.active = true;
livesObj2.active = false;
livesObj3.active = false;
livesObj4.active = false;
livesObj5.active = false;
}
}
Js_Comet :
#pragma strict
var speed : int;
var player : Js_Spaceship;
function Start () {
}
function Update () {
transform.Translate(0,-speed * Time.deltaTime,0,Space.World);
}
function OnCollisionEnter (other : Collision) {
if(other.gameObject.tag == "Player")
{
player.curLives --;
}
}
Well, lets see...
Did you make sure the player variable was assigned to your Spaceship object? If so, you can try using OnTriggerEnter() ins$$anonymous$$d of OnCollisionEnter(). Its strange, but its worked for me before. Also, did you make sure the player object is tagged "Player"? Sorry if these come off as dumb questions, but we have all wracked our brains with the smallest details. You could try using Debug.Log to be sure statements are being accessed.
Im dont really use JS, but it seams like your missing a call to the Lifer function inside the the collision function that would update the in game life total.
Answer by Bunny83 · Jul 26, 2013 at 10:55 AM
Your problem is that your "player" variable in your comet script doesn't point to the player. It points to the players prefab and is changing the value in the prefab asset. You have to link the real player at runtime when you instantiated the comets.
The better implementation is something like that:
function OnCollisionEnter (other : Collision)
{
if(other.gameObject.tag == "Player")
{
// Get the Js_Spaceship instance from the object we collided with.
var player = other.gameObject.Getcomponent(Js_Spaceship);
player.curLives --;
}
}
$$anonymous$$eep in $$anonymous$$d you only need to call the GetComponent once. You can put that line of code in your Awake function. It can get expensive calling for that everytime it collides.
If I put it on Awake() it doesn't work because of the "other" that's only inside the OnCollisionEnter function. Why is better on the awake? One time every comet collides
Its just the way bunny did it in your situation. When you use GameObject.Find() or GetComponent , etc.... You can put it in Awake() or Start(). These will only need to be called once at game start. It saves memory.
Answer by GC1983 · Jul 26, 2013 at 10:19 AM
Oh wait, I think I know the issue...Youre using rigidbody transform.Translate(). That is a physics based movement and ignores collision. I would recommend using a Character Controller for your player ship so can very accurately move your player around and any collision made with outside colliders (your enemies), it will register and respond.
I had this same issue and learned that CCs are very useful.
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
charController.Move(moveDirection * Time.deltaTime);
That is your base XY movement. Attach a CC to your object and test the collision.
you can use the premade controllers if you want. Theyre a lot to read over if youre not sure of what youre doing. I would recommend reading up on GetAxis and check out YouTube and other topics related to that topic that is something you can work off of for your particular controller situation. Its the best way to learn how it all works.