Пример #1
0
    /**
     * Forces a behaviour, interrupting the one being currently executed.
     */
    public void SetBehaviour(int behaviorHash)
    {
        // Safely disable the current behaviour.
        if (currentBehaviour)
        {
            currentBehaviour.enabled = false;
            currentBehaviour.onExitState();
        }

        try
        {
            // Start the new behaviour.
            currentBehaviour         = behaviours[behaviorHash];
            currentBehaviour.enabled = true;
            currentBehaviour.onEnterState();
        }
        catch (KeyNotFoundException)
        {
            currentBehaviour = null;
        }
    }
Пример #2
0
        private void UpdateParticipantsList()
        {
            participants.Clear();
            participants.Add(Brain);

            GenericActorInteractionBehaviour[] behaviours;
            for (int i = 0; i < SensedThings.Count; i++)
            {
                //TODO would be more efficient to pull the behaviours from the target brain
                //TODO this is duplicated in StartBehaviour
                behaviours = SensedThings[i].GetComponentsInChildren <GenericActorInteractionBehaviour>();
                if (behaviours.Length == 0)
                {
                    continue;
                }

                //TODO Don't test if the currently active behaviour is the same. Instead have a "handshake" protocol in which both actors agree to participate in the same behaviour on the next frame.
                AbstractAIBehaviour behaviour = behaviours[0].Brain.ActiveBlockingBehaviour;
                if (behaviour != null && behaviour.DisplayName == this.DisplayName)
                {
                    participants.Add(behaviours[0].Brain);
                }
            }
        }
Пример #3
0
 /// <summary>
 /// Deegister a behaviour from the active list for this brain. Only registered behaviours will
 /// be evaluated for execution according to the brains decision making cycle.
 /// </summary>
 /// <param name="behaviour">The behaviour to deregister.</param>
 /// <returns>True if removed from the active list of behaviours.</returns>
 public bool DeregisterBehaviour(AbstractAIBehaviour behaviour)
 {
     return(m_AvailableBehaviours.Remove(behaviour));
 }
Пример #4
0
        /// <summary>
        /// Iterates over all the behaviours available to this actor and picks the most important one to be executed next.
        /// </summary>
        private void UpdateActiveBehaviour()
        {
            if (ActiveBlockingBehaviour != null && ActiveBlockingBehaviour.IsExecuting && !ActiveBlockingBehaviour.IsInteruptable)
            {
                return;
            }

            bool isInterupting = false;

            if (ActiveBlockingBehaviour != null && ActiveBlockingBehaviour.IsExecuting)
            {
                isInterupting = true;
            }

            StringBuilder       log = new StringBuilder();
            AbstractAIBehaviour candidateBehaviour = null;
            float highestWeight = float.MinValue;
            float currentWeight = 0;

            for (int i = 0; i < m_AvailableBehaviours.Count; i++)
            {
                log.Append("Considering: ");
                log.AppendLine(m_AvailableBehaviours[i].DisplayName);

                if (m_AvailableBehaviours[i].IsExecuting)
                {
                    if (m_AvailableBehaviours[i].IsInteruptable)
                    {
                        log.AppendLine("Already executing but can interupt - checking requirements are still valid.");
                    }
                    else
                    {
                        log.AppendLine("Already executing and cannot interupt - no need to start it again though.");
                        if (m_AvailableBehaviours[i].Weight(this) > highestWeight)
                        {
                            candidateBehaviour = m_AvailableBehaviours[i];
                            highestWeight      = m_AvailableBehaviours[i].Weight(this);
                            log.Append(m_AvailableBehaviours[i].DisplayName);
                            log.Append(" has a weight of ");
                            log.AppendLine(currentWeight.ToString());
                        }
                        continue;
                    }
                }

                if (m_AvailableBehaviours[i].IsAvailable)
                {
                    log.AppendLine(m_AvailableBehaviours[i].reasoning.ToString());

                    currentWeight = m_AvailableBehaviours[i].Weight(this); log.Append(m_AvailableBehaviours[i].DisplayName);
                    log.Append(" has a weight of ");
                    log.AppendLine(currentWeight.ToString());
                    if (currentWeight > highestWeight)
                    {
                        candidateBehaviour = m_AvailableBehaviours[i];
                        highestWeight      = currentWeight;
                    }
                }
                log.AppendLine(m_AvailableBehaviours[i].reasoning.ToString());
            }

            if (candidateBehaviour == null)
            {
                return;
            }

            if (isInterupting && candidateBehaviour != ActiveBlockingBehaviour)
            {
                ActiveBlockingBehaviour.FinishBehaviour();
            }

            if (candidateBehaviour.IsBlocking)
            {
                ActiveBlockingBehaviour = candidateBehaviour;
                if (ActiveBlockingBehaviour is GenericInteractionAIBehaviour)
                {
                    TargetInteractable = ((GenericInteractionAIBehaviour)ActiveBlockingBehaviour).CurrentInteractableTarget;
                    if (TargetInteractable == null)
                    {
                        ActiveBlockingBehaviour = m_FallbackBehaviour;
                        if (ActiveBlockingBehaviour != null)
                        {
                            ActiveBlockingBehaviour.StartBehaviour(ActiveBlockingBehaviour.MaximumExecutionTime);
                        }
                    }
                    else
                    {
                        ActiveBlockingBehaviour.IsExecuting = true;
                        // Don't start the behaviour since we need the interactable to trigger the start.
                    }
                }
                else
                {
                    TargetInteractable = null;
                    ActiveBlockingBehaviour.StartBehaviour(ActiveBlockingBehaviour.MaximumExecutionTime);
                }
            }
            else
            {
                candidateBehaviour.EndTime     = 0;
                candidateBehaviour.IsExecuting = true;
                candidateBehaviour.StartBehaviour(ActiveBlockingBehaviour.MaximumExecutionTime);
                ActiveNonBlockingBehaviours.Add(candidateBehaviour);
            }


            log.Insert(0, "\n");
            // Note this section is inserted in reverse as we want it at the start of the string.
            if (TargetInteractable != null)
            {
                log.Insert(0, TargetInteractable.name);
                log.Insert(0, " at ");
                log.Insert(0, TargetInteractable.InteractionName);
            }
            else
            {
                if (ActiveBlockingBehaviour == candidateBehaviour)
                {
                    log.Insert(0, candidateBehaviour.DisplayName);
                }
                else
                {
                    log.Insert(0, candidateBehaviour.DisplayName);
                    log.Insert(0, " look for a place to ");
                }
            }
            log.Insert(0, " decided to ");
            log.Insert(0, DisplayName);

            Log(log.ToString());
        }
Пример #5
0
 /// <summary>
 /// Register a behaviour as being active for this brain. All registered behaviours will
 /// be evaluated for execution according to the brains decision making cycle.
 /// </summary>
 /// <param name="behaviour">The behaviour to register.</param>
 public void RegisterBehaviour(AbstractAIBehaviour behaviour)
 {
     m_AvailableBehaviours.Add(behaviour);
 }