本文内容为UE4.27的文档教程

GameMode确定

新建的项目会自动生成GameMode,如果有更改,而不是使用默认的GameMode类,就需要在引擎的设置中更改

角色的实现

前后左右移动

//前后 MoveForward
void AFPSCharacter::MoveForward(float value)
{
//利用控制器方向寻找前进的方向就是角色朝向
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::X);
AddMovementInput(Direction, value);
}
//左右MoveRight
void AFPSCharacter::MoveRight(float value)
{
//
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::Y);
AddMovementInput(Direction, value);
}

利用AddMovementInput函数传入方向

在模板自带的PlayerInputComponent方法下,绑定行为函数

void AFPSCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent); PlayerInputComponent->BindAxis("MoveForward", this, &AFPSCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AFPSCharacter::MoveRight);
}

绑定轴的移动:BindAxis

鼠标控制视角的转动

PlayerInputComponent->BindAxis("Turn", this, &AFPSCharacter::AddControllerYawInput);
PlayerInputComponent->BindAxis("LookUp", this, &AFPSCharacter::AddControllerPitchInput);

AddControllerYawInput,AddControllerPitchInput为基类自带可以直接使用来控制视角的转动

跳跃

跳跃与bPressedJump绑定这是模板基类设置好的。所以在Character的源文件和头文件中定义两个函数来控制这个变量值

void AFPSCharacter::StartJump()
{
bPressedJump = true;
} void AFPSCharacter::StopJump()
{
bPressedJump = false;
}

在模板自带的PlayerInputComponent方法下,绑定行为函数

PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AFPSCharacter::StartJump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &AFPSCharacter::StopJump);

绑定按键操作:BindAction,IE_Pressed表示设置的按键按下,IE_Released表示设置的按键松开

实现第一人称视角

FPS游戏常见的方法就是使用两个分开的角色网格体,一个是全身网格,一个是“武器和手部”的局部网格,全身网格可以用于第三人称视角,局部网格用于第一人称视角。

主要操作,摄像机组件Attach在全身网格下,局部网格Attach在摄像机下。禁用某些阴影更加真实(防止第一个网格体的影响)

FPSMesh->bCastDynamicShadow = false;
FPSMesh->CastShadow = false;

发射物的实现

设置一个球状发射物利用USphereComponent,利用UProjectileMovementComponent确定发射物的移动,定义一个函数用于管理发射物的发射

//传入发射方向,在角色类中获取,乘以发射速度
void AFPSProjectile::FireInDirection(const FVector& ShootDirection)
{
ProjectileMovementComponent->Velocity = ShootDirection * ProjectileMovementComponent->InitialSpeed;
}

在角色类中利用BindAction绑定按键,并且编写Fire函数,在角色类中需要新增一个变量用来确定角色需要发射哪一类发射物虽然现在只有1类。

BindAction需要一个角色类中的操作(函数),所以需要在角色类中再写一个Fire函数,其中调用发射物类中的发射函数

//在头文件中
UPROPERTY(EditDefaultsOnly, Category = Projectile)
TSubclassOf<class AFPSProjectile> ProjectileClass;

实现射击

在角色类的头文件中include发射物头文件,编写Fire函数,利用SpawnActor方法来生成发射物,调用发射物类中的发射函数实现发射。

void AFPSCharacter::Fire()
{
// 试图发射发射物。
if (ProjectileClass)
{
// 获取摄像机变换。
FVector CameraLocation;
FRotator CameraRotation;
GetActorEyesViewPoint(CameraLocation, CameraRotation); // 设置MuzzleOffset,在略靠近摄像机前生成发射物。
MuzzleOffset.Set(100.0f, 0.0f, 0.0f); // 将MuzzleOffset从摄像机空间变换到世界空间。
FVector MuzzleLocation = CameraLocation + FTransform(CameraRotation).TransformVector(MuzzleOffset); // 使目标方向略向上倾斜。
FRotator MuzzleRotation = CameraRotation;
MuzzleRotation.Pitch += 10.0f; UWorld* World = GetWorld();
if (World)
{
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
SpawnParams.Instigator = GetInstigator(); // 在枪口位置生成发射物。
AFPSProjectile* Projectile = World->SpawnActor<AFPSProjectile>(ProjectileClass, MuzzleLocation, MuzzleRotation, SpawnParams);
if (Projectile)
{
// 设置发射物的初始轨迹。
FVector LaunchDirection = MuzzleRotation.Vector();
Projectile->FireInDirection(LaunchDirection);
}
}
}
}

设置发射物的生命和碰撞

在发射物类的源文件中的构造函数中利用InitialLifeSpan设置生命周期

在引擎设置Collision中自定义Collision文件,在源文件构造函数中对SphereComp绑定该文件

SphereComp->BodyInstance.SetCollisionProfileName(TEXT("Projectile"));

当发射物碰撞物体消失

利用OnComponentHit事件,在发射物类中

SphereComponet->OnComponentHit.AddDynamic(this, &AFPSProjectile::OnHit);

void AFPSProjectile::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, FVector NormalImpulse, const FHitResult& Hit)
{
if (OtherActor != this && OtherComponent->IsSimulatingPhysics())
{
OtherComponent->AddImpulseAtLocation(ProjectileMovementComponent->Velocity * 100.0f, Hit.ImpactPoint);
} Destroy();
}

