- Home /
Opening a door with a mouse click (c#) (3D)
Hi.
I've been looking all day for an easy way to have a door open by just clicking it, but I haven't come up with anything that works. I am a student and I still get quite confused when it comes to C# code, but especially when it comes to Unity itself, I tend to completely lose track of how I'm supposed to do things.
I've seen there are numerous ways of doing this:
Using an animation: I've watched this video tutorial, but I can't get the door out of automatically starting its animation.
Using normal clicks to simply destroy the door: I got this to work, however it's not the result I really want, and you'd also have to click the door with your actual mouse, not with the center point of the camera.
Using Raycasts: this is most likely the way I want it to be done in the end, but the problem is, I don't understand Raycast, Vector3, Quaternion and those things at all.
Another problem I've run into using each one of those methods: I can't seem to scale the box collider without scaling the entire door. What I've done is created the actual body of the door, then created a cube, ticked off the Mesh Renderer component and placed it to the right side of it, where the actual hinges would be. I then made the body a child of this pivot point:
The rotation works the way I want it to, but apparently it's necessary to scale this cube to cover the entire door, otherwise clicking the door itself won't work to open it.
So, to sum up:
I'm looking for someone who'd have the time to explain to me how I would have to use Raycasting in order to get a door to rotate -90 degrees on the Y axis, and if it's necessary, how to scale a cube that's parent of a door, so that it actually covers said door entirely.
I hope my explanation is clear enough, it's my first time on this forum, and I'm Belgian, so that should explain any grammatical or spelling errors.
Thanks in advance!
Answer by Mmmpies · Feb 17, 2015 at 08:59 PM
OK this is what I just tested. created a simple scene with 3 cubes expanded so I had 2 walls and a door (looks rubbish but you never asked for pretty!)
Opened the animation window and set the position and rotation as Curves. Set the door as closed in the first frame and set a new frame at 1 second and moved the door to an open position/rotation:
I duplicated that animation and called it CloseDoor then swapped the frames over so the first frame becomes the last frame and the last becomes the first.
I then added the animations to the "door" Cube and added this script to it.
using UnityEngine;
using System.Collections;
public class ClickMe : MonoBehaviour {
private bool doorOpen = false;
private float animationFinished = 0;
public void OnMouseUp()
{
Debug.Log ("Ive been clicked");
if(Time.time > animationFinished)
{
if(doorOpen)
{
animation.Play("CloseDoor");
}
else
{
animation.Play("OpenDoor");
}
animationFinished = Time.time + 1;
doorOpen = !doorOpen;
}
}
}
Dragged that script onto my Cube/Door and ...
When I click on the door it opens and once the animation time finishes I can click it again to close it.
Hope that helps.
Nicer door than $$anonymous$$e as well :¬)
Good description of raycasting @Downstream but I'm not convinced @$$anonymous$$ar $$anonymous$$ommy needs raycasting, On$$anonymous$$ouseUp will do all the heavy lifting for a GamwObject and mouse clicks.
Still we've given them options, which is good.
Hi @$$anonymous$$ar $$anonymous$$ommy as this is your first question just some advice on Unity Answers. You should really tick the answer that helped you the most.
It lets people know its been answered so it stops people wasting time providing new answers. It can also help people with similar issues, on top of that it also gives both the answerer and you some karma points.
Glad you got it sorted though.
$$anonymous$$issingComponentException: There is no 'Animation' attached to the "door3" game object, but a script is trying to access it. You probably need to add a Animation to the game object "door3". Or your script needs to check if the component is attached before using it.
i get this error twice whenever i click the door with my fps
Answer by Downstream · Feb 17, 2015 at 08:50 PM
Raycast works by taking a vector from a position and checking if there's a collider in the path of that vector, basically like a bullet. You can then use the data in the raycasthit variable type to do different operations with the knowledge that you hit something, in our bullet analogy: apply particle effect, hit sound and a decal for bullet hole.
Simple example
I have this script attached to an empty game object at 0,0,0 in my scene:
using UnityEngine;
using System.Collections;
public class ray_test : MonoBehaviour {
void Update() {
Vector3 fwd = transform.TransformDirection(Vector3.forward);
if (Physics.Raycast(transform.position, fwd, 10)){
Debug.DrawRay(transform.position, transform.forward*10f, Color.red);
print("There is something in front of the object!");
}else{
Debug.DrawRay(transform.position, transform.forward*10f, Color.green);
print("There is nothing in front of the object.");
}
}
}
What it does is cast a ray forwards, it then notifies if a collider is or isn't caught in the ray; see pictures below. I used Debug.DrawRay to visualize the ray itself to you.
From a raycast hit TYPE you can detect what was hit.
Here's an alternative script that will tell you what you hit:
using UnityEngine;
using System.Collections;
public class ray_test : MonoBehaviour {
RaycastHit rayhit;
void Update() {
Vector3 fwd = transform.TransformDirection(Vector3.forward);
if (Physics.Raycast(transform.position, fwd, out rayhit)){
Debug.DrawRay(transform.position, transform.forward*10f, Color.red);
print("The ray hit: " + rayhit.transform.gameObject.name);
}else{
Debug.DrawRay(transform.position, transform.forward*10f, Color.green);
print("There is nothing in front of the object.");
}
}
}
Continued
Remember to set pivot mode to pivot, instead of center.. nearly confused myself there.
So one last script, this allows us to open a door when it intersects the ray, our door is an empty gameobject with a a parented cube collider shaped into a door:
door.cs:
using UnityEngine;
using System.Collections;
public class door : MonoBehaviour {
public bool Open = false;
public float angle = 90f;
public float speed = 500f;
private float zero;
void Awake(){
zero = transform.localEulerAngles.y;
}
void Update(){
if(Open && (transform.localEulerAngles.y < (zero + angle))){
transform.Rotate(transform.up * Time.deltaTime * speed);
}
if(!(Open) && (transform.localEulerAngles.y > zero)){
transform.Rotate(-transform.up* Time.deltaTime * speed);
}
}
}
ray_test.cs:
using UnityEngine;
using System.Collections;
public class ray_test : MonoBehaviour {
RaycastHit rayhit;
float timer = 1f;
private door d;
void Update() {
timer -= Time.deltaTime;
Vector3 fwd = transform.TransformDirection(Vector3.forward);
if (Physics.Raycast(transform.position, fwd, out rayhit)){
Debug.DrawRay(transform.position, transform.forward*10f, Color.red);
// New stuff here
d = rayhit.transform.root.GetComponent<door>();
Debug.Log(d);
if(Input.GetKeyDown(KeyCode.Space)&&(timer < 0f)){
if(d.Open){
Debug.Log("User closed door");
}else{
Debug.Log("User opened door");
}
d.Open = !(d.Open);
timer = 1f;
}
print("The ray hit: " + rayhit.transform.gameObject.name);
}else{
Debug.DrawRay(transform.position, transform.forward*10f, Color.green);
print("There is nothing in front of the object.");
}
}
}
If you were having trouble resizing the collider then either you're not setting the collider size in the collider inspector or you have the objects parented the wrong way around is my guess.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Need cube to carry other cube - 3D, C#, Collisions 2 Answers
Raycast and colliders problem. Corners of two colliders 0 Answers