// 更新行为树 public int UpdateBehavior(float gameTime, float deltaTime) { if (m_BehaviorTree == null) { return(1); } AIBehaviorRequest currentRequest = m_BehaviorWorkData.request; if (currentRequest == null) { return(1); } //if(currentRequest.isRequestCompleted) // return 1; m_BehaviorWorkData.gameTime = gameTime; m_BehaviorWorkData.deltaTime = deltaTime; if (m_BehaviorTree.Evaluate(m_BehaviorWorkData)) { m_BehaviorTree.Update(m_BehaviorWorkData); } return(0); }
public override bool IsTrue(TBTWorkingData wData = null) { // 判断物体是否在视野范围内 BattleBehaviorWorkingData data = wData as BattleBehaviorWorkingData; AIBehaviorRequest request = data.request; BattleUnit owner = data.owner; float viewRange = owner.GetViewRange(); Vector2 targetPos = request.target.Get2DPosition(); Vector2 ownerPos = owner.Get2DPosition(); float distanceSquare = (targetPos - ownerPos).magnitude; BattleLog.Log(string.Format("【CON_IsInRange】距离:{0},可见范围:{1}", distanceSquare, viewRange * viewRange)); return(distanceSquare <= viewRange * viewRange); }
protected override int onExecute(TBTWorkingData wData) { BattleBehaviorWorkingData behaviorData = wData as BattleBehaviorWorkingData; float deltaTime = behaviorData.deltaTime; BattleUnit source = behaviorData.owner; AIBehaviorRequest request = behaviorData.request; Unit target = request.target; Vector2 sourcePos = source.Get2DPosition(); Vector2 targetPos = target.Get2DPosition(); Vector2 sourceForward = source.Get2DForward(); Vector2 targetForward = (targetPos - sourcePos).normalized; float turnSpeed = source.GetTurnSpeed(); float angle = Vector2.Angle(targetForward, sourceForward); float radianToTurn = turnSpeed * deltaTime; //BattleLog.Log("【NOD_TurnTo】angle:{0},{1}", angle, radianToTurn * Mathf.Rad2Deg); if (angle < radianToTurn * Mathf.Rad2Deg) { source.Set2DForward(targetForward); GameMsg.instance.SendMessage(GameMsgDef.Hero_TurnTo2D, new HeorTurnEventArgs() { id = source.id, forward = targetForward, }); return(TBTRunningStatus.FINISHED); } // 叉积算出方向 unity是左手坐标系,所以反过来了 Vector3 cross = Vector3.Cross(targetForward, sourceForward); if (cross.z > 0) { radianToTurn = -radianToTurn; } Vector2 newForward = BattleMath.Vector2RotateFromRadian(sourceForward.x, sourceForward.y, radianToTurn); //BattleLog.Log("【NOD_TurnTo】自己朝向:{0} 目标朝向:{1} 相隔角度:{2} 旋转弧度:{3} 叉乘:{4} 新的朝向:{5}", sourceForward.ToString(),targetForward.ToString(), angle.ToString(),(radianToTurn * Mathf.Rad2Deg).ToString(), cross.ToString(), newForward.ToString()); source.Set2DForward(newForward); GameMsg.instance.SendMessage(GameMsgDef.Hero_TurnTo2D, new HeorTurnEventArgs() { id = source.id, forward = newForward, }); return(TBTRunningStatus.EXECUTING); }
public override bool IsTrue(TBTWorkingData wData) { BattleBehaviorWorkingData behaviorData = wData as BattleBehaviorWorkingData; BattleUnit owner = behaviorData.owner; AIBehaviorRequest request = behaviorData.request; Unit target = request.target; Vector2 ownerPos = owner.Get2DPosition(); Vector2 targetPos = target.Get2DPosition(); Vector2 toForward = targetPos - ownerPos; Vector2 ownerForward = owner.Get2DForward(); float angle = Vector2.Angle(toForward, ownerForward); //BattleLog.Log("【CON_IsAngleNeedTurnTo】angle:{0}", angle); return(angle > 0.1f); }
protected override int onExecute(TBTWorkingData wData) { BattleBehaviorWorkingData behaviorData = wData as BattleBehaviorWorkingData; float deltaTime = behaviorData.deltaTime; BattleUnit source = behaviorData.owner; AIBehaviorRequest request = behaviorData.request; Unit target = request.target; Vector2 ownerPos = source.Get2DPosition(); Vector2 targetPos = target.Get2DPosition(); float attackRange = source.GetAttackRange(); float distance = (targetPos - ownerPos).magnitude; if (distance <= attackRange) { return(TBTRunningStatus.FINISHED); } float moveSpeed = source.GetMoveSpeed(); float detalTime = behaviorData.deltaTime; float toForwardX = (targetPos.x - ownerPos.x) / distance; float toForwardZ = (targetPos.y - ownerPos.y) / distance; float newPosX = ownerPos.x + detalTime * moveSpeed * toForwardX; float newPosZ = ownerPos.y + detalTime * moveSpeed * toForwardZ; source.Set2DPosition(newPosX, newPosZ); //BattleLog.Log("【NOD_MoveTo】移动速度:{0} 当前位置:{1},{2} 目标位置:{3},{4} newPosX:{5} newPosZ:{6}}", // moveSpeed.ToString(), ownerPos.x.ToString(),ownerPos.y.ToString(), targetPos.x.ToString(),targetPos.y.ToString() // ,newPosX.ToString(),newPosZ.ToString()); GameMsg.instance.SendMessage(GameMsgDef.Hero_MoveTo, new HeorMoveEventArgs() { id = source.id, targetPos = new Vector3(newPosX, 0, newPosZ), forward = new Vector3(toForwardX, 0, toForwardZ) }); return(TBTRunningStatus.EXECUTING); }
public override bool IsTrue(TBTWorkingData wData) { BattleDecisionWorkingData decisionData = wData as BattleDecisionWorkingData; BattleUnit battleEntity = decisionData.owner; if (!battleEntity.IsCanDecision()) { return(false); } // 新的决策 AIBehaviorRequest request = decisionData.request; if (request == null) { return(true); } else { //上一个请求已经执行完成,就更新新请求 return(request.IsRequestCompleted()); } }
// 更新请求 public int UpdateRequest(float gameTime, float deltaTime) { AIBehaviorRequest foregroundRequest = m_BehaviorWorkData.request; AIBehaviorRequest backgroundRequest = m_DecisionWorkData.request; if (backgroundRequest != foregroundRequest) { //比对决策树和行为树的请求是否一致 if (foregroundRequest != null) { GameLog.Log("【UpdateRequest】当前在处理的请求(前端):" + foregroundRequest.ToString()); } if (backgroundRequest != null) { GameLog.Log("【UpdateRequest】下一个要处理的请求(后端):" + backgroundRequest.ToString()); } //reset bev tree 清理一些状态 m_BehaviorTree.Transition(m_BehaviorWorkData); //assign to current m_BehaviorWorkData.request = backgroundRequest; } return(0); }
// 决策层:输入(游戏世界信息),输出(请求) // 行为层:输入(请求),输出(修改游戏世界的相关信息) public void SetDecisionRequest(AIBehaviorRequest request) { m_DecisionWorkData.request = request; }