基础游戏快速入门

  • 基础游戏快速入门

    • 概述
    • 项目创建
      • UnrealScript 项目
      • 内容目录
    • 游戏可玩性类
      • 相机
      • PlayerController
      • Pawn
      • HUD
      • Gametype
    • 编译
    • 测试

概述


如果您是个新手,那么新建一个游戏项目并运行,这个过程对您来说是极为困难的。您可能会苦于不知从何处入手,到哪里应该做些什么操作等等。设计该文档的目的就是要快速突出强调新建游戏需要掌握的重要内容和关键问题。在阅读的过程中,您将会经历创建一个非常基础的游戏骨架,然后可以对其进行自定义,使其适用于任何类型的游戏。

项目创建


在开始新建一个游戏时首先要完成的事情是,创建各种可以用来保存您的游戏脚本和内容的项目目录。需要注意的是虚幻引擎 3 的设计是每次只能创建一个单独的项目。如果您需要创建多个项目,那么最好使用多个安装,因为在一个单独的安装中转换多个项目非常麻烦令人费解。

UnrealScript 项目

任何新游戏项目最终都会需要使用 UnrealScript 创建自定义类来构成游戏的游戏性。添加新 UnrealScripts 需要创建一个自定义 UnrealScript 项目,以便保存脚本,这些脚本已经被编译为一个新的 UnrealScript 软件包(.u 文件)。

要创建一个 UnrealScript 项目,首先要在您的虚幻安装中找到 ..\Development\Src 目录。在目录内部,使用您希望命名给项目的名称创建一个新文件夹。通常,它是您的游戏名称的缩写版本,后面紧接着 "Game"。例如,Unreal Tournament 游戏使用的是 UTGame 。

在这里创建的示例游戏中,UnrealScript 项目将会被命名为 UDNGame 。创建完成后,新文件夹位于 ..\Developement\Src 目录中:

在这个 UDNGame 文件夹中,创建一个新的文件夹,名为 Classes 。这是真正要包含项目脚本的文件夹。

要了解设置自定义 UnrealScript 项目的详细指南,请参阅自定义 UnrealScript 项目页面。

内容目录

没有内容,游戏就不能称之为游戏。您必须在屏幕上显示视觉元素,播放音频等等,当然还需要使用地图将所有内容组合在一起,然后将这些内容显示给玩家。通常,内容存储在软件包中(地图也是一个软件包),软件包本身存储在虚幻安装的 ..\[GameName]\Content 目录中。通常在可以组织软件包和地图的 Content 目录中提供了诸如 Characters 、 Environments 、 Maps 和 Sounds 这样的文件夹等等。

如果使用的是 UDK,示例内容中都包含这些子文件夹。您可以轻而易举地将您的游戏自定义内容软件包和地图保存在这些文件夹中,一切都会正常运作。然而,如果您希望将您的自定义内容与其他内容区分开,那么您只需在 Content 目录中创建一个新的文件夹,可以用您的游戏名称命名,然后将您的软件包保存在这个文件夹中。您甚至可以在这个文件夹中添加多个文件夹,使用与 Content 目录中相似的方式组织软件包。

游戏可玩性类


我们的示例游戏框架几乎全部是由一些在 UnrealScript 中创建并保存在我们的自定义 UnrealScript 项目中的重要游戏可玩性类组成。使用这些类的目的是制作一个可行但是通用或普通的游戏性体验。我们目前创建的不是最终游戏。现在的目的是创建一个项目,您可以将其作为创建您的游戏的基础。

相机

所有游戏的一个最基本内容是玩家观看这个世界的方式。在虚幻中,玩家视点的位置和方位由 PlayerController 类的 GetPlayerViewPoint() 函数控制。默认情况下,如果提供了玩家相机对象,可以使用它处理计算结果。它可以使用下面两个方法中的其中一种计算位置和方位:

  • 通过 UpdateCamera() 函数调用 Pawn 中的 CalcCamera() 。
  • 直接在 UpdateCamera() 函数中计算视角。

