• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 72,  comments - 4,  trackbacks - 0
            泰坦之旅的ai

            titan quest的AI用的是切換式的狀態(tài)機,而尋路用的是path engine第3方庫,游戲中有一個任務(wù)編輯器主要是生成每一個任務(wù),每個任務(wù)中可以生成多個觸發(fā)器(trigger),每個觸發(fā)器可以生成一系列條件(condition),并可生成條件成立時要觸發(fā)的動作(action). 這個有點類似war3的事件編輯器。

            以下是切換式狀態(tài)機跟蹤的一些記錄,很亂,沒寫總結(jié),只是用于備忘。。。
            AI移動跟蹤
            WinMain消息循環(huán)中的Game::Run()中先
            1. gGameEngine->GetFrustumForPlayer(updateFrustum, player->GetCoords().origin); 得到frustum

            2. gEngine->Update(&updateFrustum);進行更新, 其中
               調(diào)用 world->Update(worldFrustumList);

               然后遍歷每個frustum取得對應(yīng)region進行更新

               a. 看看當(dāng)前region是否與frustum相交,如果是則load,否則擴大一點再相交,這時如果相交則將添加到后臺加載。
               b. 查看portal相關(guān)region進行更新
               3. 查看connectedRegions(在地圖裝載得到玩家出生位置后進行玩家所在region擴大后跟其它region判斷相交所得)進行更新 

            3. Region的更新中進行l(wèi)evel更新:
              level->Update(frustumList, numFrustums, elapsedTime);
              在其中先取得在frustum中的Entity, 然后再遍歷更新所有Entity,
              之后再更新Entity所在4叉樹空間.

            4. 角色的更新:
               Entity的更新中, 先UpdateSelf再UpdateAttachedEntities
               (Entity中有PhysicsRigidBody成員physicsObject)

            5. UpdateSelf會跑到Character::PreAnimationUpdate中執(zhí)行 baseController->Update(localTimeDelta);從而跳到ContrallerAI中執(zhí)行GetExecutingState()->OnUpdate(deltaTime); 從而到達ControllerNpcStateIdle的更新中進行狀態(tài)切換到SetState("Wander", ControllerAIStateData(0, 0, 0)); 
            之后再跑到ControllerNpcStateWander::OnBegin()
            處理:
                int closestPoint = GetClosest(GetController().GetWanderPoints());
                GetController().SetCurrentWanderPoint(closestPoint);
                if (!MoveToCurrentWanderPoint())
                {
                    SetState("Idle", ControllerAIStateData());
                    return;
                }
            這個在MoveToCurrentWanderPoint()函數(shù)里從隊列中取出當(dāng)前目標點并ControllerAI::WalkTo
            其中會GetController().WalkTo(location, target);即ControllerAI::WalkTo(。。), 這會執(zhí)行:
             HandleAction(new WalkAction(GetParentId(), GetAI()->GetPathPosition(), location, target));
            這個會執(zhí)行:
                    SetCurrentAction(action);
                    GetCurrentAction()->Execute();從而運行了WalkAction::Execute(), 這其中又調(diào)用了Character::WalkTo
             這又會:
                movementMgr->SetNewPathTarget進行處理


            最后在CharacterMovementManager::Update()中進行角色位置更新:

                    CreateLocalPath(deltaTime, speed);

                    if (!MoveDownPath(deltaTime, speed))
                    {
                        return false;
                    }
                    UpdateCharacterPosition(deltaTime, speed);

            void UIDialogWindow::OnOpen()會調(diào)用 myNpc->AddSocialTarget( target );
            在void ControllerNpcStateIdle::OnUpdate(Time deltaTime)中判斷如果有SocialTarget則進入Chat狀態(tài)處理

            【狀態(tài)處理例子】
            Monster的初始狀態(tài)是Idle,在Monster的更新函數(shù)里:
            一)。進行搜敵,并切換成pursue狀態(tài)
            ,并調(diào)追捕狀態(tài)的OnBegin()函數(shù)處理,如果Monster不能行走則切回Idle狀態(tài),否則如果搜不到敵
            人則切換到Return狀態(tài),否則根據(jù)當(dāng)前技能id找出要移到的位置點.
            ------------------------------------------------------
            【注意】找到要移到的位置點細節(jié):
            I. (Character::GetMoveToPoint)找出目標點:
              1. 目標是自己則直接return自己位置
              2. 沒有目標則保存goalPoint=目標點,distance=技能施放范圍,待后處理.
              3. 目標是FixedItem則return FixedItem->GetMoveToPoint(..)里進行處理
              4. 目標是StrategicMovementBase,則return sm->GetMoveToPoint(..)里進行處理
              5. 目標是Entity,則goalPoint = entity->GetCoords().origin;并且如果entity阻擋則讓goalPoint回移一點以免浮點出錯?否則distance=GetExtents() + entity-

            >GetExtents();待后處理
              6. 目標是Character,則,
                 a. 如果是朋友
                   1)如果當(dāng)前是移動狀態(tài),則要求目標給出DefenseSlot(防御位置點)作為goalPoint直接返回.
                   2)否則如果能直線通路到目標點的話就直接返回離目標比較近的一點(去掉半徑),不能直通則返回0點  
                 b. 如果是敵人
                   1)如果沒有技能,則goalPoint=目標點,distance=GetExtents() + target->GetExtents();待后處理
                   2)如果技能不需要AttackSlot或者this是Player, 則
                    goalPoint=目標點,distance = GetExtents() + target->GetExtents() + skill->GetRange();待后處理
                   3)否則直接返回目標算出的AttackSlot攻擊點位置.
              上述2和5以及6中的b.的1)和2)需要待后處理的最后通過 
                WorldVec3 finalPoint = movementMgr->GetPointAwayFromGoal(goalPoint, distance);
              得到最終位置, 這個位置還要特殊判斷一下如果不在Region中或者路徑不能到達的話,則直接用TranslateToFloor到goalPoint.

            【說明】:
              1. 什么是AttackSlot/DefenseSlot:
            每個角色可以有n個x距離的AttackSlot/DefenseSlot,它會在周圍x半徑的圓上平分出n個位置點,當(dāng)有其它人要攻擊它或者要來幫助(防御)它時,它就會在旁邊找一個較近的還

            沒其它人用過的slot分給這個其它人。
              2. movementMgr->GetPointAwayFromGoal()函數(shù)細節(jié):
                先是FindPath(目標)得出path,再用path->Advance(pathLength - distance)得到回退一點的位置。

            II. 找到目標點后,還要調(diào)用movementGoalManager->GetClosestMovePoint(目標點) 進行處理:
                這個函數(shù)主要是給范圍武器用的,如果不是使用范圍武器的Monster則不會調(diào)整目標點。
                如果是的話則遍歷全局對象movementGoalManager中的m_MoveGoalMap目標點映射表,求出其它在同一region中的Monster
                所在目標點跟當(dāng)前Monster所在目標點的距離,如果距離比較近則調(diào)用GetPointAwayFromGoal(目標點, 3.0);調(diào)整當(dāng)前Monster的目標點回退一點,并將些處理后的位置及些

            Monsterid映射到m_MoveGoalMap目標點映射表中。這樣遍歷過所有其它Monster的目標點進行一一檢測處理后就會盡量避免與其它Monster擠到一起。
            ------------------------------------------------------

            找到要移到的位置點之后,
            1. 用(CloseEnoughToUseSkill(GetCurrentEnemy(), GetCurrentSkillID()))判斷是否在技能攻擊范圍內(nèi),
            如果在則用IsPathClear(GetCurrentEnemy())來判斷是不是到直通目標,是則切換成Attack狀態(tài)后返回,否則切換成NavigateObstacle狀態(tài)后返回。

            2. 否則敵人不在攻擊范圍內(nèi)就看當(dāng)前是否已站在目標點,是則切回Idle狀態(tài)后返回

            3. 不在目標點則看是不是能夠移到目標點,不能則切回Idle狀態(tài)后返回。

            4. 能移到目標點則MoveTo到目標點.
               這個MoveTo會調(diào)用
               HandleAction(new MoveToAction(GetParentId(), GetAI()->GetPathPosition(), location, target, GetAI()->GetSkillReferenceNumber(skill), 1.0, animType));
               這個會執(zhí)行到MoveToAction, 其中會轉(zhuǎn)調(diào):
                    monseter->SetCurrentAttackTarget(targetId, location, skillNumber);
                    monseter->SkillWarmUp( skillNumber, false );
                    monseter->MoveTo(location, GetBlendTime(), animType);
                    monseter->PlayLoopingRunningSound();
              而monseter->MoveTo又會調(diào)用 movementMgr->SetNewPathTarget(movementMgr->GetPathPosition(), surfacePoint, alreadyThere))
              然后再用SetActionState(Character_ActionState_Move);設(shè)置Action的狀態(tài)為Move,并通過PlayAnimation播放run動作(即調(diào)用GetAnimationBase( type ).PlayAnimation( 

            actor, selection, speedModifier, loop, iteration ),這個可以參考我另一個動畫跟蹤文檔看細節(jié))

            二)。搜敵后會接著調(diào)用ControllerAI::Update()更新函數(shù):
               1. 先進行當(dāng)前狀態(tài)更新()
                  由于前面Monster切換到了pursue追捕狀態(tài),所以執(zhí)行到
                  ControllerMonsterStatePursue::OnUpdate(),其中:
                  a. 追捕所用時間過了,則切換回return狀態(tài)
                  b. 重新選擇技能時間到了則重新找出一個bestSkill.(這也避免了萬一當(dāng)前技能是melee,而玩家總是繞著Monster轉(zhuǎn),怪就會不停地追不上而沒法肉搏攻擊)
                  c. 用CloseEnoughToUseSkill判斷是否夠技能施放距離,夠的話用IsPathClear判斷攻擊方向是否可通,是則轉(zhuǎn)Attack狀態(tài),不通則轉(zhuǎn)NavigateObstacle狀態(tài).

               2. 再遍歷執(zhí)行m_PreloadQuestActionList中action.

            上述都在【更祥細一點】中1。Character::UpdateSelf()中進行
            接著會到【更祥細一點】中2。 Update subsystems:中的FollowPath()進行真正的移動處理.
            posted on 2012-08-13 10:09 flipcode 閱讀(349) 評論(0)  編輯 收藏 引用

            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            久久婷婷五月综合97色直播| 国产亚洲精久久久久久无码77777| 九九久久自然熟的香蕉图片| 久久婷婷五月综合色高清| 精品午夜久久福利大片| 久久久久国色AV免费看图片| 亚洲国产日韩欧美综合久久| 精品久久久久久亚洲精品 | 潮喷大喷水系列无码久久精品| 91精品国产综合久久婷婷| 欧洲性大片xxxxx久久久| 一本久久a久久精品vr综合| 一本久久a久久精品综合夜夜| 久久久久亚洲AV综合波多野结衣| 午夜欧美精品久久久久久久| 久久久免费观成人影院 | 久久婷婷人人澡人人| 狠狠色婷婷久久一区二区| 久久中文字幕一区二区| 久久久久亚洲精品日久生情 | 欧美国产成人久久精品| 国产精品久久精品| 浪潮AV色综合久久天堂| 亚洲?V乱码久久精品蜜桃 | 精品国产乱码久久久久软件| 99久久国语露脸精品国产| 国产69精品久久久久APP下载| 久久久久国产一级毛片高清版| 亚洲AV日韩AV永久无码久久| 久久久精品久久久久影院| 久久精品国产99国产精品| 国产精品久久久久久久久鸭| 欧美一区二区三区久久综合 | 国产免费福利体检区久久| 狠狠久久亚洲欧美专区| 国产午夜久久影院| AV狠狠色丁香婷婷综合久久| 精品永久久福利一区二区| 麻豆成人久久精品二区三区免费| 日本欧美久久久久免费播放网| 97久久国产综合精品女不卡|