redeyerabbit

博客园 首页 新随笔 联系 订阅 管理

TwinStickShooter模板应该是比较好的了解UE基本Pawn和Projectile的一个C++例子。以下是一些问题。

一、这个模板以纯C++编写,没有蓝图,所以第一步,我想测试下如何引用蓝图,以修改子弹的外观为例。

  • 从ATwinStickShooterProjectile派生蓝图类,称为BP_TwinStickShooterProjectile好了,然后在BP_TwinStickShooterProjectile中修改子弹的颜色(材质了),改为红色。那么纯粹的C++如何引用并产生蓝图的实例呢?

这样实现:在pawn类中添加 TSubclassOf<ATwinStickShooterProjectile> ProjectileTemplate 成员变量,加不加UPROPERTY均可,因为我们将引用资源,资源是客观存在的,不是我们动态产生的,不会GC。然后在对应的实现文件(.cpp)的构造函数中,添加如下代码:

	//设置子弹蓝图的引用
	ConstructorHelpers::FClassFinder<ATwinStickShooterProjectile> AssetProjectile(TEXT("Blueprint'/Game/Blueprints/BP_TwinStickShooterProjectile.BP_TwinStickShooterProjectile_C'"));
	if (AssetProjectile.Succeeded())
	{
		ProjectileTemplate = AssetProjectile.Class;
	}

 特别注意字符串后面添加"_C",即:Blueprint'/Game/Blueprints/BP_TwinStickShooterProjectile.BP_TwinStickShooterProjectile_C。这个字符串直接在编辑器中点选子弹对应的蓝图,然后copy reference,粘贴到对应的位置,然后添加后缀_C。因为这是蓝图类,后面都应该有后缀,话说UE版本号都15.1了,怎么还这个德性?

在FireShot函数中,如下修改:

			UWorld* const World = GetWorld();
			if (World != NULL)
			{
				// spawn the projectile
				//World->SpawnActor<ATwinStickShooterProjectile>(SpawnLocation, FireRotation);
				// 产生蓝图子弹
				World->SpawnActor<ATwinStickShooterProjectile>(ProjectileTemplate, SpawnLocation, FireRotation);
			}

 桔色是原来模板的,注释掉,然后添加红色代码,编译,可以观察到的确生成了自定义的子弹。

其中pawn类的tick函数值得研究,例如在输入绑定时,如果BindAxis,无论是否有输入,系统就回调自己的函数,BindAction则不存在这个问题。这个例子给出了一个较好的解决方案,只绑定名称,不绑定回调函数,这样我们在需要的时候,自己调用GetInputAxis,这两种实现各有千秋,只是后一种是传统的方式,比较熟悉。

 

未完待续,卡壳了……

 继续。

UProjectileMovementComponent有几个属性很好玩,如下:


如果设置bIsHomingProjectile = true; 生成子弹的Actor后,设置HomingTargetComponet,则子弹将以HomingTargetComponent为目标,实现跟踪效果。。。当然,还得设置UProjectileMovementComponent的HomingAccelerationMagnitude,这个值决定加速度,,犀利!

在子弹的构造函数中如下添加代码:

	// 添加测试代码
	ProjectileMovement->bIsHomingProjectile = true;
	ProjectileMovement->HomingAccelerationMagnitude = 2500;

 在Pawn的开火函数中如下添加代码:

			if (World != NULL)
			{
				// spawn the projectile
				//World->SpawnActor<ATwinStickShooterProjectile>(SpawnLocation, FireRotation);
				// 产生蓝图子弹
				ATwinStickShooterProjectile* Projectile = World->SpawnActor<ATwinStickShooterProjectile>(ProjectileTemplate, SpawnLocation, FireRotation);
				//添加HomingTargetComponent
				if (TargetHome)
				{
					Projectile->GetProjectileMovement()->HomingTargetComponent = TargetHome->GetRootComponent();
				}
			}

 红色的为添加的代码,当然在测试时,要在collision中把子弹与pawn和子弹之前的响应设置为ignore,要不然,子弹产生的太快,彼此会碰撞,并且开户追踪后,子弹会击中玩家自己,效果不好,选择ignore就ok了。效果图:


nice! 有空再扒扒UMovementComponent中的碰撞的实现。

posted on 2017-03-23 18:03  redeyerabbit  阅读(440)  评论(0编辑  收藏  举报