- Home /
Having a door open/disappear when collided with a specific particle...
For those who do not know, I am working on a game that involves the character changing his state (fire, water, air, etc...) via standing on a trigger. He then has the power to shoot fire/water/air/other when in the specific mode. I have that basic functionality in place. Now, however, I was looking forward to something more advanced - Involving the player having to shoot a fireball at a door in order for it to open, and it would not work with other powers. I have tried collision and triggers, but have failed miserably, and consulted this helpful community instead.
If any of you can guide me/help me out with the script, I would greatly appreciate it. Preferably I would like it in C#.
Answer by aldonaletto · Feb 01, 2013 at 11:20 PM
It depends on how you're implementing the fireball. A simple "fireball recipe": create an empty object ("Fireball") and add to it a sphere collider, the particle effect, an AudioSource and a kinematic rigidbody (set Is Kinematic in the Inspector), then set the collider's Is Trigger field in the Inspector to make it a trigger. Tag this object as "Fireball" and add the script below to it:
using UnityEngine;
using System.Collections;
public class Fireball: MonoBehaviour {
public float speed = 8.0f;
public AudioClip hitSound; // add a hit sound, if desired
void Start(){
Destroy(gameObject, 6); // suicide in 6 seconds
}
void Update(){
// move the fireball forward at speed units/second
transform.Translate(0, 0, speed * Time.deltaTime);
}
void OnTriggerEnter(){ // hit something:
// play the hit sound, if any...
if (hitSound) AudioSource.PlayClipAtPoint(hitSound, transform.position);
Destroy(other.gameObject); // and die
}
}
If you set the AudioSource Clip property to some sound, the fireball will play it when instantiated (Play On Awake is set by default). You can also add a hit sound to the field Hit Sound in the Inspector.
Finally, drag this object to the Project view to make it a prefab.
Now, the door: add a script like below to the door prefab, so that it will destroy itself when some trigger tagged "Fireball" hits it:
using UnityEngine;
using System.Collections;
public class FireballDoor: MonoBehaviour {
void OnTriggerEnter(Collider other){
if (other.tag == "Fireball"){
Destroy(gameObject);
}
}
}
You may of course elaborate the OnTriggerEnter function so that it makes more interesting things when hit - like sinking in the ground with a convenient sound, for instance:
...
public class FireballDoor: MonoBehaviour {
public float speed = 2.5f; // sinking speed in units/second
public float doorHeight = 1.8f; // the door height
IEnumerator OnTriggerEnter(Collider other){ // this is a coroutine now!
if (other.tag == "Fireball"){ // if hit by a fireball...
float endY = transform.position.y - doorHeight;
if (audio) audio.Play(); // if some audio effect, play it
while (transform.position.y > endY){ // repeat until door completely sunk
transform.position -= new Vector3(0, speed * Time.deltaTime, 0);
yield return null;
}
}
}
You should add an AudioSource to the door, and set its Clip property to some suitable audio clip in order to have a nice "sinking" sound.
Thank you very much! This works very nicely together. There's one thing I wanted to know more about - When I applied this to different doors (such as water, air, earth, etc...) it did not function correctly. Why would that be the case?
Do you mean shooting a fireball at a non fireball door? What doesn't work correctly, and what's it doing?
Shooting a fireball at a non-fireball door does nothing(that is exactly what I want it to do). But I have duplicated the script and edited it to recognize the other tags (I have all the tags in place) such as "Waterball" and "Airball", but it does nothing. I wonder why this does not function correctly, but I remain un-knowing until I seek the wisdom of your graymatter...
You could use exactly the same first script for WaterBall or AirBall - only the prefabs should be tagged as "Waterball" and "Airball". The door script could be almost the same as above - just compare to the appropriate tag. If this isn't working, start adding debug lines to your code - add this line to the door script, for instance:
void OnTriggerEnter(Collider other){
Debug.Log(other.tag); // add this line
if (other.tag == ...
This debug line prints the tag of the object that hit the door - if the tag is ok, place another debug line inside the if, and so on.