pub fn state(name: &str) -> StateExamples found in repository?
examples/compiler_global.rs (line 20)
12 fn construct_data() -> AnimGraph {
13 fn global_number(name: &str) -> Expression {
14 Expression::CompilerGlobal(name.to_owned())
15 }
16
17 let condition = bind_parameter::<f32>("a").ge(global_number(ALMOST_PI));
18 let endpoint = endpoint(state_event(TEST_EVENT, condition, EventEmit::Always));
19
20 let machines = [state_machine("Root", [state("StateA").with(endpoint, [])])];
21
22 AnimGraph {
23 state_machines: machines.into(),
24 ..Default::default()
25 }
26 }More examples
examples/third_person.rs (line 572)
530fn create_locomotion_graph() -> AnimGraph {
531 let resources = init_res([
532 SKELETON,
533 IDLE_CLIP,
534 WALKING_CLIP,
535 RUNNING_CLIP,
536 JUMPING_CLIP,
537 FALLING_CLIP,
538 DANCING_CLIP,
539 DANCING_UPPER_CLIP,
540 UPPER_BODY_MASK,
541 ]);
542
543 let parameters = vec![
544 init("grounded", true),
545 init("falling", true),
546 init("locomotion_speed", 0.0f32),
547 init("overdrive", 1.0f32),
548 init("moving", false),
549 init("dance", false),
550 ];
551
552 let locomotion_layer = {
553 let idle_node = alias("Idle", animation_pose(IDLE_CLIP));
554 let walking_node = alias("Walking", animation_pose(WALKING_CLIP));
555 let running_node = alias("Running", animation_pose(RUNNING_CLIP));
556
557 let locomotion_blend = endpoint(alias(
558 "locomotion",
559 blend_ranges(
560 bind_parameter("locomotion_speed"),
561 [(0.0, idle_node), (2.0, walking_node), (6.0, running_node)],
562 ),
563 ));
564
565 let speed_scaled_locomotion = preprocess(
566 speed_scale(bind_parameter("overdrive"), ALPHA_ONE),
567 locomotion_blend,
568 );
569
570 state_machine(
571 "Locomotion",
572 [state("Blend").with(speed_scaled_locomotion, [])],
573 )
574 };
575
576 let jump_layer = {
577 const STATE_FALLING: &str = "Falling";
578 const STATE_JUMPING: &str = "Jumping";
579 const STATE_OFF: &str = "Off";
580
581 let not_grounded = bind_parameter::<bool>("grounded").not();
582 let has_fallen = bind_parameter::<bool>("falling").and(not_grounded.clone());
583
584 let state_off = state(STATE_OFF)
585 .with_branch(endpoint(inactive_layer()))
586 .with_transitions([
587 has_fallen.transition(STATE_FALLING, TRANSITION_DURATION),
588 not_grounded.transition(STATE_JUMPING, TRANSITION_DURATION),
589 ]);
590
591 let is_grounded = bind_parameter::<bool>("grounded").as_expr();
592 let is_falling = bind_parameter::<bool>("falling").as_expr();
593 let state_jumping = state(STATE_JUMPING)
594 .with_branch(endpoint(tree([
595 animation_pose(JUMPING_CLIP),
596 state_event("jumped", true, EventEmit::Entry),
597 ])))
598 .with_transitions([
599 is_grounded
600 .clone()
601 .transition(STATE_OFF, TRANSITION_DURATION),
602 is_falling.transition(STATE_FALLING, TRANSITION_DURATION),
603 ]);
604
605 let state_falling = state(STATE_FALLING)
606 .with_branch(endpoint(animation_pose(FALLING_CLIP)))
607 .with_transitions([is_grounded.transition(STATE_OFF, TRANSITION_DURATION)]);
608
609 state_machine("Jump", [state_off, state_jumping, state_falling])
610 };
611
612 let dance_layer = {
613 const STATE_OFF: &str = "Off";
614 const STATE_FULL: &str = "Full Body";
615 const STATE_UPPER: &str = "Upper Body";
616
617 let is_dancing =
618 bind_parameter::<bool>("dance").and(state_is("::Dance::Off", QueryType::Entered));
619 let is_moving_and_dancing = bind_parameter::<bool>("moving")
620 .or(bind_route::<bool>("action_active"))
621 .and(is_dancing.clone());
622 let state_off = state(STATE_OFF)
623 .with_branch(endpoint(inactive_layer()))
624 .with_transitions([
625 is_moving_and_dancing.transition(STATE_UPPER, TRANSITION_DURATION),
626 is_dancing.transition(STATE_FULL, TRANSITION_DURATION),
627 ]);
628
629 let state_full = {
630 let dancing_pose = endpoint(animation_pose(DANCING_CLIP));
631 let not_dancing = bind_parameter::<bool>("dance").not();
632 let is_moving = bind_parameter::<bool>("moving");
633 state(STATE_FULL)
634 .with_branch(dancing_pose)
635 .with_transitions([
636 not_dancing.transition(STATE_OFF, FADE_OUT_DURATION),
637 is_moving.transition(STATE_UPPER, TRANSITION_DURATION),
638 ])
639 };
640
641 let state_upper = {
642 let dancing_upper = endpoint(tree([
643 animation_pose(DANCING_UPPER_CLIP),
644 pose_mask(UPPER_BODY_MASK),
645 ]));
646 let is_idle_or_not_dancing =
647 bind_parameter::<bool>("dance")
648 .not()
649 .or(bind_parameter::<bool>("moving")
650 .not()
651 .and(bind_route::<bool>("action_active").not()));
652
653 state(STATE_UPPER)
654 .with_branch(dancing_upper)
655 .with_transitions([is_idle_or_not_dancing.transition(STATE_OFF, FADE_OUT_DURATION)])
656 };
657
658 state_machine("Dance", [state_off, state_upper, state_full])
659 };
660
661 let action_layer = {
662 const STATE_OFF: &str = "Off";
663 const STATE_FULL: &str = "Full Body";
664 const STATE_UPPER: &str = "Upper Body";
665
666 state_machine(
667 "Action",
668 [
669 state(STATE_OFF)
670 .with_branch(endpoint(inactive_layer()))
671 .with_transitions([
672 bind_route::<bool>("action_active").transition(STATE_FULL, TRANSITION_DURATION),
673 bind_route::<bool>("upper_body_action_active")
674 .transition(STATE_UPPER, TRANSITION_DURATION),
675 ]),
676 state(STATE_FULL)
677 .with_branch(endpoint(reference_pose()))
678 .with_transitions([bind_route::<bool>("action_active")
679 .not()
680 .or(bind_parameter::<bool>("moving"))
681 .transition(STATE_OFF, TRANSITION_DURATION)]),
682 state(STATE_UPPER)
683 .with_branch(endpoint(tree([
684 reference_pose(),
685 pose_mask(UPPER_BODY_MASK),
686 ])))
687 .with_transitions([bind_route::<bool>("upper_body_action_active")
688 .not()
689 .or(bind_route::<bool>("action_active"))
690 .or(bind_parameter::<bool>("moving"))
691 .transition(STATE_OFF, FADE_OUT_DURATION * 2.0)]),
692 ],
693 )
694 };
695
696 let root = state_machine(
697 "Root",
698 [state("Layers").with_layers([
699 submachine("Locomotion"),
700 submachine("Jump"),
701 preprocess(
702 tree([
703 alias("action_active", event_emitted(ACTION_EVENT)),
704 alias(
705 "upper_body_action_active",
706 event_emitted(UPPER_BODY_ACTION_EVENT),
707 ),
708 ]),
709 submachine("Action"),
710 ),
711 submachine("Dance"),
712 ])],
713 );
714
715 AnimGraph {
716 resources,
717 parameters,
718 state_machines: vec![
719 root,
720 locomotion_layer,
721 jump_layer,
722 action_layer,
723 dance_layer,
724 ],
725 ..Default::default()
726 }
727}
728
729fn create_action_graph() -> AnimGraph {
730 let resources = init_res([
731 SKELETON,
732 SITTING_CLIP,
733 TURN_AND_SIT_CLIP,
734 POINTING_FORWARD_CLIP,
735 UPPER_BODY_MASK,
736 ]);
737
738 let parameters = vec![
739 init(
740 "fade_out",
741 InitialParameterValue::Event(FADE_OUT_EVENT.into()),
742 ),
743 init("turn_and_sit", false),
744 init("sit", InitialParameterValue::Event(SIT_EVENT.into())),
745 init("point_of_interest", InitialParameterValue::Vector([0.0; 3])),
746 init("enable_point_of_interest", false),
747 init(
748 "poi_cooldown",
749 InitialParameterValue::Event(COOLDOWN_EVENT.into()),
750 ),
751 ];
752
753 const COOLDOWN_EVENT: &str = "cooldown";
754 const FADE_OUT_EVENT: &str = "fade_out";
755 const SIT_EVENT: &str = "sit";
756
757 const POINTED_EVENT: &str = "pointed";
758
759 let pointing_cooldown = endpoint(tree([
760 reference_pose(),
761 state_event(COOLDOWN_EVENT, true, EventEmit::Entry),
762 alias("bounce_back", blend_in(ALPHA_ZERO, Seconds(5.0))),
763 ]));
764
765 let off_pose = endpoint(tree([
766 reference_pose(),
767 alias(
768 "poi_offset",
769 transform_offset("Hips", bind_parameter("point_of_interest")),
770 ),
771 ]));
772
773 const EMIT_ON_ENTER: EventEmit = EventEmit::Or(FlowState::Entering, FlowState::Entered);
774
775 let sitting_pose = endpoint(tree([
776 animation_pose(SITTING_CLIP),
777 state_event(ACTION_EVENT, true, EMIT_ON_ENTER),
778 ]));
779 let turn_and_sit_pose = endpoint(tree([
780 animation_pose(TURN_AND_SIT_CLIP),
781 state_event(ACTION_EVENT, true, EMIT_ON_ENTER),
782 ]));
783 let pointing_forward = endpoint(tree([
784 animation_pose(POINTING_FORWARD_CLIP),
785 remaining_event(
786 bind_route("animation_pose"),
787 POINTED_EVENT,
788 true,
789 TRANSITION_DURATION,
790 EventEmit::Never,
791 ),
792 state_event(UPPER_BODY_ACTION_EVENT, true, EMIT_ON_ENTER),
793 ]));
794 use QueryType::*;
795
796 const POINTING_STATE: &str = "Pointing";
797 const COOLDOWN_STATE: &str = "Cooldown";
798 let idling = state_machine(
799 "Idle",
800 [
801 state(OFF_STATE).with_branch(off_pose).with_transitions([
802 bind_route::<f32>("bounce_back")
803 .not_equal(1.0)
804 .immediate_transition(COOLDOWN_STATE),
805 bind_parameter::<bool>("enable_point_of_interest")
806 .and(contains_inclusive(
807 (0.4, 1.5),
808 bind_route::<[f32; 3]>("poi_offset").projection(Projection::Length),
809 ))
810 .and(
811 bind_route::<[f32; 3]>("poi_offset")
812 .projection(Projection::Back)
813 .gt(0.1),
814 )
815 .transition(POINTING_STATE, FADE_OUT_DURATION),
816 ]),
817 state(POINTING_STATE)
818 .with_branch(pointing_forward)
819 .with_transitions([bind_parameter::<bool>("enable_point_of_interest")
820 .not()
821 .or(event_is(POINTED_EVENT, QueryType::Active))
822 .transition(COOLDOWN_STATE, FADE_OUT_DURATION * 2.0)]),
823 state(COOLDOWN_STATE)
824 .with_branch(pointing_cooldown)
825 .with_transitions([bind_route::<f32>("bounce_back")
826 .equals(1.0)
827 .immediate_transition(OFF_STATE)]),
828 ],
829 );
830
831 const OFF_STATE: &str = "Off";
832 const TURN_AND_SIT_STATE: &str = "Turn and sit";
833 const SITTING_STATE: &str = "Sitting";
834
835 let root = state_machine(
836 "Root",
837 [
838 state(OFF_STATE)
839 .with_branch(submachine("Idle"))
840 .with_transitions([
841 event_is(FADE_OUT_EVENT, Exited)
842 .and(event_is(SIT_EVENT, Active))
843 .transition(SITTING_STATE, TRANSITION_DURATION),
844 event_is(FADE_OUT_EVENT, Exited)
845 .and(bind_parameter::<bool>("turn_and_sit"))
846 .transition(TURN_AND_SIT_STATE, TRANSITION_DURATION),
847 ]),
848 state(SITTING_STATE)
849 .with_branch(sitting_pose)
850 .with_global_condition(
851 event_is(FADE_OUT_EVENT, Exited).and(event_is(SIT_EVENT, Active)),
852 )
853 .with_transitions([event_is(SIT_EVENT, Exited)
854 .as_expr()
855 .transition(OFF_STATE, FADE_OUT_DURATION)]),
856 state(TURN_AND_SIT_STATE)
857 .with_branch(turn_and_sit_pose)
858 .with_global_condition(
859 event_is(FADE_OUT_EVENT, Exited).and(bind_parameter::<bool>("turn_and_sit")),
860 )
861 .with_transitions([
862 event_is(FADE_OUT_EVENT, Active)
863 .as_expr()
864 .transition(OFF_STATE, FADE_OUT_DURATION),
865 event_is(SIT_EVENT, Active)
866 .as_expr()
867 .transition(SITTING_STATE, TRANSITION_DURATION),
868 ]),
869 ],
870 );
871
872 AnimGraph {
873 resources,
874 parameters,
875 state_machines: vec![root, idling],
876 ..Default::default()
877 }
878}