基础示例游戏将会使用第三人称视角。如上所述,可以通过使用 CalcCamera() 函数在 Pawn 类中进行这项操作,但是将相机逻辑规则封装在一个单独类中的设计理念以及使用一个提供所有相机功能(例如后期处理和相机动画)访问权限的 camera 类的实际情况,这个示例将会使用一个自定义 Camera 类控制定位相机。尽管该示例使用的是第三人称视角,但是通过更改计算相机位置和旋转的逻辑规则可以轻松地实现任何其他相机类型。

相机技术指南中提供了相机的详细说明以及其他视角实现的示例。

class UDNPlayerCamera extends Camera;var Vector CamOffset;
var float CameraZOffset;
var float CameraScale, CurrentCameraScale; /** 默认相机距离的乘数 */
var float CameraScaleMin, CameraScaleMax;function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime)
{local vector      HitLocation, HitNormal;local CameraActor   CamActor;local Pawn          TPawn;local vector CamStart, CamDirX, CamDirY, CamDirZ, CurrentCamOffset;local float DesiredCameraZOffset;// 不要在插值的过程中更新输出观察目标if( PendingViewTarget.Target != None && OutVT == ViewTarget && BlendParams.bLockOutgoing ){return;}// 视图目标上的默认 FOVOutVT.POV.FOV = DefaultFOV;// 浏览相机 actor。CamActor = CameraActor(OutVT.Target);if( CamActor != None ){CamActor.GetCameraView(DeltaTime, OutVT.POV);// 通过 CameraActor 获取长宽比。bConstrainAspectRatio   = bConstrainAspectRatio || CamActor.bConstrainAspectRatio;OutVT.AspectRatio      = CamActor.AspectRatio;// 查看 CameraActor 是否需要覆盖使用的 PostProcess 设置。CamOverridePostProcessAlpha = CamActor.CamOverridePostProcessAlpha;CamPostProcessSettings = CamActor.CamOverridePostProcess;}else{TPawn = Pawn(OutVT.Target);// 为 Pawn Viewtarget 提供了一个指定相机位置的机会。// 如果 Pawn 没有覆盖相机视图,那么我们将会继续使用我们自己的默认设置if( TPawn == None || !TPawn.CalcCamera(DeltaTime, OutVT.POV.Location, OutVT.POV.Rotation, OutVT.POV.FOV) ){/*************************************** Calculate third-person perspective* Borrowed from UTPawn implementation**************************************/OutVT.POV.Rotation = PCOwner.Rotation;CamStart = TPawn.Location;CurrentCamOffset = CamOffset;DesiredCameraZOffset = 1.2 * TPawn.GetCollisionHeight() + TPawn.Mesh.Translation.Z;CameraZOffset = (DeltaTime < 0.2) ? DesiredCameraZOffset * 5 * DeltaTime + (1 - 5*DeltaTime) * CameraZOffset : DesiredCameraZOffset;CamStart.Z += CameraZOffset;GetAxes(OutVT.POV.Rotation, CamDirX, CamDirY, CamDirZ);CamDirX *= CurrentCameraScale;TPawn.FindSpot(Tpawn.GetCollisionExtent(),CamStart);if (CurrentCameraScale < CameraScale){CurrentCameraScale = FMin(CameraScale, CurrentCameraScale + 5 * FMax(CameraScale - CurrentCameraScale, 0.3)*DeltaTime);}else if (CurrentCameraScale > CameraScale){CurrentCameraScale = FMax(CameraScale, CurrentCameraScale - 5 * FMax(CameraScale - CurrentCameraScale, 0.3)*DeltaTime);}if (CamDirX.Z > TPawn.GetCollisionHeight()){CamDirX *= square(cos(OutVT.POV.Rotation.Pitch * 0.0000958738)); // 0.0000958738 = 2*PI/65536}OutVT.POV.Location = CamStart - CamDirX*CurrentCamOffset.X + CurrentCamOffset.Y*CamDirY + CurrentCamOffset.Z*CamDirZ;if (Trace(HitLocation, HitNormal, OutVT.POV.Location, CamStart, false, vect(12,12,12)) != None){OutVT.POV.Location = HitLocation;}}}// 最后应用相机修改器(例如,视图浮动)ApplyCameraModifiers(DeltaTime, OutVT.POV);
}defaultproperties
{CamOffset=(X=12.0,Y=0.0,Z=-13.0)CurrentCameraScale=1.0CameraScale=9.0CameraScaleMin=3.0CameraScaleMax=40.0
}

