苹果真的偷了施乐 苹果的 GUI 吗

UE4蓝图教程,实现伤害,以及弹药系统_udk吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:12,136贴子:
UE4蓝图教程,实现伤害,以及弹药系统收藏
先建立一个空项目选择FPS的模板先来说弹药系统吧,其实是非常简单的找到这个角色蓝图打开它添加一个变量变量类型设置成整数型,名称为“弹药量”不要忘记设置弹药量的默认值选中变量就可以设置找到这个部分连上,现在已经有效果了,为了看到效果添加一个连上后会自动出现这个不用管运行游戏,开火你会看到屏幕上面的输出信息说明已经成功了,但是你会发现弹药到0的时候还是可以继续开火而,下面的教程是如何禁止开火这样连接,= = 好了现在弹药系统你已经实现了!下面是把弹药量显示出来的教程在内容浏览器里右键打开它,拖出一个文本块到屏幕中这样连接在到角色蓝图中添加一个beginplay连上(右键&用户界面&创建控件)在连一个Add to viewport完成更正一个问题这个地方不应该用 == 判断 应该用&
3D双端东方魔幻网游「大青云」勾魂公测,穿越逆转,封神故事,全新演绎!
下面是实现伤害的教程添加一个叫做生命值的整数型变量,默认值是100我就不说的那么细了,这些太基础给角色添加一个box当做角色的身体如图连接再打开你的FirstPersonProjectile碰撞类型改成trigger已经完成了拖出一个“你”到场景中向他不停的射击,如果他消失了说明你成功了
项目文件正在上传中
项目文件下载
顶一个,看上去不错
奇峰这个教程真好!
似乎是少了一些图。。mark一下
手机看却图,电脑是正常的,我也不知道是怎么回事
文档翻译,年终钜惠!注册就送268元体验金!
先赞一个,希望奇峰大神时间土豪以后能行为树节点解释教程(⊙o⊙)…
支持原创教学
大神,来段完整的视频
可不可以写成一个武器系统和角色分开呢?
类型转换为 firstpersoncharacter
怎么好的贴!怎么能不顶呢?顺便问一下ue4可以把布料设置在角色身上吗?比如披风啊!裤子啊!
我想学习这个 应该从哪里开始学呢
这个怎么设置射程?
大神我枪都不会搞
我的连接好为啥不打印ne ? 是不是落下细节了?
引入到第三人称射击游戏能不能用_(:з」∠)_
楼主选中 变量怎么设置 能具体一下吗 我点了 没任何变化 小白 求教 我是4.11版本的
是不是学我的,说。我们也用了结构体和跨蓝图调用变量
楼主,我想加个准星,怎么加呢?
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或UE4 TMap - pengyingh - 博客园
Key-Value Hash
enum class EPieceType
struct FPiece
int32 PlayerId;
EPieceType T
FIntPoint P
FPiece(int32 InPlayerId, EPieceType InType, FIntVector InPosition) :
PlayerId(InPlayerId),
Type(InType),
Position(InPosition)
class FBoard
// Using a TMap, we can refer to each piece by its position
TMap&FIntPoint, FPiece& D
bool HasPieceAtPosition(FIntPoint Position)
return Data.Contains(Position);
FPiece GetPieceAtPosition(FIntPoint Position)
return Data[Position];
void AddNewPiece(int32 PlayerId, EPieceType Type, FIntPoint Position)
FPiece NewPiece(PlayerId, Type, Position);
Data.Add(Position, NewPiece);
void MovePiece(FIntPoint OldPosition, FIntPoint NewPosition)
FPiece Piece = Data[OldPosition];
Piece.Position = NewP
Data.Remove(OldPosition);
Data.Add(NewPosition, Piece);
void RemovePieceAtPosition(FIntPoint Position)
Data.Remove(Position);
void ClearBoard()
Data.Empty();
TMap&int32, FString& FruitM
add添加元素
FruitMap.Add(5, TEXT("Banana"));
FruitMap.Add(2, TEXT("Grapefruit"));
FruitMap.Add(7, TEXT("Pineapple"));
// FruitMap == [
{ Key:5, Value:"Banana"
{ Key:2, Value:"Grapefruit" },
{ Key:7, Value:"Pineapple"
add同key元素会覆盖
FruitMap.Add(2, TEXT("Pear"));
// FruitMap == [
{ Key:5, Value:"Banana"
{ Key:2, Value:"Pear"
{ Key:7, Value:"Pineapple" }
不带值得键会重载,初始化默认值""
FruitMap.Add(4);
// FruitMap == [
{ Key:5, Value:"Banana"
{ Key:2, Value:"Pear"
{ Key:7, Value:"Pineapple" },
{ Key:4, Value:""
Emplace&代替 Add,避免插入映射时创建出临时文件:
FruitMap.Emplace(3, TEXT("Orange"));
// FruitMap == [
{ Key:5, Value:"Banana"
{ Key:2, Value:"Pear"
{ Key:7, Value:"Pineapple" },
{ Key:4, Value:""
{ Key:3, Value:"Orange"
使用 Append 函数进行合并即可插入来自另一个映射的所有元素:同key覆盖
TMap&int32, FString& FruitMap2;
FruitMap2.Emplace(4, TEXT("Kiwi"));
FruitMap2.Emplace(9, TEXT("Melon"));
FruitMap2.Emplace(5, TEXT("Mango"));
FruitMap.Append(FruitMap2);
// FruitMap == [
{ Key:5, Value:"Mango"
{ Key:2, Value:"Pear"
{ Key:7, Value:"Pineapple" },
{ Key:4, Value:"Kiwi"
{ Key:3, Value:"Orange"
{ Key:9, Value:"Melon"
for (auto& Elem :FruitMap)
FPlatformMisc::LocalPrint(
*FString::Printf(
TEXT("(%d, \"%s\")\n"),
*Elem.Value
// Output:
// (5, "Mango")
// (2, "Pear")
// (7, "Pineapple")
// (4, "Kiwi")
// (3, "Orange")
// (9, "Melon")
映射还提供其自身的迭代器类型,以便对迭代进行更直接的控制。CreateIterator&函数提供对元素的读写访问,CreateConstIterator&函数提供只读访问。迭代器对象自身提供&Key()&和&Value()&函数进行键和值访问。代码中可使用任意形式:
for (auto It = FruitMap.CreateConstIterator(); It; ++It)
FPlatformMisc::LocalPrint(
*FString::Printf(
TEXT("(%d, \"%s\")\n"),
// same as It-&Key
*It.Value() // same as *It-&Value
使用&Num&函数可询问映射保存的元素数量:
int32 Count = FruitMap.Num();
// Count == 6
可结合键使用索引运算符 [],获得给定键相关数值的引用。在非常量映射上调用运算符 [] 将返回非常量引用,而在常量映射上调用将返回常量引用。如键不存在,将出现断言:
FString Val7 = FruitMap[7];
// Val7 == "Pineapple"
FString Val8 = FruitMap[8]; // assert!
可使用&Contains&函数进行检查,确定特定键是否存在于映射中:
bool bHas7 = FruitMap.Contains(7);
bool bHas8 = FruitMap.Contains(8);
// bHas7 == true
// bHas8 == false
多数情况下,查找元素无需知晓键是否存在。使用后面带操作符 [] 的 Contains 函数将进行键的双重查找,最好不要进行此操作。使用&Find函数可进行单一查找,返回指向找到元素数值的指针,而非引用;键不存在时,将返回 null。
FString* Ptr7 = FruitMap.Find(7);
FString* Ptr8 = FruitMap.Find(8);
// *Ptr7 == "Pineapple"
Ptr8 == nullptr
如在常量映射上调用,返回的指针也将为常量。
FindOrAdd&函数将搜索给定键并返回引用到关联值;如键不存在,则在返回引用前将添加默认构建的值。因可能需要添加,此函数无法在常量映射上被调用:
FString& Ref7 = FruitMap.FindOrAdd(7);
== "Pineapple"
// FruitMap == [
{ Key:5, Value:"Mango"
{ Key:2, Value:"Pear"
{ Key:7, Value:"Pineapple" },
{ Key:4, Value:"Kiwi"
{ Key:3, Value:"Orange"
{ Key:9, Value:"Melon"
FString& Ref8 = FruitMap.FindOrAdd(8);
// FruitMap == [
{ Key:5, Value:"Mango"
{ Key:2, Value:"Pear"
{ Key:7, Value:"Pineapple" },
{ Key:4, Value:"Kiwi"
{ Key:3, Value:"Orange"
{ Key:9, Value:"Melon"
{ Key:8, Value:""
注意:如已发生重新分配,此处的 Ref7 引用可能已被 FruitMap.FindOrAdd(8) 的调用无效化。
无视&FindRef&函数的名称,因为它搜索键返回的是值,而非引用。如找到键,则返回关联值的副本;如未找到,则返回默认构建值类型。这会导致和 FindOrAdd 相似的行为,但因 FindRef 函数返回的是值而非引用,映射将不会被修改,因此可在常量对象上被调用:
FString Val7 = FruitMap.FindRef(7);
FString Val6 = FruitMap.FindRef(6);
== "Pineapple"
// FruitMap == [
{ Key:5, Value:"Mango"
{ Key:2, Value:"Pear"
{ Key:7, Value:"Pineapple" },
{ Key:4, Value:"Kiwi"
{ Key:3, Value:"Orange"
{ Key:9, Value:"Melon"
{ Key:8, Value:""
FindKey&函数允许执行逆向查找(找到键给定值)。使用该函数时需注意,因为值和键不同,不会被散列。因此键查找是线性操作。此外,数值不保证为唯一。因此,如映射包含重复值,键返回的特定值为任意的。
const int32* KeyMangoPtr
= FruitMap.FindKey(TEXT("Mango"));
const int32* KeyKumquatPtr = FruitMap.FindKey(TEXT("Kumquat"));
// *KeyMangoPtr
KeyKumquatPtr == nullptr
GenerateKeyArray&和&GenerateValueArray&函数分别允许以全部键和值的副本对阵列进行填入。在两种情况下,被传递的阵列在填入前会被清空,因此元素的生成数量将始终等于映射中的元素数量。
TArray&int32&
TArray&FString& FruitV
FruitKeys.Add(999);
FruitKeys.Add(123);
FruitMap.GenerateKeyArray
(FruitKeys);
FruitMap.GenerateValueArray(FruitValues);
// FruitKeys
== [ 5,2,7,4,3,9,8 ]
// FruitValues == [ "Mango","Pear","Pineapple","Kiwi","Orange",
"Melon","" ]
使用&Remove&函数并提供要删除的元素键即可将元素从映射移除:
FruitMap.Remove(8);
// FruitMap == [
{ Key:5, Value:"Mango"
{ Key:2, Value:"Pear"
{ Key:7, Value:"Pineapple" },
{ Key:4, Value:"Kiwi"
{ Key:3, Value:"Orange"
{ Key:9, Value:"Melon"
移除元素将在数据结构(在 Visual Studio 的观察窗口中可视化映射时可看到)中留下洞,但为保证清晰性,此处将忽略洞。
FindAndRemoveChecked&函数可用于移除元素,并返回关联值。名称中的 checked 部分意味着将检查键是否存在。如不存在,则断言:
FString Removed7 = FruitMap.FindAndRemoveChecked(7);
// Removed7 == "Pineapple"
// FruitMap == [
{ Key:5, Value:"Mango"
{ Key:2, Value:"Pear"
{ Key:4, Value:"Kiwi"
{ Key:3, Value:"Orange" },
{ Key:9, Value:"Melon"
FString Removed8 = FruitMap.FindAndRemoveChecked(8); // assert!
RemoveAndCopyValue&函数作用相似,但会引用将被传出的值类型,并返布尔型说明键是否已找到。它可结合缺失键使用,不会出现运行时错误。如未找到键,调用将返回 false,传递对象和映射保持不变:
bool bFound2 = FruitMap.RemoveAndCopyValue(2, Removed);
// bFound2
// Removed
// FruitMap == [
{ Key:5, Value:"Mango"
{ Key:4, Value:"Kiwi"
{ Key:3, Value:"Orange" },
{ Key:9, Value:"Melon"
bool bFound8 = FruitMap.RemoveAndCopyValue(8, Removed);
// bFound8
// Removed
== "Pear", i.e. unchanged
// FruitMap == [
{ Key:5, Value:"Mango"
{ Key:4, Value:"Kiwi"
{ Key:3, Value:"Orange" },
{ Key:9, Value:"Melon"
最后,使用&Empty&函数可将所有元素移除:
TMap&int32, FString& FruitMapCopy = FruitM
// FruitMapCopy == [
{ Key:5, Value:"Mango"
{ Key:4, Value:"Kiwi"
{ Key:3, Value:"Orange" },
{ Key:9, Value:"Melon"
FruitMapCopy.Empty();
// FruitMapCopy == []
可对 TMap 进行临时排序。映射上的下次迭代将以排序顺序展示元素,之后对映射进行的修改可能导致映射重新排序。排序并不稳定,因此相等元素可能以各种排列方式出现。
使用&KeySort&和&ValueSort&函数可分别按键和值进行排序,两个函数均接受二元谓词指定排序顺序:
FruitMap.KeySort([](int32 A, int32 B) {
return A & B; // sort keys in reverse
// FruitMap == [
{ Key:9, Value:"Melon"
{ Key:5, Value:"Mango"
{ Key:4, Value:"Kiwi"
{ Key:3, Value:"Orange" }
FruitMap.ValueSort([](const FString& A, const FString& B) {
return A.Len() & B.Len(); // sort strings by length
// FruitMap == [
{ Key:4, Value:"Kiwi"
{ Key:5, Value:"Mango"
{ Key:9, Value:"Melon"
{ Key:3, Value:"Orange" }
和 TArray 一样,TMap 是常规值类型,可通过标准复制构建函数或赋值运算符进行复制。因映射严格拥有其元素,映射复制为深,因此新映射将拥有其自身的元素副本:
TMap&int32, FString& NewMap = FruitM
NewMap[5] = "Apple";
NewMap.Remove(3);
// FruitMap == [
{ Key:4, Value:"Kiwi"
{ Key:5, Value:"Mango"
{ Key:9, Value:"Melon"
{ Key:3, Value:"Orange" }
// NewMap == [
{ Key:4, Value:"Kiwi"
{ Key:5, Value:"Apple" },
{ Key:9, Value:"Melon" }
TMap 还支持移动语意。使用&MoveTemp&函数可调用此语意。在移动后,源映射将保证为空:
FruitMap = MoveTemp(NewMap);
// FruitMap == [
{ Key:4, Value:"Kiwi"
{ Key:5, Value:"Apple" },
{ Key:9, Value:"Melon" }
// NewMap == []
TMap 也拥有&slack&的概念,可用于优化映射的填入。Reset&与 Empty() 调用作用相似,但不会释放元素之前使用的内存。
FruitMap.Reset();
// FruitMap == [&invalid&, &invalid&, &invalid&]
此处映射按照 Empty 相同的方式进行清空,但用于储存的内存不会被释放,仍为 slack。
TMap 不会像 TArray::Max() 一样提供检查预分配元素的数量,但仍然支持预分配 slack。Reserve 函数可用于在添加之前预分配特定数量元素的 slack。
FruitMap.Reserve(10);
for (int32 i = 0; i != 10; ++i)
FruitMap.Add(i, FString::Printf(TEXT("Fruit%d"), i));
// FruitMap == [
{ Key:9, Value:"Fruit9" },
{ Key:8, Value:"Fruit8" },
{ Key:1, Value:"Fruit1" },
{ Key:0, Value:"Fruit0" }
注意:Slack 会导致新元素以倒序被添加。这是为什么不可信赖映射中元素排序的原因。
Shrink&函数和 TArray 中相等函数的相同之处是 - 它将从容器末端移除被废弃的 slack。然而,因为 TMap 允许其数据结构中存在洞,这只会从遗留在结构末端的洞上移除 slack。
for (int32 i = 0; i != 10; i += 2)
FruitMap.Remove(i);
// FruitMap == [
{ Key:9, Value:"Fruit9" },
&invalid&,
{ Key:7, Value:"Fruit7" },
&invalid&,
{ Key:5, Value:"Fruit5" },
&invalid&,
{ Key:3, Value:"Fruit3" },
&invalid&,
{ Key:1, Value:"Fruit1" },
FruitMap.Shrink();
// FruitMap == [
{ Key:9, Value:"Fruit9" },
&invalid&,
{ Key:7, Value:"Fruit7" },
&invalid&,
{ Key:5, Value:"Fruit5" },
&invalid&,
{ Key:3, Value:"Fruit3" },
&invalid&,
{ Key:1, Value:"Fruit1" }
注意:只有一个无效元素已从 Shrink 调用移除,因为末端只有一个洞。Compact&函数可用于在缩小前移除所有洞。
// FruitMap == [
{ Key:9, Value:"Fruit9" },
{ Key:7, Value:"Fruit7" },
{ Key:5, Value:"Fruit5" },
{ Key:3, Value:"Fruit3" },
{ Key:1, Value:"Fruit1" },
&invalid&,
&invalid&,
&invalid&,
FruitMap.Shrink();
// FruitMap == [
{ Key:9, Value:"Fruit9" },
{ Key:7, Value:"Fruit7" },
{ Key:5, Value:"Fruit5" },
{ Key:3, Value:"Fruit3" },
{ Key:1, Value:"Fruit1" }
只要类型拥有一个运算符 == 和一个非成员 GetTypeHash 重载,则可被用作 TMap 的一个 KeyType,无需进行任何修改。然而,不便于重载这些函数时可将类型作为键使用。在这些情况下,您可提供自定义的&KeyFuncs。
KeyFuncs 需要 2 个 typedefs 和 3 个静态函数的定义:
KeyInitType&- 用于传递键
ElementInitType&- 用于传递元素
KeyInitType GetSetKey(ElementInitType Element)&- 返回元素的键。
bool Matches(KeyInitType A, KeyInitType B)&- 返回 A 和 B 是否相等。
uint32 GetKeyHash(KeyInitType Key)&- 返回键的散列值。
KeyInitType 和 ElementInitType 是键类型和元素类型普通传递惯例的 typedefs。它们通常为浅显类型的一个值和非浅显类型的一个常量引用。需牢记:映射的元素类型为 TPair。
自定义 KeyFuncs 的实例如下:
struct FMyStruct
// String which identifies our key
FString UniqueID;
// Some state which doesn't affect struct identity
float SomeF
explicit FMyStruct(float InFloat)
:UniqueID (FGuid::NewGuid().ToString())
, SomeFloat(InFloat)
template &typename ValueType&
struct TMyStructMapKeyFuncs :
BaseKeyFuncs&
TPair&FMyStruct, ValueType&,
typedef BaseKeyFuncs&
TPair&FMyStruct, ValueType&,
typedef typename Super::ElementInitType ElementInitT
typedef typename Super::KeyInitType
static KeyInitType GetSetKey(ElementInitType Element)
return Element.Key.UniqueID;
static bool Matches(KeyInitType A, KeyInitType B)
return A.Compare(B, ESearchCase::CaseSensitive) == 0;
static uint32 GetKeyHash(KeyInitType Key)
return FCrc::StrCrc32(*Key);
此处类型拥有一个唯一辨识符将作为其状态的部分,但还存在一些对辨识其身份没有帮助的其他状态。GetTypeHash 和运算符 == 不适合在此使用。因为它会使运算符 == 忽略部分状态,而且 GetTypeHash 需要和运算符 == 相匹配;如运算符 == 已被正确定义,则无法进行。然而,出于在映射中识别此类型的目的,我们可只使用状态的 UniqueID。
最后,我们将继承&BaseKeyFuncs,因为它有助于为我们进行一些内容的定义,包括 KeyInitType 和 ElementInitType。直接将它们从 Super 拉到派生类中,以便在实现的剩余部分中使用。
BaseKeyFuncs 接受两个模板参数:映射的元素类和键的类型(从 GetSetKey 返回的对象)。和所有的映射一样,元素类型是 TPair,接受 FMyStruct 作为其 KeyType、接受 TMyStructMapKeyFuncs 的模板参数作为其 ValueType。我们使替代 KeyFuncs 成为模板,使 ValueType 以每个函数为基础进行指定;每次创建 FMyStruct 上有键的 TMap 时,均无需对新的 KeyFuncs 进行定义。第二个 BaseKeyFuncs 参数是键类型,不要将其与 TPair 的&KeyType&混淆。此 KeyType 存储在元素的键区中。需要将 FMyStruct::UniqueID 作为键使用,因此我们需要在此处指定 FString。
然后对所需要的 3 个 KeyFuncs 静态函数进行指定。第一个是 GetSetKey,被给定一个元素类型,将返回键。我们的元素类型是 TPair,key 是 UniqueID,因此我们将直接返回。
第二个静态函数是 Matches,它接受两个元素的键(已使用 GetSetKey 从元素类型中提取),然后将它们进行比较,确定是否为相等。FString 的运算符 == 不区分大小写,但我们需要执行区分大小写的搜索,因此应结合适当的选项使用 FString::Compare 函数。
最后,GetKeyHash 静态函数接受提取键,并返回一个它的散列值。再次提醒,FString 的 GetTypeHash 行为会忽略大小写,因此我们调用一个区分大小写的 FCrc 函数进行散列的计算。
现在我们可使用新 KeyFuncs 创建一个 TMap。我们还需要提供一个分配器,因为 KeyFuncs 参数在最后,但我们可对默认进行替代:
FMyStruct,
FDefaultSetAllocator,
TMyStructMapKeyFuncs&int32&
& MyMapToInt32;
// Add some elements
MyMapToInt32.Add(FMyStruct(3.14f), 5);
MyMapToInt32.Add(FMyStruct(1.23f), 2);
// MyMapToInt32 == [
UniqueID:"D06AABBA466CAA4EB62D2F",
SomeFloat:3.14f
UniqueID:"AD6C9C5DCB",
SomeFloat:1.23f
提供自己的 KeyFuncs 时需注意:TMap 假定对比相等的两个项目使用 KeyFuncs::Matches 从 KeyFuncs::GetKeyHash 返回相同的值。此外,如修改现有映射元素的键时会改变任意一个这些函数的结果,则会被理解为未定义行为,因为这会无效化 TMap 的内部散列。使用默认 KeyFuncs 时,这些规则还会应用到运算符 == 和 GetKeyHash 的重载。
CountBytes&和&GetAllocatedSize&函数用于估计阵列当前应用的内存量。CountBytes 接受 FArchive,GetAllocatedSize 可被直接调用。它们常用于统计报告。
Dump&函数接受 FOutputDevice 并写出关于映射内容的部分实现信息。它通常用于调试。1309人阅读
填坑UE4(21)
一、C++创建
1.&&&&&&创建一个C++类,继承自Character,取名MyThirdCharacter
2.&&&&&&在头文件中声明一个摄像机目标点CameraBoom,一个摄像机FollowCamera,再声明两个控制移动的函数,与跳跃的函数
#include &GameFramework/Character.h&
#include &MyThirdCharacter.generated.h&
class MYFIRSTNULLPROJECT_API AMyThirdCharacter : public ACharacter
GENERATED_BODY()
//摄像机目标点
class USpringArmComponent* CameraB
//跟随相机
class UCameraComponent* FollowC
// Sets default values for this character's properties
AMyThirdCharacter();
// Called when the game starts or when spawned
virtual void BeginPlay()
// Called every frame
virtual void Tick( float DeltaSeconds )
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent)
//控制前后移动
void MoveForward(float value);
//控制左右移动
void MoveRight(float value);
3.&&&&&&在构造函数中,初始化一些控制参数与创建自己所需要的组件
4.&&&&&&在输入中,处理控制函数
#include &MyFirstNULLProject.h&
#include &MyThirdCharacter.h&
// Sets default values
AMyThirdCharacter::AMyThirdCharacter()
// 设置这个Character每帧调用Tick函数
PrimaryActorTick.bCanEverTick =
//设置控制器不受旋转影响
bUseControllerRotationPitch =
bUseControllerRotationRoll =
bUseControllerRotationYaw =
//设置胶囊碰撞体的大小
GetCapsuleComponent()-&InitCapsuleSize(42.f, 96.f);
//设置控制器在移动时可以旋转
GetCharacterMovement()-&bOrientRotationToMovement =
//在本地找到模型文件,并赋值给mesh设置相应参数
static ConstructorHelpers::FObjectFinder&USkeletalMesh& playerPawn(TEXT(&/Game/Animation/mon_goblinWizard/mon_goblinWizard&));
GetMesh()-&SetSkeletalMesh(playerPawn.Object);
GetMesh()-&SetRelativeLocation(FVector(0, 0, -95.f));
GetMesh()-&SetRelativeRotation(FRotator(0,-90.f,0.f));
//创建一个摄像机目标点 USpringArmComponent 设置父级 长度 可旋转
CameraBoom = CreateDefaultSubobject&USpringArmComponent&(TEXT(&CameraBoom&));
CameraBoom-&AttachTo(RootComponent);
CameraBoom-&TargetArmLength = 300;
CameraBoom-&bUsePawnControlRotation =
//创建一个摄像机 绑定到CameraBoom下,不受控制旋转的影响 受CameraBoom旋转影响
FollowCamera = CreateDefaultSubobject&UCameraComponent&(TEXT(&FollowCamera&));
FollowCamera-&AttachTo(CameraBoom, USpringArmComponent::SocketName);
FollowCamera-&bUsePawnControlRotation =
// Called when the game starts or when spawned
void AMyThirdCharacter::BeginPlay()
Super::BeginPlay();
//设置初始位置
RootComponent-&SetWorldLocation(FVector(0, 0, 0));
// Called every frame
void AMyThirdCharacter::Tick( float DeltaTime )
Super::Tick( DeltaTime );
// Called to bind functionality to input
//处理输入事件
void AMyThirdCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)
Super::SetupPlayerInputComponent(InputComponent);
InputComponent-&BindAxis(&MoveForward&, this, &AMyThirdCharacter::MoveForward);
InputComponent-&BindAxis(&MoveRight&, this, &AMyThirdCharacter::MoveRight);
InputComponent-&BindAxis(&Turn&, this, &APawn::AddControllerYawInput);
InputComponent-&BindAxis(&LookUp&, this, &APawn::AddControllerPitchInput);
InputComponent-&BindAction(&JumpBtn&,IE_Pressed,this, &ACharacter::Jump);
InputComponent-&BindAction(&JumpBtn&, IE_Released,this, &ACharacter::StopJumping);
void AMyThirdCharacter::MoveForward(float value)
if ((Controller != NULL) && (value != 0.0f))
// 找到当前的前方向
const FRotator Rotation = Controller-&GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
// 获取到前方向
const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
AddMovementInput(Direction, value);
void AMyThirdCharacter::MoveRight(float value)
if ((Controller != NULL) && (value != 0.0f))
// 找到当前的前方向
const FRotator Rotation = Controller-&GetControlRotation();
const FRotator YawRotation(0, Rotation.Yaw, 0);
// 获取到右方向
const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
AddMovementInput(Direction, value);
5.&&&&&&设置GameMode的DefaultPawnClass,编译运行
二、蓝图创建
1.创建一个新的蓝图,继承自Character,取名MyThirdHero
2.双击打开蓝图,选择MyThirdHero,确定bUseControllerRotationPitch,bUseControllerRotationRoll,bUseControllerRotationYaw均为false,不受旋转影响
3.选中mesh,在SkeletalMesh中,选择自己的导入的模型,并设置位置旋转等相应参数,可在Viewport中看见详细情况
4.选中CapsuleComponent,在Shape栏下,可以根据模型大小调整碰撞胶囊的大小、
5.创建一个摄像机目标点,点击AddComponent,在Camera分类中有一个Spring Arm,点击创建,选中在右边可以设置他的参数,比如TargetArm
Length则是,他与摄像机的距离,这里主要还得勾选UsePawn Control Rotation,让他可以旋转
6.创建一个摄像机,让他作为SpringArm的子节点,确定摄像机的Use Pawn Control Rotation为不勾选状态,摄像机跟随父节点的旋转
7.选中CharacterMovement,确定OrientRotationtoMovement为勾选状态,让他可以在移动的时候旋转
8.开始编写输入控制,让角色可以动起来
9.编译,设置GameMode的DefaultPawnClass,编译,运行
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:97048次
积分:1943
积分:1943
排名:第16309名
原创:89篇
评论:211条
阅读:9958
阅读:17932
(1)(7)(4)(4)(10)(5)(8)(10)(3)(4)(8)(4)(4)(2)(1)(1)(6)(5)(4)(2)

我要回帖

更多关于 施乐会是真的吗 的文章

 

随机推荐