- Home /
Calculating Door Hinge Pivots
I'm trying to move an empty game object to a hinge position on a door, so I can use it as the pivot point to swing the door open. The door script I've written has a setting which allows the player to open it in multiple different ways; slide it left / right / up / down, or swing it in / out on either the left or right hinge.
Initially I ran into problems trying to get the slide movements working correctly depending on the axis the door was aligned on, but I managed to work that one out. Now I'm having a few issues with the swing movements.
This method is executed in the Start() method of my door script:
public Transform Pivot { get; private set; }
/// <summary>
/// Creates an empty gameobject that can be used as the door's pivot point when swinging open / closed
/// </summary>
private void SetUpDoorPivot() {
var doorPivot = new GameObject(string.Concat(name, "_pivot"));
// Move the pivot object to the door's pivot point, depending on the swing type
// By default, just set the pivot to the device's world location
var pivotPosition = transform.position;
// TODO: Calculate the bottom hinge position for each swing type
switch (_doorTransitionType) {
case TransitionType.SwingAwayLeftHinge:
pivotPosition = renderer.bounds.min; // add depth
break;
case TransitionType.SwingAwayRightHinge:
pivotPosition = renderer.bounds.max;
break;
case TransitionType.SwingTowardsLeftHinge:
pivotPosition = renderer.bounds.min;
break;
case TransitionType.SwingTowardsRightHinge:
pivotPosition = renderer.bounds.max; // add depth
break;
}
doorPivot.transform.position = pivotPosition;
// Assign the pivot object to the same parent as the door device
doorPivot.transform.parent = transform.parent;
// Set the door device's parent to the pivot object
transform.parent = doorPivot.transform;
// Save the pivot for later use
Pivot = doorPivot.transform;
}
Everything works expected, except the hinges don't sit in the right place on the door; I get spurious results depending on which axis the door is aligned on (X or Z), and which swing type I have set.
All of my doors are currently just cubes that have been resized - they have a considerable depth at the moment, in order to better see where the hinges are. Here are some quick screenshots (gizmos are displayed where the pivot object is):
I can't upload any more pics, but you hopefully get the idea.
As you can see, I'm creating the pivot at runtime, and making it the parent of the door object. This all works fine - however, the final positioning performed in the switch statement is where I'm falling. I'm struggling to get my head around the bounds object - I'm not sure what each property refers to (I have experimented), and the unity documentation is a bit sparse on the subject.
At the moment, the SwingAwayRightHinge and SwingTowardsLeftHinge pivot is put in a valid location for doors that are aligned on the world X axis (though both pivots are not placed at the bottom of the object - which isn't too much of a problem, as I'm rotating around the Y axis anyway), but not on any other axis. The other pivots are placed on the opposite hinge, meaning that the door clips into the rest of the scenery. This is what I'm trying to avoid, by calculating the relevant pivot point at runtime.
The main issue is that when I rotate the doors to another axis (see the door on the left in the above pic), the hinge positions change for each setting. I know what I have to do, but I'm having issues working out how I do it! Any help will most definitely be appreciated - even if you can provide me with some tutorials, white papers or blog posts on bounds and how to calculate vertices.
Can't see your pics, but it may be the scale of the door object affecting things. Can you try making the scaled visual door mesh a child of the door object so it has a uniform scale of 1?
Fixed the pictures. Also found this, that seriously helps to explain how unity provides and deals with the bounds property on different types of objects:
http://raypendergraph.wikidot.com/unity-developer-s-notes#toc10
Answer by Spikeh · Dec 15, 2013 at 03:43 PM
Well, after much testing, and many experiments, I've managed to sort this out myself. I've had to use a combination of the door's forward / right vectors, then multiply them by the mesh's extents, and use the localScale to resize the mesh appropriately. Here's the finished code, for anyone who might hit the same issue:
/// <summary>
/// Creates an empty gameobject that can be used as the door's pivot point when swinging open
/// </summary>
private void SetUpDoorPivot() {
var doorPivot = new GameObject(string.Concat(name, "_pivot"));
var gizmo = doorPivot.AddComponent<CircleGizmo>();
gizmo.Size = .10f;
gizmo.Color = new Color().RandomiseChannels();
// Move the pivot object to the door's pivot point, depending on the swing type
// By default, just set the pivot to the device's center
var pivotPosition = collider.bounds.center;
var mesh = GetComponent<MeshFilter>().mesh;
var depth = transform.right * (mesh.bounds.extents.x * transform.localScale.x);
var direction = transform.forward * (mesh.bounds.extents.z * transform.localScale.z);
switch (_doorTransitionType) {
case TransitionType.SwingAwayLeftHinge:
pivotPosition -= (direction + depth);
break;
case TransitionType.SwingAwayRightHinge:
pivotPosition += (direction - depth);
break;
case TransitionType.SwingTowardsLeftHinge:
pivotPosition -= (direction - depth);
break;
case TransitionType.SwingTowardsRightHinge:
pivotPosition += (direction + depth);
break;
}
doorPivot.transform.localPosition = pivotPosition;
// Assign the pivot object to the same parent as the door device
doorPivot.transform.parent = transform.parent;
// Set the door device's parent to the pivot object
transform.parent = doorPivot.transform;
// Save the pivot for later use
Pivot = doorPivot.transform;
}
Answer by GraviterX · Dec 14, 2013 at 05:33 PM
Hello, I recently also made a door. I used this simple script to make a door. It allows you to press F to open a door using a trigger. You can rotate it any way to make it suitable. Here is the script: //Make an empty game object and call it "Door" //Rename your 3D door model to "Body" //Parent a "Body" object to "Door" //Make sure thet a "Door" object is in left down corner of "Body" object. The place where a Door Hinge need be //Add a box collider to "Door" object and make it much bigger then the "Body" model, mark it trigger //Assign this script to a "Door" game object that have box collider with trigger enabled //Press "f" to open the door and "g" to close the door //Make sure the main character is tagged "player"
// Smothly open a door
var smooth = 2.0;
var DoorOpenAngle = 90.0;
var AudioFile : AudioClip;
private var open : boolean;
private var enter : boolean;
private var defaultRot : Vector3;
private var openRot : Vector3;
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("f") && enter){
open = !open;
}
}
function OnGUI(){
if(enter){
GUI.Label(new Rect(Screen.width/2 - 75, Screen.height - 100, 150, 30), "Press 'F' to open the door");
}
}
//Activate the Main function when player is near the door
function OnTriggerEnter (other : Collider){
if (other.gameObject.tag == "Player") {
enter = true;
}
}
//Deactivate the Main function when player is go away from door
function OnTriggerExit (other : Collider){
if (other.gameObject.tag == "Player") {
enter = false;
}
}
//@youtube.com/user/maksimum654321
//www.warmerise.com - check this game
Hope this helps!
Thanks - that's not really what I was asking for, but it's appreciated anyway! $$anonymous$$y doors are considerably more complex than a standard door, as they are only one part of a full compliment of interactable objects. Look at them as a construction kit!
This is a problem with accessing bounds on a game object in order to ascertain a dynamic pivot, depending on the animation type selected in the unity inspector editor.
Your answer
Follow this Question
Related Questions
Best way to rotate a door 1 Answer
Hinge Joint? Unconstrained. 1 Answer
cannot rotate door on hinge 2 Answers
How to keep game object aligned with text mesh 1 Answer
How to get distance from position to transform bounds 1 Answer