コード例 #1
0
ファイル: State.cs プロジェクト: heavymoons/core.ai
 public void Execute(StateMachine machine)
 {
     OnExecute(machine);
     StateMachine?.Execute(machine);
     if (BehaviourMachine != null)
     {
         machine.NodeResult = BehaviourMachine.Execute(machine);
     }
 }
コード例 #2
0
        public override void OnGUI(SerializedNodeProperty property, BehaviourMachine.ActionNode node, GUIContent guiContent)
        {
            // Now draw the property as a Slider or an IntSlider based on whether it’s a float or integer.
            if ( property.type != typeof(MinMaxRangeSO) )
            Debug.LogWarning( "Use only with MinMaxRange type" );
            else
            {
                var range = attribute as MinMaxRangeSAttribute;
                var so=(MinMaxRangeSO)property.value;

                //set or reset to default full range
                if(so.rangeStart==so.rangeEnd){
                    so.rangeStart=range.minLimit;
                    so.rangeEnd=range.maxLimit;

                }

                var newMin =so.rangeStart;
                var newMax = so.rangeEnd;

            Rect position=	GUILayoutUtility.GetRect(Screen.width-32f,32f);

            var xDivision = position.width * 0.33f;
            var yDivision = position.height * 0.5f;
            EditorGUI.LabelField( new Rect( position.x, position.y, xDivision, yDivision )
                                 , guiContent );

            EditorGUI.LabelField( new Rect( position.x, position.y + yDivision, position.width, yDivision )
                                 , range.minLimit.ToString( "0.##" ) );
            EditorGUI.LabelField( new Rect( position.x + position.width -28f, position.y + yDivision, position.width, yDivision )
                                 , range.maxLimit.ToString( "0.##" ) );

            EditorGUI.MinMaxSlider( new Rect( position.x + 24f, position.y + yDivision, position.width -48f, yDivision )
                                   , ref newMin, ref newMax, range.minLimit, range.maxLimit );

            EditorGUI.LabelField( new Rect( position.x + xDivision, position.y, xDivision, yDivision )
                                 , "From: " );
            newMin = Mathf.Clamp( EditorGUI.FloatField( new Rect( position.x + xDivision + 30, position.y, xDivision -30, yDivision )
                                                       , newMin )
                                 , range.minLimit, newMax );
            EditorGUI.LabelField( new Rect( position.x + xDivision * 2f, position.y, xDivision, yDivision )
                                 , "To: " );
            newMax = Mathf.Clamp( EditorGUI.FloatField( new Rect( position.x + xDivision * 2f + 24, position.y, xDivision -24, yDivision )
                                                       , newMax )
                                 , newMin, range.maxLimit );

            so.rangeStart = newMin;
            so.rangeEnd = newMax;

                property.ValueChanged();

                property.ApplyModifiedValue();

                property.serializedNode.ApplyModifiedProperties();
            }
        }
コード例 #3
0
    /// <summary>
    /// 构造函数 抽象类不建议是public构造函数
    /// </summary>
    /// <param name="parent"></param>
    protected BehaviourAI(Actor parent)
    {
        mRunningProperty                      = new AIRunningProperty();
        mRunningProperty.SelfActor            = parent;
        mRunningProperty.OriginalSelfActorPos = parent.transform.position;
        mRunningProperty.AI                   = this;
        mRunningProperty.ViewRange            = GetActorViewRange();
        mPathWalker = new AIActorPathWalker(parent);

        mMachine = new BehaviourMachine(this);
        mAmbient = new AIAmbientState(this);
    }
コード例 #4
0
ファイル: DecoratorNode.cs プロジェクト: heavymoons/core.ai
        public override bool Execute(BehaviourMachine machine, INode parentNode)
        {
            base.Execute(machine, parentNode);

            var result = ConditionCallback?.Invoke(machine, this) ?? false;

            if (result)
            {
                return(ChildNode.Execute(machine, this));
            }

            return(false);
        }
