2019-10-29 15:34:26 m0_37251750 阅读数 228
  • 从这里开始虚幻4-第2辑-蓝图 v4.18

    本课程系列取名英译系列,是录制人员参考国外英文原版经典教程,结合中国人的习惯录制而成。希望能够给大家以帮助。从这里开始虚幻4系列教程,是Unreal的官方发布的入门教学,非常经典,是学习Unreal的佳入口。

    2158 人正在学习 去看看 杨石兴

参考简书链接和百度百科:<ahref=‘https://www.jianshu.com/p/3868a1896b42’>https://www.jianshu.com/p/3868a1896b42

1、什么是游戏引擎

       游戏引擎是指一些已编写好的可编辑电脑游戏系统或者一些交互式实时图像应用程序的核心组件。这些系统为游戏设计者提供各种编写游戏所需的各种工具,其目的在于让游戏设计者能容易和快速地做出游戏程式而不用由零开始。大部分都支持多种操作平台,如Linux、Mac OS X、微软Windows。游戏引擎包含以下系统:渲染引擎(即“渲染器”,含二维图像引擎和三维图像引擎)、物理引擎、碰撞检测系统、音效、脚本引擎、电脑动画、人工智能、网络引擎以及场景管理。

2、什么是虚幻Unreal引擎

       UE(Unreal Engine)是目前世界最知名授权最广的顶尖游戏引擎,占有全球商用游戏引擎80%的市场份额。自1998年正式诞生至今,经过不断的发展,虚幻引擎已经成为整个游戏界–运用范围最广,整体运用程度最高,次世代画面标准最高的一款游戏引擎。 UE4是美国Epic游戏公司研发的一款3A级次时代游戏引擎。它的前身就是大名鼎鼎的虚幻3(免费版称为UDK),许多我们耳熟能详的游戏大作,都是基于这款虚幻3引擎诞生的,例如:剑灵、鬼泣5、质量效应、战争机器、爱丽丝疯狂回归等等。其渲染效果强大以及采用pbr物理材质系统,所以它的实时渲染的效果做好了,可以达到类似[Vray]静帧的效果,成为开发者最喜爱的引擎之一。

3、什么是Unity引擎

       Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。Unity类似于Director,Blender game engine, Virtools 或 Torque Game Builder等利用交互的图型化开发环境为首要方式的软件。其编辑器可运行在Windows、Linux(目前仅支持Ubuntu和Centos发行版)、Mac OS X下,可发布游戏至Windows、Mac、Wii、iPhone、WebGL(需要HTML5)、Windows phone 8和Android平台。也可以利用Unity web player插件发布网页游戏,支持Mac和Windows的网页浏览。它的网页播放器也被Mac 所支持。
       2012年11月15日,Unity Technologies公司正式推出Unity 4.0版本,新加入对于DriectX 11的支持和Mecanim动画工具,以及为用户提供Linux及Adobe Flash Player的部署预览功能。目前最新版本为Unity2018.3。Unity是免费的,官方为Unity Pro和Unity iOS Pro提供30天全功能试用期。可以使用C#快速开发。

4、UE4优势

UE4不仅涉及主机游戏、PC游戏、手游等游戏方面,还涉及高精度模拟,战略演练,工况模拟,可视化与设计表现,无人机巡航等诸多领域。
虽然游戏的IP不是一款引擎能够左右的,但一个决定性要素:画面,却必须依靠虚幻4这样过硬的引擎作为支持,这也必定是未来的发展趋势,也是如今人才缺口大的重要原因之一。
UE4的优势
作为后起之秀,UE4在虚拟现实游戏开发者界大出风头,其强大的开发能力和开源策略,瞬间吸引了大量VR游戏开发者的目光。目前,大量以UE4开发的VR游戏已经登陆各大平台,而VR爱好者的普遍评价都是虚幻4引擎游戏在游戏画面和沉浸体验方面要明显优于Unity3D 游戏。
UE4画面效果完全达到3A游戏水准,光照和物理渲染即便在缩水的状况下也足以秒杀Unity。UE4蓝图系统让游戏策划不用再写劳神费力编辑代码,其强大的材质编辑器实在让开发者们大呼德玛西亚,各种官方插件齐全也让开发者不用在自编第三方插件并担心兼容接口问题。更重要的是针对虚拟现实游戏,UE4为手柄、VR控制器提供了良好支持。而UE4提供的各种游戏模版,让其与Blueprint配合做原型甚至比Unity更快。

5、UE4的就业前景如何

去年9月份, VRSTAR发布的数据显示,全球VR从业者分布来看,美国的人才最多,占比40%,需求占全球48%;相较之下,中国的VR人才仅有2%,但是需求却占全球18%。
需求量大,但人才短缺严重。首先熟悉UE4(虚幻引擎4)的技术很是紧缺。我们知道,VR游戏如果要很好的效果的话,基本上都会选择用UE4开发,而国内跳过了主机游戏时代,能够使用UE4的人很少,U3D的反而多些。接下来是美术,一定需要有技术美术,因为虚幻引擎是一个集成化的开发环境,内部有各种各样的编辑器,材质、粒子、关卡、动画,编译器非常多,所以需要有技术美术来做这个事情,还要关卡美术,最好具有一些技术背景,才能做起来更快更方便。最后,策划也需要完全变换思维,不能用传统的游戏设计思维来设计游戏。

6、对比分析

UE4和Unity3D应该可以算的上是目前市场上最为热门的游戏引擎,也各自拥有为数众多的开发者。虽然一些大型的游戏公司仍然运用自家开发的引擎来制作游戏,但是在巨大的市场需求下,独立开发者与游戏工作室依然需要一款优秀的引擎来支持项目的开发。那么Unity3D和UE4究竟哪个才是游戏开发者的最爱呢?

