- Home /
door script problems
I have a couple issues with my current door script. So far i can open and close doors my dragging the mouse up or down. However my problems are that:
1) There are multiple doors facing different directions, and i dont know how to keep track of each door's individual rotation
2) If i open a door, go behind it, then try to close it, i have to move mouse in opposite direction for it to work.
3) if i open a door, then open another door, then go back to the previous door, the minimum rotation starts off where it ended, which is fully opened.
var mouseX : float = 0;
var rotSpeed : float = 10;
var minX : float = 0;
var maxX : float = 0;
private var cam : GameObject;
var mouseYAxis : float;
var flipMouseAxis : boolean = false;
var swapYforX : boolean = false;
function Start() {
cam = GameObject.FindWithTag("camera");
//if door is facing the x axis, make sure it rotates negatively
if(transform.forward == Vector3.right) {
minX = transform.eulerAngles.y - 80;
maxX = transform.eulerAngles.y;
mouseX = maxX;
flipMouseAxis = true;
} else {
minX = transform.eulerAngles.y;
maxX = transform.eulerAngles.y + 80;
}
}
function DoorOpen() {
forward = cam.transform.TransformDirection(cam.transform.forward);
doorPos = transform.InverseTransformDirection(transform.position);
camPos = transform.InverseTransformDirection(cam.transform.position);
doorDistance = doorPos - camPos;
forward.Normalize();
doorDistance.Normalize();
if(Vector3.Dot(forward, doorDistance) < 0) {
Debug.Log("door is in front of us: "+ Vector3.Dot(forward, doorDistance));
mouseX += mouseYAxis * rotSpeed;
mouseX = Mathf.Clamp(mouseX, minX, maxX);
} else {
Debug.Log("door is behind us"+ Vector3.Dot(forward, doorDistance));
mouseX -= mouseYAxis * rotSpeed;
mouseX = Mathf.Clamp(mouseX, minX, maxX); }
//make axis move negative since door is facing x axis
if(flipMouseAxis == true) {
mouseYAxis = -Input.GetAxis("Mouse Y");
} else { mouseYAxis = Input.GetAxis("Mouse Y"); }
transform.localRotation = Quaternion.Lerp(transform.localRotation, Quaternion.Euler(0, mouseX, 0), 2);
}
I know that there are multiple questions here, and that they are confusing to understand, but my problems are hard to explain so bare with me. Any help with any of these problems would be appreciated. I was thinking about making an array keeping track of the doors and their rotations, but im not sure how to implement that. A dictionary doesnt seem to work.
i tried but it doesnt work like it use to, or i dont know how to use it.
Answer by speedything · Aug 03, 2012 at 01:06 AM
I think the first step is to refactor your code. Not only is it hard to follow but I think its probably creating the problems.
First, I'd keep the door code and the input code completely separate. If you haven't already, create a "CONTROLS" object, and on that you want to put all the code about clicking the mouse and raycasting.
My javascript is very rusty so apologies for any errors. Hopefully this should at least give you some idea of what the script should like...
function Update () {
if(Input.GetMouseButton(0)) {
var hit : RaycastHit;
if(Physics.Raycast(transform.position, transform.forward, hit, 3)) {
if(hit.collider.gameObject.tag == "door") {
hit.collider.gameObject.GetComponent(DoorScript).OpenClose();
}
}
}
}
When we detect an input and detect a door, that's when we call the function "DoorScript" (change to whatever's appropriate). The important thing about this is that each door will have it's own DoorScript component, and we won't need to keep track of individual doors in a clunky array or list. Also, if there's no need to raycast continuously then its best not to. Just fire the ray when you press the button.
On the new script "DoorScript" which will be attached to the door (attach it to the door Prefab) we now have all the door information, along with the function "OpenClose" to control the movement of the door.
By doing this, each door will have a memory of the minX / maxX variables and anything else you want to include. Next time you access that door, the variables will start at the place you left them rather than being shared across every door you have, which is what happens when they're all placed in the same script.
Hope that helps you tackle your problem.
I was thinking of that approach but I kinda of decided not to because i didnt want the doors to have the scripts, but you are right its probably best that way. Also, wouldn't it be cleaner if the raycasting was done in the doorscript ins$$anonymous$$d of the player? Just to keep code relevant with each other
The problem with this method so far is that it affects ALL the doors. I edited what i have so far.
never$$anonymous$$d, i did what you said this time and they act individually now, but i dont understand the difference between what you are saying in your code, and what i was in the code edited above. Why does yours only affect one door and $$anonymous$$e affects all of them?
I'll post an answer with the code based on what you said.
have the raycast from the door is not a good idea, because you have a function update for each door, and too much update increase work of pc
and if you have 2 doors closer to player are both open or closed
maybe could interest in this, http://answers.unity3d.com/questions/294310/button-on-wall.html
yeah i changed it so the update is only on the player. $$anonymous$$y next issue is comparing the direction of the player to the door to deter$$anonymous$$e which way to move the mouse in order to open it. I trying to use Vector3.Dot but i doesnt seem to be helping. I'll update the code again I hate the code formatter. It formats in the preview, and then looks horrible when it updates.
Answer by kag359six · Aug 03, 2012 at 04:55 PM
This is the input function stuff
function DetectDoor() {
if(Input.GetMouseButton(0)) {
var hit : RaycastHit;
Debug.DrawRay(transform.position, transform.forward * 1, Color.green);
if(Physics.Raycast(transform.position, transform.forward, hit, 2)) {
if(hit.collider.gameObject.tag == "door") {
//get current door being hit and assign it to currentDoor currentDoor = hit.collider.gameObject; //set openDoor to true so door will open regardless of ray hitting it openDoor = true; lookAround = false;
}
}
//if openDoor is true, get current door open script and turn on opening functions if(openDoor) {
currentDoor.GetComponent(doorMouseOpen).DoorOpen();
}
//if we aren't clicking the left mouse button, set look around to true } else if(!Input.GetMouseButton(0)) {
lookAround = true; openDoor = false;
}
}
This is the actual door open code:
var mouseX : float = 0;
var rotSpeed : float = 10;
var minX : float = 0;
var maxX : float = 0;
function Start() {
minX = transform.eulerAngles.y; maxX = transform.eulerAngles.y + 80;
}
function DoorOpen() {
mouseX += Input.GetAxis("Mouse Y") * rotSpeed;
mouseX = Mathf.Clamp(mouseX, minX, maxX);
transform.localRotation = Quaternion.Lerp(transform.localRotation, Quaternion.Euler(0, mouseX, 0), 2);
}
I think the problem might be the - Input.GetAxis("$$anonymous$$ouse Y")
Does this still happen if you change it to - Input.mouseposition.y ?
at the link in my precedent post there is the input part, at now miss only the boolean
var smooth = 2.0;
var DoorOpenAngle = 90.0;
var DoorCloseAngle = 0.0;
var open : boolean;
var enter : boolean;
function Update (){
if(open == true){
var target = Quaternion.Euler (0, DoorOpenAngle, 0);
// Dampen towards the target rotation
transform.localRotation = Quaternion.Slerp(transform.localRotation, target,
Time.deltaTime * smooth);
}
if(open == false){
var target1 = Quaternion.Euler (0, DoorCloseAngle, 0);
// Dampen towards the target rotation
transform.localRotation = Quaternion.Slerp(transform.localRotation, target1,
Time.deltaTime * smooth);
}
if(enter == true){
if(Input.Get$$anonymous$$eyDown("f")){
open = !open;
}
}
}
Your answer
Follow this Question
Related Questions
Open door without using tag 1 Answer
Door script lag with rotation (Quaternion.slerp ?) 0 Answers
How to make 2 doors with 2 diffrent keys 2 Answers
Scripting issue with opening a door with a key. 2 Answers
Door Movement Animation 3 Answers