PlayerController

所有游戏的另一个基础内容是如何处理玩家的输入信息以及如何对其进行转换控制游戏,直接控制画面上的主要角色,还是使用点击界面控制游戏,或者是任何其他控制游戏的方法。显而易见,负责确定玩家控制游戏的方式的类是 PlayerController 类。

基础 PlayerController 执行函数足以使玩家可以到处跑,因为它们可以处理玩家输入信息并将其转化为运动。在这个示例中使用的自定义 PlayerController 类只是用来对我们在上面创建的自定义 Camera 类进行赋值。当然,在您不断丰富您的游戏内容过程中,您一定会需要修改这个类,以便添加您的游戏特定执行函数需要的逻辑规则。

角色技术指南详细说明了 PlayerController 类以及如何定制它使其适用于新的游戏类型。

class UDNPlayerController extends GamePlayerController;defaultproperties
{CameraClass=class'UDNGame.UDNPlayerCamera'
}

Pawn

虽然 PlayerController 类可以确定如何使用玩家输入信息控制游戏,在这个示例中将会涉及直接控制角色,角色的视觉表现形式和决定他与物理世界之间的交互的逻辑规则都封装在 Pawn 类中。在这个示例中的自定义Pawn 类将不会为与环境之间的交互添加任何特殊逻辑规则,但是它将会负责设置角色的视觉表现形式。也就是说它需要设置一个骨架网格物体、动画和物理资源来显示游戏中的角色。

角色技术指南详细说明了 Pawn 类以及它与 PlayerController 类合作的工作原理。

class UDNPawn extends Pawn;var DynamicLightEnvironmentComponent LightEnvironment;defaultproperties
{WalkingPct=+0.4CrouchedPct=+0.4BaseEyeHeight=38.0EyeHeight=38.0GroundSpeed=440.0AirSpeed=440.0WaterSpeed=220.0AccelRate=2048.0JumpZ=322.0CrouchHeight=29.0CrouchRadius=21.0WalkableFloorZ=0.78Components.Remove(Sprite)Begin Object class="DynamicLightEnvironmentComponent" Name=MyLightEnvironmentbSynthesizeSHLight=TRUEbIsCharacterLightEnvironment=TRUEbUseBooleanEnvironmentShadowing=FALSEEnd ObjectComponents.Add(MyLightEnvironment)LightEnvironment=MyLightEnvironmentBegin Object class="SkeletalMeshComponent" Name=WPawnSkeletalMeshComponent//您的网格物体属性SkeletalMesh=SkeletalMesh'CH_LIAM_Cathode.Mesh.SK_CH_LIAM_Cathode'AnimTreeTemplate=AnimTree'CH_AnimHuman_Tree.AT_CH_Human'PhysicsAsset=PhysicsAsset'CH_AnimCorrupt.Mesh.SK_CH_Corrupt_Male_Physics'AnimSets(0)=AnimSet'CH_AnimHuman.Anims.K_AnimHuman_BaseMale'Translation=(Z=8.0)Scale=1.075//通用网格物体属性bCacheAnimSequenceNodes=FALSEAlwaysLoadOnClient=trueAlwaysLoadOnServer=truebOwnerNoSee=falseCastShadow=trueBlockRigidBody=TRUEbUpdateSkelWhenNotRendered=falsebIgnoreControllersWhenNotRendered=TRUEbUpdateKinematicBonesFromAnimation=truebCastDynamicShadow=trueRBChannel=RBCC_Untitled3RBCollideWithChannels=(Untitled3=true)LightEnvironment=MyLightEnvironmentbOverrideAttachmentOwnerVisibility=truebAcceptsDynamicDecals=FALSEbHasPhysicsAssetInstance=trueTickGroup=TG_PreAsyncWorkMinDistFactorForKinematicUpdate=0.2bChartDistanceFactor=trueRBDominanceGroup=20bUseOnePassLightingOnTranslucency=TRUEbPerBoneMotionBlur=trueEnd ObjectMesh=WPawnSkeletalMeshComponentComponents.Add(WPawnSkeletalMeshComponent)Begin Object Name=CollisionCylinderCollisionRadius=+0021.000000CollisionHeight=+0044.000000End ObjectCylinderComponent=CollisionCylinder
}

