本文内容为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. virtualbox中给redhat安装增强功能

    关于虚拟机中安装redhat请参考其他教程: 1.点击虚拟机菜单:设备--安装增强功能.... 2.ssh连接到redhat,执行以下操作: [root@rhel-server ~]# mount / ...

  2. 【Android逆向】脱壳项目frida_dump 原理分析

    脱dex核心文件dump_dex.js 核心函数 function dump_dex() { var libart = Process.findModuleByName("libart.so ...

  3. java怎么打印一个对象的内存地址

    在Java一般使用HashCode来代表对象的地址,但是两个相同的对象就不行了,两个相同的对象的hashcode是相同的. 如果要对比两个相同的对象的地址可以使用,System.identityHas ...

  4. OpenCV开发笔记(五十九):红胖子8分钟带你深入了解分水岭算法(图文并茂+浅显易懂+程序源码)

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  5. pwd模块

    # pwd模块提供了获取UNIX平台用户的账户与密码信息(通过文件/etc/passwd),在所有的UNIX版本平台都可以用. # pwd模块返回的是一个类似元组的对象,该对象的各个属性对应于pass ...

  6. 第一百一十篇:内存泄漏和垃圾回收(JS)

    好家伙,本篇内容为<JS高级程序设计>第四章的学习笔记 1.内存泄露 1.1.什么是内存泄漏? 内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释 ...

  7. PHP项目&TP框架&SQL&XSS&架构&路由&调试&写法

    开发基础-TP框架-入口&调试&路由&写法等 参考手册-TP5开发手册-为了掌握了解框架 首页文件看APP_PATH定义-为了后期分析核心代码 全局搜索:THINK_VERSI ...

  8. C++ //类模板分文件编写问题及解决 //第一中解决方式 直接包含源文件 //第二种解决方法 将.h 和 cpp的内容写到一起,将后缀改为.hpp文件

    1 //第一种方式被注释 2 //未被注释是第二种方式 3 //类模板分文件编写问题及解决 4 5 6 #include <iostream> 7 #include <string& ...

  9. 从 HPC 到 AI:探索文件系统的发展及性能评估

    随着 AI 技术的迅速发展,模型规模和复杂度以及待处理数据量都在急剧上升,这些趋势使得高性能计算(HPC)变得越来越必要.HPC 通过集成强大的计算资源,比如 GPU 和 CPU 集群,提供了处理和分 ...

  10. koa-generator - koa 脚手架

    koa-generator - koa 脚手架 npm install -g koa-generator 创建 koa2 /tmp/foo && cd /tmp/foo 资料: 基于N ...