日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

虚幻引擎C++开发学习(三)

發布時間:2023/12/14 c/c++ 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 虚幻引擎C++开发学习(三) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這一章,我們要實現一個俯視視角的坦克小游戲,玩家可以操作坦克在地圖中移動。敵人是固定的,但是具備一定的AI,可以瞄準玩家,并且在玩家進入攻擊范圍后,對玩家進行攻擊。如果玩家被摧毀,則游戲結束。反之,玩家需要摧毀所有的敵人后,達成游戲勝利的條件。

一、前言介紹

在開始之前,我們先介紹這一章會涉及到的內容:

  • 創建一個坦克,可以在地圖中自由移動
  • 解決輸入問題(WASD移動,鼠標點擊射擊,鼠標轉動明確攻擊方向)
  • 創建一個敵方炮臺類
  • 添加開火功能,玩家和炮臺都可以開火攻擊敵人
  • 添加血條、傷害和破壞效果
  • 添加HUD的勝利和失敗界面

關于綁定輸入,這里就不多贅述,如下圖:

關于素材和地圖,這里也不是我們的重點,暫時略過,感興趣的可以自行尋找。我們直接進入編碼步驟。

二、創建BasePawn

1.1?創建BasePawn

由于我們這里會有兩個pawn(玩家和敵人),我們可以先創建一個BasePawn類。這將具有坦克和炮塔共享的基本功能。然后我們就可以創建我們的兩個子類,炮臺和坦克。

我們新建一個C++類:

?但是哪一個才最適合我們想要做的事情?

  • Actor類,可以被放置在世界中,有相應的視覺表現
  • Pawn類,可由控制器擁有,可以處理運動輸入
  • Character類,有一些特定于角色的東西,適合雙腿的運動模式或類似飛行和游泳運動。

所以,Pawn應該是我們想要的。我們創建對應的C++類即可。

1.2 Component

USceneComponent:

  • has a transform(旋轉或位置)
  • supports attachment(這意味著我們可以將其他組件附加到場景組件)
  • no visual representation

UCapsuleComponent:

  • handle collision

UStaticMeshComponent:

  • visual representation

我們討論組件的目的,是要理清之后的操作思路。我們首先知道我們的Pawn有自己的root component,它的類型是USceneComponent。我們知道他是沒有visual representation,是不可見的。

但是我們可以使用其他類型從SceneComponent(場景組件)派生的對象重新assign該根組件。我們知道UCapsuleComponent來自SceneComponent。如果我們創建一個Capsule,我們可以assign這個,作為Root,替換默認的SceneComponent:

RootComponent(UCapsuleComponent) = CapsuleComp(UCapsuleComponent)

具體的思路可以見下圖:

藍圖中,我們創建一個Actor藍圖,然后添加Capsule,接著添加靜態網格體組件,并選擇車身網格體,同理添加炮臺。

?結果:

?在C++中,我們先在.h中定義

private:UPROPERTY()class UCapsuleComponent* CapsuleComp;

然后在.cpp中添加頭文件,并將其設置為Root

CapsuleComp = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule Collider")); RootComponent = CapsuleComp;

這樣我們將BasePawn拖入場景中時,會有:

?接下來我們要將BaseMesh和TurretMesh,attach到Root上(和之前的操作相同):

UPROPERTY() UStaticMeshComponent* BaseMesh;UPROPERTY() UStaticMeshComponent* TurretMesh;UPROPERTY() USceneComponent* ProjectileSpawnPoint; BaseMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Base Mesh")); BaseMesh->SetupAttachment(CapsuleComp);TurretMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Turret Mesh")); TurretMesh->SetupAttachment(BaseMesh);ProjectileSpawnPoint = CreateDefaultSubobject<USceneComponent>(TEXT("Spawn Point")); ProjectileSpawnPoint->SetupAttachment(TurretMesh);

接下來我們可以為BasePawn創建一個基于BasePawn的藍圖類,這樣我們進入后,可以看見這樣的組件結構:

?然后我們還要創建一個藍圖類作為敵人,命名為BP_PawnTurret。

1.3 UPROPERTY

但是有一點要注意的是,當我們選中左邊的組件時,右邊的細節面板內容不見了。這是因為 C++ 方面的藍圖沒有任何內容。我們可以通過UPROPERTY來對齊進行操作。

UPROPERTY Specifiers:

DefaultsInstanceEvent Graph(l藍圖的事件圖表)
Read OnlyVisibleAnyWhereBluePrintReadOnly
VisibleDefaultsOnlyVisibleInstanceOnly
Read/Write(set)EditAnyWhereBluePrintReadWrite
EditDefaultOnly

EditInstanceOnly

關于事件圖表,我們在C++中可以使用:

UPROPERTY(VisibleAnyWhere,BluePrintReadWrite) int32 visibleAnywhere = 12;

這樣我們在事件圖表中搜索visibleAnywhere,就會有兩個節點Set和Get。

其次還有一個需要注意的點是,對于private,會有報錯(同樣對于BluePrintReadOnly):

BluePrintReadWrite should not be used on private members

對于這種情況,我們仍然可以在事件圖表中訪問私有變量,我們需要添加:

UPROPERTY(VisibleAnyWhere,BluePrintReadWrite,meta = (AllowPrivateAccess = "true"))

當然我們可以為其添加Category,這個在之前有提到過。

在這一步之后,別忘了給坦克和炮臺添加網格體,移動project point位置

二 Moving Tank

2.1 Component

要實現坦克的移動和玩家輸入,炮臺的站立,我們要創建新的派生類:

其次,為了實現坦克的移動,我們首先要保證視角跟隨,即坦克的身后有一個攝像機——Camera Component(UCameraComponent)和一個固定距離的Spring arm component(USpingArmComponent)。

在藍圖中:

所以我們回到藍圖中,添加彈簧臂組件到Capsule下:

?然后我們選中彈簧臂組件,再添加一個攝像機組件:

但是我們的主要目標是C++。

在C++中:

我們在.h中創建:

public:ATank(); private:UPROPERTY(VisibleAnyWhere,Category = "Component")class UCameraComponent* Camera;UPROPERTY(VisibleAnyWhere,Category = "Component")class USpringArmComponent* SpringArm;

在.cpp中:

ATank::ATank(){SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("Spring Arm"));SpringArm->SetupAttachment(RootComponent);Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));Camera->SetupAttachment(SpringArm); }

然后在藍圖中,可以在類設置修改父類:

?這樣我們就可以看到剛剛設置的組件:

?還有一個需要注意的是,我們進入游戲后,場景中哪個是我們要操控的?我們可以選中坦克,然后分配player0:

?這樣在游戲開始后,我們操控的就是坦克。

2.2 處理輸入

2.2.1 Bind Axis Mapping

我們需要在游戲的每幀,獲得按鍵的輸入。

我們把BasePawn中的SetupPlayerInputComponent函數移動到Tank中,并且我們定義一個Move函數
?

void Move(float value);

在之前的函數中,加入一句:

PlayerInputComponent->BindAxis(TEXT("MoveForward"),this,&ATank::Move);

然后我們在Move函數中,添加測試的輸出:

UE_LOG(LogTemp,Warning,TEXT("The Value is %f"),value);

這樣在游戲中的輸出日志中,我們可以看到按下W和S的value值(1和-1)。證明我們Bind成功。

2.2.2 Adding the Offset

要想在引擎中移動,就要對其添加位移。但是這里要弄清楚,我們是在Local space還是在World Space。

我們在場景中選中的Actor,有它們自己的Local方向,但是這個不一定和World方向相同。所以我們希望,當按下W鍵時,坦克能按照它的Local方向進行前進。

我們將使用AddActorLocalOffset來完成這件事情。我們轉到它的定義位置:

void AActor::AddActorLocalOffset(FVector DeltaLocation, bool bSweep, FHitResult* OutSweepHitResult, ETeleportType Teleport) {if(RootComponent){RootComponent->AddLocalOffset(DeltaLocation, bSweep, OutSweepHitResult, Teleport);}else if (OutSweepHitResult){*OutSweepHitResult = FHitResult();} }

我們可以看到它會檢查RootComponent是否為Null,所以這里實際做的是對RootComponent添加位移。

我們可以在BasePawn里進行測試(別忘了測試完成后刪除):

void ABasePawn::Tick(float DeltaTime) {Super::Tick(DeltaTime);FVector DeltLocation(0.f);DeltLocation.X = 2.f;AddActorLocalOffset(DeltLocation); }

我們在虛幻中進行模擬,可以看到所有的坦克和炮臺都朝著自己的X方向進行移動。既然了解了怎么移動,我們可以在Move函數中,進行操作:

FVector DeltLocation = FVector::ZeroVector; DeltLocation.X = value; AddActorLocalOffset(DeltLocation);

這樣在場景中,我們可以按住W和S控制前進和后退。

2.2.3 Speed?

關于這個的修改,我們在之前的藍圖學習中有提到過,要使用Delta time。

我們先定義一個可以調整的速度參數:

UPROPERTY(EditAnyWhere,Category ="Movement") float Speed = 200.f;

然后再利用Delta time來做Scale。

DeltLocation.X = value * Speed * UGameplayStatics::GetWorldDeltaSeconds(this);

這樣之后也可以在藍圖中調整速度。

2.3 Local Rotation

我們先來介紹一下Sweeping

在游戲編程中,sweeping是引擎完成的一種技術,只要它處于開啟。如果我們有一個移動的物體,比如有一個圓代表的一個球體,當這個球體移動時,每一幀,引擎都會執行sweep?檢查。

這意味著它正在檢查這個特定幀的移動是否會導致兩個對象之間的重疊。

假設某一幀,一個球體和長方體重合了。那么此時Sweeping啟用的功能是,引擎將檢測到這種重疊并將該球體移回該特定幀,以便它永遠不會真正穿透對象。

在官方文檔中:

Whether we sweep to the destination location, triggering overlaps along the way and stopping short of the target if blocked by something. Only the root component is swept and checked for blocking collision, child components move without sweeping. If collision is off, this has no effect.

注意最后一句,所以要保證碰撞enabled,Sweeping才能正常工作。

所以我們現在代碼中加入:

AddActorLocalOffset(DeltLocation,true);

然后在藍圖設置中將碰撞預設修改為BlockAllDynamic。

  • 注意:如果無法移動,大概率是因為和地板重合。

這樣Sweeping這項功能設置完成。

而添加旋轉的方式和之前的類似:

void ATank::Turn(float value){FRotator DeltaRotation = FRotator::ZeroRotator;DeltaRotation.Yaw = value * TurnRate * UGameplayStatics::GetWorldDeltaSeconds(this);AddActorLocalRotation(DeltaRotation,true); }

但是這樣只是完成了整個坦克的旋轉,對于坦克的上半身我們沒有添加旋轉,而這個需要用到鼠標的輸入。

我們希望坦克的上身能跟隨鼠標的方向進行轉動,我們可以得到鼠標的位置,如果我們要從相機直接向光標畫一條線并擊中世界中的某個物體,我們可以獲得該位置并使用該位置來設置坦克炮塔的旋轉。

具體應該怎么做,我們還需要了解Casting。

只要對象本身是我們試圖轉換為的類型,casting?就會將一個指針的類型cast為另一種指針類型。

我們在BeginPlay中加入代碼:

PlayerControllerRef = Cast<APlayerController>(GetController());

這樣我們獲得了獲得了對Controller的訪問。并且用cast函數從Acontroller* 到APlayerController*。

  • 注釋:
  • Casting Quick Start Guide(官方文檔)

我們再整理一下思路:

?我們要完成這個操作在每一幀,所以我們需要Tick函數。然后在函數中:

Super::Tick(DeltaTime);if (PlayerControllerRef){FHitResult HitResult;PlayerControllerRef->GetHitResultUnderCursor(ECollisionChannel::ECC_Visibility,false,HitResult);}

在我們call這個函數后,HitResult會被line trace的數據填充。我們可以獲得碰撞事件的point等。

我們現在可以畫一個debugsphere來進行測試:

DrawDebugSphere(GetWorld(),HitResult.ImpactPoint,25.f,12, FColor::Red,false,-1.f);}

我們到引擎中編譯,可以看到我們鼠標的位置會有一個球體,準確的說是在鼠標連線之間的物體碰撞位置(僅供測試):

現在我們可以嘗試利用鼠標控制炮臺的旋轉了。關于向量的計算,這里就不多介紹了。

需要注意的一點是,如果我們的鼠標在地面上,會導致炮臺不是水平方向上的旋轉,會指向地面。這個效果不是我們想要的,我們希望它能水平,也就是說,我們只希望它旋轉的部分數值。

我們將代碼放置在BasePawn中,這樣后續敵方炮臺也可以使用。

protected: //任何放置在這里的函數或變量,只能被它的子類訪問。 void RotateTurret(FVector LookAtTarget); void ABasePawn::RotateTurret(FVector LookAtTarget){FVector ToTarget = LookAtTarget - TurretMesh->GetComponentLocation();FRotator LookAtRotation = FRotator(0.f,ToTarget.Rotation().Yaw,0.f);TurretMesh->SetWorldRotation(LookAtRotation); }

然后我們回到Tank中,添加。

RotateTurret(HitResult.ImpactPoint);

現在我們可以移動鼠標來讓炮臺轉動了(轉出殘影):

?接下來,我們還要保證敵人炮臺的轉動,讓它們一直瞄準坦克(需要對Tick函數overwrite)。

我們先從BasePawn創建一個派生類Tower。

在.h中:

public:virtual void Tick(float DeltaTime) override;protected:virtual void BeginPlay() override; private:class ATank* Tank;UPROPERTY(EditDefaultsOnly,Category = "Combat")float FireRange = 300.f;

.cpp中:

void ATower::Tick(float DeltaTime){Super::Tick(DeltaTime);//當坦克進入范圍后,才進行瞄準//做法:找到坦克的Location,找到炮臺的Location,利用FVector::Dist()計算距離。if (Tank){float Distance = FVector::Dist(GetActorLocation(),Tank->GetActorLocation());if (Distance <= FireRange){//轉動炮臺RotateTurret(Tank->GetActorLocation());}}//查看Tank是否在距離內}void ATower::BeginPlay(){Super::BeginPlay();//獲得TankTank = Cast<ATank>(UGameplayStatics::GetPlayerPawn(this, 0)); }

我們可以在藍圖中,將炮臺的父類設置為Tower,然后修改Range參數。

三、Fire

3.1 Bind Action Mapping

Axis Mapping的觸發像Tick函數,在每一幀觸發。傳入float值,根據按下的按鈕而改變。

而Action Mapping不同,綁定到Action Mapping的回調函數不需要輸入參數,所有發生的事情都是在您按下按鈕時。不會在每幀觸發,只有當按鈕按下時觸發。

我們綁定Action Mapping和函數,使用:BindAction()。

為了方便后續坦克和敵人的使用,我們在BasePawn里定義Fire函數。

然后我們先在Tank.cpp中添加綁定:

PlayerInputComponent->BindAction(TEXT("Fire"),IE_Pressed,this,&ATank::Fire);

然后對Fire函數,加入測試:

FVector ProjectileSpawnPointLocation = ProjectileSpawnPoint->GetComponentLocation();DrawDebugSphere(GetWorld(),ProjectileSpawnPointLocation,25.f,12,FColor::Red,false,3.f);

我們進入編譯查看結果,在我們鼠標點擊的位置會有測試結果:

?接下來我們把它也應用到Tower中。我們這里會用到Timers。

.h中:

//2秒的等待時間//查看我們是否可以開火FTimerHandle FireRateTimerHandle;float FireRate = 2.f;void CheckFireCondition();

.cpp中,首先在BeginPlay中:

GetWorldTimerManger().SetTimer(FireRateTimerHandle,this,&ATower::CheckFireCondition,FireRate,true); void ATower::CheckFireCondition(){if (Tank){float Distance = FVector::Dist(GetActorLocation(),Tank->GetActorLocation());if (Distance <= FireRange){//轉動炮臺Fire();}} }

我們測試結果:

?可以看到,當我們靠近炮臺時,Fire函數被使用。關于重構的部分暫時略過。

3.2 發射子彈

我們創建一個Projectile Class,過程和之前類似(Actor),這里簡單說一下:

創建Projectile Class,創建UStaticMeshComponent,并設置為RootComponent,創建基于它的藍圖,設置網格體。

接下來我們就要在場景中生成(spawn)子彈,這需要SpawnActor函數。

在這之前,我們先學習TSubclassOf:

TSubclassOfhttp://tsubclassof/在BasePawn中添加

UPROPERTY(EditDefaultsOnly,Category = "Combat")TSubclassOf<class AProjectile> ProjectileClass;

然后回到BP_PawnTank藍圖中,右邊的細節面板就有了選項:

我們選擇藍圖,是因為TSubClassof允許我們設置這個Projectile class為一個特定的type,基于Projectile。這樣選擇之后,Projectile class被設置為BP?Projectile 類型。? ? ? ??

那為什么要設置這個?我們要了解SpawnActor的怎樣工作的。

SpawnActor是屬于UWorld class的函數,Spawn actor 可以在游戲運行時在運行時調用,它可以創建 actor。

SpawnActor:關于SpawnActor<>(),如果我們想生成子彈,我們需要首先傳入C++ class type在<>里Aprojectile。

我們在BasePawn中的fire函數生成子彈:

void ABasePawn::Fire(){FVector Location = ProjectileSpawnPoint->GetComponentLocation();FRotator Rotation = ProjectileSpawnPoint->GetComponentRotation();GetWorld()->SpawnActor<AProjectile>(ProjectileClass,Location,Rotation); }

進入編譯器查看結果:

?但是子彈沒有移動,我們接下來設置子彈的移動。想要完成子彈的移動有幾個方法:

  • 1 設置子彈的方向和距離,這需要每幀更新
  • 2 添加Impulse,引擎進行物理模擬
  • 3 使用MoveMent組件

我們使用Projectile Movement Component:UProjectileMovementComponenthttps://docs.unrealengine.com/4.27/en-US/API/Runtime/Engine/GameFramework/UProjectileMovementComponent/

我們添加組件斌,并且對炮臺也分配子彈網格體:

UPROPERTY(VisibleAnyWhere,Category = "MoveMent")class UProjectileMovementComponent* ProjectileMoveMent; ProjectileMoveMent = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("Projectile Movement Component"));ProjectileMoveMent->MaxSpeed = 1300.f;ProjectileMoveMent->InitialSpeed = 1300.f;

進入編譯器,現在我們和炮臺都可以發射子彈了:

四 Damage

4.1 Hit Event

首先我們要確定碰撞事件,即子彈的碰撞事件,這樣我們可以摧毀子彈。

在.h中

UFUNCTION()void OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,FVector NormalImpulse,const FHitResult& Hit);

在BeginPlay中:

ProjectileMesh->OnComponentHit.AddDynamic(this, &AProjectile::OnHit);

關于delegates(代理委托):
虛幻4:代理委托基礎(delegate) - 知乎

https://docs.unrealengine.com/4.27/en-US/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Delegates/

關于AddDynamic:

it's a macro usually used to bind a function to an event

https://docs.unrealengine.com/4.26/zh-CN/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Delegates/Dynamic/

void AProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,FVector NormalImpulse,const FHitResult& Hit){UE_LOG(LogTemp, Warning, TEXT("OnHit"));UE_LOG(LogTemp, Warning, TEXT("HitComp: %s"), *HitComp->GetName());UE_LOG(LogTemp, Warning, TEXT("OtherActor: %s"), *OtherActor->GetName());UE_LOG(LogTemp, Warning, TEXT("OtherComp: %s"), *OtherComp->GetName());}

我們在輸出日志中,輸出碰撞事件的結果:

4.2 Damage/Health Class

既然要造成傷害,那就需要血條或生命值。我們在之前了解過USceneComponent,它derived from UActorComponent:

  • UActorComponent:No transform,No attachment
  • USceneComponent:Has transform,Support attachment

由于我們要處理傷害和健康,我們不需要多余的東西,UActorComponent足夠了。

了解了這些,我們新建Actor組件的C++類——HealthComponent。在里面定義一些簡單的變量:

private:UPROPERY(EditAnywhere)float MaxHealth = 100.f;float Health=0.f;

在BeginPlay中

Health = MaxHealth;

然后我們在坦克和炮臺的藍圖中加入Health組件。

接下來:

UFUNCTION()//因為我們要將其bind到delegate,它需要正確的輸入參數適合那個delegate。對于要bind到OntakeAnyDamage的函數,輸入參數列表如下://受到傷害的Actor,傷害數值//我們有這個輸入參數的原因是虛幻引擎有DamageType的概念。我們可以創建具有額外數據的自定義傷害類型,這些數據可以通知你執行不同的操作,具體取決于你可能具有火焰傷害、毒藥傷害、爆炸傷害等的傷害類型。//An instigator is the controller responsible for the damage.//This is the actual actor causing the damage.這是子彈本身void DamageTaken(AActor *DamagedActor, float Damage, const UDamageType *DamageType, class AController *Instigator, AActor *DamageCauser) GetOwner()->OnTakeAnyDamage.AddDynamic(this,&UHealthComponent::DamageTaken);

這樣當我們產生damage事件時,我們都會從該委托中獲得廣播,這將導致調用damage taken函數。我們接著要使用ApplyDamage,這需要一些輸入:

我們先在Projectile里定義一個Damge數值,然后在BasePawn-fire中

auto Projectile = GetWorld()->SpawnActor<AProjectile>(ProjectileClass,Location,Rotation); Projectile->SetOwner(this);

這樣我們就可以訪問最新生成的子彈;然后當pawn生成子彈時,它會設置那個子彈的owner,這樣我們再使用GetOwner時,我們會獲得那個擁有子彈的class的實例。

我們在projectile-Onhit中:

auto MyOwner = GetOwner();if(MyOwner == nullptr) return;auto MyOwnerInstigator = MyOwner->GetInstigatorController();auto DamageTypeClass = UDamageType::StaticClass();if (OtherActor&& OtherActor != this && OtherActor != MyOwner){UGameplayStatics::ApplyDamage(OtherActor, Damage, MyOwnerInstigator, this, DamageTypeClass);Destory();}

接著回到DamageTaken中:

if(Damage<=0.f) return;Health -= Damage;UE_LOG(LogTemp,Warning,TEXT("Health: %f"),Health);

4.3 Death

我們使用GameMode來確定游戲的開始和結束,我們首先創建一個GameMode的C++類:

然后再創建一個基于他的藍圖:

?然后再項目設置中,將其設置為默認游戲模式。并在藍圖中修改默認pawn類為坦克藍圖:

?接下來為了實現death,我們有如下思路:

  • 創建HandleDestruction(BasePawn)
  • 創建ActorDied函數(GameMode)
  • Call?HandleDestruction in ActorDied
  • Call?ActorDied ?health成為0時
  • 第一步:我們先定義HandleDestruction函數,然后進入Tower中。對于炮臺,我們先進行簡單的摧毀。

    void ATower::HandleDestruction(){Super::HandleDestruction();Destroy(); }

    對于坦克,我們現階段希望其能隱藏。

    void ATank::HandleDestruction(){Super::HandleDestruction();SetActorHiddenInGame(true);//禁用TickSetActorTickEnabled(false); }

    第二步+第三步:

    public:void ActorDied(AActor* DeadActor); void AToonTanksGameMode::ActorDied(AActor* DeadActor){//如果坦克被摧毀了if(DeadActor == Tank){Tank->HandleDestruction();if(Tank->GetTankPlayerController()){//禁止輸入按鍵響應Tank->DisableInput(Tank->GetTankPlayerController());//確保Mouse cursor不顯示Tank->GetTankPlayerController()->bShowMouseCursor = false;}}else if(ATower* DestoryedTower = Cast<ATower>(DeadActor)){DestoryedTower->HandleDestruction();} }

    第四步,我們首先要在HealthComponent中獲得GameMode:

    class AtonTanksGameMode* ToonTanksGameMode;

    在BeginPlay中:

    ToonTanksGameMode = Cast<AToonTanksGameMode>(UGameplayStatics::GetGameMode(this));

    然后在DamageTaken中:

    if(Health <= 0.f &&ToonTanksGameMode){ToonTanksGameMode->ActorDied(DamagedActor);}

    現在我們就可以在場景中消滅炮臺,并被消滅。但是我們還需要添加音效,特效,勝利及失敗界面等內容。

    五、游戲特效及輸贏界面

    5.1?custom player Controller

    我們首先創建一個PlayerController的c++類,和一個基于它的藍圖類。我們需要設置這個藍圖類為默認Player Controller。只要在GameMode藍圖中設置一下即可:

    ?然后添加代碼:

    void AToonTanksPlayerController::SetPlayerEnabledState(bool bPlayerEnabled){if(bPlayerEnabled){GetPawn()->EnableInput(this);}else{GetPawn()->DisableInput(this);}bShowMouseCursor = bPlayerEnabled; }

    這樣我們可以將之前ActorDied中的部分代碼用這個函數替換掉。

    我們再進入該藍圖中,設置默認鼠標光標為十字準星:?

    當然現階段我們還不能看到,因為我們還沒有顯示鼠標。

    5.2?Starting the Game

    我們回到GameMode中,在private:

    //過多久游戲可以開始,并接受玩家的輸入float StartDelay = 3.f;//函數void HandleGameStart();

    在cpp中:

    void AToonTanksGameMode::HandleGameStart(){//移動之前的BeginPlay代碼Tank = Cast<ATank>(UGameplayStatics::GetPlayerPawn(this, 0));ToonTanksPlayerController =Cast<AToonTanksPlayerController>(UGameplayStatics::GetPlayerController(this,0));if(ToonTanksPlayerController){ToonTanksPlayerController->SetPlayerEnabledState(false);FTimerHandle PlayerEnabledTimerHandle;FTimerDelegate PlayerEnabledTimerDelegate = FTimerDelegate::CreateUObject(ToonTanksPlayerController,&AToonTanksPlayerController::SetPlayerEnabledState,true);GetWorldTimerManager().SetTimer(PlayerEnabledTimerHandle,PlayerEnabledTimerDelegate,StartDelay,false);}}

    這樣我們進入游戲后,3秒不能接受玩家的輸入,且我們的鼠標變為了十字瞄準。

    接下來我們要在屏幕上顯示這些信息,這需要用到藍圖的implementable event。我們首先在GameMode的protected下:

    //我們不需要在C++中為其提供body,虛幻會希望我們在藍圖中完成它的實現UFUNCTION(BlueprintImplementableEvent)void StartGame();

    然后在HandleGameStart函數中加入StartGame,進入引擎編譯,然后進入GameMode藍圖中。

    我們可以在藍圖中加入StartGame事件:

    ?接著我們創建一個新的控件藍圖(這部分我們之前有提到過):

    ?并在里面加入一個簡單的文本框:

    ?我們接下來要嘗試將其加入到屏幕中,回到藍圖:

    這只是個簡單的實現,我們要做的是在屏幕上顯示倒計時,這部分主要用藍圖實現,和之前的內容多有重復,就不多做記錄,只放入最后的藍圖。

    ?5.3 獲勝和失敗界面

    我們可以創建一個Gameover函數來完成這個目標,在GameMode中:

    UFUNCTION(BlueprintImplementableEvent)void GameOver(bool bWonGame);

    并在ActorDied中加入函數,false:

    GameOver(false);

    在Towerdead中,加入計數,如果敵人被全部消滅,則為true。為了完成計數,我們創建:

    int32 TargetTower = 0;int32 GetTargetTowerCount();

    我們可以使用GetAllActorsOfClass:

    int32 AToonTanksGameMode::GetTargetTowerCount(){TArray<AActor*> Toewers;UGameplayStatics::GetAllActorsOfClass(this,ATower::StaticClass(),Toewers);return Toewers.Num(); }

    并在HandleGameStart中獲取TargetTower,我們還要保證其更新:

    --TargetTower;if(TargetTower == 0){GameOver(true);}

    這樣我們可以在GameMode藍圖中創建GameOver事件,并將其添加到ViewPort:

    ?我們先將之前的StartGame復制一份,命名為EndGame,刪除除了DisPlay文本之外的所有藍圖和變量,然后再GameMode中添加藍圖:

    ?這樣我們的勝利和失敗條件和界面就完成了。

    5.4 特殊效果

    我們需要回到之前的Projectile中添加

    UPROPERTY(EditAnyWhere,Category = "Combat")class UParticleSystem* HitParticles;

    然后回到子彈藍圖中添加對應效果(可以自行選擇免費素材)。然后我們需要在子彈擊中后生成該粒子效果。我們在Projectile的OnHit中添加:

    void AProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,FVector NormalImpulse,const FHitResult& Hit){auto MyOwner = GetOwner();if(MyOwner == nullptr) {Destroy();return;}auto MyOwnerInstigator = MyOwner->GetInstigatorController();auto DamageTypeClass = UDamageType::StaticClass();if (OtherActor&& OtherActor != this && OtherActor != MyOwner){UGameplayStatics::ApplyDamage(OtherActor, Damage, MyOwnerInstigator, this, DamageTypeClass);if(HitParticles){UGameplayStatics::SpawnEmitterAtLocation(this,HitParticles,GetActorLocation(),GetActorRotation());} }Destroy();}

    然后我們編譯進入游戲,查看效果,這是子彈擊中的效果:

    接下來我們再添加跟隨子彈的粒子系統,我們需要添加組件來完成這件事。我們在Projectile添加:

    UPROPERTY(EditAnyWhere,Category = "Combat")class UparticleSystemComponent* TrailPatticles; TrailPatticles = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("Smoke Trail"));TrailPatticles->SetupAttachment(RootComponent);

    然后我們進入藍圖分配資源即可,查看效果:

    ?接下來在BasePawn中我們添加死亡的特效:

    UPROPERTY(EditAnywhere,Category = "Combat")class UParticleSystem* DeathParticles;

    并在HandleDestruction中:

    void ABasePawn::HandleDestruction(){if(DeathParticles){UGameplayStatics::SpawnEmitterAtLocation(this,DeathParticles,GetActorLocation(),GetActorRotation());} }

    然后同樣的,我們進入藍圖進行設置。

    ?接下來我們再為其添加聲音,首先創建對應變量,然后進入藍圖進行設置:
    在Projectile:

    UPROPERTY(EditAnyWhere,Category = "Combat")class USoundBase* LaunchSound; UPROPERTY(EditAnyWhere,Category = "Combat")USoundBase* HitSound;

    BasePawn:

    UPROPERTY(EditAnywhere,Category = "Combat")class UParticleSystem* DeathParticles;

    ?設置完成后,我們就要播放這些音效。進入Projectile的OnHit中:

    if(HitSound){UGameplayStatics::PlaySoundAtLocation(this,HitSound,GetActorLocation());}

    BeginPlay:

    if(LaunchSound){UGameplayStatics::PlaySoundAtLocation(this,LaunchSound,GetActorLocation());}

    同樣的對Basepawn。

    六、結尾

    我們對游戲進行最后的優化:

    • 使攝像機移動更加平滑
    • 解決玩家死亡后,敵人仍在射擊的問題

    首先我們進入坦克并選中SpringArm,勾選下面兩項:

    ?同樣我們也可以通過調整下面的參數來調整,使攝像機的移動更加平滑。

    關于下一個問題,我們進入Tank,創建一個bool變量:

    bool bAlive = true;

    然后進入HandleDestruction中,將其設置為false。然后進入Tower中

    void ATower::CheckFireCondition(){if(Tank == nullptr){return;}if (InFireRange() && Tank->bAlive){Fire();} }

    到此為止,這個小游戲就完成了。

    總結

    以上是生活随笔為你收集整理的虚幻引擎C++开发学习(三)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    国产黄大片| 最近2019中文免费高清视频观看www99 | 国产永久网站 | 免费看十八岁美女 | 天天想夜夜操 | 西西人体www444 | 国产在线观看av | 日韩在线大片 | 国产精品色婷婷视频 | 丁香色婷婷 | 在线视频国产区 | 久久国产精品免费 | 99 久久久久 | 人人干干人人 | 2019中文 | 最近中文字幕免费观看 | 久久久久女人精品毛片 | 国产黄色片久久久 | 精品视频一区在线观看 | 亚洲精品mv在线观看 | 波多野结衣视频一区 | 婷婷丁香六月天 | 在线看福利av | 夜夜躁狠狠燥 | 日韩中文字幕免费电影 | 97看片网| 麻豆 videos | 色www精品视频在线观看 | av免费看看| 免费视频你懂得 | 久久伊人八月婷婷综合激情 | 天天操天天色综合 | 3d黄动漫免费看 | 国产中文字幕精品 | 国产精品一区二区中文字幕 | 精品国产视频在线观看 | 97在线视频免费观看 | 国产亚洲精品久久久久动 | 久久综合九色综合欧美狠狠 | 日韩综合视频在线观看 | 免费高清看电视网站 | 久久精品在线视频 | 色婷婷国产在线 | 欧美日产在线观看 | 一区二区三区国产欧美 | 色com网| 色多多视频在线观看 | 欧美极品裸体 | 精品福利国产 | 国产视频精品在线 | av免费网 | 日韩在线观看精品 | 亚a在线| 国产精品久久久久永久免费 | 黄色.com| 日韩av播放在线 | 久久伦理网| 在线中文字幕av观看 | 亚洲美女视频网 | 美女又爽又黄 | 久久久福利影院 | 黄色特级片 | www.在线观看视频 | 国产色一区| 亚洲激情综合 | 免费在线色电影 | h文在线观看免费 | 在线观看亚洲免费视频 | 狠狠色网 | 亚洲理论视频 | 中文字幕在线视频一区二区 | 亚洲最新av| 天天亚洲| 99999精品视频| 色a综合 | 精品一区久久 | 成x99人av在线www | 新版资源中文在线观看 | 91中文字幕网 | 国产精品第一视频 | 亚洲精品免费播放 | 中文字幕视频观看 | 91色在线观看 | 日日爽 | 亚洲精品乱码久久久久久9色 | 欧美精品久久久久久久免费 | 久久久久草| 久久精品一| 狠狠的干| 亚洲精品在线观看中文字幕 | 日韩av免费大片 | 在线视频免费观看 | 国产在线观看你懂得 | 人人澡人人澡人人 | 欧美成年人在线观看 | 亚洲精品视频在线观看免费视频 | 啪啪小视频网站 | 黄色资源在线观看 | 久久久久久久久久免费 | 国内视频在线 | 欧美精品久久久久久久久久 | 国产一级电影免费观看 | 少妇bbbb搡bbbb桶 | 婷婷丁香狠狠爱 | 久草视频国产 | 久久精品综合一区 | 亚洲日b视频 | 欧美美女一级片 | 久久69精品久久久久久久电影好 | av在线永久免费观看 | 97精品视频在线播放 | 亚洲国产精品久久久久 | 国产精品一区二区无线 | 亚洲视频免费在线观看 | 91精品一| 欧美va天堂在线电影 | 成人在线黄色 | 国产精品不卡视频 | 337p日本欧洲亚洲大胆裸体艺术 | 日韩3区| 香蕉免费 | 91福利视频免费观看 | 夜色成人av| 91九色在线视频观看 | av黄色在线| 久久久久电影网站 | 99视频精品视频高清免费 | 97品白浆高清久久久久久 | 中文字幕在线观看第三页 | 国外av在线 | 91亚洲永久精品 | 色国产在线 | 欧美性极品xxxx做受 | 国产精品久久久影视 | 欧美日韩一级久久久久久免费看 | 欧美一级久久久 | 98涩涩国产露脸精品国产网 | 看av在线 | 五月综合激情婷婷 | 欧美va天堂va视频va在线 | 麻豆超碰 | 日日夜夜网站 | 久碰视频在线观看 | 91色国产在线 | 久久久久久久久久网站 | 天天草av | 三级在线视频播放 | 久久黄色a级片 | 国产精品久久久久亚洲影视 | 国产一性一爱一乱一交 | www.av中文字幕.com| 成人福利av| 日日婷婷夜日日天干 | 国产91av视频在线观看 | 高清av在线免费观看 | 午夜电影久久久 | 天天干婷婷 | 青青久视频 | 99视频偷窥在线精品国自产拍 | 久久视频在线免费观看 | 狠狠干综合网 | 日韩精品亚洲专区在线观看 | 日日夜夜免费精品视频 | 国产欧美精品一区二区三区 | 手机在线看永久av片免费 | 久久综合九色综合97婷婷女人 | 国产免费视频在线 | 波多野结衣一区二区 | 99久久精品免费看国产免费软件 | 亚洲精品国产第一综合99久久 | 狠狠躁日日躁狂躁夜夜躁 | 五月婷社区 | 成年人黄色免费看 | 啪啪肉肉污av国网站 | 国产麻豆果冻传媒在线观看 | 亚洲一区二区三区在线看 | 久久精品免费看 | 热re99久久精品国产66热 | 日本不卡123区 | 亚洲成人av影片 | 激情电影在线观看 | 久久久久久国产精品999 | 色婷婷综合在线 | 美女国产网站 | 不卡av在线免费观看 | 成人小视频免费在线观看 | 日韩毛片在线免费观看 | 久久综合狠狠 | 成人av在线观 | 日本在线观看中文字幕无线观看 | 国产精品第54页 | 91亚·色| 久久综合色影院 | 日韩高清一二三区 | 国产人成免费视频 | 97av在线视频免费播放 | 免费看三级 | 天天撸夜夜操 | 五月婷婷网站 | 国产精品一区二区在线观看免费 | 黄色av网站在线免费观看 | 国产精品一区二区三区四区在线观看 | 最新国产在线视频 | 69精品视频在线观看 | 91色综合 | 99久久精品无免国产免费 | 国产乱对白刺激视频不卡 | 一区二区三区国 | 69性欧美| 免费视频91| 精品国产伦一区二区三区免费 | 99精品免费在线观看 | 在线观看中文字幕网站 | 欧美日韩一级在线 | 六月丁香婷婷网 | 日本性高潮视频 | 五月天婷亚洲天综合网精品偷 | 久草综合视频 | 久草视频免费看 | 国产黄a三级三级三级三级三级 | 久久久三级视频 | 欧美激情综合五月色丁香小说 | 欧美日韩久 | 黄色一集片| 成人9ⅰ免费影视网站 | 成年人在线观看 | 日韩在线观看一区二区 | 日韩在线观看视频免费 | 精品国产视频在线观看 | 国内成人av | 国产精品第52页 | 天天草天天插 | 国产日韩在线视频 | 免费大片av | 中文字幕人成人 | 日本久久电影 | 日韩精品久久久久久中文字幕8 | 亚洲视频1| 高潮久久久 | 91.麻豆视频 | 久久激情片 | 五月天色丁香 | 久久久精品影视 | 日韩欧美高清一区二区 | 黄色特级毛片 | av7777777| 天天干夜夜夜操天 | 国产精品自产拍在线观看 | 色综合久久久久久久久五月 | 成人午夜在线观看 | 99精品在线看 | 麻豆视频国产 | 九九热免费视频在线观看 | 国产精品久久久久久高潮 | 久久精品免视看 | 天堂网一区二区三区 | 精品亚洲在线 | 日韩一级电影网站 | 久久久精品一区二区 | 欧美一级片 | 美女网站久久 | 69视频在线播放 | 国产黄| 久久永久免费视频 | 91电影福利 | 在线天堂亚洲 | 中文区中文字幕免费看 | 蜜桃久久久| 中文字幕在线免费播放 | 国产精品一区二区久久久久 | 91麻豆精品国产91久久久久 | 久久综合色播五月 | 91自拍视频在线观看 | 四虎成人精品永久免费av九九 | 91黄色小网站 | 成人在线观看日韩 | 91在线小视频 | 丝袜美腿在线视频 | 五月婷婷亚洲 | 在线免费观看麻豆 | 国产一区在线免费观看视频 | 欧美福利网站 | 国产又粗又猛又黄又爽视频 | 午夜骚影 | 天天射天天射 | 久久人人射| 日韩毛片在线免费观看 | 国产精品久久久久久久久久久杏吧 | 夜夜躁日日躁狠狠久久88av | 成人午夜电影在线观看 | 国产日韩视频在线 | 午夜精品99久久免费 | 欧美日韩在线视频观看 | 亚洲免费精彩视频 | 91视频 - x99av | 久久黄色免费视频 | 成人福利av| 国产精品一区二区久久国产 | av福利资源 | 欧美不卡视频在线 | 国产亚洲精品久久久久久久久久久久 | 欧美a级在线 | 国产精品男女啪啪 | 亚洲成av人片一区二区梦乃 | 久久精品美女视频网站 | 午夜天天操 | 亚洲一区天堂 | 91午夜精品 | 91久久久久久久 | 日韩国产精品一区 | 在线亚洲人成电影网站色www | 美女视频黄是免费的 | 69亚洲乱| 激情欧美一区二区三区 | 91在线看网站 | av 一区二区三区 | 日韩久久久 | 欧美视频在线二区 | 欧美日韩三区二区 | 国产午夜影院 | 超碰97公开| 亚洲最新合集 | 亚洲精品高清在线 | 碰超在线观看 | 久久综合中文色婷婷 | 国产日本三级 | 狠狠色狠狠综合久久 | 青春草视频 | 91免费看片黄 | 亚洲成人精品国产 | 麻豆传媒在线视频 | 久久久午夜电影 | 在线观看v片 | 日韩黄色在线电影 | 开心激情五月婷婷 | 国产精品综合av一区二区国产馆 | www.午夜 | 永久中文字幕 | 探花视频在线观看 | av女优中文字幕在线观看 | 久久综合免费视频影院 | adn—256中文在线观看 | 97国产情侣爱久久免费观看 | 狠狠干狠狠艹 | 91免费黄视频 | 国产精品伦一区二区三区视频 | 国产成人三级在线播放 | 亚洲资源片 | 波多野结衣一区二区 | 国产一级在线 | 亚洲精品视频网站在线观看 | 啪啪免费视频网站 | 亚洲成人第一区 | 狠狠色丁香婷婷综合 | 久久人视频| 精品国产一区二区三区久久久久久 | 欧美在线aa | 五月激情av | 97精品超碰一区二区三区 | 久久久久国产视频 | www色综合 | 久久久国产精品麻豆 | 黄色精品一区 | 欧美一二三视频 | 激情欧美国产 | 亚洲天天综合网 | 日韩欧美区 | 国产又黄又爽又猛视频日本 | 国产午夜精品一区二区三区 | 九九久久成人 | 日韩毛片在线播放 | 欧美日韩国产精品一区二区亚洲 | av片子在线观看 | 天堂网在线视频 | 国产免费叼嘿网站免费 | 国产精久久久久久妇女av | 黄色网址av| 国产精品久久一区二区三区, | 国产日本在线观看 | 日本三级在线观看中文字 | 91av蜜桃 | 永久免费在线 | 日产av在线播放 | 丰满少妇在线观看 | 中文字幕一区二区三区在线观看 | 免费看片黄色 | 日韩在线免费看 | 国产日韩精品一区二区在线观看播放 | 国产精品嫩草69影院 | 国产91学生| 日本动漫做毛片一区二区 | 2023国产精品自产拍在线观看 | h文在线观看免费 | 91av在线免费 | 日韩电影在线观看一区二区三区 | 久久久国产精品人人片99精片欧美一 | 91精品国产高清自在线观看 | av字幕在线| 91av亚洲| 国产九九九精品视频 | 91九色成人 | 在线国产一区 | 九色视频网站 | 9797在线看片亚洲精品 | 在线视频欧美精品 | 天天av在线播放 | 免费黄色av电影 | 免费特级黄毛片 | 欧美黄色免费 | 国产精品久久久久久久久久久免费看 | 成人影片免费 | 成在线播放 | 在线播放 亚洲 | 国产一区二区三区免费在线 | 蜜桃视频成人在线观看 | 最近中文字幕高清字幕在线视频 | 久久精彩视频 | 人人爱人人做人人爽 | 国产福利91精品张津瑜 | 欧美日韩一区三区 | 免费在线观看国产黄 | 久久久久久免费毛片精品 | 日韩av片无码一区二区不卡电影 | 久草线 | 天天做天天干 | 丁香六月婷婷开心 | 在线国产片 | www日| 91久久偷偷做嫩草影院 | 欧美另类网站 | 91喷水| 国产免费又爽又刺激在线观看 | 成人免费在线视频 | 2024国产精品视频 | 毛片网站免费在线观看 | 又色又爽的网站 | 奇米影视777四色米奇影院 | 免费三级a | 波多野结衣视频一区二区三区 | 精品国产一区二区三区av性色 | 91麻豆精品国产午夜天堂 | 天堂av网址| 综合色综合 | 成人激情开心网 | 九九精品无码 | 日本黄色免费网站 | 九九热免费在线视频 | 天天撸夜夜操 | 中文字幕亚洲欧美日韩 | 色中色资源站 | 91福利在线观看 | 国产不卡网站 | 免费观看v片在线观看 | 一本一本久久a久久精品综合 | 婷婷久久精品 | 天天插狠狠插 | 最新中文字幕视频 | 国产成人黄色片 | 狠狠的干 | 国产精品美女久久久久久久久久久 | 99国产在线视频 | 亚洲午夜久久久久久久久久久 | 99色视频 | 久一网站 | 国产午夜av| 国内精品久久久久久久久久久久 | 久精品在线观看 | 亚洲一级片 | 欧美国产日韩一区 | 97偷拍视频 | 欧美成人黄色片 | 国产视频在 | 中文资源在线官网 | 天天搞天天干天天色 | 亚洲国产精品成人va在线观看 | 亚洲天天在线 | 在线观看免费版高清版 | 91插插插免费视频 | 综合久久精品 | 亚洲欧美日本国产 | 久草网站在线 | 美女黄网站视频免费 | 成人黄色免费在线观看 | 狠狠色丁香婷婷综合橹88 | 69视频国产 | 色视频在线观看免费 | 亚洲黄色在线播放 | 国产麻豆视频免费观看 | 色婷婷97| 中文字幕.av.在线 | 狠狠躁日日躁狂躁夜夜躁av | 色久天| 天天操天天操天天操天天操天天操天天操 | 国产一及片 | 亚洲精品在线免费看 | 久久五月天色综合 | 九九热在线免费观看 | av三级在线播放 | 国产精品99久久久精品免费观看 | 国产在线无 | 欧美性大战 | 久久精品香蕉视频 | 国产91丝袜在线播放动漫 | 成人黄色电影免费观看 | 人人搞人人干 | 中文字幕在线观看1 | 久久久精品国产一区二区电影四季 | 亚洲国产午夜视频 | 特级毛片在线免费观看 | 91在线视频免费观看 | 亚洲永久精品国产 | 黄色91免费观看 | 久久久网 | 中文字幕在线网 | 日韩视频一 | 欧美日韩3p | 亚洲国产精品电影在线观看 | 日本三级吹潮在线 | 国产精品成人国产乱 | 久久久久久久久久影院 | 天天草天天| 在线国产精品一区 | 亚洲精品欧美精品 | 成年在线观看 | 1024久久| 狠狠色狠狠色合久久伊人 | 亚洲免费av观看 | 91av在 | 五月婷婷一级片 | 国内精品久久久久久久久久久 | 狠狠的日 | 韩国av不卡 | 精品国产成人 | 97超碰人| 日日干夜夜操视频 | 国产一级免费视频 | 亚洲一区日韩精品 | 久久国产精品偷 | 亚洲精品国产精品乱码不99热 | 亚洲视频大全 | 日韩精品一区二区三区视频播放 | 99色免费 | 精品自拍av | 91人人插| 99久久久| 色婷婷狠狠五月综合天色拍 | 亚洲视屏一区 | 日本99干网 | 国产精品av免费在线观看 | 亚洲视频久久久久 | 欧美色综合久久 | 麻豆精品传媒视频 | 久久伦理电影 | 欧美精彩视频在线观看 | 最新成人av | 三级黄色在线观看 | 久久精品久久99精品久久 | 中文伊人| 国产99在线免费 | 99se视频在线观看 | 欧美坐爱视频 | 国产一区二区在线影院 | 日韩精品视频在线观看免费 | 亚洲精品国产综合久久 | 成人免费看黄 | 亚洲精品视频免费在线 | 丁香六月国产 | 婷婷六月天丁香 | 国产亚洲精品精品精品 | 中文字幕一区二区在线播放 | 日狠狠 | 三级av在线播放 | 99久久久久久 | 日韩精品免费一区二区 | 精品自拍网 | 精品久久久久久综合 | a黄色大片 | 992tv又爽又黄的免费视频 | 亚洲精品免费观看 | 91成人免费电影 | 免费看十八岁美女 | 日韩三级.com | 17videosex性欧美 | 2022久久国产露脸精品国产 | 国内精品毛片 | 天干啦夜天干天干在线线 | 国产精品一区二区三区在线免费观看 | 91爱爱网址| 中文字幕在线观看91 | 日p在线观看 | 精品国产乱码久久久久久1区2匹 | 久久久亚洲网站 | 在线免费国产 | 亚洲 中文 欧美 日韩vr 在线 | 国产精品黄色 | 成人精品国产免费网站 | 亚洲精选视频免费看 | 免费高清在线观看成人 | 久草视频免费观 | 成人午夜电影在线播放 | 日韩av一区二区三区 | 91福利区一区二区三区 | 欧美日韩国产亚洲乱码字幕 | 欧美性生活大片 | 久久桃花网 | 免费av看片| 在线观看日韩专区 | 视频成人免费 | 九九激情视频 | 欧美一区二区精美视频 | 成人av电影在线播放 | 欧美极度另类 | 国产护士在线 | 成年人在线观看免费视频 | 射久久久 | 免费又黄又爽的视频 | 天天综合网久久综合网 | 免费视频网 | 人人舔人人舔 | 激情五月激情综合网 | 在线免费观看视频一区二区三区 | 俺要去色综合狠狠 | av天天草| 色综合久久悠悠 | 日韩.com | 国产五月婷 | av黄色免费在线观看 | 黄色精品国产 | 91最新网址 | 狠狠色香婷婷久久亚洲精品 | 在线播放91 | 一级黄色在线免费观看 | www.久久免费视频 | 天天天插| 777视频在线观看 | 午夜视频在线观看一区二区三区 | 日韩久久精品一区二区三区下载 | 一级黄网 | 久久av高清| 国产一级片观看 | 久久国产经典 | 美女视频黄在线 | 欧美久久久久久久久中文字幕 | 国产一级片一区二区三区 | 日韩在线高清 | 亚洲区视频在线 | 夜夜操狠狠干 | 日韩网站免费观看 | 九九九九九九精品 | 在线观看视频你懂得 | 精品国偷自产在线 | www.久久久com | 天天躁日日躁狠狠躁av中文 | 婷婷九月激情 | 日韩精品专区在线影院重磅 | 在线之家官网 | 久久久久久久久艹 | av网址在线播放 | 国产精品一区二区三区在线 | 高清在线一区 | 亚洲日韩中文字幕 | 国产无套精品久久久久久 | 精品国产资源 | 成人免费在线电影 | 国产91精品一区二区麻豆网站 | 久久99免费视频 | 五月婷婷激情六月 | 国产精品va在线观看入 | 日本精品视频网站 | 九九免费在线视频 | 欧美日韩另类视频 | 蜜臀久久99静品久久久久久 | 99热国产在线 | 九热精品 | 最近日本中文字幕a | 日韩免费一区 | 国产无套视频 | 精品国产伦一区二区三区 | 国产一级片在线播放 | 激情欧美一区二区三区 | 亚洲在线黄色 | 国产精品国产亚洲精品看不卡 | 97视频总站 | 亚洲欧洲精品在线 | 久久免费国产精品1 | 久草精品视频在线播放 | 视频在线观看亚洲 | 超碰人人做 | 亚洲一级免费观看 | 亚洲黄色app | 免费看亚洲毛片 | 最新av在线免费观看 | 四虎欧美 | 我要看黄色一级片 | 日韩性色 | 婷婷六月丁香激情 | 久久精精品视频 | 国产色就色 | 伊人狠狠色丁香婷婷综合 | 久久高清毛片 | 久久一区二区三区国产精品 | 国内精品久久久久久久久久久久 | 日韩精品偷拍 | 亚洲高清免费在线 | 91日韩在线 | 特级毛片爽www免费版 | 免费在线观看不卡av | 人人插人人澡 | 日韩 在线 | 人人干干人人 | 亚洲日本精品视频 | 91av在线视频免费观看 | 国产精品久久久久久一区二区三区 | 一级免费片 | 日韩精品一区二区三区在线视频 | 99热9| 又黄又爽又刺激的视频 | 国产精品久久久久久久久久99 | 欧美日韩后 | 国产精品第7页 | 亚洲精品www | 美女黄网站视频免费 | 久久96国产精品久久99软件 | 欧美激情精品久久 | 国产一区二区三区在线免费观看 | 天天艹天天干天天 | 免费观看一区 | 综合久色 | 中文字幕资源站 | 国产黄免费在线观看 | 婷婷中文字幕在线观看 | 国产精品国产三级国产 | 国内精品久久久久久久久久清纯 | 最近中文字幕免费av | 黄色国产高清 | 国产久草在线观看 | 亚洲婷婷免费 | 九九九热| 精品久久久精品 | 亚洲国产精品一区二区久久hs | 日韩欧美综合视频 | 国外调教视频网站 | 国产精品v a免费视频 | 久久草视频 | 国产精品无av码在线观看 | 国产视频在线观看一区二区 | 久久久久久久久久久久久影院 | 日韩极品在线 | 欧美日产在线观看 | 91精品久久久久久 | 国产精品 国内视频 | 色综合久久中文综合久久牛 | 91精品啪| 成人免费视频观看 | free,性欧美 九九交易行官网 | 婷婷 中文字幕 | 在线精品视频免费观看 | 精品专区| 91最新视频 | 久久久久久久影视 | 天天综合区 | 国产福利a | 91精品一区二区三区久久久久久 | 国产999免费视频 | 男女男视频 | 天天干天天色2020 | 色.www| 激情综合亚洲精品 | 天天干天天怕 | 黄色软件视频大全免费下载 | 亚洲91在线| 懂色av一区二区三区蜜臀 | 97超碰人人看 | 激情综合交| 色综合久久久久久久久五月 | 亚洲综合激情网 | 日本性xxx| 99久久99久久免费精品蜜臀 | 亚洲精品777 | 色综合久久88色综合天天免费 | 成人毛片一区二区三区 | 五月婷av | 久久久国产精品电影 | 日韩大片免费在线观看 | 欧美aaa大片| 日日操日日 | 中文字幕色综合网 | 91麻豆国产福利在线观看 | 成人毛片久久 | 伊人五月 | 久久综合婷婷综合 | 黄色一级在线视频 | 亚洲春色成人 | 日韩国产在线观看 | 国产成人亚洲精品自产在线 | 91污视频在线观看 | 99久久精品免费看国产麻豆 | 美女久久久久久久久久久 | 黄在线免费观看 | 国产精品久久久久久久7电影 | 狠日日| 色婷婷国产 | 久久av在线 | 特级免费毛片 | 国产精品福利午夜在线观看 | 日本精品久久久久中文字幕 | 日韩免费不卡av | 又色又爽又黄高潮的免费视频 | 日本99精品 | 91最新国产| 欧美日韩在线视频观看 | 国产91在线播放 | 西西4444www大胆视频 | 色多多视频在线观看 | 欧美电影在线观看 | jizz18欧美18 | 91精选| 欧美在线视频一区二区三区 | 国产精品一区二区三区在线播放 | 五月天久久久久 | 色婷婷视频网 | 少妇搡bbbb搡bbb搡忠贞 | 综合色狠狠 | av大全在线| 国产爽妇网 | 51久久夜色精品国产麻豆 | 欧美日韩高清国产 | 51精品国自产在线 | 欧美日韩久久不卡 | 亚洲免费在线观看视频 | 国产精品久久久一区二区 | 国产亚洲精品久久久久5区 成人h电影在线观看 | 玖玖视频 | 欧洲一区二区三区精品 | 成片免费 | 在线观看av的网站 | 国产成人精品久 | 日韩欧美观看 | 亚洲国产精品女人久久久 | 美女久久一区 | 国产一区私人高清影院 | 久久成人18免费网站 | 中文字幕亚洲精品日韩 | 久久中文字幕在线视频 | 亚洲精品国产综合99久久夜夜嗨 | 免费看一级一片 | 久久精品国产免费 | 四虎影视成人永久免费观看视频 | 久久成人精品电影 | 亚洲国产精品视频在线观看 | 成人精品999 | 免费日韩电影 | 亚洲成av人片在线观看 | 国产成人精品免费在线观看 | 天天操天天添天天吹 | av中文字幕在线看 | 国产精品丝袜在线 | 精品一区二区在线免费观看 | 国产精品嫩草影院99网站 | 91精品视频一区二区三区 | 在线观看视频在线 | 日韩在线视频线视频免费网站 | 国产高清精品在线 | 亚洲日本国产精品 | 亚洲欧美日韩国产精品一区午夜 | 免费看黄的视频 | 国产高清免费在线观看 | 亚洲国产wwwccc36天堂 | 日本成人免费在线观看 | 久久高视频| 日韩免费不卡av | 天天干天天干天天 | 黄色影院在线观看 | 久草色在线观看 | 成年人黄色av | 99视频国产在线 | 在线一二区 | 天堂视频中文在线 | 欧美在线aaa| 人人cao| 99视频精品在线 | 中文字幕一区二区三区精华液 | 69国产成人综合久久精品欧美 | 国产亚洲视频在线 | 国产精品一区二区三区在线看 | 亚洲国产福利视频 | 美女黄频 | 亚洲精品日韩一区二区电影 | 91九色在线视频 | 西西大胆啪啪 | 黄色成人在线观看 | 中文字幕在线观看免费高清电影 | 免费成人av在线看 | 亚洲综合视频在线播放 | 国产高清永久免费 | 91成品视频 | 97超碰中文字幕 | 超碰最新网址 | 一区二区精品在线 | 黄色三几片| 久久精品成人欧美大片古装 | 国产高清视频免费在线观看 | 成人a视频在线观看 | 97精产国品一二三产区在线 | 丁香色婷婷 | 韩日精品中文字幕 | 97超碰免费| 国模一区二区三区四区 | 日韩欧美国产精品 | 91香蕉国产在线观看软件 | 国产精品三级视频 | 人人爽久久涩噜噜噜网站 | 欧美a级在线免费观看 | 免费看在线看www777 | a天堂免费 | 国产视频一区在线播放 | 亚洲一区二区三区四区在线视频 | 91香蕉视频在线下载 | 久草电影在线观看 | 亚洲国产成人在线 | 日本久久久久久久久久久 | 国产999在线观看 | 精品国产一区在线观看 | 国产精品美女久久久免费 | 99性视频 | 久久美女高清视频 | 免费黄色小网站 | 久久国内免费视频 | 日韩在线免费小视频 | 国产精品初高中精品久久 | 免费久草视频 | 天天综合久久综合 | 黄色大片网 | 久久综合久久综合这里只有精品 | 人人超碰97| wwwwww色| 欧美成人h版 | 中文字幕视频在线播放 | 三级av片| 伊人激情网| 国产精品99久久久精品 | 久久99国产精品免费网站 | 国产精品久久久久一区二区三区 | 国产在线观看高清视频 | 国产一级二级在线观看 | 国产91av视频在线观看 | 日韩中文字幕电影 | 日韩在线 一区二区 | 日韩高清免费观看 | 国产亚洲成人网 | 久久久久国产精品免费免费搜索 | 日韩精品在线播放 | 人成在线免费视频 | av大全免费在线观看 | 在线天堂中文在线资源网 | 六月丁香综合网 | 国产在线a不卡 | 国产又粗又硬又爽的视频 | 99久久婷婷国产一区二区三区 | 精品uu| 91精品国产综合久久婷婷香蕉 | 亚州欧美视频 | 狠狠狠色丁香婷婷综合激情 | 成人av在线看 | 中文亚洲欧美日韩 | 国产91免费在线观看 | 在线 你懂| 久久久久久久影视 | 日韩高清观看 | 欧美韩日在线 | 国产精品一区二区久久精品爱涩 | 超黄视频网站 | 手机看片99 | 久久精品79国产精品 | 成人在线视频论坛 | 91精品人成在线观看 | 亚洲精品免费看 | 成人免费网视频 | 久久久久久蜜桃一区二区 | av中文字幕第一页 | 色综合久久天天 | 亚洲黄色a | 精品国产乱码久久久久久三级人 | 亚洲 成人 欧美 | 奇米网777 | 日韩最新理论电影 | 综合网色 | 久草com | 在线观看免费一级片 | 免费下载高清毛片 | 国产精品久久久久久久久久久久 | 五月天婷婷在线观看视频 | 日韩精品一区在线播放 | 久久国产一区二区三区 | 色视频国产直接看 | 久久久久综合网 | 99热 精品在线 | 亚洲视频精品在线 |