コード例 #5
0
        public ApproachMachine()
        {
            DataStorage[PlayerPosition] = new Point(10, 10);
            DataStorage[GoalPosition]   = new Point(0, 0);
            DataStorage[Switch]         = false;

            var switchOffState = new State();

            this[SwitchOff] = switchOffState;
            switchOffState.OnExecuteEvent = (machine, state) =>
            {
                Debug.WriteLine($"SwitchOff");
                if ((bool)machine.DataStorage[Switch])
                {
                    machine.NextStateName = SwitchOn;
                }
            };

            var switchOnState = new State();

            this[SwitchOn] = switchOnState;

            var behaviourMachine = new BehaviourMachine();

            behaviourMachine.DataStorage.ReferTo(DataStorage, PlayerPosition);
            behaviourMachine.DataStorage.ReferTo(DataStorage, GoalPosition);

            switchOnState.OnExecuteEvent = (machine, state) =>
            {
                Debug.WriteLine($"SwitchOn");
                behaviourMachine.Execute();
            };

            var moveOrTeleportSelector = new SelectorNode();

            behaviourMachine.RegisterRootNode(moveOrTeleportSelector);

            var moveDecorator = new DecoratorNode();

            moveOrTeleportSelector.ChildNodes.Add(moveDecorator);
            moveDecorator.ConditionCallback = (machine, node) =>
            {
                Debug.WriteLine($"move condition check");
                var playerPosition = (Point)machine.DataStorage[PlayerPosition];
                var goalPosition   = (Point)machine.DataStorage[GoalPosition];
                Debug.WriteLine($"P:{playerPosition} G:{goalPosition}");
                return(!playerPosition.Equals(goalPosition));
            };
            var moveAction = new ActionNode();

            moveDecorator.ChildNode   = moveAction;
            moveAction.ActionCallback = (machine, node) =>
            {
                Debug.WriteLine($"Move");
                var playerPosition = (Point)machine.DataStorage[PlayerPosition];
                var goalPosition   = (Point)machine.DataStorage[GoalPosition];
                var diffX          = Math.Abs(playerPosition.X - goalPosition.X);
                var diffY          = Math.Abs(playerPosition.Y - goalPosition.Y);
                if (diffX >= diffY)
                {
                    playerPosition.X += playerPosition.X > goalPosition.X ? -1 : 1;
                }
                else
                {
                    playerPosition.Y += playerPosition.Y > goalPosition.Y ? -1 : 1;
                }
                machine.DataStorage[PlayerPosition] = playerPosition;
                return(true);
            };

            var teleportAction = new ActionNode();

            teleportAction.DataStorage[TeleportCounter] = 10;
            moveOrTeleportSelector.ChildNodes.Add(teleportAction);
            teleportAction.ActionCallback = (machine, node) =>
            {
                Debug.WriteLine($"teleport");
                var teleportCounter = (int)node.DataStorage[TeleportCounter];
                teleportCounter--;
                node.DataStorage[TeleportCounter] = teleportCounter;
                Debug.WriteLine($"teleport counter: {teleportCounter}");
                if (teleportCounter > 0)
                {
                    return(false);
                }

                var playerPosition = (Point)machine.DataStorage[PlayerPosition];
                playerPosition.X = new Random().Next(-10, 10);
                playerPosition.Y = new Random().Next(-10, 10);
                machine.DataStorage[PlayerPosition] = playerPosition;

                node.DataStorage[TeleportCounter] = 10;
                Debug.WriteLine($"teleport to {playerPosition}");
                return(true);
            };
        }
コード例 #6
0
ファイル: StatusEventArgs.cs プロジェクト: osmanzeki/bmachine
 public StatusEventArgs(BehaviourMachine.Status status)
 {
     this.status = status;
 }
コード例 #7
0
 public override bool Execute(BehaviourMachine machine, INode parentNode)
 {
     base.Execute(machine, parentNode);
     return(ActionCallback.Invoke(machine, this));
 }
