下面展示 Unity 行为树节点开发——A*移动控制
。
using UnityEngine;
using Pathfinding;
using MR_LBS.Client.Unity3D;
namespace BehaviorDesigner.Runtime.Tasks
{
[TaskCategory("GC_CL")]
public class PathFinding_Test : Action
{
public SharedFloat moveSpeed;
//A* 是否开启寻路
public SharedBool canMove = true;
public SharedGameObject target;
MonsterControlBase monsterControl;
Monster monster;
//A* 到达距离
public SharedFloat arriveDistance = 2f;
//public SharedVector3 targetPosition;
BehaviorTree tree;
//A* 到达下一个点的距离
//public SharedFloat pickNextWaypointDist = 1f;
AIPath aIPath;
private bool canChangeAStar;
public override void OnAwake()
{
monsterControl = GetComponent<MonsterControlBase>();
tree = (BehaviorTree)base.Owner;
monster = monsterControl.Monster_P;
aIPath = GetComponent<AIPath>();
canChangeAStar = (bool) tree.GetVariable("CanChangeAStar").GetValue();
}
public override void OnStart()
{
canChangeAStar = (bool)tree.GetVariable("CanChangeAStar").GetValue();
if (canChangeAStar)
{
aIPath.maxSpeed = moveSpeed.Value;
//打开寻路
aIPath.canMove = true;
aIPath.endReachedDistance = arriveDistance.Value;
if (target.Value == null)
{
monsterControl.PathFindingCon(null);//null 虫洞坐标
target.Value = monsterControl.Wormhole.gameObject;
//transform.LookAt(target.Value.transform);
}
else
{
monsterControl.PathFindingCon(target.Value.gameObject);
//transform.LookAt(target.Value.transform);
}
}
else if (!canChangeAStar)
{
aIPath.canMove = false;
}
}
public override TaskStatus OnUpdate()
{
canChangeAStar = (bool)tree.GetVariable("CanChangeAStar").GetValue();
//默认情况下可以第一判断不会对寻路产生影响
//如果有特殊效果影响寻路则更改第一层判定,暂停行为树中的寻路效果
if (canChangeAStar)
{
var position = Target();
// Return a task status of success once we've reached the target
if (Vector3.Magnitude(transform.position - position) < arriveDistance.Value)
{
//Debug.Log(Vector3.Magnitude(transform.position - position));
aIPath.canMove = false;
//Debug.Log(Vector3.Magnitude(transform.position - position));
return TaskStatus.Success;
}
if (((SharedGameObject)tree.GetVariable("FireTarget")).Value != null)
{
return TaskStatus.Success;
}
if (target.Value != null)
{
//Debug.Log(4444);
//transform.LookAt(target.Value.transform);
return TaskStatus.Success;
}
else
return TaskStatus.Failure;
}
else
{
if (canChangeAStar==false)
{
//Debug.Log("Worn");
}
//Debug.Log("false");
//这里不能让行为树卡在这里 所以应该是判定失败从新判定
return TaskStatus.Failure;
}
}
private Vector3 Target()
{
if (target == null || target.Value == null)
{
return monsterControl.Wormhole.position;
}
return target.Value.transform.position;
}
}
}