个人认为还是要具体问题具体分析,像独立游戏、手游之类,小团队更倾向用Unity。如果做一些比较大型的游戏,对画质要求比较高的话,UE4显然更具优势。这两者不存在哪个更有前景的对比性,这个问题就好比问你独立游戏与3A哪个更好一样,各有千秋,因人而已。

从国内的情况来看,PC与主机游戏貌似远不如手游这么火爆,国内的游戏产业与设计也都远不如日本欧美,可能Unity更好一些。不过随着国内玩家的审美的普遍提升,对高质量的游戏呼声越来越高涨,UE4很有可能在未来成为主流。

如何选择一款适合自己的引擎进行游戏开发,下面小编就从几个维度帮大家分析一下:

编程语言:

UE4采用C++的开发语言,而Unity使用C#与JavaScript,我们可以依照个人的能力与喜好来决定采用UE4或是Unity,虽然说有的人觉得C++已经过时了,但还是有不少的开发者偏好使用此编程技术,如果我们擅长的语言是C#,那么投入Unity的怀抱是毋庸置疑的选择。

图形能力:

在图像的表现上面,UE4的确已经建立一个超高的标准,也符合大家对3A级游戏的定义,从复杂的粒子模拟效果与先进的动态照明技术,UE4带给开发者一个全新的开发平台。图像的能力虽然不能代表一切,毕竟以现在的游戏市场来说,有创意性的游戏往往更能吸引用户的关注,尤其是以手游市场的整体效益来看,小而精致的游戏确实比起一些游戏大作更受到玩家的喜爱。

哪一个更容易上手?

在一些论坛里面多数人讨论的一个话题是,到底是UE4好上手还是Unity更利于开发? 其实讨论这个主题的意义不大,Unity在国内的使用人口与学习资源皆高于虚幻引擎,市场上招聘的开发人员也多以Unity为主,所以我们认为讨论这个主题必须根据区域的情况来做为前提,例如有人学了UE4后,发现市场的需求与机会不是很多,那是不是意味着必须放弃UE4来学习Unity?最简单的方法就是直接拿一个项目来做练习,分别将项目导入UE4与Unity,在实施过程中就会发现到许多的问题,这时就能根据自己的解决能力与手上的资源来判断哪一个引擎更适合自己。

如果有意向入坑游戏开发的话,个人建议如果没有基础的话,先学习Unity3d累计游戏开发经验,有基础有工作经验之后可以进阶学习UE4。要说前景的话,两个来说都是比较相近没有谁比谁更有前景,但是学习到高级进阶的话,又有长期从事游戏开发的经验,就业机会和待遇都要好很多。

7、Unity&Unreal引擎对比

对于目前市场,3D手游的引擎选择主要分四部分:

Unity:在移动端更有优势占据手游市场70%的占有率,各种品类游戏都有;
Unreal:两款正版吃鸡手游都是使用Unreal引擎,但手游MMO目前国内还没有上线产品,国内端游MMO成功的也很少;
自研引擎:例如楚留香的Messiah,太极熊猫的Flexi等,优点在于非常熟悉可以提供深度定制和优化;
其他引擎:应用较少不进行考虑。
这里其实选择的余地比较小,对于大部分没有自研引擎的公司来说,还是选择Unity居多,但是随着硬件的不断发展以及Epic公司自己的不断优化和持续更新,Unreal在手机上也有越来越多的公司和项目选择使用了。

部分已知手游项目:
在这里插入图片描述
选择引擎的基本原则
按照软件工程的开发流程,我们首先应该明确需求。以下是一些常见的需求点:
游戏类型?目标用户,目标平台,目标机型是什么?项目周期,成本和团队实力?更倾向画质品质还是适配性?是否有特殊的技术需求?是否大世界?是否支持物理?是否写实风格
何种同步技术?等等

引擎的功能划分和对比
有一句话说的好:
美术资源决定了游戏世界的外观,脚本资源决定了游戏世界的内容,而引擎部分决定了游戏世界的规则。
一款引擎往往包含,图形模块,AI模块,物理模块,寻路模块,输入模块,网络模块,UI模块,渲染模块,声音模块,编辑器模块等等,如果要全面评估我们应该针对各个模块进行详细的评估和对比。
但说道引擎,往往大家的第一印象都是引擎的图形渲染能力,可见图形对于引擎来说是至关重要的,因此我们会分为两部分,图形模块和其他模块,然后进行详细的比较。
图形模块
图形是游戏引擎的重中之中,主要功能就是提供封装底层的渲染接口(D3D,OpenGL,Metal,Vulkan等),渲染管线的定制(前向渲染,延迟渲染,多线程等),适配(PC,IOS,Android),以及一些基本渲染功能的提供例如后处理(抗锯齿,景深,屏幕矫色,扭曲,描边,SSAO等等),阴影,地形,捏脸,动画,天气等等。
在这里插入图片描述
由此可见在高端渲染技术上Unreal更有优势有强大的官方支持,性能也极佳,但是相对的低端设备的兼容性会略差特别是Android版本。Unity也可以实现相同的效果但是很多工作都需要自己开发。
在这里插入图片描述
经过对比可知Unity更容易上手前期开发更快速,更容易做出适配更广(内存和稳定性)的游戏,但一些次时代技术需要自己实现。而Unreal学习成本较高开发效率较低,但是更容易做出顶尖效果的游戏,更适合开放世界,大型项目。
总结
如果是项目周期和成本比较宽裕,希望开发超高画质超高品质,开放世界的游戏,同时图形向技术积累较弱推荐使用Unreal,特别是FPS射击类游戏;如果希望开发周期更短,或者有着深厚技术积累和技术支持推荐使用Unity。此外引擎的选择也受美术和策划的影响,特别是美术同学,对编辑器和引擎的熟悉成度对进度,效果和性能也有着非常大的影响。

