Directional Swing Door

Free

*censored*
VVO Supporter 🍦🎈👾❤
Joined
Sep 22, 2018
Messages
41,730
Location
Moonbase Caligula
SL Rez
2008
Joined SLU
2009
SLU Posts
55565
Directional Swing Door is an LSL script for use with a path cut (see note) door prim. It swings the door based on the direction it's collided with (similar to how saloon doors work).

Adjustable variables:
collide_time (float): Amount of time (secs.frac) the door remains open on collision.
touch_time (float): Amount of time (secs.frac) the door remains open on touch/click.
swing_deg (integer): Degree to which the door swings or rotates open.

Issues:
  • The direction of a door's swing action is based on the position of your avatar, so it's primarily meant for handling door swings based on collision. This means it swings the same direction (away from your avatar) no matter which side it's touched (clicked on).
  • The motion of the door is adequately smooth. However, an issue with either the viewer or sims causes a door to swing open abruptly on first use after each login.
Note: Any prim used as a door with this script must have a Path Cut which begins at 0.375, and ends at 0.875, so that the door's rotational axis is at one end of the prim, rather than the center. Sorry, mesh-based door owners!

Java:
// Directional Swing Door (collision & touch based interaction)
//
// This script is free to redistribute/modify, as long as
// copies are also made freely redistributable/modifyable.
//
// Version 1.0.1, August 2025 ~Free Xue

float collide_time = 0.25;  // time door remains open on touch
float touch_time = 6.0;     // time door remains open on collision
integer swing_deg = 90;     // door swing range/degree

float swing_time;
rotation rot_closed;
rotation last_rot;
vector avatar_direction;
vector avatar_position;

default {
    state_entry() {
        last_rot = rot_closed = llGetLocalRot();
        llSetTimerEvent(1.0);
    }

    touch(integer total_number) {
        swing_time = touch_time;
        avatar_position = llDetectedPos(0);
        avatar_direction = llVecNorm(avatar_position - llGetPos()) / llGetRot();
        state open_door;
    }

    collision(integer total_number) {
        swing_time = collide_time;
        avatar_position = llDetectedPos(0);
        avatar_direction = llVecNorm(avatar_position - llGetPos()) / llGetRot();
        state open_door;
    }

    timer()
    {
        rotation cur_rot = llGetLocalRot();
        if (cur_rot != last_rot)
        {
            llResetScript();  // If door's rotational positon changes, reset script
        }
    }

    changed(integer change)
    {
        if (change & (CHANGED_OWNER | CHANGED_INVENTORY | CHANGED_SCALE))
            llResetScript();
    }

    on_rez(integer start_param)
    {
        llResetScript();
    }
}

state open_door {
    state_entry() {
        if( avatar_direction.x > 0 ) {
            llSetLocalRot(llGetLocalRot() * llEuler2Rot(<0,0,swing_deg*DEG_TO_RAD>));
        } else {
            llSetLocalRot(llGetLocalRot() * llEuler2Rot(<0,0,-swing_deg*DEG_TO_RAD>));
        }

        llSetTimerEvent(swing_time);
    }

    touch(integer total_number) {
        llSetLocalRot(rot_closed);
        state default;
    }

    timer() {
        llSetLocalRot(rot_closed);
        llSetTimerEvent(0);
        state default;
    }
}

Change Log

1.0.1
(08/24/2025) Removed unnecessary variable; Adjusted commenting.
 
Last edited: