标签:概述 pat 环境 epo goto corrupt add 解决 类型
使用2011 年 6 月的UDK版本进行了最后测试
虚幻引擎中的角色由两部分组成: Pawn和Controller。Pawn是世界中的玩家或非玩家控制角色(NPC)的物理表示。它不知道角色由玩家控制和由AI控制之间的区别。Pawn具有网格物体、碰撞以及使它们处理角色和世界进行物理交互所涉及的所有功能。它们也包含了利用其它玩家或它们周围的环境的功能、产生声音、播放动画以及武器功能比如持有 并/或 开火武器(尽管武器开火过程从技术上讲是从controller (控制器类开始的))。
任何时刻每个Pawn都可以有一个单独的Controller(控制器)。Controller,正如它的名字所暗示的,它负责告诉Pawn做什么及如何表现。它实质上是Pawn后面的大脑。Controllers具有不同的形式,比如PlayerControllers和AIControllers,但是它们的主要目的是从世界中的玩家或其它刺激物接受输入,处理那个输入,并展现相应的行为。这通常会导致向Pawn传送一个命令或一系列命令。
在正常情况下,GameInfo 类将会处理在玩家登陆时为所有玩家创建Controller,然后比赛开始时为每个Controller(控制器)创建一个Pawn并把它分配给那个Controller。这最后一步处理称为 possession(占有) ,因为现在Pawn被Controller所占有并且在它的控制之下。完整的玩家创建过程在以下时序图中进行了表示。
当然,不一定全是这样的情况。您的游戏或许由在世界中手动地到处放置的NPC组成,而不是动态地创建NPC。这些NPC大多数是基类Pawn的子类,Pawn类将处理它们的Controller的创建,并把那些NPC分配给那个Controller。
Controller(控制器)是一个非物理的Actor,它附加到Pawn上来控制Pawn的动作。它使用从玩家或它的周围环境接收的信息,并使用那个信息来使得玩家产生相应的行为。Controller负责运动,无论它是对玩家输入做出反应、遍历导航系统产生的路径还是基于各种事件执行一些动作。当Pawn在游戏中运动时,Pawn那样运动是因为Controller告诉它那样做。Controller接收为它们控制的Pawn产生很多事件通知,比如查看或监听敌人。Controller使用这些事件来实现Pawn对相应事件做出反应的适当的行为。
Controller的两个主要子类是 PlayerController
和 AIController
。当创建您的新角色时,您将需要根据您要创建的角色类型来继承这些类其中的一个,或者它们的其中一个子类。
Controller,特别是AIControllers,大量地使用了States(状态),它允许控制器重载同一个类中函数,并让它们根据Controller的当前状态执行不同的动作。States(状态)也提供了使用latent代码和latent函数的功能,比如AI角色使用其导航世界的运动函数。
Controller 基类包含了关于Pawn控制的一般性的函数和事件,它没有必要特定地针对Pawn是玩家控制的Pawn 还是AI控制的Pawn。
这些函数涉及到了占有及不占有Pawns。
这些函数是和拾取物、武器及其它和武器相关的功能有关。
请参照武器技术指南页面获得关于武器的更多信息。
这些函数和使得被占用的Pawn在世界上到处移动有关;这意味着将给Pawn一个命令让它到达特定的目标,并且运动是动态的不需要每次tick都进行更新。
这个部分的函数是于视口和Controller及它的Pawn瞄准有关的函数。
PlayerController及它的子类实现了从人类玩家接受输入并把那个输入处理成为您在游戏中可以看到的动作的功能。在很大程度上,这意味着PlayerController 处理这样的动作,比如移动Pawn、控制相机(通过Pawn的方式)、及根据玩家已经按下的按钮或按键切换武器或是武器开火。以下是PlayerController 类的一些主要函数,并逐个对它们进行了解释。
这些函数从本质上是具有通用性的,它们不属于特定的类别。
这些函数是关于玩家的输入和运动的。
AIController及它的子类实现了观察Pawn的周围环境,并根据那个信息做出智能决策的功能。它从本质上使用了它自己自包含的决策循环来不断地在决策过程中进行循环,并基于这些决策执行适当的动作。下面解释了AIController 类的主函数。
当处理 AI控制的敌人时,决策过程显然是非常重要的。如果没有东西处理信息并根据那些信息决定做什么或怎么表现行为,那么您的NPC角色只是雕像而已,没有任何用途。显然,关于如何创建好的AI的讨论已经超出了本文档的范围,但是您仍然需要知道如何及在哪里把您的AI代码添加到AIController 类结构中。以下的函数是在决策过程中的主要函数。
注意: 这些函数是在UDKBot 类中实现的,而不是在AIController 基类中。您需要扩展UDKBot或UTBot来使用这些函数。
Pawn类是Unreal中的所有玩家、角色、怪物和其它类型敌人的基类。正如之前所提到的,它负责玩家或AI同世界间的物理交互。当创建一个自定义的Pawn类时,您首先要知道的是已经存在了哪些功能,以便您可以合理地决定通过重载哪个现有函数来实现您的新角色要需要的行为,同时节约必要的时间,使您有更充足的时间来添加那些全新的功能。为了帮助大家解决这个问题,下面解释了Pawn类的重要函数,把它们按照功能进行了分类。
这些函数包含了Pawn和Controller进行交互、Controller占有Pawn和不占有Pawn相关的功能。
武器库的大部分功能是由PostBeginPlay()事件中产生的Pawn的InventoryManager(武器库管理器)处理的。虽然,Pawn确实处理了某些功能并且通过使用几个特定的武器库函数把命令传递给InventoryManager(武器库管理器)。但是Pawn类也包含了几个关于武器和这些武器开火相关的函数。以下列出了这些函数。
Pawn类包含了治愈及从武器和其它环境受到伤害的功能。和伤害及生命值相关的函数如下所示。
Pawn使用骨架网格物体作为它们的主要可视化组件。尽管动作(比如运动)的大量动画播放都是由分配给Pawn的AnimTree 进行处理的,但是它们确实有一些播放内置动画的有限功能。这样的大多数函数都是以帮助函数的形式出现的,它会把命令传递给Pawn的骨架网格物体组件。以下解释了这些函数。
注意: Mesh变量引用了Pawn的SkeletalMeshComponent,它包含了播放单独的动画序列相关的功能。请记住使用这个功能时要求在Pawn的AnimTree中的唯一的动画节点是AnimNodeSequence 节点。这意味着您将失去AnimTree 系统的许多高级功能,比如混合;但是如果需要,这个功能是存在的。
当Pawn是当前的视图目标以及为玩家或NPC设置当前的目标时,这些函数包含了控制玩家的相机位置及方位的功能。
为了示范使用自定义网格物体添加一个新的玩家控制的角色,我们将会使用3个新类: Pawn、PlayerController和GameInfo。这个示例的目标是展示创建由玩家控制的角色的基本知识。一旦您具有了基本的实现,您所需要做的就是简单地使用已有的东西或添加您自己的自定义功能来创建一个适合您游戏的新的角色。
在这个示例中,我们对新的Pawn类添加了一点新功能。我们决定给它设置一个内置的生命值再生功能。在Tick()函数中,有时会给Pawn的当前Health (生命值)添加指定量的生命值。为了完成这个功能,需要添加一些类变量,然后重载Tick函数,添加生命值再生功能。
UDNPawn.uc
class UDNPawn extends UTPawn;<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
var float ElapsedRegenTime;<?xml:namespace prefix = o />
var float RegenAmount;<?xml:namespace prefix = o />
var float RegenTime;<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
event Tick(float DeltaTime)<?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
//计算已经过去的时间<?xml:namespace prefix = o />
ElapsedRegenTime += DeltaTime;<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
//已经过去了足够的时间量了吗?<?xml:namespace prefix = o />
if(ElapsedRegenTime >= RegenTime)<?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
//治愈Pawn并充值已经过去的时间量<?xml:namespace prefix = o />
HealDamage(RegenAmount, Controller, class‘DamageType‘);<?xml:namespace prefix = o />
ElapsedRegenTime = 0.0f;<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
defaultproperties<?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
//为再生属性设置默认值<?xml:namespace prefix = o />
RegenAmount=2<?xml:namespace prefix = o />
RegenTime=1<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
新的PlayerController 类是UTPlayerController 类的子类。它简单地添加了新的类成员变量来存放用作为玩家的角色类,然后通过使用现有的ServerSetCharacterClass()函数把它设置为玩家角色。
UDNPlayerController.uc
class UDNPlayerController extends UTPlayerController;<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
var class<UTFamilyInfo> CharacterClass;<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
simulated event PostBeginPlay()<?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
super.PostBeginPlay();<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
SetupPlayerCharacter();<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
/** 设置玩家的角色信息类&执行任何其它的初始化*/<?xml:namespace prefix = o />
function SetupPlayerCharacter()<?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
//把角色设置为我们的自定义角色<?xml:namespace prefix = o />
ServerSetCharacterClass(CharacterClass);<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
defaultproperties<?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
//把您的自定义角色指向UTFamilyInfo 类<?xml:namespace prefix = o />
CharacterClass=class‘UTFamilyInfo_Liandri_Male‘<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
为了满足将要使用的新的Pawn和PlayerController 类,我们需要一种新的游戏类型。当您使用UDK创建您自己的游戏时,您大部分时候都会使用一个自定义的游戏类型,以便您仅需要想那个类中添加一些适当的默认属性即可,而不必创建一个新类。这个示例中,创建了新的游戏类型,并简单地设置DefaultPawnClass和PlayerControllerClass属性指向新的Pawn和PlayerController 类。
UDNGame.uc
class UDNGame extends UTDeathMatch;<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
defaultproperties<?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
//指向您的自定义Pawn类<?xml:namespace prefix = o />
DefaultPawnClass=class‘UDNPawn‘<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
//指向您自定义的PlayerController类 <?xml:namespace prefix = o />
PlayerControllerClass=class‘UDNPlayerController‘<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
现在,如果我们使用这个新的游戏类型运行一张地图,当玩家受到伤害时它应该可以自动复原,并且使用自定义的角色。
为了演示简单的AI控制的Pawn,需要创建一个新的 Pawn和Controller类。Pawn 类在虚幻编辑器中是可以放置的,并且它将会处理设置网格物体、动画、物理属性以及设置要使用的Controller类的工作。Controller将负责使NPC在世界中到处闲逛,每当NPC到达当前的目的地时再给它选择一个随机目的地。
Pawn类是非常简单的。它添加了一些属性,但是这些属性仅是现有属性的复制,这样可以使得设计人员更加容易使用。使用一个SkeletalMeshComponent(骨架网格物体组件)来设置所有的可见属性,比如网格物体、AnimTree、AnimSets、PhysicsAsset等。在默认属性块汇总设置这些属性的默认值。类用于设置控制NPC所使用的Controller 类。PostBeginPlay()函数用于设置现有的ControllerClass 变量给新的NPCController变量。最后,重载 SetCharacterClassFromInfo() 函数,它没有做任何事情,因为这个NPC实现不需要它。
类的完整代码显示在这里:
UDNPawn_NPC.uc
class UDNPawn_NPC extends UTPawn<?xml:namespace prefix = o />
placeable;<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
var(NPC) SkeletalMeshComponent NPCMesh;<?xml:namespace prefix = o />
var(NPC) class<AIController> NPCController;<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
simulated event PostBeginPlay()<?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
if(NPCController != none)<?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
//为我们新的NPCController 类设置现有的ControllerClass <?xml:namespace prefix = o />
ControllerClass = NPCController;<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
Super.PostBeginPlay();<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
//重载该函数并且不做任何操作<?xml:namespace prefix = o />
simulated function SetCharacterClassFromInfo(class<UTFamilyInfo> Info)<?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
defaultproperties <?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
//设置默认的NPC网格物体<?xml:namespace prefix = o />
Begin Object class="SkeletalMeshComponent" Name=NPCMesh0<?xml:namespace prefix = o />
SkeletalMesh=SkeletalMesh‘CH_LIAM_Cathode.Mesh.SK_CH_LIAM_Cathode‘<?xml:namespace prefix = o />
PhysicsAsset=PhysicsAsset‘CH_AnimCorrupt.Mesh.SK_CH_Corrupt_Male_Physics‘<?xml:namespace prefix = o />
AnimSets(0)=AnimSet‘CH_AnimHuman.Anims.K_AnimHuman_BaseMale‘<?xml:namespace prefix = o />
AnimtreeTemplate=AnimTree‘CH_AnimHuman_Tree.AT_CH_Human‘<?xml:namespace prefix = o />
End Object<?xml:namespace prefix = o />
NPCMesh=NPCMesh0<?xml:namespace prefix = o />
Mesh=NPCMesh0<?xml:namespace prefix = o />
Components.Add(NPCMesh0)<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
//指向您的自定义AIController类 - 作为默认值<?xml:namespace prefix = o />
NPCController=class‘UDNBot‘<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
Controller类是关于最基本的导航实现的类。ExecuteWhatToDoNext()函数,它是主要的决策函数,我们重载了该函数使得可以持续地把Controller发送到Roaming(闲逛)状态。这个状态简单地检查目的地是否存在或者Pawn是否到达了当前的目的地,如果必要可以设置新的目的地,然后告诉Controller向那个目的地运动。最后,调用LatentWhatToDoNext()函数来时的在下一个tick(更新)时再次调用ExecuteWhatToDoNext()函数,从而可以再次重新启动所有的决策循环。
controller类的完整代码显示在这里:
UDNBot.uc
class UDNBot extends UTBot;<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
var Actor Destination;<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
protected event ExecuteWhatToDoNext()<?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
//跳转到roaming(闲逛)状态<?xml:namespace prefix = o />
GotoState(‘Roaming‘);<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
state Roaming<?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
Begin:<?xml:namespace prefix = o />
//如果我们刚刚开始或者我们已经到达了特定目的地<?xml:namespace prefix = o />
//随机地获取一个新的目的地<?xml:namespace prefix = o />
if(Destination == none || Pawn.ReachedDestination(Destination))<?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
Destination = FindRandomDest();<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
//找到一条到达目的地的路径,并移动到这个路径的下一个节点。<?xml:namespace prefix = o />
MoveToward(FindPathToward(Destination), FindPathToward(Destination));<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
//启动下一个决策循环<?xml:namespace prefix = o />
LatentWhatToDoNext();<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
<?xml:namespace prefix = o />
defaultproperties<?xml:namespace prefix = o />
{<?xml:namespace prefix = o />
}<?xml:namespace prefix = o />
您的新的NPC类别可以在Actor Classes(Actor 类别)中找到。可以使用搜索控件轻松地进行查找。
一旦在内容浏览器的Actor列表标签中选中了该actor,那么您现在就可以在游戏视口中右击来弹出关联菜单。在关联菜单中,选择菜单项 Add UDN_PawnNPC Here(在这里添加UDN_PawnNPC) 。
现在,该NPC就在世界中了。您可以使用PIE(在编辑器中播放)功能来测试游戏。
转载自:
http://www.cnblogs.com/Zephyroal/archive/2012/02/09/2343644.html
转载自:
http://blog.csdn.net/pizi0475/article/details/47323081
标签:概述 pat 环境 epo goto corrupt add 解决 类型
原文地址:http://www.cnblogs.com/wodehao0808/p/6105171.html