其实对于大部分的游戏,两款引擎都可以满足需求,主要的差异还是在品质,时间,成本的项目管理三角形的取舍上。适合自己的才是最好的。

2017-11-21 14:38:40 WAN_EXE 阅读数 1072
  • 从这里开始虚幻4-第2辑-蓝图 v4.18

    本课程系列取名英译系列,是录制人员参考国外英文原版经典教程,结合中国人的习惯录制而成。希望能够给大家以帮助。从这里开始虚幻4系列教程,是Unreal的官方发布的入门教学,非常经典,是学习Unreal的佳入口。

    2158 人正在学习 去看看 杨石兴

这个算是第一个比较深入到Unreal引擎编码的例子,这个例子中,可以通过A,S,D,W控制球体的移动,通过鼠标控制转向,有燃烧的火球,非常的逼真。

下面是运行的示例图,跑动的时候效果会更赞,可以看到燃烧的火球:

先贴上四个文件的代码,然后再来分析。

CollidingPawn.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "Particles/ParticleSystemComponent.h"
#include "CollidingPawn.generated.h"


UCLASS()
class QUICKSTART_API ACollidingPawn : public APawn
{
	GENERATED_BODY()

public:
	// Sets default values for this pawn's properties
	ACollidingPawn();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

	UParticleSystemComponent* OurParticleSystem;
	class UCollidingPawnMovementComponent* OurMovementComponent;

	virtual UPawnMovementComponent* GetMovementComponent() const override;

	void MoveForward(float AxisValue);
	void MoveRight(float AxisValue);
	void Turn(float AxisValue);
	void ParticleToggle();	
};

CollidingPawn.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "QuickStart.h"
#include "CollidingPawn.h"
#include "CollidingPawnMovementComponent.h"
#include "Components/SphereComponent.h"
#include "UObject/ConstructorHelpers.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"


// Sets default values
ACollidingPawn::ACollidingPawn()
{
 	// Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	// Our root component will be a sphere that reacts to physics
    USphereComponent* SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent"));
    RootComponent = SphereComponent;
    SphereComponent->InitSphereRadius(40.0f);
    SphereComponent->SetCollisionProfileName(TEXT("Pawn"));

    // Create and position a mesh component so we can see where our sphere is
    UStaticMeshComponent* SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation"));
    SphereVisual->SetupAttachment(RootComponent);
    static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
    if (SphereVisualAsset.Succeeded())
    {
        SphereVisual->SetStaticMesh(SphereVisualAsset.Object);
        SphereVisual->SetRelativeLocation(FVector(0.0f, 0.0f, -40.0f));
        SphereVisual->SetWorldScale3D(FVector(0.8f));
    }

    // Create a particle system that we can activate or deactivate
    OurParticleSystem = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("MovementParticles"));
    OurParticleSystem->SetupAttachment(SphereVisual);
    OurParticleSystem->bAutoActivate = false;
    OurParticleSystem->SetRelativeLocation(FVector(-20.0f, 0.0f, 20.0f));
    static ConstructorHelpers::FObjectFinder<UParticleSystem> ParticleAsset(TEXT("/Game/StarterContent/Particles/P_Fire.P_Fire"));
    if (ParticleAsset.Succeeded())
    {
        OurParticleSystem->SetTemplate(ParticleAsset.Object);
    }

    // Use a spring arm to give the camera smooth, natural-feeling motion.
    USpringArmComponent* SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraAttachmentArm"));
    SpringArm->SetupAttachment(RootComponent);
    SpringArm->RelativeRotation = FRotator(-45.f, 0.f, 0.f);
    SpringArm->TargetArmLength = 400.0f;
    SpringArm->bEnableCameraLag = true;
    SpringArm->CameraLagSpeed = 3.0f;

    // Create a camera and attach to our spring arm
    UCameraComponent* Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("ActualCamera"));
    Camera->SetupAttachment(SpringArm, USpringArmComponent::SocketName);

    // Take control of the default player
    AutoPossessPlayer = EAutoReceiveInput::Player0;

	// Create an instance of our movement component, and tell it to update our root component.
    OurMovementComponent = CreateDefaultSubobject<UCollidingPawnMovementComponent>(TEXT("CustomMovementComponent"));
    OurMovementComponent->UpdatedComponent = RootComponent;
}

// Called when the game starts or when spawned
void ACollidingPawn::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void ACollidingPawn::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void ACollidingPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	InputComponent->BindAction("ParticleToggle", IE_Pressed, this, &ACollidingPawn::ParticleToggle);

    InputComponent->BindAxis("MoveForward", this, &ACollidingPawn::MoveForward);
    InputComponent->BindAxis("MoveRight", this, &ACollidingPawn::MoveRight);
    InputComponent->BindAxis("Turn", this, &ACollidingPawn::Turn);
}

UPawnMovementComponent* ACollidingPawn::GetMovementComponent() const
{
    return OurMovementComponent;
}

void ACollidingPawn::MoveForward(float AxisValue)
{
    if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent))
    {
        OurMovementComponent->AddInputVector(GetActorForwardVector() * AxisValue);
    }
}

