Unreal Engine 4 学习笔记(九):PlayController

首先,PlayController自身也是一个Actor,通过它,玩家才能控制游戏中的Actor、Pawn、Character等。

UObject-+
        |-AActor-+
                 |-AController--+
                                |-APlayerController

如何设置PlayController才能绑定事件?

对于Actor

在Actor的Blueprint中,通过 Input -> Auto Receive Input  设置Play X

void AActor::PreInitializeComponents()
{
	if (AutoReceiveInput != EAutoReceiveInput::Disabled)
	{
		const int32 PlayerIndex = int32(AutoReceiveInput.GetValue()) - 1;

		APlayerController* PC = UGameplayStatics::GetPlayerController(this, PlayerIndex);
		if (PC)
		{
			EnableInput(PC);
		}
		else
		{
			GetWorld()->PersistentLevel->RegisterActorForAutoReceiveInput(this, PlayerIndex);
		}
	}
}

void AActor::EnableInput(APlayerController* PlayerController)
{
	if (PlayerController)
	{
		// If it doesn't exist create it and bind delegates
		if (!InputComponent)
		{
			InputComponent = NewObject<UInputComponent>(this);
			InputComponent->RegisterComponent();
			InputComponent->bBlockInput = bBlockInput;
			InputComponent->Priority = InputPriority;

			if (UInputDelegateBinding::SupportsInputDelegate(GetClass()))
			{
				UInputDelegateBinding::BindInputDelegates(GetClass(), InputComponent);
			}
		}
		else
		{
			// Make sure we only have one instance of the InputComponent on the stack
			PlayerController->PopInputComponent(InputComponent);
		}

		PlayerController->PushInputComponent(InputComponent);
	}
}

以上代码就是Unreal Engine 4中的具体实现。

设置完成后,就可以在自己的实现类的void AActor::BeginPlay()中使用InputComponent绑定事件了,比如:

if (InputComponent != nullptr)
{
	InputComponent->BindAction("Fire", IE_Pressed, this, &ABatteryActor::Fire);
}

对于Pawn

在Pawn的Blueprint中,通过 Pawn -> Auto Possess Player 中设置Play X

void APawn::PreInitializeComponents()
{
	Super::PreInitializeComponents();

	if (Instigator == nullptr)
	{
		Instigator = this;
	}

	if (AutoPossessPlayer != EAutoReceiveInput::Disabled && GetNetMode() != NM_Client )
	{
		const int32 PlayerIndex = int32(AutoPossessPlayer.GetValue()) - 1;

		APlayerController* PC = UGameplayStatics::GetPlayerController(this, PlayerIndex);
		if (PC)
		{
			PC->Possess(this);   // 此方法内会将  AController* APawn::Controller 设置成PC
		}
		else
		{
			GetWorld()->PersistentLevel->RegisterActorForAutoReceiveInput(this, PlayerIndex);
		}
	}

	UpdateNavigationRelevance();
}

以上代码就是Unreal Engine 4中的具体实现。

设置完成后,就可以在void APawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)中使用InputComponent绑定事件了。

而SetupPlayerInputComponent方法是在如下方法中被调用的:

void APawn::PawnClientRestart()
{
	Restart();

	APlayerController* PC = Cast<APlayerController>(Controller);
	if (PC && PC->IsLocalController())
	{
		// Handle camera possession
		if (PC->bAutoManageActiveCameraTarget)
		{
			PC->AutoManageActiveCameraTarget(this);
		}

		// Set up player input component, if there isn't one already.
		if (InputComponent == NULL)
		{
			InputComponent = CreatePlayerInputComponent();
			if (InputComponent)
			{
				SetupPlayerInputComponent(InputComponent);
				InputComponent->RegisterComponent();
				if (UInputDelegateBinding::SupportsInputDelegate(GetClass()))
				{
					InputComponent->bBlockInput = bBlockInput;
					UInputDelegateBinding::BindInputDelegates(GetClass(), InputComponent);
				}

			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/netyeaxi/article/details/81539182