Forum rules - please read before posting.

Action with two different timed exits

Let's say I have a custom action that can run a predefined number of player animations like pickup, give and take. The animations have two event, action point and finished.
Now I would like to run an action when the action point is hit, for example when the player's hand is stretched out and we want the object being picked up to disappear. But I also want the animation action to continue only after the animation is finished. Right now I can only choose one, either action point or finished.
Is is yet possible to implement such action? Or does it already exist? If so, I apologize for missing it.

Comments

  • These are Unity's "animation events"?

    These are intended to work by calling a function attached to the same GameObject on the Animator - it'd be tricky to get an Action to listen out for it, as I'd expect you'd need an interim script on the Animator.

    If you've managed it, however, I don't see why you couldn't listen for both. It'd be down to the way your Action's Run function is written, though.

    If an Action runs over multiple frames, it will continue to run until the Run function both sets "isRunning" to False, and returns zero.

  • Sorry, I forgot to mention that.
    Yes, every such animator has a special script attached, that is then referenced in the Action (only objects of those types actually). Those scripts listen to those two animation events and set a flag. The action checks during run if that flag was set and continues only after that. Or after a timeout.

    I am utilizing the isRunning and float return feature, but this doesn't help me in running another action, only how long to wait to continue with the next one.

    Could I use two Action Skip functions, one, that is already present and one, for the first event?

  • I checked the code for actions Run in parallel and Check random number. Both have a End function that contain a list of all actions in that actionList and return the next action to be run (hope I understood that correctly).
    I could use this for my own custom action but actions with End do not appear to support a Run function since they only check things. Is this correct?
    If not, would the action continue to run after End is called?
    I hope this isn't written too confusing!

  • Could I use two Action Skip functions, one, that is already present and one, for the first event?

    Skip() is only called if the ActionList it's a part of is being skipped by the player, which is done by invoking the "EndCutscene" input. It's intended as an optional override to Run(), since it needs to perform the effects of the Action over a single frame.

    I could use this for my own custom action but actions with End do not appear to support a Run function since they only check things. Is this correct?

    All Actions support a Run() function. The only exception to the "returned value = wait time" is the ActionList: Run in parallel Action, but this is hard-coded internally.

    If not, would the action continue to run after End is called?

    End() is called once the Action is complete. If you need something to continue afterwards, consider moving the code that performs this in a separate script - so that the Action itself merely triggers it.

  • Thank you for your help.

    I played a bit around with some base Action functions and managed to make it work. What I did was I duplicated SkipActionGUI to create a input for our "secondary" action. Did some checks so that the selected action is not this action, the next one to skip to and has ResultAction set to Stop, since we only want one "secondary" action to run.
    Then, I've overridden AssignParentList to get all actions of our actionlist, from which we select the "secondary" action in editor mode and runtime.
    At runtime, I wait for the animation actionpoint. Once it hits, I run
    actions[secondaryActionIndex].AssignValues(null);
    actions[secondaryActionIndex].Run();

    which runs the selected action. Had to call AssignValues beforehand since the runtime values are set there and are null otherwise. I first tried thisActionList.RunFromIndex(secondaryActionIndex) but this would also stop the animation action.
    The second part seems a bit hacky, I know, but it works. I will do more testing to see how well it does in actual use. What is your opinion on this? Do you think it is safe enough to use? Any suggestions? Thanks!

  • I'm afraid I don't quite follow your steps. I wouldn't have thought it'd be so complicated, but if it works, it works!

  • edited July 2019

    This should be useful for others aswell so I'll explain it more step by step.

    1. Have an Action that supports both Actionpoint and Animation finish events, that the action listens to from the animated object.
    2. Add fields to the action to hold data for the action you want to run when anim actionpoint is hit.
    3. Override AssignParentList(ActionList actionList) which gives us a list of actions of the actionlist this action is in. Is called both in editor and runtime.
    4. Create an editor function that will display a dropdown for selecting that action. Add some checks to prevent it from selecting itself or to create a loop.

    This should be it! Now when the animation hits actionpoint and the action detects that, the action will run the in-between action and still waits until the animation ends! Highly useful for pickup animations, where the character comments after pickup.

    Example custom action

    Code snippets for the whole thing

    This code is very experimental! Had the secondary action stuck sometimes. I am still working on improvements.

  • edited July 2019

    I think that the safest way to run that action is to instantiate an ActionListAsset, add the action and run it. That way this action is completely seperated from our original actionlist.

    var al = ScriptableObject.CreateInstance();
    al.actions.Add(actions[secondaryActionIndex]);
    al.Interact();

    @ChrisIceBox What do you think of this?:)

  • Thanks for the added info - the annotated screenshot was the info I was missing.

    Yes, it would be safer to programattically generate and run an ActionListAsset - but only if the ActionList as a whole cannot be skipped by the player by invoking the "EndCutscene" input. In this case, AC needs to be able to refer to the ActionListAsset file - which likely wouldn't be possible if it was generated at runtime.

    The safest alternative IMO would be to create a short Timeline that animates both the Player, and hides the Newspaper, with the correct timing. The two Actions in your screenshot can then be replaced with a single Engine: Control Timeline Action.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.