void ACollidingPawn::MoveRight(float AxisValue)
{
    if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent))
    {
        OurMovementComponent->AddInputVector(GetActorRightVector() * AxisValue);
    }
}

void ACollidingPawn::Turn(float AxisValue)
{
    FRotator NewRotation = GetActorRotation();
    NewRotation.Yaw += AxisValue;
    SetActorRotation(NewRotation);
}

void ACollidingPawn::ParticleToggle()
{
    if (OurParticleSystem && OurParticleSystem->Template)
    {
        OurParticleSystem->ToggleActive();
    }
}

CollidingPawnMovementComponent.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PawnMovementComponent.h"
#include "CollidingPawnMovementComponent.generated.h"

/**
 * 
 */
UCLASS()
class QUICKSTART_API UCollidingPawnMovementComponent : public UPawnMovementComponent
{
	GENERATED_BODY()
	
public:
	virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;	
};

CollidingPawnMovementComponent.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/PawnMovementComponent.h"
#include "CollidingPawnMovementComponent.generated.h"

/**
 * 
 */
UCLASS()
class QUICKSTART_API UCollidingPawnMovementComponent : public UPawnMovementComponent
{
	GENERATED_BODY()
	
public:
	virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;	
};


2019-02-24 12:01:58 qq_31788759 阅读数 432
  • 从这里开始虚幻4-第2辑-蓝图 v4.18

    本课程系列取名英译系列,是录制人员参考国外英文原版经典教程,结合中国人的习惯录制而成。希望能够给大家以帮助。从这里开始虚幻4系列教程,是Unreal的官方发布的入门教学,非常经典,是学习Unreal的佳入口。

    2158 人正在学习 去看看 杨石兴

教程链接:Unreal Engine 4 虚幻引擎蓝图中级教程物理碰撞

想共享的小伙伴可以E-mail我:lxbcolorgalaxy@qq.com

目录

第一章 常见的物理现象及分析

1蓝图模板中的物理现象

2创建子弹抛射

3自动追踪

4碰撞事件

5纯物理模拟子弹

第二章 碰撞体

1简易碰撞体

2DOP碰撞体

3凸面碰撞体

4567UBX导入碰撞体

8从其他模型复制碰撞体

9碰撞体积

第三章 物理刚体

1物理刚体

2质量

3质心

4运动衰减

6运动空间锁定

第四章 碰撞通道

1类型、反馈、通道

2UE4中的碰撞设置

3碰撞案例测试

4类型与反馈案例

5添加自定义碰撞

第五章 碰撞事件

1ACTOR交叉触发

2OnComponent触发

3击中

4击伤事件

5伤害类型

6点伤害

7范围伤害规则

8完全伤害

第六章 射线检测

1零粗细(很细)射线检测

2零检测返回结果

4球体非零粗细检测

5调试检测结果

6多重零粗细检测

7盒子、胶囊体检测

8逐多边形检测


 

第一章 常见的物理现象及分析

1蓝图模板中的物理现象

分析了第一人称射击模板中的物理现象,比如子弹飞行、碰撞、产生力的效果与消失。

2创建子弹抛射

1.给子弹击中物体施加一个同方向的冲击力——子弹蓝图

 

2.子弹模型添加Projectile Movement Component组件,引擎自带的子弹模拟,可设置子弹参数

 

3.控制生成的子弹位置、播放角色动画

3自动追踪

1.设置子弹反弹参数

 

2.设置子弹追踪导航功能

蓝图中设置追踪目标

 

4碰撞事件

1.Overlap重叠事件(类似Unity里的触发器,又不同)两者均需要勾选Generate Overlap

5纯物理模拟子弹

1.删除projectile组件,更改Sphere Mesh的碰撞预设,给小球生成时添加Physics Linear Velocity,更改发射方向。

2.选中Actor,修改生命周期

第二章 碰撞体

1简易碰撞体

2DOP碰撞体

10DOP分别沿着X Y Z轴创建更复杂的碰撞体

3凸面碰撞体

 

4567UBX导入碰撞体

3DMAX中制作碰撞体的命名规则:盒型UBX、球形USP、不规则UCX,紧跟其中一个模型的名称。不规则时,每个内角要小于180°,是一个凸边形。

 

8从其他模型复制碰撞体

选中其他已有碰撞体的相同模型,在无碰撞体的模型中选择Copy

9碰撞体积

Blocking Volume通常当作场景的边界碰撞盒,可同BSP模型一样进行编辑修改

第三章 物理刚体

1物理刚体

2质量

3质心

4运动衰减

6运动空间锁定

第四章 碰撞通道

1类型、反馈、通道

Object Type ——> Response ——> Channel

2UE4中的碰撞设置

3碰撞案例测试

1.阴影烘培效果,Movable是实时的,Static需要构建

2.可破坏物体 设置碰撞时可破碎

3.各种Object Response设置

4类型与反馈案例

5添加自定义碰撞

 

第五章 碰撞事件

1ACTOR交叉触发

Event ActorBeginOverlap——碰撞物体触发

Event ActorEndOverlap

2OnComponent触发

Add On Component Begin Overlap——碰撞组件触发

Add On Component End Overlap

3击中

Event Hit

开启Hit事件 碰撞响应要设置为Block

4击伤事件

1.应用伤害Apply Damage

2.接受伤害

Event AnyDamage

Event PointDamage

Event RadialDamage

5伤害类型

1.DamageType的预设类别

2.创建一个继承DamageType的自定义DamageType蓝图

 

3.代替Add Impulse产生冲击力,设置Damage Type中的Damage Impulse为80。但Apply Damage无法触发代码Add Impluse At Location(Apply Point/Radial Damage可以)。

