first commit
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
using System.Collections.Generic;
|
||||
using NodeCanvas.Framework;
|
||||
using ParadoxNotion.Design;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NodeCanvas.DialogueTrees
|
||||
{
|
||||
|
||||
[Category("Branch")]
|
||||
[Description("Select a child to execute based on it's chance to be selected. An optional pre-Condition Task can be assigned to filter the child in or out of the selection probability.\nThe actor selected will be used for the condition checks.")]
|
||||
[ParadoxNotion.Design.Icon("ProbabilitySelector")]
|
||||
[Color("b3ff7f")]
|
||||
public class ProbabilitySelector : DTNode
|
||||
{
|
||||
|
||||
public class Option
|
||||
{
|
||||
public BBParameter<float> weight;
|
||||
public ConditionTask condition;
|
||||
public Option(float weightValue, IBlackboard bbValue) {
|
||||
weight = new BBParameter<float> { value = weightValue, bb = bbValue };
|
||||
condition = null;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField, AutoSortWithChildrenConnections]
|
||||
private List<Option> childOptions = new List<Option>();
|
||||
private List<int> successIndeces;
|
||||
|
||||
public override int maxOutConnections { get { return -1; } }
|
||||
|
||||
public override void OnChildConnected(int index) {
|
||||
if ( childOptions.Count < outConnections.Count ) {
|
||||
childOptions.Insert(index, new Option(1, graphBlackboard));
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnChildDisconnected(int index) {
|
||||
childOptions.RemoveAt(index);
|
||||
}
|
||||
|
||||
protected override Status OnExecute(Component agent, IBlackboard blackboard) {
|
||||
|
||||
successIndeces = new List<int>();
|
||||
for ( var i = 0; i < outConnections.Count; i++ ) {
|
||||
var condition = childOptions[i].condition;
|
||||
if ( condition == null || condition.CheckOnce(finalActor.transform, blackboard) ) {
|
||||
successIndeces.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
var probability = Random.Range(0f, GetTotal());
|
||||
for ( var i = 0; i < outConnections.Count; i++ ) {
|
||||
|
||||
if ( !successIndeces.Contains(i) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( probability > childOptions[i].weight.value ) {
|
||||
probability -= childOptions[i].weight.value;
|
||||
continue;
|
||||
}
|
||||
|
||||
DLGTree.Continue(i);
|
||||
return Status.Success;
|
||||
}
|
||||
|
||||
return Status.Failure;
|
||||
}
|
||||
|
||||
float GetTotal() {
|
||||
var total = 0f;
|
||||
for ( var i = 0; i < childOptions.Count; i++ ) {
|
||||
var option = childOptions[i];
|
||||
if ( successIndeces == null || successIndeces.Contains(i) ) {
|
||||
total += option.weight.value;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
protected override void OnReset() {
|
||||
successIndeces = null;
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------------------------
|
||||
///---------------------------------------UNITY EDITOR-------------------------------------------
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public override string GetConnectionInfo(int i) {
|
||||
var result = childOptions[i].condition != null ? childOptions[i].condition.summaryInfo + "\n" : string.Empty;
|
||||
if ( successIndeces == null || successIndeces.Contains(i) ) {
|
||||
return result + Mathf.Round(( childOptions[i].weight.value / GetTotal() ) * 100) + "%";
|
||||
}
|
||||
return result + "Condition Failed";
|
||||
}
|
||||
|
||||
public override void OnConnectionInspectorGUI(int i) {
|
||||
DrawOptionGUI(i, GetTotal());
|
||||
}
|
||||
|
||||
protected override void OnNodeInspectorGUI() {
|
||||
|
||||
base.OnNodeInspectorGUI();
|
||||
|
||||
if ( outConnections.Count == 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var total = GetTotal();
|
||||
for ( var i = 0; i < childOptions.Count; i++ ) {
|
||||
EditorUtils.BoldSeparator();
|
||||
DrawOptionGUI(i, total);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawOptionGUI(int i, float total) {
|
||||
NodeCanvas.Editor.TaskEditor.TaskFieldMulti<ConditionTask>(childOptions[i].condition, DLGTree, (c) => { childOptions[i].condition = c; });
|
||||
EditorUtils.Separator();
|
||||
GUILayout.BeginHorizontal();
|
||||
NodeCanvas.Editor.BBParameterEditor.ParameterField("Weight", childOptions[i].weight);
|
||||
GUILayout.Label(Mathf.Round(( childOptions[i].weight.value / total ) * 100) + "%", GUILayout.Width(38));
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user