コード例 #8
0
        public override void OnGUI(SerializedNodeProperty property, BehaviourMachine.ActionNode node, GUIContent guiContent)
        {
            Rect position=	GUILayoutUtility.GetRect(Screen.width-32f,32f);

            Rect typePos = new Rect (position.x, position.y, 80, position.height);
            position.xMin = typePos.xMax;
            Rect varPos = new Rect (position.x, position.y, position.width, position.height);

            Type type;

            GUIContent[] displayOptionsTypes;
            Type[] types;

            UniUnityVariablePropertyAttribute attributeUni = attribute as UniUnityVariablePropertyAttribute;

            if (property.value == null)
                type = EditorGUILayoutEx.unityTypes [0];
            else
                type = ((UnityVariable)property.value).ValueType;

            //blackboard vars LOCAL
            BlackboardCustom blackboard = node.blackboard as BlackboardCustom;

            List<UnityVariable> blackboardVariablesLocalList = blackboard.GetVariableBy (type);

            List<GUIContent> displayOptionsVariablesLocal=	 blackboardVariablesLocalList.Select ((item) => new GUIContent ("Local/" + item.name)).ToList();

            //blackboard vars GLOBAL

            if (attributeUni.typesCustom != null) {

                GUIContent[] displayOptionsCustom=attributeUni.typesCustom.Select((itm)=>new GUIContent(itm.Name)).ToArray();

                if(attributeUni.only){
                    types=attributeUni.typesCustom;
                    displayOptionsTypes=displayOptionsCustom;
                }else{

                    types=attributeUni.typesCustom.Concat<Type>(EditorGUILayoutEx.unityTypes).ToArray();

                    displayOptionsTypes = displayOptionsCustom.Concat<GUIContent>(EditorGUILayoutEx.unityTypesDisplayOptions).ToArray();

                }

            }else{

                    displayOptionsTypes=EditorGUILayoutEx.unityTypesDisplayOptions;
                    types=EditorGUILayoutEx.unityTypes;

            }

            //String name = attributeUni.name;

            //create types selection popup
            typeSelected = EditorGUILayoutEx.CustomObjectPopup<Type> (null, type,displayOptionsTypes , types,null,null,null,null,typePos);

                                //if change of type create new variable
                                if (typeSelected != type && !typeSelected.IsSubclassOf (type) /*&& type!=typeof(UnityEngine.Object)*/) {

                                    property.value = UnityVariable.CreateInstanceOf(typeSelected);
                                }

            property.value=EditorGUILayoutEx.UnityVariablePopup(null,property.value as UnityVariable,typeSelected,displayOptionsVariablesLocal,blackboardVariablesLocalList,varPos);

            property.serializedNode.ApplyModifiedProperties();
        }
コード例 #9
0
        public void SimpleSearcherTest()
        {
            const string hitpoint        = "hp";
            const string distanceToTower = "distance";

            var machine = new BehaviourMachine();

            machine.DataStorage[hitpoint]        = 100;
            machine.DataStorage[distanceToTower] = 10;

            machine.OnExecuteEvent += (m) =>
            {
                var hp       = (int)m.DataStorage[hitpoint];
                var distance = (int)m.DataStorage[distanceToTower];
                Debug.WriteLine($"HP: {hp}");
                Debug.WriteLine($"Distance: {distance}");
            };

            var selector = new SelectorNode();

            machine.RegisterRootNode(selector);

            var decoratorHp = new DecoratorNode();

            selector.ChildNodes.Add(decoratorHp);

            decoratorHp.ConditionCallback = (m, n) => m.DataStorage.GetValue <int>(hitpoint) > 5;
            var attackNearEnemy = new ActionNode();

            attackNearEnemy.ActionCallback = (m, n) =>
            {
                Debug.WriteLine("近くの敵を攻撃");

                var distance = (int)m.DataStorage[distanceToTower];
                distance += 1;
                m.DataStorage[distanceToTower] = distance;

                var hp = (int)m.DataStorage[hitpoint];
                hp -= 5;
                m.DataStorage[hitpoint] = hp;
                return(true);
            };
            decoratorHp.ChildNode = attackNearEnemy;

            var sequencer = new SequencerNode();

            selector.ChildNodes.Add(sequencer);

            var moveToNearTower = new ActionNode();

            sequencer.ChildNodes.Add(moveToNearTower);

            moveToNearTower.ActionCallback = (m, n) =>
            {
                var distance = (int)m.DataStorage[distanceToTower];
                if (distance <= 0)
                {
                    return(true);
                }

                Debug.WriteLine("近くのタワーに移動");
                distance--;
                m.DataStorage[distanceToTower] = distance;
                return(true);
            };

            var wait = new ActionNode();

            sequencer.ChildNodes.Add(wait);

            wait.ActionCallback = (m, n) =>
            {
                Debug.WriteLine("待機");

                var distance = (int)m.DataStorage[distanceToTower];
                if (distance < 5)
                {
                    var hp = (int)m.DataStorage[hitpoint];
                    hp += 20;
                    m.DataStorage[hitpoint] = hp;
                }

                return(true);
            };

            for (var i = 0; i < 100; i++)
            {
                machine.Execute();
            }
        }