AnyDamage连接下的

6点伤害

1.子弹蓝图里触发Damage

7范围伤害规则

1.球形范围伤害

2.由于Damage Prevention Channel的原因,侧面和后面的方块受到的爆破力被阻碍

8完全伤害

1.C++引擎源码中的ApplyRadialDamge蓝图节点信息

h头文件

/** Hurt locally authoritative actors within the radius. Will only hit components that block the Visibility channel.
	 * @param BaseDamage - The base damage to apply, i.e. the damage at the origin.
	 * @param Origin - Epicenter of the damage area.
	 * @param DamageRadius - Radius of the damage area, from Origin
	 * @param DamageTypeClass - Class that describes the damage that was done.
	 * @param DamageCauser - Actor that actually caused the damage (e.g. the grenade that exploded).  This actor will not be damaged and it will not block damage.
	 * @param InstigatedByController - Controller that was responsible for causing this damage (e.g. player who threw the grenade)
	 * @param bFullDamage - if true, damage not scaled based on distance from Origin
	 * @param DamagePreventionChannel - Damage will not be applied to victim if there is something between the origin and the victim which blocks traces on this channel
	 * @return true if damage was applied to at least one actor.
	 */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category="Game|Damage", meta=(WorldContext="WorldContextObject", AutoCreateRefTerm="IgnoreActors"))
	static bool ApplyRadialDamage(const UObject* WorldContextObject, float BaseDamage, const FVector& Origin, float DamageRadius, TSubclassOf<class UDamageType> DamageTypeClass, const TArray<AActor*>& IgnoreActors, AActor* DamageCauser = NULL, AController* InstigatedByController = NULL, bool bDoFullDamage = false, ECollisionChannel DamagePreventionChannel = ECC_Visibility);
	
	/** Hurt locally authoritative actors within the radius. Will only hit components that block the Visibility channel.
	 * @param BaseDamage - The base damage to apply, i.e. the damage at the origin.
	 * @param Origin - Epicenter of the damage area.
	 * @param DamageInnerRadius - Radius of the full damage area, from Origin
	 * @param DamageOuterRadius - Radius of the minimum damage area, from Origin
	 * @param DamageFalloff - Falloff exponent of damage from DamageInnerRadius to DamageOuterRadius
	 * @param DamageTypeClass - Class that describes the damage that was done.
	 * @param DamageCauser - Actor that actually caused the damage (e.g. the grenade that exploded)
	 * @param InstigatedByController - Controller that was responsible for causing this damage (e.g. player who threw the grenade)
	 * @param bFullDamage - if true, damage not scaled based on distance from Origin
	 * @param DamagePreventionChannel - Damage will not be applied to victim if there is something between the origin and the victim which blocks traces on this channel
	 * @return true if damage was applied to at least one actor.
	 */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category="Game|Damage", meta=(WorldContext="WorldContextObject", AutoCreateRefTerm="IgnoreActors"))
	static bool ApplyRadialDamageWithFalloff(const UObject* WorldContextObject, float BaseDamage, float MinimumDamage, const FVector& Origin, float DamageInnerRadius, float DamageOuterRadius, float DamageFalloff, TSubclassOf<class UDamageType> DamageTypeClass, const TArray<AActor*>& IgnoreActors, AActor* DamageCauser = NULL, AController* InstigatedByController = NULL, ECollisionChannel DamagePreventionChannel = ECC_Visibility);

cpp实现

bool UGameplayStatics::ApplyRadialDamage(const UObject* WorldContextObject, float BaseDamage, const FVector& Origin, float DamageRadius, TSubclassOf<UDamageType> DamageTypeClass, const TArray<AActor*>& IgnoreActors, AActor* DamageCauser, AController* InstigatedByController, bool bDoFullDamage, ECollisionChannel DamagePreventionChannel )
{
	float DamageFalloff = bDoFullDamage ? 0.f : 1.f;
	return ApplyRadialDamageWithFalloff(WorldContextObject, BaseDamage, 0.f, Origin, 0.f, DamageRadius, DamageFalloff, DamageTypeClass, IgnoreActors, DamageCauser, InstigatedByController, DamagePreventionChannel);
}

