- Home /
How to make an Interactive Door (Raycasting)
Hi guys,
So,I'm creating a door for my Tavern which will be interactive.
What I want to achieve: I want to make it so that the player holds down left click on the door, and if he pushes his mouse up slowly, it will slowly play the animation forward, if he pushes it fast, the animation will play faster, if he brings the mouse back, it will rewind the animation.
What I have achieved: I have been learning some raycasting, but I'm struggling. I have added a collider to where I want it for the door. The question now is, how do I manage to make this complicated script? I know it's something to do with float values, so that the animation plays with a float from 0 to 1 and if the door is quarter open, the value will be like 0.233.
So, I have started off a script and now I don't even know how to progress on. Can anyone help me?
Code so far:
public var hit : RaycastHit;
public var range : float ;
public var mesh : GameObject;
public var DoorOpenClose : float = false;
function Start () {
}
function Update () {
}
Answer by robertbu · Jul 06, 2014 at 07:39 PM
Functionality like this is better handled with script than with an animation. That way the code can directly tie the users mouse movement to the door. But in constructing such a script, there are a number of issues:
If you base the movement on screen coordinates, the amount the door moves will vary from device to device.
Doors can open from either side (or even from top or bottom given a flap door), and may open either in or out.
Doors may start either open, closed, or perhaps just cracked so the user can see through but not go through the door.
The initial world rotation of the door will be different for different walls.
Doors built out of Unity cubes have the pivot point in the center, where you want to open a door from the hinge.
Here is a simple solution that addresses all these issues:
By converting the coordinates from Screen to Viewport coordinates, the movement will be standardized.
It expects an empty game object as a parent. This parent should be positioned on the middle of the hinge edge. In addition, it is best if the rotation of the empty game object is (0,0,0) when the door is closed. The easiest way to make this happen is to close the door, create an empty game object, position the empty game object on the hinge edge, make the visible door a child, then if the starting of the door is open, rotate the empty game object.
Attach the following script to the visible door (not the empty game object). It uses the OnMouse* functions rather than raycasting. You will need to set the values for the public variables. 'factor' is how much the door opens for a given mouse movement.
public var angleClosed = 0.0;
public var angleOpen = -150.0;
public var factor = 400.0;
public var angleCurrent = 0.0;
private var prevPos : Vector3;
private var direction = 1.0;
function Start() {
if (angleOpen < angleClosed)
direction = -1.0;
transform.parent.eulerAngles = Vector3(0.0, angleCurrent, 0.0);
}
function OnMouseDown() {
prevPos = Camera.main.ScreenToViewportPoint(Input.mousePosition);
}
function OnMouseDrag() {
var pos = Camera.main.ScreenToViewportPoint(Input.mousePosition);
var delta = pos.y - prevPos.y;
Debug.Log("delta="+delta * factor * direction);
angleCurrent += delta * factor * direction;
if (angleClosed > angleOpen)
angleCurrent = Mathf.Clamp(angleCurrent, angleOpen, angleClosed);
else
angleCurrent = Mathf.Clamp(angleCurrent, angleClosed, angleOpen);
prevPos = pos;
transform.parent.eulerAngles = Vector3(0.0, angleCurrent, 0.0);
}
Note that in dealing with eulerAngles, it is best to treat them is write-only. This code does not read eulerAngles...it only sets them.
Also, what do you mean by:
converting the coordinates from Screen to Viewport coordinates, the movement will be standardized.
Do I parent or child the hinge to anything or do I just keep it in the middle center of the empty game object?
UPDATE:
Ignore the errors! I done it for C#, I was being dopy and didn't realise it was JavaScript! :(
Hey, so I got this working, but when I turn the door, it doesn't stay on the hinge.. It rotates as if there is no hinge.. Do you know what the problem could be?
The hinge (empty game object) needs to be place on the edge of the door where you want the hinge to be. The easiest way to accomplish this is to position the empty game object before making the visible object a child. I like to work with world origin, so typically I would 1) move the door to (0,0,0), 2) place the empty hinge game object at (0,0,0), 3) move the hinge game object on the 'x' axis (or 'z' if you built your door differently) so that it is on the edge of the door, 4) make the visible door a child of the empty game object, and 5) put the script on the visible game object.
Viewport coordinates go from (0,0) in the lower left of the screen to (1,1) in the upper right. In addition, the amount your camera sees vertically remains constant regardless of the number of pixels in your screen. So by translating a pixel movement to a Viewport movement, the movement as a percentage of the screen remains constant across multiple devices. For example, if it takes a movement of 1/4 of the height to rotate the door from closed to fully open, then it will take 1/4 on all devices regardless of the resolution.
Note I wrote the example in Javascript because your start or a script was in Javascript.
Your answer
Follow this Question
Related Questions
Can someone help me fix my Javascript for Flickering Light? 6 Answers
Setting Scroll View Width GUILayout 1 Answer
Trouble with raycasting 0 Answers
How to enable/disable scripts on keyboard input (java)? 1 Answer
Gun Script Help 2 Answers