HUD

HUD 类主要负责向玩家显示游戏的相关信息。信息以及显示方式完全由游戏指定。因为这样,这个示例执行函数将只需提供一个空白的石板,您可以通过它创建您自己的自定义 HUD,可以使用 Canvas 对象或Scaleform GFx。

HUD 技术指南提供了关于在虚幻引擎 3 中使用 Canvas 对象或 Scaleform GFx 集成创建抬头显示器的详细信息。

class UDNHUD extends MobileHUD;defaultproperties
{
}

Gametype

游戏类型是游戏的核心内容。它可以决定游戏的规则和游戏进行或结束的条件。说清楚一点就是它完全取决于游戏。游戏类型还可以负责通知引擎哪些类可以用作 PlayerControllers 、 Pawns 和 HUD 等等。游戏类型的示例执行函数只会在 defaultproperties 中指定这些类,然后剩下的执行函数由您决定。

游戏类型技术指南中进一步阐述了游戏类型的概念,而且会深入探讨定制您的自定义游戏类型这部分内容。

class UDNGame extends FrameworkGame;defaultproperties
{PlayerControllerClass=class'UDNGame.UDNPlayerController'DefaultPawnClass=class'UDNGame.UDNPawn'HUDType=class'UDNGame.UDNHUD'bDelayedStart=false
}

编译


 要点: 您必须关闭编辑器才能编译脚本。如果编辑器正处于打开状态,那么请马上将其关闭。

为了将 UnrealScript 项目编译为一个可以使游戏性框架在游戏中使用的软件包,引擎需要多加注意这个项目。以上操作可以通过将项目添加到 DefaultEngine.ini 文件的 [UnrealEd.EditorEngine] 部分中的 EditPackages数组完成。添加 UDNGame 项目的语法如下所示:

+EditPackages=UDNGame

如果您使用的是 UDK,那么您将会注意到在这部分还包含一些其他项目,即 UTGame 和 UTGameContent 项目。是否要这样做要根据您制作的游戏类型决定。现在,最终的 [UnrealEd.EditorEngine] 部分应该如下所示:

[UnrealEd.EditorEngine]
+EditPackages=UTGame
+EditPackages=UTGameContent
+EditPackages=UDNGame

这里不乏强行编译脚本的方法。您可以使用下面的方法:

  • 运行 Make 命令行开关
  • 编译 UnrealFrontend
  • 运行游戏或编辑器

上面任意一种方法都可以编译脚本。但是,我们将只需运行编辑器就可以自动编译脚本。运行编辑器,然后您应该会看到下面的对话框:

选择“是”,然后会出现一个控制台窗口,其中显示的是编译过程状态。

您应该会看到

Success - 0 error(s), 0 warning(s),前提是编译成功。如果出现错误,那么错误消息会通知您发生错误的文件名和行编号,这样可以使查找和解决错误的过程变得简单。