bool UGameplayStatics::ApplyRadialDamageWithFalloff(const UObject* WorldContextObject, float BaseDamage, float MinimumDamage, const FVector& Origin, float DamageInnerRadius, float DamageOuterRadius, float DamageFalloff, TSubclassOf<class UDamageType> DamageTypeClass, const TArray<AActor*>& IgnoreActors, AActor* DamageCauser, AController* InstigatedByController, ECollisionChannel DamagePreventionChannel)
{
	FCollisionQueryParams SphereParams(SCENE_QUERY_STAT(ApplyRadialDamage),  false, DamageCauser);

	SphereParams.AddIgnoredActors(IgnoreActors);

	// query scene to see what we hit
	TArray<FOverlapResult> Overlaps;
	if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
	{
	World->OverlapMultiByObjectType(Overlaps, Origin, FQuat::Identity, FCollisionObjectQueryParams(FCollisionObjectQueryParams::InitType::AllDynamicObjects), FCollisionShape::MakeSphere(DamageOuterRadius), SphereParams);
	}

	// collate into per-actor list of hit components
	TMap<AActor*, TArray<FHitResult> > OverlapComponentMap;
	for (int32 Idx=0; Idx<Overlaps.Num(); ++Idx)
	{
		FOverlapResult const& Overlap = Overlaps[Idx];
		AActor* const OverlapActor = Overlap.GetActor();

		if ( OverlapActor && 
			OverlapActor->bCanBeDamaged && 
			OverlapActor != DamageCauser &&
			Overlap.Component.IsValid() )
		{
			FHitResult Hit;
			if (DamagePreventionChannel == ECC_MAX || ComponentIsDamageableFrom(Overlap.Component.Get(), Origin, DamageCauser, IgnoreActors, DamagePreventionChannel, Hit))
			{
				TArray<FHitResult>& HitList = OverlapComponentMap.FindOrAdd(OverlapActor);
				HitList.Add(Hit);
			}
		}
	}

	bool bAppliedDamage = false;

	if (OverlapComponentMap.Num() > 0)
	{
	// make sure we have a good damage type
	TSubclassOf<UDamageType> const ValidDamageTypeClass = DamageTypeClass ? DamageTypeClass : TSubclassOf<UDamageType>(UDamageType::StaticClass());

		FRadialDamageEvent DmgEvent;
		DmgEvent.DamageTypeClass = ValidDamageTypeClass;
		DmgEvent.Origin = Origin;
		DmgEvent.Params = FRadialDamageParams(BaseDamage, MinimumDamage, DamageInnerRadius, DamageOuterRadius, DamageFalloff);

	// call damage function on each affected actors
	for (TMap<AActor*, TArray<FHitResult> >::TIterator It(OverlapComponentMap); It; ++It)
	{
		AActor* const Victim = It.Key();
		TArray<FHitResult> const& ComponentHits = It.Value();
		DmgEvent.ComponentHits = ComponentHits;

		Victim->TakeDamage(BaseDamage, DmgEvent, InstigatedByController, DamageCauser);

		bAppliedDamage = true;
	}
	}

	return bAppliedDamage;
}

2.Apply Radial Damage with Falloff (falloff为0不衰减,越大衰减越快

第六章 射线检测

1零粗细(很细)射线检测

 

射线通道TraceChannel

Visibility——适用于两点之间,存在障碍物时触发

Camera——适用于从相机发出射线

TraceComplex——针对复杂物体,检测复杂碰撞体还是简单的碰撞体,一般不开启

 

Note设置Start End Position

绘制射线的持续时间

2零检测返回结果

法线

测试

 

4球体非零粗细检测

5调试检测结果

蓝图

预测

实际

6多重零粗细检测

1.立方体 碰撞预设设置由BlockAll变为OverlapAll

Blocking Hit 绿色为false,红色为true

7盒子、胶囊体检测

Orientation——方向

 

8逐多边形检测

Trace Complex 不勾选——检测碰撞体

勾选——检测多边形模型

同时,模型选择Use Complex Collision As Simple Collision

 

 

2005-03-27 21:21:00 casualgame 阅读数 4411
  • 从这里开始虚幻4-第2辑-蓝图 v4.18

    本课程系列取名英译系列,是录制人员参考国外英文原版经典教程,结合中国人的习惯录制而成。希望能够给大家以帮助。从这里开始虚幻4系列教程,是Unreal的官方发布的入门教学,非常经典,是学习Unreal的佳入口。

    2158 人正在学习 去看看 杨石兴

物理引擎分析报告

前言:

物理引擎已经作为游戏引擎的重要组成部分,在3D的游戏中,开发者对物理表现的追求日趋苛刻,因此物理引擎必然会象图形引擎那样独立分支出来,作为专攻对象,这是一个趋势。最近由美国AGEIA公司开发的专门用作物理运算的硬件PPUPhysics processing unit),SEGAUBISoftEPIC都率先表示支持这个技术,EPIC甚至表示把这个技术整合到Unreal3.0的引擎上。从以上种种事例,物理引擎得到的重视已可见一斑。

一般的游戏引擎都会包括物理模块,但我们今天讨论的是专业的物理引擎,分别是HavokVortexodeNovodeXtakamak等。下面将对这几款引擎进行横向的比较。

简述:

Ø         Havok

http://www.havok.com

简介:

HavokPS2XBOXGameCubePC多种游戏平台都有支持。也是世界顶级游戏公司ValveHalf Life的公司),PandemciRemedy等的合作伙伴。这个物理引擎曾经支持过各种类型的游戏,包括racing gamefirst-persion shooterMMOGsadventure gamespuzzle games等等。Hovak还曾经负责电影Matrix的部分效果处理。

成功案例:

Crash Nitro KartHalf-Life 2Max Payne 2Medal of HonorF.E.A.R.Lord of the Rings: Middle Earth Online

Ø         Vortex

http://www.cm-labs.com/

简介:

       CMlabs公司的产品和Havok专注的方向不同,他是着重于工程领域的应用,而非游戏领域。专攻机器方面的模拟,所以追求运算的精确性。

       因为他的合作伙伴多数是一些非游戏公司,这里就不作介绍了。

Ø         Ode

http://www.ode.org/

简介:

       Ode是一个开源的引擎,支持跨平台。Ode能够高效的模拟刚体动力学,例如模拟汽车,还有真实环境中的各种物件。现在已经有很多电脑游戏采用了此开发库。

成功案例:

       BloodRayne2Xpand Rally18 Wheels of Steel: Pedal to the Metal

Ø         NovodeX

http://www.ageia.com/novodex.html

简介:

       NovodeX是由开发PPU的公司AGEIA进行维护,因此对于将来PPU硬件的支持,无疑NovodeX是最有优势的。NovodeX是一个模拟刚体动力学的物理引擎,支持速度,加速度,动量,冲量,碰撞等等的物理概念。NovodeX的开发库支持跨平台,多线程,高速碰撞检测等特性,专门对汽车物理的模拟做了优化。

