Jump to content

Stopping an animation when coming out of mouselook


Miguelito Shilova
 Share

You are about to reply to a thread that has been inactive for 1108 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hi Everyone,

I'm trying to do a little modification on an open source gun script. I left off the globals and the default / state entry section, and what's below that is what I'm needing help with.

Basically it's working mostly as intended. When the pistol is attached it plays the 'racking' animation ('gRackAnimation') once, and when I go into mouselook AND squeeze off a round, the 'gShootAnimation' animation plays. What I'm trying to do though is turn off 'gShootAnimation' when I come out of mouselook, and I can't seem to figure out where to put llStopAnimation(gShootAnimation) to make that happen.

Additionally, I would like to have 'gShootAnimation' play as soon as I go into mouselook, not after the first shot.

Any suggestions, as always, are greatly appreciated! Thanks!

--Mig

 

    attach(key id)
    {
        if (id)
            llRequestPermissions(id, gPermFlags);
        else
        {
            llStopAnimation(gShootAnimation);
            llReleaseControls();
        }
    }
 
    changed(integer change)
    {
        if (change & (CHANGED_OWNER | CHANGED_INVENTORY) )
            llResetScript();
    }
 
    run_time_permissions(integer perm)
    {
        //  ensure ALL required permissions have been granted
        if ( (perm & gPermFlags) == gPermFlags)
        {
            llTakeControls(CONTROL_ML_LBUTTON, TRUE, FALSE);
            llStartAnimation(gRackAnimation);
            llPlaySound(gPistolRack, 1.0);
            llOwnerSay("Gun is ready. Enter mouselook and use left click to fire!");
        }
    }
 
    control(key id, integer held, integer change)
    {
        rotation Rot = llGetCameraRot();
        llStartAnimation(gShootAnimation);
        if ( held & change & CONTROL_ML_LBUTTON)
        {
            if (llGetInventoryType(gShootSound) == INVENTORY_SOUND)
                llPlaySound(gShootSound, 1.0);
                
 
            llRezAtRoot(gBullet, llGetCameraPos() + <1.5, 0.0, 0.0>*Rot, gVelocity*llRot2Fwd(Rot), Rot, 10);

            llSleep(gReloadTime);
        }

    }

 

Link to comment
Share on other sites

another way is in the control event, play the shoot animation on mouse_down and stop it on mouse_up. Example mod of your code:

control(key id, integer held, integer change)
{
   if ( held & change & CONTROL_ML_LBUTTON)
   {
      rotation Rot = llGetCameraRot();
      llStartAnimation(gShootAnimation);

      if (llGetInventoryType(gShootSound) == INVENTORY_SOUND)
         llPlaySound(gShootSound, 1.0);
                
      llRezAtRoot(gBullet, llGetCameraPos() + <1.5, 0.0, 0.0>*Rot, gVelocity*llRot2Fwd(Rot), Rot, 10);

      llSleep(gReloadTime);
   }
   else if (change & CONTROL_ML_BUTTON)
   {  // when CONTROL_ML_LBUTTON is released
      llStopAnimation(gShootAnimation);
   }
}

edit: oops! missed including the condition for mouse_up

  • Like 1
Link to comment
Share on other sites

Thanks for the help! I tried adding both the timer event and the GetAgentInfo poll in the control section of the script, and it did save, but I'm not seeing llStartAnimation(gShootAnimation) actually run ... how should I tweak it to solve that problem?

 

 control(key id, integer held, integer change)
    {
        llSetTimerEvent(0.3);
        rotation Rot = llGetCameraRot();
        llStartAnimation(gShootAnimation);
        if ( held & change & CONTROL_ML_LBUTTON)
        {
            if (llGetInventoryType(gShootSound) == INVENTORY_SOUND)
                llPlaySound(gShootSound, 1.0);
                llMessageLinked(LINK_ALL_OTHERS,60,"fire","");
                
 
            llRezAtRoot(gBullet, llGetCameraPos() + <1.5, 0.0, 0.0>*Rot, gVelocity*llRot2Fwd(Rot), Rot, 10);

//            llSleep(gReloadTime);
        }

        else if (llGetAgentInfo( llGetOwner() ) &~ AGENT_MOUSELOOK)
        {
            llStopAnimation(gShootAnimation);
        }
    }

 

Link to comment
Share on other sites

1 hour ago, Miguelito Shilova said:

I tried adding both the timer event and the GetAgentInfo poll in the control section of the script

That's not how timers work. Events can't be placed inside other events, so saying you placed the timer event into the control event would be invalid. However, from what you posted, it seems you mistook the llSetTimerEvent function call for the timer event - they are two separate things. llSetTimerEvent is just a command whose only purpose is to start (or stop) a repeating internal countdown. It basically sets up the timer. When that countdown elapses, the script will trigger the timer event and run whatever code is inside it. That is where it was suggested you poll for the agent's status.

In your case, I imagine you'd want to start the timer when the object is attached (and stop it when detached for completeness sake). Then in the timer event, poll the agent's info and play/stop the animation as appropriate. Additionally, I think it would be a good idea to include an extra global variable to keep track of the agent's status. That way, you can add logic to avoid unnecessarily starting the animation when it's already playing, as well as unnecessarily trying to stop an animation that's already stopped.

Something to the effect of:

if llGetAgentInfo says the agent is in mouselook and the global variable  is FALSE, then we can assume we've just entered mouselook. So set the global variable to TRUE and start the animation. On the other hand, if llGetAgentInfo  says the agent is not in mouselook and the global variable is TRUE, then we can surmise we've just exited mouselook. So in that case, set the global variable to FALSE and stop the animation.

By fencing off the starting and stopping of the animation behind those explicit checks, we can have tighter control over when the commands are run and avoid doing them when it isn't necessary.

 

Edited by Fenix Eldritch
  • Like 1
Link to comment
Share on other sites

5 hours ago, Fenix Eldritch said:

Additionally, I think it would be a good idea to include an extra global variable to keep track of the agent's status. That way, you can add logic to avoid unnecessarily starting the animation when it's already playing, as well as unnecessarily trying to stop an animation that's already stopped.

Personally I haven't found there to be any significant performance improvements (or side-effects) from not doing this. Essentially I just:

timer()
{
    if(llGetAgentInfo(owner) & AGENT_MOUSELOOK)
    {
        llStopAnimation(ANM_HOLD);
        llStartAnimation(ANM_AIM);
    }
    else
    {
        llStopAnimation(ANM_AIM);
        llStartAnimation(ANM_HOLD);
    }
}

Unless of course you need/want something to happen only once when entering/leaving mouselook, like playing sound effects.

Edited by Wulfie Reanimator
Link to comment
Share on other sites

True, as long as ANM_HOLD and ANM_AIM are static animations.  If you were running looping animations (like a drinking anim, for example) you would want to follow Fenix's advice rather than restarting the anim each time the timer event gets triggered.

Link to comment
Share on other sites

2 hours ago, Rolig Loon said:

True, as long as ANM_HOLD and ANM_AIM are static animations.  If you were running looping animations (like a drinking anim, for example) you would want to follow Fenix's advice rather than restarting the anim each time the timer event gets triggered.

They are looping animations and there are no issues.

Using llStartAnimation with an animation that's already playing doesn't "restart" it visually. It'll just keep playing as if nothing happened (whether or not it's looping or non-looping).

Edited by Wulfie Reanimator
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1108 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...