发生错误的文件名应该会在上面的图片中标明。行编号会显示在文件名后面的括号 () 中。同时还会显示错误的相关描述。这个错误将通知我们等号 (=) 后面的项无效。这可能是由于名称拼写错误、变量未声明等等原因造成的。解决这个错误,然后使用与上面相同的程序再次进行编译,最后编译才会成功。

测试


为了测试在这个示例中创建的游戏框架,您可以在下面两种方法中任选一种:

  • 在虚幻编辑器中,在您的测试地图 WorldInfo 属性中将 UDNGame 设置为 PIE 游戏类型。
  • 在 DefaultGame.ini 配置文件中,将 UDNGame 设置为引擎的默认游戏类型。

地图游戏类型

要将 UDNGame 游戏类型设置为供在虚幻编辑器或引擎中游戏时特殊地图使用的 Gametype,请从 View(视图) 菜单中选择 World Properties(世界属性) 。接下来将会显示 WorldInfo 属性窗口。

展开 Game Type 类别,然后找到 Gametype for PIE 属性。在可用的游戏类型列表中选择 UDNGame 。

现在,您可以在编辑器中使用 Play in PIE 或 Play from here 功能运行地图,与此同时它应该使用自定义游戏类型,通过完全可以控制的角色显示第三人称视角。

您还可以将 Default Game Type(默认游戏类型) 属性设置为 UDNGame 强制这个地图使用自定义游戏类型,无论 .ini 文件(下面将会进行讲解)中的默认设置是什么。

默认游戏类型

注意: 在编辑 .ini 文件时应该关闭编辑器。

要将 UDNGame 游戏类型设置为引擎的默认游戏类型,请在您的虚幻安装的 ..\[GameName]\Config 目录中打开 Defaultgame.ini 配置文件。这样在地图 URL 中没有指定游戏类型或地图没有游戏类型前缀的情况下,在所有的地图中都会使用这个游戏类型。在 [Engine.GameInfo] 项中,要将 UDNGame 游戏类型赋给三个属性。同时还要将 PlayerController 类赋给属性。最后,这里有一些额外的代码行,它们可以设置那些只适用于将会被删除的 UT3 示例游戏的游戏类型前缀。

最后的 [Engine.GameInfo] 项如下所示:

[Engine.GameInfo]
DefaultGame=UDNGame.UDNGame
DefaultServerGame=UDNGame.UDNGame
PlayerControllerClassName=UDNGame.UDNPlayerController
GameDifficulty=+1.0
MaxPlayers=32
DefaultGameType="UDNGame.UDNGame"

现在,在引擎中运行或者在虚幻编辑器中使用 Play on PC(在计算机上游戏) 功能的所有地图使用的应该都是自定义游戏类型 - 通过完全可以控制的角色显示第三人称视角(除非被 World(世界)属性中被地图 URL 或 Default Game Type(默认游戏类型) 覆盖。)

转载于:https://www.cnblogs.com/wodehao0808/p/7256561.html

