实例甜点 Unreal Engine 4迷你教程(6)之三个重要基础操作SpawnActor、TArray的Add和Remove
本小节的教程需要完成前置教程:建议阅读《实例甜点 Unreal Engine 4迷你教程(5)》,因为5里面提到了本节的工程,不过也可以在不看5的前提下直接阅读本教程。
第一步:Empty的工程(C++ Basic Code);
第二步:新建MyActor类;
第三步:新建一个叫做sand的Actor类:
Tips:我在调试过程中遇到很恶心的事情,就是修改了代码之后发现没有用,这可能是热加载失败的表现,请重新打开UE4(VS不用重启)。
第四步:
Sand文件不用修改,只需要修改MyActor的文件如下:
▼代码开始 // Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "sand.h" #include "MyActor.generated.h" UCLASS() class EMPTY_API AMyActor : public AActor { GENERATED_BODY() public: // Sets default values for this actor's properties AMyActor(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; public: // Called every frame virtual void Tick(float DeltaTime) override; UPROPERTY() TArray<Asand* > arr;//【注意最好有UPROPERTY()标注】 }; ▲代码结束 ▼代码开始 // Fill out your copyright notice in the Description page of Project Settings. #include "MyActor.h" // Sets default values AMyActor::AMyActor() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; } // Called when the game starts or when spawned void AMyActor::BeginPlay() { Super::BeginPlay(); for (auto i = 0; i < 4; i++) { Asand* newSand = GetWorld()->SpawnActor<Asand>(Asand::StaticClass());//【SpawnActor的方法】 arr.Add(newSand);//【Add的方法】 UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("[log by wenjie] i ve added a sand tinto arr"));//【打印的方法】 } } // Called every frame void AMyActor::Tick(float DeltaTime) { Super::Tick(DeltaTime); static int32 Timer = 0; if (Timer++ == 20) { UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("[log by wenjie] Time==20")); /* 不正确的方法: for (auto i : arr) {//【不建议的remove方法】 arr.Remove(i); UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("[log by wenjie] removed one instance")); } 上面的remove的方法不十分优雅: 在执行过程中报如下错误【可能死机也可能不死机】: LogOutputDevice:Error: === Handled ensure: === LogOutputDevice:Error: Ensure condition failed: Lhs.CurrentNum == Lhs.InitialNum [File:D:\UE4.16.3\UE_4.16\Engine\Source\Runtime\Core\Public\Containers/Array.h] [Line: 197] LogOutputDevice:Error: Array has changed during ranged-for iteration! 以下提供恰当的remove方法: //参考资料: //https://forums.unrealengine.com/showthread.php?69383-A-Little-Tip-Remove-elements-from-an-array-in-one-pass-with-a-reverse-for-loop */ for (auto i = arr.Num() - 1; i >= 0; i--) { arr.RemoveAt(i); UE_LOG(LogTemp, Warning, TEXT("%s"), *FString("[log by wenjie] removed one instance")); } } } ▲代码结束
补充说明:不是说remove(实例引用)不对,而是不应该把它和foreachloop搭配,正确的做法是倒序移除。
你看,完全没有红色的报错:
——小江村儿的文杰 zouwj5@qq.com 2017年8月7日21:50:52