private void RefreshAccessClasses() { AccessLimitDecoratorData data = (AccessLimitDecoratorData)_ALItem.Data; _AccessClassField.Options.Clear(); _AccessClassField.SelectedIndex = -1; if (_ALItem.Editor.Asset.SharedKeys != null) { int selectedIndex = -1; for (int i = 0; i < _ALItem.Editor.Asset.SharedKeys.Length; i++) { var sk = _ALItem.Editor.Asset.SharedKeys[i]; if (sk != null) { Skill.Editor.UI.PopupOption op = new UI.PopupOption(i, sk.name); _AccessClassField.Options.Add(op); if (sk.name == data.ClassName) { selectedIndex = i; } } } _AccessClassField.SelectedIndex = selectedIndex; } else { data.ClassName = string.Empty; } RefreshAccessKeys(); }
private static void CheckAccessKey(DecoratorData decorator) { if (decorator.Type == Framework.AI.DecoratorType.AccessLimit) { AccessLimitDecoratorData accessLimitDecorator = (AccessLimitDecoratorData)decorator; if (string.IsNullOrEmpty(accessLimitDecorator.AccessKey)) { Debug.LogError(string.Format("The provided AccessKey '{0}' for behavior node '{1}' does not exist.", accessLimitDecorator.AccessKey, accessLimitDecorator.Name)); _ErrorFound = true; return; } if (string.IsNullOrEmpty(accessLimitDecorator.ClassName)) { Debug.LogError(string.Format(" Invalid AccessKey for behavior node '{0}'", accessLimitDecorator.Name)); _ErrorFound = true; } else { SharedAccessKeysData ac = null; foreach (var item in _AccessKeys) { if (item != null) { if (item.Name == accessLimitDecorator.ClassName) { ac = item; break; } } } if (ac == null) { Debug.LogError(string.Format(" Invalid AccessKey for behavior node '{0}'", accessLimitDecorator.Name)); _ErrorFound = true; } else { if (ac.Keys.Count(c => c.Key == accessLimitDecorator.AccessKey) < 1) { Debug.LogError(string.Format("The provided AccessKey '{0}' for behavior node '{1}' does not exist.", accessLimitDecorator.AccessKey, accessLimitDecorator.Name)); _ErrorFound = true; } } } } }
private void RefreshAccessKeys() { AccessLimitDecoratorData data = (AccessLimitDecoratorData)_ALItem.Data; _AccessKeyField.Options.Clear(); _AccessKeyField.SelectedIndex = -1; if (!string.IsNullOrEmpty(data.ClassName) && _AccessClassField.SelectedOption != null) { SharedAccessKeysAsset asset = null; foreach (var item in _ALItem.Editor.Asset.SharedKeys) { if (item.name == data.ClassName) { asset = item; } } if (asset != null) { int selectedIndex = -1; var keys = asset.Load().Keys; for (int i = 0; i < keys.Length; i++) { Skill.Editor.UI.PopupOption op = new UI.PopupOption((int)keys[i].Type, keys[i].Key); _AccessKeyField.Options.Add(op); if (keys[i].Key == data.AccessKey) { selectedIndex = i; } } _AccessKeyField.SelectedIndex = selectedIndex; } else { data.AccessKey = string.Empty; } } else { data.AccessKey = string.Empty; } }
/// <summary> /// Detect Behavior data from Given XmlElement and load it /// </summary> /// <param name="behavior">XmlElement contains Behavior data</param> /// <returns>Loaded Behavior</returns> public static BehaviorData CreateBehaviorFrom(XmlElement behavior) { BehaviorData result = null; Skill.Framework.AI.BehaviorType behaviorType = Skill.Framework.AI.BehaviorType.Action; bool isCorrect = false; try { behaviorType = behavior.GetAttributeValueAsEnum <Skill.Framework.AI.BehaviorType>("BehaviorType", Skill.Framework.AI.BehaviorType.Condition); isCorrect = true; } catch (Exception) { isCorrect = false; } if (isCorrect) { switch (behaviorType) { case Skill.Framework.AI.BehaviorType.Action: result = new ActionData(); break; case Skill.Framework.AI.BehaviorType.Condition: result = new ConditionData(); break; case Skill.Framework.AI.BehaviorType.Decorator: Skill.Framework.AI.DecoratorType decoratorType = behavior.GetAttributeValueAsEnum <Skill.Framework.AI.DecoratorType>("DecoratorType", Skill.Framework.AI.DecoratorType.Default); switch (decoratorType) { case Skill.Framework.AI.DecoratorType.Default: result = new DecoratorData(); break; case Skill.Framework.AI.DecoratorType.AccessLimit: result = new AccessLimitDecoratorData(); break; default: break; } break; case Skill.Framework.AI.BehaviorType.Composite: Skill.Framework.AI.CompositeType selectorType = behavior.GetAttributeValueAsEnum <Skill.Framework.AI.CompositeType>("CompositeType", Skill.Framework.AI.CompositeType.Sequence); switch (selectorType) { case Skill.Framework.AI.CompositeType.Sequence: result = new SequenceSelectorData(); break; case Skill.Framework.AI.CompositeType.Concurrent: result = new ConcurrentSelectorData(); break; case Skill.Framework.AI.CompositeType.Random: result = new RandomSelectorData(); break; case Skill.Framework.AI.CompositeType.Priority: result = new PrioritySelectorData(); break; case Skill.Framework.AI.CompositeType.Loop: result = new LoopSelectorData(); break; case Skill.Framework.AI.CompositeType.State: result = new BehaviorTreeStateData(); break; } break; case Skill.Framework.AI.BehaviorType.ChangeState: result = new ChangeStateData(); break; } } return(result); }
private static void SearchForBehaviorWarnings() { foreach (var b in _Behaviors) { if (b.BehaviorType == Framework.AI.BehaviorType.Composite) { CompositeData composite = (CompositeData)b; if (composite.Count == 0) { Debug.LogError(string.Format("Composite node {0} has not any children.", composite.Name)); _ErrorFound = true; } if (composite.CompositeType == Framework.AI.CompositeType.Priority || composite.CompositeType == Framework.AI.CompositeType.Concurrent || composite.CompositeType == Framework.AI.CompositeType.State) // check if a Decorator with NeverFaile property is child of PrioritySelector or ConcurrentSelector { foreach (var child in composite) { if (child != null && child.BehaviorType == Framework.AI.BehaviorType.Decorator) { if (((DecoratorData)child).NeverFail) { if (composite.CompositeType == Framework.AI.CompositeType.Priority || composite.CompositeType == Framework.AI.CompositeType.State) { Debug.LogWarning(string.Format("Decorator '{0}' with 'NeverFail' property setted to 'true' is child of PrioritySelector '{1}'. This cause next children unreachable.", child.Name, b.Name)); } else if (composite.CompositeType == Framework.AI.CompositeType.Concurrent) { if (((ConcurrentSelectorData)composite).SuccessPolicy == Framework.AI.SuccessPolicy.SucceedOnOne) { Debug.LogWarning(string.Format("Decorator '{0}' with 'NeverFail' property setted to 'true' is child of ConcurrentSelector '{1}' width 'SuccessPolicy' property setted to 'SucceedOnOne' . This cause ConcurrentSelector never fail.", child.Name, b.Name)); } } } } } } if (composite.CompositeType != Framework.AI.CompositeType.Random) { foreach (var child in composite) { if (child != null && child.BehaviorType == Framework.AI.BehaviorType.ChangeState) { int index = composite.IndexOf(child); if (index < composite.Count - 1) { Debug.LogWarning(string.Format("There are unreachable behaviors in Composite '{0}', after ChangeState '{1}'", composite.Name, child.Name)); } } } } } else if (b.BehaviorType == Framework.AI.BehaviorType.Decorator) { DecoratorData decorator = (DecoratorData)b; if (decorator.Type == Framework.AI.DecoratorType.AccessLimit) { AccessLimitDecoratorData al = (AccessLimitDecoratorData)decorator; if (decorator.Child.BehaviorType == Framework.AI.BehaviorType.ChangeState && al.KeyType == Framework.AI.AccessKeyType.CounterLimit) { Debug.LogWarning(string.Format("AccessLimitDecorator '{0} with CounterLimit accesskey' has a ChangeState child '{1}'. CounterLimit key will be unlocked after change state.", decorator.Name, decorator.Child.Name)); } } } } }
void AddMenuItem_Click(object sender, System.EventArgs e) { if (_TreeView.SelectedItem == null) { return; } if (!(_TreeView.SelectedItem is TreeViewFolder)) { return; } Skill.Editor.UI.MenuItem item = (Skill.Editor.UI.MenuItem)sender; BehaviorData behavior = null; if (string.IsNullOrEmpty(item.Tag)) { Skill.Framework.AI.BehaviorType type = (Framework.AI.BehaviorType)item.UserData; switch (type) { case Skill.Framework.AI.BehaviorType.Action: behavior = new ActionData() { Name = _Editor.GetUniqueName("NewAction") }; break; case Skill.Framework.AI.BehaviorType.Condition: behavior = new ConditionData() { Name = _Editor.GetUniqueName("NewCondition") }; break; default: behavior = null; break; } } else if (item.Tag == "Decorator") { Skill.Framework.AI.DecoratorType type = (Framework.AI.DecoratorType)item.UserData; switch (type) { case Skill.Framework.AI.DecoratorType.Default: behavior = new DecoratorData() { Name = _Editor.GetUniqueName("NewDecorator") }; break; case Skill.Framework.AI.DecoratorType.AccessLimit: behavior = new AccessLimitDecoratorData() { Name = _Editor.GetUniqueName("NewAccessDecorator") }; break; default: behavior = null; break; } } else if (item.Tag == "Composite") { Skill.Framework.AI.CompositeType type = (Framework.AI.CompositeType)item.UserData; switch (type) { case Skill.Framework.AI.CompositeType.Sequence: behavior = new SequenceSelectorData() { Name = _Editor.GetUniqueName("NewSequence") }; break; case Skill.Framework.AI.CompositeType.Concurrent: behavior = new ConcurrentSelectorData() { Name = _Editor.GetUniqueName("NewConcurrent") }; break; case Skill.Framework.AI.CompositeType.Random: behavior = new RandomSelectorData() { Name = _Editor.GetUniqueName("NewRandom") }; break; case Skill.Framework.AI.CompositeType.Priority: behavior = new PrioritySelectorData() { Name = _Editor.GetUniqueName("NewPriority") }; break; case Skill.Framework.AI.CompositeType.Loop: behavior = new LoopSelectorData() { Name = _Editor.GetUniqueName("NewLoop") }; break; default: behavior = null; break; } } if (behavior != null) { TreeViewFolder tvf = (TreeViewFolder)_TreeView.SelectedItem; tvf.Foldout.IsOpen = true; tvf.AddBehavior(behavior); _Editor.AddToList(behavior); _Editor.RefreshTree(); SelectItem(tvf, behavior); } }
public AccessLimitDecoratorItem(AccessLimitDecoratorData data) : base(data) { }