(官网)虚幻3--基础游戏快速入门相关推荐

  1. python编程基础语法-Python编程基础语法快速入门

    1. 课程咨询加老师助理微信:助理1微信: chenjinglei88 ,助理2微信: omf6757 2. 决定购买并想得到陈敬雷老师亲自指导(课程或自己项目难题均可)加老师微信: chenjing ...

  2. 零基础编程入门python视频-Python编程零基础小白快速入门完整全系列精品课

    1. 课程咨询加老师助理微信:助理1微信: chenjinglei88 ,助理2微信: omf6757 2. 决定购买并想得到陈敬雷老师亲自指导(课程或自己项目难题均可)加老师微信: chenjing ...

  3. python编程语法教程-Python编程基础语法快速入门

    1. 课程咨询加老师助理微信:助理1微信: chenjinglei88 ,助理2微信: omf6757 2. 决定购买并想得到陈敬雷老师亲自指导(课程或自己项目难题均可)加老师微信: chenjing ...

  4. 想成为淘宝美工需要学什么?零基础怎么快速入门?

    本文由:"学设计上兔课网"原创,图片素材来自网络,仅供学习分享 想成为淘宝美工需要学什么?零基础怎么快速入门?最近就有不少小伙伴私信小编,大多是问淘宝美工需要掌握哪些知识?新手要如 ...

  5. 【Python基础】快速入门Python(讲解、习题)

    0.导语 Python是一种跨平台的计算机程序设计语言.是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的.大型项目的 ...

  6. thinkph 上花院 生多行mysql_PHP_ThinkPHP3.1基础知识快速入门,在当今众多的MVC框架中,ThinkPH - phpStudy...

    ThinkPHP3.1基础知识快速入门 在当今众多的MVC框架中,ThinkPHP是一个快速.简单的基于MVC和面向对象的轻量级PHP开发框架,其遵循Apache2开源协议发布,自从诞生以来一直秉承简 ...

  7. Linux 基础命令快速入门

    Linux 基础命令快速入门: 目录 Linux 基础命令快速入门: 1.vim 命令记录 2.开机.重启和用户登录注销 3.用户管理 4.用户组相关 5.用户信息文件 6.实用指令 7.帮助指令 8 ...

  8. 物联卡查询流量_电信物联卡官网是多少?如何快速查询流量信息?

    原标题:电信物联卡官网是多少?如何快速查询流量信息? 高速率设备的使用场景需要用到5G,中速率LET-Cat1应用范围更广,而低速率则要靠窄带物联网NB-IOT去维护了.这三种网络制式全都与物联网息息 ...

  9. 「 Unity 3D」是什么?零基础如何快速入门?

    一句话说明下Unity是什么,Unity是一个开发游戏,主要用于手机游戏开发的引擎,什么是引擎,引擎就是工具的意思. 零基础想自学从哪开始?一般我们学习unity3d游戏开发是要先从C++开始学起,如 ...

  10. 学神经网络需要什么基础,神经网络快速入门

    有哪些 Python 经典书籍 . <深度学习入门>([日]斋藤康毅)电子书网盘下载免费在线阅读资源链接:链接:?pwd=bhct提取码:bhct 书名:深度学习入门作者:[日]斋藤康毅译 ...

最新文章

  1. Grafana 7.0 发布:改进的界面、新的插件平台和可视化等
  2. MYSQL编译参数详解
  3. nodeJs多线程 -- 学习记录
  4. Netty 高性能特性
  5. .net core学习
  6. jQuery EasyUI API 中文文档 - 组合表格(ComboGrid)
  7. 李迟2022年1月知识总结
  8. Python列表常用函数使用详解(内附详细案例)
  9. VS2019 OpenCV安装与配置教程
  10. 怎么读取cf卡id_simotion读写CF卡,保存/读取变量
  11. 清明节到五一的加班感触
  12. ICML 2020论文笔记:地表最强文本摘要生成模型PEGASUS(天马)
  13. Error in driver during machine creation: Machine didn‘t return an IP after 120 seconds, aborting
  14. 3D LUT调色:单反如何实现电影级调色。
  15. recover-quack-data-structure
  16. 手机开热点如何查看接入热点的所有ip
  17. 拒绝成为肉鸡 教你几招让黑客永远抓不到你
  18. 第三节 数据通信基础
  19. 郎平,你回来会毁了中国女排!
  20. android跳转小程序 bad_param

热门文章

  1. Doom3证明了“保持简单”有效。
  2. linux各个版本简介 (未完待续)
  3. mediasoup 管道通信类UnixStreamSocket分析
  4. 十问数据库:问来路,问现在,问未来
  5. 电脑磁盘数据错误(循环冗余检查)的原因以及解决办法
  6. HSSFWorkbook 锁定部分单元格,或者锁定一个单元格
  7. 统一的账号密码管理系统-信息安全课程设计
  8. AR、VR、MR、CR的意思
  9. vue获取地址栏参数值
  10. 跟谁学 英语口语20090927疑问句