案例:

       根据官方文档,已经有超过60个游戏工作室、公司和研究机构采用了NovodeX的技术。

Ø         takamak

http://www.tokamakphysics.com/index.htm

简介:

takamak是由David Lam开发的物理引擎。采用了独特的算法,尽可能的减少矩阵的运算,从而提高模拟的效率。

       案例:

       有一款智力游戏Bontago采用了此引擎,主要展现的都是规则多边形的物理表现。

横向比较

 

 

Hovok

Vortex

Ode

NevodeX

Takamak

开发公司/作者

Hovok

CMLabs

Russell Smith

AGEIA

David Lam

版本

3

2.3

0.5

2.1.2

1.21

发行日期

2005.3

2004.7

2004.5

2004.11

2005.3

是否支持C++开发

文档/Demo

详细

详细

较详细

详细

较详细

License

商业

价格需要协商

商业

价格需要协商

GNU LGPL/BSD/价格和使用需要协商

商业

价格需要协商

免费

技术支持

全面

全面

全面

其他

NA

NA

开放源码

支持PPU

NA

 

 

 

 

 

 

各个引擎的特性:

Hovok

Collision Detection - including Continuous Physics

Dynamics and Constraint Solving

Vehicle Dynamics

Data Serialization and Art Tool Support

Visual Debugger for in-game diagnostic feedback

 

 

Vortex

Fast rigid-body dynamics

Accurate collision detection

Stable constraint system

Comprehensive vehicle dynamics

Object oriented C/C++ API

Cross-platform: Microsoft Windows 95-98, NT, 2000, XP, SGI IRIX, Linux

Professional services and training

 

 

Ode

Rigid bodies with arbitrary mass distribution.

Joint types: ball-and-socket, hinge, slider (prismatic), hinge-2, fixed, angular motor, universal.

Collision primitives: sphere, box, capped cylinder, plane, ray, and triangular mesh.

Collision spaces: Quad tree, hash space, and simple.

Simulation method: The equations of motion are derived from a Lagrange multiplier velocity based model due to Trinkle/Stewart and Anitescu/Potra.

A first order integrator is being used. It's fast, but not accurate enough for quantitative engineering yet. Higher order integrators will come later.

Choice of time stepping methods: either the standard ``big matrix'' method or the newer iterative QuickStep method can be used.

Contact and friction model: This is based on the Dantzig LCP solver described by Baraff, although ODE implements a faster approximation to the Coloumb friction model.

Has a native C interface (even though ODE is mostly written in C++).

Has a C++ interface built on top of the C one.

Many unit tests, and more being written all the time.

Platform specific optimizations.

 

 

NevodeX

Fully Configurable NxJoint

'Roll your own Joint' with the new, fully configurable NxJoint! With this new flavor of NxJoint constraint you can selectively freeze, limit or free each of 6 DOF's independently, for unparalleled flexibility and ease of use. Virtually any type of joint can be expressed by setting parameters of the NxJoint--completely dynamically. For example, set up a hinge joint (1 DOF free), then convert it to a ball-and-socket (3 DOFs free) to simulate damage.

 

 

Support for Multi-Threading

Take advantage of next-generation multiprocessing systems with the new multi-threaded API in the NovodeX SDK. NovodeX makes it easy to provide state-of-the-art physical behavior for gameplay and effects by harnessing the power of leading-edge parallel system architectures.

 

 

Improved High-Speed Collision Detection

The industry's fastest and most comprehensive collision system is more robust than ever. Expect reduced tunneling artifacts and improved performance with high-speed objects.

 

 

New Raycast Vehicles

The NovodeX SDK now supports an advanced implementation of the single-rigid-body style wheeled vehicle.

 

 

Takamak

Tokamak features a unique iterative method for solving constraint.

This allows developers to make the trade-off between accuracy

and speed, as well as providing more predictable processor and

memory usage. In addition, Tokamak's constraint solver does not

involve solving large matrices, there by avoiding memory

bandwidth limitation on some game consoles.

 

 

Joints Tokamak supports a variety of joint types and joint limits.

Friction Tokamak provides a very realistic friction model and its computational cost is

minimal.

 

Stacking Tokamak is specially optimized for stacking large number of

objects; one of the most frequently requested features by game

developers.

Collision Detection Build within Tokamak is a very efficient collision

detection module. Currently, Tokamak provides collision detection

for primitives (box, sphere, capsule), combination of primitives, and

arbitrary static triangle mesh.

(NEW! Tokamak now support convex to convex collision detection..)

 

 

Rigid Particle A lightweight rigid body providing particle effects in games at minimal cost.

Breakage Constructing model which will break when collision occurs is a breeze in Tokamak. Fragment of

original model will automatically be spawn by Tokamak's built-in breakage functionality.

 

 

综述

在观看了每个引擎所提供的demo和相关的文档后,我觉得应该在NevodeXOde两者之间进行选择。

Hovok是众多引擎里面最有名气的一个,但是能够获得相关的资料却是最少。从他支持的游戏,如Half-LifeMedal of Honor等,可以看出这款引擎的实力。

VorTex是一款面向工业的物理引擎,他追求的方向是精确而非速度。汇集各个方面的因素,我觉得此款物理引擎不可取。

Ode是一款基于Open Dynamics Framework下的一款物理引擎,他十分的开放,可以让开发人员窥探里面的实现方式,甚至进行改进。一款叫做GRYPShttp://engine.hlw.co.at)的游戏引擎已经集成了Ode,这款引擎的供应商可以对此Ode的使用,集成做技术支持,但是相对其他商业引擎,支持还是显得不足。很多开发人员利用这款引擎开发了不少Demo,其中有一些汽车类的Demo,已经基本满足我们的需求。

