really confused as to whats up with this code, its attached to the FPS controller, and basically I want it to instantiate a red cross - which ive dragged onto the variable ‘accessDenied’ in the inspector, when I walk into a door without having the key for it. Yet im getting an error (see image attached)
code as follows -
var accessDenied : GameObject;
function OnControllerColliderHit (hit : ControllerColliderHit) {
if ((hit.collider.gameObject.tag == "exit") (keyPickup.gotKey == true)){
print("win");
Application.LoadLevel("win");
}
if ((hit.collider.gameObject.tag == "exit") (keyPickup.gotKey == false)){
print("find the key");
Instantiate (accessDenied, hit.collider.transform.position, hit.collider.transform.position);
}
}
I know the code works that exits the game so theres just something about the context in which im using instantiate that I assume is wrong.
That’s your first step. I’m guessing it’s this one, though:Instantiate (accessDenied, hit.collider.transform.position, hit.collider.transform.position);
One of these things does not belong. position → rotation
But I bet if you would have double clicked on the error at the bottom it would have taken you right to the line and it would have been pretty apparent after checking what Instantiate() takes. The error highlighting is quite a cool feature, I recommend it.
Yes, this is most certainly the line. Instantiate takes an UnityEngine.Object, Vector3 and a Quaternion, but is being called with a GameObject, Vector3 and Vector3.
The GameObject is okay as it inherits from UnityEngine.Object, but the second Vector3 is the problem, as there is no way to convert implicitly from a Vector3 to a Quaternion.
So this should probably become:
:Instantiate (accessDenied, hit.collider.transform.position, hit.collider.transform.rotation);
And again, I second Jon on reccomending the error highligting feature. It saves a lot of guesswork.
Now that I have no errors however, I do have many many copies of that cross, If i just want to make one appear, what should I amend.
BTW im now using a rigidbody so I can add a velocity to it and make it appear and move toward you (i’ll add code to remove it after a second or so later).
current code -
var accessDenied : Rigidbody;
function OnControllerColliderHit (hit : ControllerColliderHit) {
if ((hit.collider.gameObject.tag == "exit") (keyPickup.gotKey == true)){
print("win");
Application.LoadLevel("win");
}
if ((hit.collider.gameObject.tag == "exit") (keyPickup.gotKey == false)){
print("find the key");
var crossAppear: Rigidbody = Instantiate (accessDenied, hit.collider.transform.position, hit.collider.transform.rotation);
crossAppear.velocity = transform.TransformDirection(Vector3(0,0,-1));
}
}
… off topic, but on the line of coding style, readability and efficiency, I would rewrite the code to look like this:
var accessDenied : GameObject;
function OnControllerColliderHit (hit : ControllerColliderHit) {
if ( hit.collider.gameObject.tag == "exit" ) {
if( keyPickup.gotKey ){
print("win");
Application.LoadLevel("win");
}
else {
print("find the key");
Instantiate (accessDenied, hit.collider.transform.position, hit.collider.transform.rotation);
}
}
}
By using two levels of if you avoid comparing the tag to “exit” twice. Also I use the fact that writing if ( boolVariable == true ) { … } is equivalent to if ( boolVariable ) { … }.
Also by factoring out the initial comparison, the second if statement in your original code becomes an else clause.
You could set a flag when you create the cross and don’t instantiate a new one if it is set.
If you delete the cross object again, you must set the flag again to false.
I have tried to do what freyr suggested but its gone a bit wrong, Take a look at what i’m trying to do and see if it makes sense -
var accessDenied : Rigidbody;
var crossOn = false;
var timer = 0;
function Update(){
timer += Time.deltaTime;
print(timer);
}
function resetCross(){
if (timer > 5){
Destroy(gameObject.FindWithTag("cross"));
timer = 0;
crossOn = false;
}
}
function OnControllerColliderHit (hit : ControllerColliderHit) {
if ((hit.collider.gameObject.tag == "exit") (keyPickup.gotKey == true) (crossOn == false)){
print("win");
Application.LoadLevel("win");
}
if ((hit.collider.gameObject.tag == "exit") (keyPickup.gotKey == false) (crossOn == false)){
print("find the key");
var crossAppear: Rigidbody = Instantiate (accessDenied, hit.collider.transform.position, hit.collider.transform.rotation);
crossAppear.velocity = transform.TransformDirection(Vector3(0,0,-0.1));
crossOn = true;
resetCross();
}
}
I think i’ve overdone things a bit, there must be an easier way of doing things just once, do I need to use FixedUpdate somewhere or something? Any help much appreciated!
Now for you current script. You don’t say exactly what the problem is, but I suspect that you’r current behaviour is that you spawn a cross and then it never disappears.
When you create the cross you call reset, but as timer is less then 5 it doesn’t do anything and you never call it again. You probably mean to call reset() from the Update instead.
Thanks for the scripting advice, thats great, and I will try and implement that in future (ive amended as per your recommendation) but Im still stuck on this reset business.
Basically where I’ve declared resetCross(); ive done so because I want it to check for the value of crossOn being true, then if it is, run a function to remove it, and I thought thats what i’d done, now I understand what you’re saying is that the timer wont incremement if its not in Update, but moving the call for the function wont help, do I need to nest the resetCross function in Update or something? that doesnt seem to work - just creates errors that werent previously there on the function…
The above declaration declares timer as an integer. Thus when adding Time.deltaTime to timer, it will be converted to an int, causing the timer never to be incremented. (Because Time.deltaTime is usually a low fraction, which gets rounded to 0 when converting it to int)
that among other things were wrong - I needed to call the function in update, yes, but I hadnt considered using crossOn to decide whether to call it, silly mistake.
Will post the finished code on the mac below this post in a second…