Results 1 to 2 of 2
  1. #1

    Default NavigationMeshに関して質問

    質問ばかりして申し訳ないのですが、NavigationMeshに関して質問があります。

    NavigationMeshを利用するためにはNavigationHandleを介してパス制約の設定 、終点評価、探索等を行います。
    そこで、NavigationMeshの探索を行うクラスとNavigationHandleクラス間のや り取りはInterface_NavigationHandleを探索を行うクラスに実装することで行うと 理解しています。
    Interface_NavigationHandleを実装してるクラスは標準でCrowdAgentB aseとControllerクラスがあります。

    ここから私がやりたいことなのですが、新たに自分が作ったクラスでNavigationMeshの探索を行 いたいので、自分が作ったクラスにInterface_NavigationHandleを実装したいと考 えています。
    しかしInterface_NavigationHandleのメンバ関数はnativeで宣言されていま す。
    ということは新たにInterface_NavigationHandleを実装するクラスを作成するため にはnativeで関数を作成しなければならないのでしょうか?
    そして仮にnativeで(DLLで)作成するとしてFNavMeshPathParams等の構造体の宣 言は何処から参照すればいいのでしょうか?

    あと、上の質問とはズレるのですが、Unreal script上からPathCacheの中身を参照できないのでしょうか?
    一度検索したデータを見ることができないと「マップ上に目的地までの誘導ラインを描画」等の機能が実装でき ないと思うのですが。




    さらについでなのですが、標準のUTBotは探索にNavigationMeshを利用していません
    NavigationMeshを利用しているのはCrowd Agentのみです。
    もし自分でNavigationMeshを利用するBotを作りたい場合はUTBotを書き換える、もしく はUTBotを継承したクラスでNavigationMeshを利用するようなコードを書かなければいけま せん。
    これを知らずにマップにNavigationMeshを作成しても完全に無意味です。
    私もUTBotはNavigationMeshを利用していると勘違いしていました。
    もし知らない人がいた場合は注意しましょう。

    もし自前で実装する場合は
    http://udn.epicgames.com/Three/Navig...icalGuide.html
    の一番下でダウンロードできるサンプルコードが役に立つと思います。

    #さらにチラ裏なのですが、サンプルコードだと移動をMoveTo()で実装してる(というかNaviga tionMeshだとそれしか方法がない)
    #のですがMoveTo()だとMoveToward()と違ってStrafeするかどうかの引数がありま せんよね?
    #ってことはNavigationMeshするとAIが移動中に攻撃しなくなる・・・?
    #どうしろたもんやら。
    Last edited by Cool0707; 03-20-2012 at 01:44 PM.

  2. #2

    Default

    NavigationHandleはControllerクラスで既に定義されているので、
    それを使えばいいと思います。
    (例)Pathを見つけたい場合の命令: NavigationHandle.FindPath();

    デバッグ目的での「マップ上に目的地までの誘導ラインを描画」という機能は、
    NavigationHandle.DrawPathCache();
    もしくは
    DrawDebugLine();
    辺りで可能だと思います。(下記コード参照)

    PathCacheは
    NavigationHandle.PathCache
    で参照できるんじゃないかと思います。
    (私はそこまで使ってないので分かりませんが)



    参考までに、UTBotクラスを拡張した、MoveToward()を含むサンプルコードを以下に記してお きます。
    (いろんなところからの寄せ集めで、私自身よく分かってない部分もありますが)

    Code:
    class MyGameBot extends UTBot;
    
    var Actor MoveTowardDestActor, MoveTowardFocusActor;
    var Vector TempDest;
    var float DestinationDistance;
    var float StopDistance;
    
    function BeginMoveToward(Actor Dest, Actor ViewFocus)
    {
    	MoveTowardDestActor = Dest;
    	MoveTowardFocusActor = ViewFocus;
    	GotoState('Chase');
    }
    
    //Chases the destination actor using direct movetoward if dest-actor is reachable and pathfinding if not
    state Chase
    {
    	//Gets the navmesh path to the dest-actor
    	function bool FindNavMeshPath()
    	{
    		// Clear cache and constraints (ignore recycling for the moment)
    		NavigationHandle.PathConstraintList = None;
    		NavigationHandle.PathGoalList = None;
    
    		//Create constraints
    		class'NavMeshPath_Toward'.static.TowardGoal( NavigationHandle, MoveTowardDestActor);
    		class'NavMeshGoal_At'.static.AtActor( NavigationHandle, MoveTowardDestActor);
    
    		//Find path
    		return NavigationHandle.FindPath();
    	}
    
    	event SeePlayer(Pawn SeenPlayer)
    	{
    		//Todo:処理を追加
    	}
    
    	event HearNoise(float Loudness, Actor NoiseMaker, optional Name NoiseType )
    	{
    		//Todo:処理を追加
    	}
    
    	function Rotator GetAdjustedAimFor( Weapon InWeapon, vector ProjStart )
    	{
    		//Todo:エイム誤差を追加
    		//(これがないと100%100中になってしまう)
    
    		return Rotation;
    	}
    
    	Begin:
    
    	//Check if the destination actor is within end of chase range
    	DestinationDistance = VSize( Pawn.location - MoveTowardDestActor.location);
    
    	if (DestinationDistance < StopDistance)
    		GotoState('Roaming');
    	else if (NavigationHandle.ActorReachable(MoveTowardDestActor))
    	{
    		FlushPersistentDebugLines();
    
    		//The dest-actor is reachable so move towards him
    		MoveToward( MoveTowardDestActor, MoveTowardFocusActor, 100);
    	}
    	else if (FindNavMeshPath())
    	{
    		//The dest-actor is not reachable so use the navmesh path move towards him
    		NavigationHandle.SetFinalDestination(MoveTowardDestActor.Location);
    		FlushPersistentDebugLines();
    //		NavigationHandle.DrawPathCache(, true);//パスを画面に描画する(デバッグ用)
    
    		if (NavigationHandle.GetNextMoveLocation(TempDest, Pawn.GetCollisionRadius()))
    		{
    //			DrawDebugLine(Pawn.Location, TempDest, 0, 255, 0, true);//パスの線を画面に描画する(デバッグ用)
    			MoveTo(TempDest, MoveTowardDestActor);
    		}
    	}
    	else
    	{
    		//We can't get to the dest-actor so just go back to begin Idle.
    		GotoState('Roaming');
    	}
    	goto 'Begin';
    
    }
    
    defaultproperties
    {
    	StopDistance=250
    
    	NavigationHandleClass=class'NavigationHandle'
    }
    ただし、上記コードでは複数キャラを同時にMoveTowardさせた場合、
    私の環境ではうまくいかないことがあります。
    どの辺が問題なのかは分かっていませんが、その辺はご了承下さいませ。


    NavigationMeshを使用すると、UTBotのコードのままではMoveToward中には攻撃 しなくなります。
    なので、その辺りの攻撃処理もSeePlayer、HearNoiseなどで組み込んでおく必要があります 。
    また、向いている方向を指定している場合、攻撃が100発100中になってしまうので、
    適当にRotationを調整する命令も必要かと思います。

    他にもいろいろ機能を含めて実装するとなると、
    私のコードでは最終的に500lineぐらいの量を書く必要がありました。




    後は、注意が必要なのは、NavMeshを使うと、そのBotはPathNode探索はしなくなるようです 。
    なので、NavMeshとPathNode探索の両方の機能を使う場合、
    DefaultGame.iniに以下の命令を追加すればできます。

    Code:
    [UnrealEd.EditorEngine]
    bBuildReachSpecs=True

    参考にして下さいませ。


 

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Copyright ©2009-2011 Epic Games, Inc. All Rights Reserved.
Digital Point modules: Sphinx-based search vBulletin skin by CompletevB.com.