UnrealEngine4入门(二) 实现一个可用按键控制的球体
源码摘自官网guide,加上部分自己的理解和注释
接上篇博客 本文实现一个可用WASD控制滚动的球体
先创建一个可见的球体:
在CollidingPawn.cpp的构造函数ACollidingPawn::ACollidingPawn()中添加一个球体,一个网格组件(mesh),一个弹簧臂和相机,代码如下:
//创建一个球体
USphereComponent* SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent"));
//设置为根组件
RootComponent = SphereComponent;
//设置半径
SphereComponent->InitSphereRadius(40.0f);
SphereComponent->SetCollisionProfileName(TEXT("Pawn")); // 创建并放置网格物体组件,这样我们能看到球体的位置
UStaticMeshComponent* SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation"));
//如果不把网格附加到SphereComponent 就看不到球体
SphereVisual->AttachTo(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));
} // 使用弹簧臂来让相机获得一种平滑、自然的运动。
// 弹簧臂的目的是让视角跟SphereComponent保持一定距离,如果不加,效果像fps游戏的第一视角一样
USpringArmComponent* SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraAttachmentArm"));
SpringArm->AttachTo(RootComponent);
SpringArm->RelativeRotation = FRotator(-.f, .f, .f); //45度角
SpringArm->TargetArmLength = 400.0f; //弹簧臂长度
SpringArm->bEnableCameraLag = true;
SpringArm->CameraLagSpeed = .f; // 创建相机并附加到弹簧臂
// 如果没有相机 什么都看不到
UCameraComponent* Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("ActualCamera"));
Camera->AttachTo(SpringArm, USpringArmComponent::SocketName);
然后配置按键: 打开ue编辑器, 选择编辑->项目设置-> 输入, 然后在右边的axis mappings加入如下设置:

MoveForWard,MoveRight,Turn,Turn_Y 可自定义,表示跟各个按键的绑定关系。
然后创建一个类CollidingPawnMovementComponent继承自PawnMovementComponent(控制pawn移动的组件),我们可以把WASD绑定的行为绑定到这个component上,然后把该component绑定到我们刚才创建的球体上:
CollidingPawnMovementComponent.cpp
#include "Demo.h"
#include "CollidingPawnMovementComponent.h" void UCollidingPawnMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction); // Make sure that everything is still valid, and that we are allowed to move.
if (!PawnOwner || !UpdatedComponent || ShouldSkipUpdate(DeltaTime))
{
return;
} // Get (and then clear) the movement vector that we set in ACollidingPawn::Tick
FVector DesiredMovementThisFrame = ConsumeInputVector().GetClampedToMaxSize(1.0f) * DeltaTime * 150.0f;
if (!DesiredMovementThisFrame.IsNearlyZero())
{
FHitResult Hit;
SafeMoveUpdatedComponent(DesiredMovementThisFrame, UpdatedComponent->GetComponentRotation(), true, Hit); // If we bumped into something, try to slide along it
if (Hit.IsValidBlockingHit())
{
SlideAlongSurface(DesiredMovementThisFrame, .f - Hit.Time, Hit.Normal, Hit);
}
}
};
然后在CollidingPawn.h中加入如下代码:
class UCollidingPawnMovementComponent* OurMovementComponent;
先将movementComponent绑定到刚才加的球体上,在CollidingPawn构造函数底部加入如下代码:
// Create an instance of our movement component, and tell it to update the root.
OurMovementComponent = CreateDefaultSubobject<UCollidingPawnMovementComponent>(TEXT("CustomMovementComponent"));
OurMovementComponent->UpdatedComponent = RootComponent;
为了让游戏中的其他类知道CollidingPawn目前正在使用CollidingPawnMovementComponent作为移动控制组件,需要在CollidingPawn.h中加入以下代码:
virtual UPawnMovementComponent* GetMovementComponent() const override;
然后在CollidingPawn.cpp中加入:
UPawnMovementComponent* ACollidingPawn::GetMovementComponent() const
{
return OurMovementComponent;
}
刚才我们已经将新创建的移动控制组件绑定到了球体上,现在需要把WASD触发的函数绑定到移动组件上,在CollidingPawn中实现往前移动,往左移动,转动视角的三个方法:
// 往前(后)移动
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);
}
然后将这三个方法在ACollidingPawn::SetupPlayerInputComponent中注册:
void ACollidingPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
Super::SetupPlayerInputComponent(InputComponent); InputComponent->BindAxis("MoveForward", this, &ACollidingPawn::MoveForward);
InputComponent->BindAxis("MoveRight", this, &ACollidingPawn::MoveRight);
InputComponent->BindAxis("Turn", this, &ACollidingPawn::Turn);
}
以上就完成了一个可用WASD移动和鼠标控制左右视角的球体
如果上下移动视角,可仿照以上的ACollidingPawn::Turn方法,将NewRotation.Yaw += AxisValue; 改为NewRotation.Pitch += AxisValue;即可
UnrealEngine4入门(二) 实现一个可用按键控制的球体的更多相关文章
- OpenGL ES 2.0 Shader 调试新思路(二): 做一个可用的原型
OpenGL ES 2.0 Shader 调试新思路(二): 做一个可用的原型 目录 背景介绍 请参考前文OpenGL ES 2.0 Shader 调试新思路(一): 改变提问方式 优化 ledCha ...
- 微信硬件H5面板开发(二) ---- 实现一个灯的控制
在第一节中讲解了openApi的调用,这一篇讲一下如何实现一个灯的控制.就用微信提供的lamp例子来做,将代码扒下来(实在是没办法,没有示例),整合到自己的项目中.lamp源码:http://file ...
- UnrealEngine4入门(一) 新建一个c++项目
epic games宣布ue4免费使用(游戏发布之后,每个季度大于3000美元则收取收益的5%)之后,吸引了大批看好VR和AR前景的游戏开发者.不过国内(中文)ue4教程和资料太少,而且一大部分资料都 ...
- Asp.Net MVC4.0 官方教程 入门指南之二--添加一个控制器
Asp.Net MVC4.0 官方教程 入门指南之二--添加一个控制器 MVC概念 MVC的含义是 “模型-视图-控制器”.MVC是一个架构良好并且易于测试和易于维护的开发模式.基于MVC模式的应用程 ...
- Netty入门二:开发第一个Netty应用程序
Netty入门二:开发第一个Netty应用程序 时间 2014-05-07 18:25:43 CSDN博客 原文 http://blog.csdn.net/suifeng3051/article/ ...
- redis入门(二)
目录 redis入门(二) 前言 持久化 RDB AOF 持久化文件加载 高可用 哨兵 流程 安装部署 配置技巧 集群 原理 集群搭建 参考文档 redis入门(二) 前言 在redis入门(一)简单 ...
- 【原创】NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示
前言 NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能.这其中最流行的无非就是MINA和Netty了,MINA目前的主要版本是MINA2.而Netty的主要版本是Netty3和Netty ...
- 电赛菜鸟营培训(二)——STM32F103CB之中断控制
一.中断的概念 中断可以理解为一个有激励给它就会立马给你响应的一个东东.就是说在你执行main函数的内容时,当有这个触发时便会跳转到这个中断内存,执行这段代码. Attention: 1.中断的用法, ...
- DevExpress XtraReports 入门二 创建 data-aware(数据感知) 报表
原文:DevExpress XtraReports 入门二 创建 data-aware(数据感知) 报表 本文只是为了帮助初次接触或是需要DevExpress XtraReports报表的人群使用的, ...
随机推荐
- 数据库——MySQL——多表查询
这里多表,为了方便我只建了两张表,更复杂的表间也就是这些东西,就是复杂程度不一样. 数据源准备 建立一个学生表,和一个班级表 # 建立学生表 create table student( id int ...
- 缓存&跨域
一.前端本地缓存的几种实现方式了解一下 缓存的几种实现方式 序号 名称 参考资料 1 serviceWorker https://blog.csdn.net/ztguang/article/deta ...
- 几个常用的 Git 高级命令
Git 是一款开源优秀的版本管理工具,它最初由 Linus Torvalds 等人开发,用于管理 Linux Kernel 的版本研发.相关的书籍和教程网上琳琅满目,它们多数都详细的介绍其基本的使用和 ...
- django-auth认证模块
########django-auth认证模块######## auth模块:它是django自带的用户认证模块,帮我们解决了登陆,注册,注销,修改密码 等等一系列的操作,封装成一个个方法,方便我们使 ...
- Javascript的加载
最新博客站点:欢迎来访 1. 浏览器加载 (1) 同步加载 在网页中,浏览器加载js文件的方式是通过<script>标签.如下所示: //内嵌脚本 <script type= ...
- poj 2553 The Bottom of a Graph : tarjan O(n) 存环中的点
/** problem: http://poj.org/problem?id=2553 将所有出度为0环中的点排序输出即可. **/ #include<stdio.h> #include& ...
- ABAP术语-Authorization Check
Authorization Check 原文:http://www.cnblogs.com/qiangsheng/archive/2007/12/19/1005490.html Check perfo ...
- click与on的区别
click只能用于html在注册事件之后没有变化的:on用于html在注册事件后,还会通过JS脚本添加一些按钮,并者希望这些按钮也会有之前注册事件的按钮同样的事件话,就需要用on去为按钮的父节点去注册 ...
- Spring常见面试题
本文是通过收集网上各种面试指南题目及答案然后经过整理归纳而来,仅仅是为了方便以后回顾,无意冒犯各位原创作者. Spring框架 1. 什么是Spring? Spring 是个java企业级应用的开源开 ...
- JZOJ 5943. 树
Description