Door script going crazy on certain angles

Okay, so I looked at an online tutorial to figure out how to make a door open on a button press. I got it to work and used it on one door, so I went and tried it on another… And there were issues.

The door facing forward works fine. The door on the side flips out ever time I interact with it. I’ve been messing with the code and changing a few things, but everything I do seems to make it even worse. I’m not entirely sure, but I think it has to do with the use of transform.eulerAngles in the code.

I did a short screen recording to illustrate my problem. The door on the left goes crazy when I try to interact with it.
CloudApp

Here’s the code I have for the Door Opening script that controls how the door moves… I understand how it works but I have no idea how to fix it.

var smooth = 2.0;
var DoorOpenAngle = 90.0;
private var open : boolean;
private var enter : boolean;

private var defaultRot : Vector3;
private var openRot : Vector3;

public var GUI_X = Screen.width/2 - 75;
public var GUI_Y = Screen.height - 100;

function Start(){
defaultRot = transform.eulerAngles;
openRot = new Vector3 (defaultRot.x, defaultRot.y + DoorOpenAngle, defaultRot.z);
}

//Main function
function Update (){
if(open){
//Open door
transform.eulerAngles = Vector3.Slerp(transform.eulerAngles, openRot, Time.deltaTime * smooth);
}else{
//Close door
transform.eulerAngles = Vector3.Slerp(transform.eulerAngles, defaultRot, Time.deltaTime * smooth);
}

if(Input.GetKeyDown(KeyCode.E) && enter){
open = !open;
}}

After a brief look, I too suspect eulerAngles is the issue as well. Vector3.Lerp() and Vector3.Slerp() are very literal functions. Imagine that your door has a closed position of 335 degrees, and a open position that passes across the 360/0 boundry to 60 degrees. If you use those two angles, Lerp()/Slerp() will not take into account the 360/0 boundary and instead rotate the long way from 360 down to 60.

The simplest fix for this problem is to make defaultRot and openRot public, remove the initialization of these variables in Start(), and specify the angles in the inspector. That way you can pick values that make Lerp()/Slerp() do exactly what you want. In the 335/60 case above, you could specify 335 and 395 instead.

Another fix would be to rewrite your script using Quaternions instead of Vector3. Quaternions are lazy. Rotations using Quaternion.Slerp() and Quaternion.Lerp() always take the shortest distance between the start and end rotation and don’t have any 360/0 boundary issues.

If you are using euler angles,it should be normalized
example - StartRot=315,EndRot=StartRot+90=315+90=405 is not between 0 to 360.
Also Slerp(A,B,Time) will lerp from A to B never do B to A.
If we do normalizing,StarRot=315 EndRot=405 EndRotNormalized=45
Slerp(StarRot,EndRotNormalized,time) will lerp but in counter clockwise.

This is the explanation for the problem…

Now for overcoming this you can use Quaternion instead of Euler angles

//SOLVED CODE

var smooth = 2.0;
var DoorOpenAngle = 90.0;

private var open : boolean;
 
private var defaultRot : Quaternion;
private var openRot : Quaternion; 
private var enter : boolean;
 
function Start()
{
	defaultRot = transform.rotation;
		
	openRot = defaultRot;
	openRot=Quaternion.AngleAxis(openRot.eulerAngles.y+DoorOpenAngle,Vector3.up);

}
 
//Main function
function Update ()
{
	if(open)
	{
		//Open door
		transform.rotation = Quaternion.Slerp(transform.rotation, openRot, Time.deltaTime * smooth);
	}
	else
	{
		//Close door
		transform.rotation = Quaternion.Slerp(transform.rotation, defaultRot,  Time.deltaTime * smooth);
	}
 
	if(Input.GetKeyDown(KeyCode.E) && enter)
	{
		open = !open;
	}
}

Hope this helps…