I recently started making a new game and I'm kinda an amateur coder.
var FlashlightOn : boolean = true;
function Update () {
ButtonClicket();
}
function ButtonClicket () {
if (Input.GetButton("Flashlight")) && FlashlightOn == true {
Destroy(Flahslight);
FlashlightOn = false;
}
else
{
Instantiate (Flashlight, Vector3(i * 0, 0, 0), Quaternion.identity);
FlashlightOn = true;
}
}
In the compiler error part it says I need to put brackets at the end and some other junk that doesn't need to be done. What am I doing wrong here?
Having run the code through the compiler myself, the errors it's giving are valid. Your code simply has a syntax problem and a typo:
if (Input.GetButton("Flashlight") && FlashlightOn == true) {
The close parenthesis for the if statement was in the wrong place.
Destroy(Flashlight);
You misspelled 'Flashlight'.
Also, i isn't defined isn't this code snippet, which is fine if it's a global variable, but you may want to double check it.
Related
so i am trying to detect if i click on a object with tag "solarsystem" and if so, then load that solarsystem onto the other scene. this code worked perfectly fine before, but now it crashes in such a way that i have to end unity from the task manager with the end task button to even close it. it just stops responding completely.
here is the code where i believe to have found the error after messing around with many Debug.log s to find where the code stopped and therefore find out where unity stops responding:
RaycastHit[] hit = Physics.RaycastAll(cursorPosition, Vector3.forward,15f);
Debug.Log("test2");//this is printed to the console - code crashes below this line
for(int i = 0; i < hit.Length; i++)
{
Debug.Log("hit"); // this is never printed to console - code crashes above this line
if(currentScene == "Universe")
{
if(hit[i].collider.gameObject.tag == "SolarSystem")
{
ChangeScene("SolarSystem");
SolarSystem clickedSolarSystem = hit[i].collider.gameObject.GetComponent<SystemObjectLink>().LinkedClass;
SolarSystem LoadedSolarSystem = SolarSystemCamera.GetComponent<SolarSystem>() as SolarSystem;
LoadedSolarSystem = clickedSolarSystem;
Debug.Log("generating system clicked on");
if (LoadedSolarSystem.preGenerated == false)
{
LoadedSolarSystem.Generate();
}
else
{
LoadedSolarSystem.Regenerate();
}
break;
}
}
if(currentScene == "SolarSystem")
{
if (hit[i].collider != null)
{
if (hit[i].collider.gameObject.tag == "Planet")
{
Target = hit[i].collider.gameObject;
break;
}
else if (hit[i].collider.gameObject.tag == "Moon")
{
Target = hit[i].collider.gameObject;
break;
}
Target = hit[i].collider.gameObject;
}
}
}
i had an for(;;) statement with a hardcoded
if(<state>){
break:
}
statement to break the infinite loop. but as i click on an object in the game. it checks the code for any errors before running it. when it does this it gets caught in the infinite loop and so to fix it i did this
for(;errorIndex<99; errorIndex++){
}
my mistake and what i learned:
never use a while(true) loop or a for loop without a way of getting out of itself (for(;;))
if the unity engine/editor ever stops responding it is because it is cought in an infinite loop- look over your code and ensure there is no possible way any of your loops can go on forever
#pragma strict
var lifetime = 5.0; //lifetime of projectile
var explosion : GameObject; //explosion prefab
var counter : int = 0; //keeps track of player score
var scoreToWin : int = 20; //determines score for player to win
var col : Collider;
void; OnTriggerEnter(Collider, col);
{
//triggers collision on enemy tag
if(col.gameObject.tag == "Enemy")
{
Score();
Debug.Log("Score!");
Destroy(col.gameObject);
//destroys enemy object
var explo = Instantiate(explosion, transform.position, Quaternion.identity);
//destroy the projectile that just caused the trigger collision
Destroy(explo, 3); // delete the explosion after 3 seconds
Destroy(gameObject,lifetime);
}
}
function update()
{
guiText.text = "Score: "+counter;
}
function Score()
{
counter++;
if (counter == scoreToWin);
"setTimeout(10000, 5000)";
Debug.Log (" You Win");
Application.Quit;
}
Picture of Code
After doing some research I have found that the error means that the line of code isn't doing anything. I do not understand however how that could be. As long as my logic of the collision, timeout, and app.quit is correct. I am also trying to find a way to implement my guiText to the screen for player viewing
There's a few issues, but the main one is that you're using semi-colons in the wrong place. Here they are:
void; OnTriggerEnter(Collider, col); // Two incorrect semi-colons. Incorrect comma.
// Further down:
if (counter == scoreToWin); // Incorrect semi-colon
"setTimeout(10000, 5000)"; // What's this expected to do?
Debug.Log (" You Win"); // OK
Application.Quit; // Quit is a method
The fixes
You probably meant:
void OnTriggerEnter(col : Collider)
{
// ...
if(counter == scoreToWin)
{
Debug.Log("You Win");
Application.Quit();
}
How am I supposed to use ;?
; means end of a statement and isn't used when that statement has a block (curly brackets). void Hello(){} is one statement, but it has curly brackets, so no semi-colon is required. var score=5; is a statement which doesn't have curly brackets, so a semi-colon is used at the end.
Scoping
It looks like you're used to using something like Python where indenting also represents scoping. C# and UnityScript ("javascript") aren't like those languages.
if(score == max)
{
// Don't forget those curly brackets!
// Everything that happens when the score is 'max' goes in here.
}
However, there is an instance where those curly brackets aren't required - this is implicit curly brackets:
if(score == max)
doSomething(); // *only* this line runs if score is max. Watch out!
Debug.Log("No matter what score is, this shows up!");
When brackets are implied, only the first line after it runs when the if is true.
If you didn't put the semi-colon there, you would probably be very confused about why the debug.log shows up all the time, so I would recommend always using curly brackets - at least until you're confident with the language.
It looks like you have too many semi-colons (statement terminators).
Try changing this:
if (counter == scoreToWin);
"setTimeout(10000, 5000)";
Debug.Log (" You Win");
Application.Quit;
To this:
if (counter == scoreToWin)
{
setTimeout(10000, 5000);
Debug.Log (" You Win");
Application.Quit;
}
Similar issue in this function definition:
void; OnTriggerEnter(Collider, col);
The problem is that :
void; does nothing, it is a reserved word not meant to be used alone.
"string literal" does nothing, you have to assing it to a variable or at least do something with it
functionname does nothing you have to invoke it with () at the end.
And that's what your JS hinter is complainting about.
I have looped through some game objects to set the isTrigger property before a certain collision occurs but though the property is true collision with the object still occurs. Please see the relevant code below:
void OnCollisionEnter2D(Collision2D col) {
if (col.gameObject.tag == "object1") {
for (int i = 0; i < badGuys.Count; i++) {
badGuys[i].getBadGuyGameObject().GetComponent<Collider2D>().isTrigger = true;
}
}
else if (col.gameObject.tag == "object2") {
// collision with object1 always occurs before object2, though isTrigger is true the colliding object doesn't pass through the badGuys game objects, it bounces off on collision
}
else if (col.gameObject.tag == "object3") {
for (int i = 0; i < badGuys.Count; i++) {
badGuys[i].getBadGuyGameObject().GetComponent<Collider2D>().isTrigger = false;
}
}
else if (col.gameObject.tag == "badGuy") {
}
}
collision with object1 always occurs before object2, though isTrigger is true the colliding object doesn't pass through the badGuys game objects, it bounces off on collision. How can I solve this?
UPDATE 1
I just realized that the isTrigger value is true or false in the inspector depending on the time I stop the game. For example if I stop the game after Object1 collision the isTrigger is true and when I stop the game after collision with object3 it false. This inconsistency makes debugging very cumbersome. Is this a bug or something?
UPDATE 2
Based on recommendation from Joe Blow and Agustin0987 I used the enabled property of Collider2D instead of isTrigger. I also removed virtually all the code in OnCollisionEnter2D to get a simple test scenario. Please see code below:
void OnCollisionEnter2D(Collision2D col) {
if (col.gameObject.tag == "object1") {
if (badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = false) {
badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = true;
Debug.Log ("CHANGED TO TRUE");
Debug.Log ("bad guy collider enabled is " + badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled);
}
else if (badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = true) {
badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled = false;
Debug.Log ("CHANGED TO FALSE");
Debug.Log ("bad guy collider enabled is " + badGuys[4].getBadGuyGameObject().GetComponent<Collider2D>().enabled);
}
}
else if (col.gameObject.tag == "badGuy") {
Debug.Log("collided with bad guy"); // DOESN'T OCCUR
}
}
Instead of looping through this time, I decided to test for one. The else if is where enabled is true always satisfied though the Log prints false and the if where enabled is false is never satisfied. In the inspector, the Box Collider2D for bad guys is always unchecked. Collision with the badGuy never occurs. Based on my simple scenario code I thought it should be working.
Never, ever ever
I mean absolutely never
use "else if".
Simply, never, ever - ever - type "else if" for the rest of your life, until you die.
In the first instance, delete all your code and replace it with this:
void OnCollisionEnter2D(Collision2D col)
{
Debug.Log("We will deal with this ......... " +col.gameObject.name);
if (col.gameObject.tag == "object1")
{
Debug.Log("\t handling 'object' type issue");
HandleObjectIssue(col)
return; //NOTE HERE
}
if (col.gameObject.tag == "object1")
{
Debug.Log("\t handling 'bad guy' type issue");
HandleBadGuyIssue(col)
return; //NOTE HERE
}
}
private void HandleObjectIssue(Collision2D col)
{
Debug.Log("'\t\t object', I'm dealing with this .. " +col.gameObject.name);
}
private void HandleBadGuyIssue(Collision2D col)
{
Debug.Log("\t\t 'badguy', I'm dealing with this .. " +col.gameObject.name);
}
Run that extensively and "unit test" it. If you like, convert back (USING THAT CODE) to a "loop" method to look at all items. In any event, test that extensively.
--
Secondly, add this routine ..
private void ToggleColliderOnGameObject( GameObject gg )
{
Debug.Log("I'm supposed to toggle the collider on: " +gg.name);
Collider2D { or whatever } col = gg.GetComponent<Collider2D>();
bool currentState = GetComponent<Collider2D>().enabled;
Debug.Log("\t it is currently: " +currentState);
bool newState = ! currentState;
col.enabled = newState;
Debug.Log("\t\t but now it is: " +newState);
}
... and start unit testing with it. So you will have code like:
ToggleColliderOnGameObject( badGuys[4].getBadGuyGameObject() );
For example, try some things like this:
void Start()
{
InvokeRepeating("teste", 1f, 1f);
}
private void Teste()
{
ToggleColliderOnGameObject( badGuys[4].getBadGuyGameObject() );
}
After experimenting with that for some time and unit testing, you will be able to move on.
Note that apart from other problems, it is likely that (for example) your routine "getBadGuyGameObject" is returning the wrong thing - or some similar problem.
EDIT:
Remove badGuy = badGuyPrefab; from your public void createBadGuy(GameObject badGuyPrefab, BadGuyType badGuyType, Vector3 badGuyPosition) function. This was a mistake in Programmer's code from the link in your comment.
It seems like you are trying to enable/detect the collision between badGuys and object2 only if object1 collides with whatever object has this script attached (seems to be some kind of BadGuyManager). So I would recommend that instead of setting isTrigger to true or false, you should try to enable or disable the whole `Collider2D.
P.S: I agree with Joe Blow in that you should explain what are you trying to achieve.
I have a character that a Boolean flag which determines whether or not he is jumping (if he is jumping, he cannot jump again). When he jumps, the jump flag is set to true, and when he collides with something it is set back to false (so he can jump again).
However, he only jumps once, and jump stays true even when it's supposed to reset to false. Why is this so? My definition for OnCollisionEnter() is supposed to reset the flag.
var trump;
var jump = false;
function Start() {
// Assigns the Rigidbody to a variable
trump = GetComponent(Rigidbody2D);
// Variable Switches:
}
function OnCollisionEnter() {
jump = false;
trump.velocity.y = 0;
trump.velocity.x = 0;
}
function FixedUpdate() {
trump.velocity.x = Input.GetAxis("Horizontal") * 10;
if ((Input.GetKeyDown(KeyCode.UpArrow)) && (jump == false)) {
trump.AddForce(Vector2(0, 10), ForceMode2D.Impulse);
jump = true;
}
}
EDIT: Based on an answer given I tried adding the Collision parameter to OnCollisionEnter(), but it still doesn't look like the function is being called after I added a Debug.Log() inside of it to check. Is there something else wrong?
function OnCollisionEnter(collision: Collision) {
jump = false;
Debug.log("He Hit The Wall");
trump.velocity.y = 0;
trump.velocity.x = 0;
}
Your function signature for OnCollisionEnter() is incorrect. When defining these MonoBehaviour-specific functions, it is imperative that the name and parameters of the function match that shown in the documentation. Otherwise, the MonoBehaviour won't recognize them and the function won't be called when expected.
In this case, OnCollisionEnter() requires a Collision parameter:
function OnCollisionEnter(collision: Collision) {
jump = false;
trump.velocity.y = 0;
trump.velocity.x = 0;
}
Note: The above was written before the question was edited to implement the suggestion - before, OnCollisionEnter() was being defined without a parameter.
However, in your case that isn't the only problem - you're using Unity's 2D physics, which means you should actually be using the 2D variant of the function: OnCollisionEnter2D, which also takes a slightly different parameter of a Collision2D.
So you would need:
function OnCollisionEnter2D(collision: Collision2D) {
jump = false;
trump.velocity.y = 0;
trump.velocity.x = 0;
}
Hope this helps! Let me know if you have any questions.
I'm having a bit of trouble with some Unityscript.
What I want to do is have a GUI message appear when certain objects are touched (then vanish after a time). I think I have it mostly worked out, but the message trips automatically.
My attempted solution is to have a conditional part of the GUI message that only allows it to appear when a boolean is true. Then in a different script that is already tripped when the object is touched, the boolean is set to true, so the script can run, and reset the boolean to false.
However I'm getting a "You can only call GUI functions from inside OnGUI. I'm not sure what that means.
Message code:
youdied.js
static var deathMessageShow : boolean = false;
function OnGUI() {
if(deathMessageShow == true){
if(Time.time >= 5 )
GUI.Box(Rect(200,300,275,150),"You Died");
}
deathMessageShow = false;
}
Other code (truncated):
dead.js
function OnTriggerEnter()
{
//code that resets environment
youdied.deathMessageShow = true;
}
Any suggestions on what is going on, or a better solution would be greatly appreciated.
The following code will show GUI message for 5 seconds then hides it:
youdied.js
static var deathMessageShow : boolean = false;
function OnGUI()
{
if(deathMessageShow)
{
GUI.Box(Rect(200,300,275,150),"You Died");
// call the function HideDeathMessage() after five seconds
Invoke("HideDeathMessage", 5.0f);
}
}
function HideDeathMessage()
{
deathMessageShow = false;
}
Other code:
dead.js
function OnTriggerEnter()
{
//code that resets environment
youdied.deathMessageShow = true;
}