NevodeX是一款商业物理引擎,从他的Demo来看,模拟的真实感到运行速度,与Ode不相上下,而且文档更加的详细。此款引擎又是由AGEIA进行开发,对于将来PPU的使用也会更加方便。

Takamak是由一个爱好者开发的,因此技术实力比较单薄,而且对于技术支持方面做得不足,应该不予考虑。

备注

以上提及到的引擎demo和文档可以通过我的popo共享文件夹下载。

popo:blue_bean@163.com

2011-03-14 22:05:00 pizi0475 阅读数 2735
  • 从这里开始虚幻4-第2辑-蓝图 v4.18

    本课程系列取名英译系列,是录制人员参考国外英文原版经典教程,结合中国人的习惯录制而成。希望能够给大家以帮助。从这里开始虚幻4系列教程,是Unreal的官方发布的入门教学,非常经典,是学习Unreal的佳入口。

    2158 人正在学习 去看看 杨石兴

Unreal3(以下简称U3)是一个以脚本为主体的游戏引擎,所有代码几乎都为脚本服务,意味着所有源码都会提供相应的脚本函数在脚本中使用。
UObject是U3中很重要的一个基类,所有由UObject派生的类都可以导出到脚本中(不从UObject派生行不行?不知道呢),但我对U3的脚本不熟。暂且从C++角度来分析下UObject是如何实现的。
UObject顾名思义是一个“基本对象”,材质、mesh、文件、玩家等等都是从这个UObject继承而来,这个类做了很多事情:

1、属性的统一访问接口,脚本中就可以通过这个接口来访问属性了;
2、成员函数的统一访问接口,脚本中可以通过这些接口来调用UObject或其派生类的成员函数;
3、串行化的统一接口,实现了一个保存所有对象的UPackage包管理器,从而做到保存到二进制文件、从二进制文件读取,这样做的好处是持久化对象(比如游戏中的材质列表)的载入非常快速,由于是二进制格式,不需要任何字符串数据转换;
4、提供对象的垃圾回收功能;
5、提供编辑器的相应功能,如:对象的“属性”有各种编辑器所需的标记(是否可编辑CPF_Edit等)、对象在编辑器中的渲染DrawThumbnail、对象描述GetThumbnailDesc、对象选择IsSelected、是否更改了包MarkPackageDirty等等;
6、提供一个对象的管理器,这个对象管理器是通过UObject中的一堆静态函数来实现的,如:从管理器中查找一个对象StaticFindObject、分配一个对象StaticAllocateObject、从包中载入一个对象StaticLoadObject、根据类型来遍历管理器中的所有对象FObjectIterator/TObjectIterator、遍历所有选择了的对象TSelectedObjectIterator(编辑器使用)
7、提供配置管理器,通过UObject中的LoadConfig、SaveConfig实现
8、提供类描述信息,描述了这个类从哪个类派生、有什么属性、每个属性的访问方式、有什么函数,从而实现了动态类型判断、脚本属性访问、脚本函数访问、属性串行化等等
9、其他。。。。

简单分析下UObject中的各个成员变量的意义:
Index,用来记录这个UObject在所有UObject列表GObjObjects中的唯一索引
HashNext,用来记录全局UObject Hash表GObjHash中跟这个UObject 的Hash值相同的下一个UObject的指针,用来配合全局Hash表GObjHash通过StaticFindObject函数快速搜索一个指定名称的UObject
StateFrame,脚本相关的咚咚,还没看
_Linker,通过在包文件中载入时的载入器
_LinkerIndex,通过包文件载入时的UPackage包对象在GObjObjects中的唯一索引,相当于Outer->Index
Outer,这个对象所属的包
ObjectFlags,这个对象的一些标记,具体参见EObjectFlags枚举,不同标记来决定这个对象的一些行为,比如是否可以保存、是否可见等等
Name,对象名称,通过一个FName来实现,这个FName可是个好东西哦,字符串比较变成了一个Hash值比较
Class,用来描述这个类,就是以上第1、2、8点说到的。这个Class在调用UObject::StaticClass或派生类的StaticClass静态函数时会一次性初始化,意味着即使创建多少个UObject,但Class只会有一个实例,我们通过这个类,可以使用TFieldIterator的统一方式来遍历这个类的所有属性、函数。

UObject的静态变量,这些静态变量其实就是UObject对象管理器使用的变量,如果用Ogre的设计方法来做,就相当于另外一个class UObjectManager : public Singleton<UObjectManager>,然后在里面把这些静态变量拿到UObjectManager中去。简要分析下静态变量的意义:
GObjInitialized,对象管理器是否已经初始化,全局对象管理器只需要初始化一次就够了;
GObjNoRegister,调用StaticInit时会设置成1;
GObjBeginLoadCount,有多少个对象被BeginLoad了;
GObjRegisterCount,ProcessRegistrants中使用
GImportCount,还没细看哦
GObjHash,通过每个UObject的Name的Hash值取低12位作为索引值保存在GObjHash表中,Hash值的低12位相同的,只记录第一个在GObjHash表中,其他的通过链表方式使用UObject的HashNext来链接起来
GAutoRegister,自动注册的对象列表
GObjRoot,对象树种的顶层对象
GObjObjects,所有对象的列表

先说这么多了,继续学习。

虚幻引擎源码分析(4)

博文 来自: wangnan8015
没有更多推荐了,返回首页