简单c++构建第一人称的更多相关文章

  1. D3D游戏编程系列(六):自己动手编写第一人称射击游戏之第一人称视角的构建

    说起第一人称射击游戏,不得不提第一人称视角啊,没有这个,那么这个第一就无从谈起啊,我作为一个观察者究竟如何在这个地图上顺利的移动和观察呢,那么,我们一起来研究下. 我们首先来看下CDXCamera类: ...

  2. 开发一个最简单的Cardboard虚拟现实应用(四)做一个Cardboard第一人称控制器

    [开源互助-原创文章,转载请说明出处]第三帖中已经创建了一个cardboard自带的demo应用,但它是不能移动的,玩家只能站在原地,通过头部转动来观察四周,除此之外,玩家并没有更多的手段与游戏场景进 ...

  3. 【转】265行JavaScript代码的第一人称3D H5游戏Demo

    译文:http://blog.jobbole.com/70956/ 原文:http://www.playfuljs.com/a-first-person-engine-in-265-lines/ 这是 ...

  4. 如何使用threejs实现第一人称视角的移动

    在数据可视化领域利用webgl来创建三维场景或VR已经越来越普遍,各种开发框架也应运而生.今天我们就通过最基本的threejs来完成第一人称视角的场景巡检功能.如果你是一位threejs的初学者或正打 ...

  5. ThingJS平台制作第一人称视角下的巡更效果

    今天想要做一个类似巡更的过程,就像是在学校保安巡更,小区保安巡更一样.巡更需要用到相应的场景,比如说:园区.学校.超市以及工厂等等,然后需要规划好路线也就是巡更的路线,并且视角要跟随路线来变换,从而达 ...

  6. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十五章:第一人称摄像机和动态索引

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十五章:第一人称摄像机和动态索引 代码工程地址: https://g ...

  7. Microsoft Hyperlapse——让第一人称视频更快更流畅

    Hyperlapse--让第一人称视频更快更流畅" title="Microsoft Hyperlapse--让第一人称视频更快更流畅"> 职业摄影师Nick Di ...

  8. 【Unity3D】Unity自带组件—完成第一人称人物控制

    1.导入unity自带的Character Controllers包 2.可以看到First Person Controller组件的构成 Mouse Look() : 随鼠标的移动而使所属物体发生旋 ...

  9. 基于HTML5及WebGL开发的2D3D第一人称漫游进行碰撞检测

    为了实现一个基于HTML5的场景小游戏,我采用了HT for Web来实现,短短200行代码,我就能实现用“第一人称”来操作前进后退上下左右,并且实现了碰撞检测. 先来看下实现的效果:http://h ...

  10. unity中制作模拟第一人称视角下的指南针

    private int zRotation; public GameObject obj; public void Update() { //obj = GameObject.Find("C ...

随机推荐

  1. Oracle insert all语句介绍

    Oracle 中insert语句的高级用法,INSERT ALL 语句介绍: 1.无条件insert all 全部插入 CREATE TABLE t1(product_id NUMBER, produ ...

  2. 异常处理try...except...finally---day26

    1.认识异常处理 # ### 认识异常处理 #IndexError 索引超出序列范围 #lst = [1,2,3,4] #print(lst[10]) #KeyError 字典中查找一个不存在的关键字 ...

  3. rpm的一些命令

    rpm -q xx #查询当前的包是否安装 rpm -qi xx # 查询当前包的详细信息 rpm -qpi 包文件路径 # 没装之前先查看包的信息 rpm -qpl 包文件路径 # 预计装上后会在系 ...

  4. C#程序全局异常处理—WPF和Web API两种模式

    C#程序的全局异常处理,网上搜下资料都是一大堆,我这里最近也是独立做一个B/S结构的小项目, 后面又增加了需求用WPF实现相同的功能,这里将我所使用的全局异常处理方式做一个简短的总结分享. Web A ...

  5. 求求你别再用OkHttp调用API接口了,快来试试这款HTTP客户端库吧

    引言 在日常业务开发中,我们时常需要使用一些其他公司的服务,调用第三方系统的接口,这时就会涉及到网络请求,通常我们可以使用HttpClient,OkHttp等框架去完成网络请求.随着RESTful A ...

  6. 以Servlet来解释 抽象实现类

    在 Java Servlet API 中: Servlet 接口定义了一个 Servlet 的基本行为.这个接口是抽象的,因为它包含抽象方法,比如 service(), init(), 和 destr ...

  7. Web常见漏洞描述及修复建议(转载)

    Web常见漏洞描述及修复建议 我太难了king 白帽聚集地 1 week ago 1.SQL注入 漏洞描述 Web程序中对于用户提交的参数未做过滤直接拼接到SQL语句中执行,导致参数中的特殊字符破坏了 ...

  8. CodeGeeX vscode代码提示,智能问答

    CodeGeeX 官网 https://codegeex.cn/zh-CN/ CodeGeeX vscode代码提示,智能问答

  9. 摆脱鼠标系列 - vscode 新建终端 默认最大化显示

    摆脱鼠标系列 - vscode 新建终端 默认最大化显示 实现 搜索 opens max 改成 always

  10. 修改 markdown 二级标题的编号 - 自动编号 autoNumber.js nodejs

    需求 我在写 https://www.vuejsdev.com/01FE/must-know-knowledge.html 这个页面的时候, 二级页面 标题前面有编号,但是有时候我会把顺序换下,每次手 ...