上一次修改时间:2019-03-04 02:32:15

角色90度旋转示例

  1. 绑定的按键响应事件中的具体键位,需要在项目设置下进行设置

    图片.png

  2. PikaqiuThirdTestCharacter.h

  3. // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
    
    #pragma once
    
    #include "CoreMinimal.h"
    #include "GameFramework/Character.h"
    #include "PikaqiuThirdTestCharacter.generated.h"
    
    UCLASS(config=Game)
    class APikaqiuThirdTestCharacter : public ACharacter
    {
        GENERATED_BODY()
    
        /** Camera boom positioning the camera behind the character */
        UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
        class USpringArmComponent* CameraBoom;
    
        /** Follow camera */
        UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
        class UCameraComponent* FollowCamera;
    public:
        APikaqiuThirdTestCharacter();
    
        /** Base turn rate, in deg/sec. Other scaling may affect final turn rate. */
        UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
        float BaseTurnRate;
    
        /** Base look up/down rate, in deg/sec. Other scaling may affect final rate. */
        UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
        float BaseLookUpRate;
    
    protected:
    
        /** Resets HMD orientation in VR. */
        void OnResetVR();
    
        /** Called for forwards/backward input */
        void MoveForward(float Value);
    
        /** Called for side to side input */
        void MoveRight(float Value);
    
        /** 
         * Called via input to turn at a given rate. 
         * @param Rate    This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
         */
        void TurnAtRate(float Rate);
    
        /**
         * Called via input to turn look up/down at a given rate. 
         * @param Rate    This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
         */
        void LookUpAtRate(float Rate);
    
        /** Handler for when a touch input begins. */
        void TouchStarted(ETouchIndex::Type FingerIndex, FVector Location);
    
        /** Handler for when a touch input stops. */
        void TouchStopped(ETouchIndex::Type FingerIndex, FVector Location);
    
    protected:
        // APawn interface
        virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
        // End of APawn interface
    
    public:
        /** Returns CameraBoom subobject **/
        FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
        /** Returns FollowCamera subobject **/
        FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }
    
    /********************************系统生成的代码分割线**********************************/
    
    private:
        //右手状态
        bool rightState;
        //左手状态
        bool leftState;
        //能否旋转
        bool canTrun;
        //死亡状态
        bool deathState;
        //导向旋转
        FRotator desireRotation;
    
    protected:
        //右转身函数
        void RightTurn();
        //左转身函数
        void LeftTurn();
        //按键响应函数
        void PikaSetupPlayerInputComponent(class UInputComponent *InputComponent);
    
    public:
        //模拟的构造函数
        void PikaStructure();
        //重载BeginPlay和Tick函数
        virtual void BeginPlay() override;
        virtual void Tick(float DeltaSeconds) override;
    
        //自动向前跑
        void KeepMoving();
        FVector JudgeRAndL(FRotator pikaRotation);
        FVector AddInputMoveForworld();
    
        void PikaPirnt(FString  pikaStr);
    
        FRotator PikaCombinRotation(FRotator rotation1 , FRotator rotation2);
    
        //设置角色的转向
        void PikaCharacterTurn();
    }
  4. PikaqiuThirdTestCharacter.cpp

  5. // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
    
    #include "PikaqiuThirdTestCharacter.h"
    #include "HeadMountedDisplayFunctionLibrary.h"
    #include "Camera/CameraComponent.h"
    #include "Components/CapsuleComponent.h"
    #include "Components/InputComponent.h"
    #include "GameFramework/CharacterMovementComponent.h"
    #include "GameFramework/Controller.h"
    #include "GameFramework/SpringArmComponent.h"
    #include "Engine.h"
    
    //////////////////////////////////////////////////////////////////////////
    // APikaqiuThirdTestCharacter
    
    APikaqiuThirdTestCharacter::APikaqiuThirdTestCharacter()
    {
        // Set size for collision capsule
        GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);
    
        // set our turn rates for input
        BaseTurnRate = 45.f;
        BaseLookUpRate = 45.f;
    
        // Don't rotate when the controller rotates. Let that just affect the camera.
        bUseControllerRotationPitch = false;
        bUseControllerRotationYaw = false;
        bUseControllerRotationRoll = false;
    
        // Configure character movement
        GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input...    
        GetCharacterMovement()->RotationRate = FRotator(0.0f, 540.0f, 0.0f); // ...at this rotation rate
        GetCharacterMovement()->JumpZVelocity = 600.f;
        GetCharacterMovement()->AirControl = 0.2f;
    
        // Create a camera boom (pulls in towards the player if there is a collision)
        CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
        CameraBoom->SetupAttachment(RootComponent);
        CameraBoom->TargetArmLength = 300.0f; // The camera follows at this distance behind the character    
        CameraBoom->bUsePawnControlRotation = true; // Rotate the arm based on the controller
    
        // Create a follow camera
        FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
        FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation
        FollowCamera->bUsePawnControlRotation = false; // Camera does not rotate relative to arm
    
        // Note: The skeletal mesh and anim blueprint references on the Mesh component (inherited from Character) 
        // are set in the derived blueprint asset named MyCharacter (to avoid direct content references in C++)
    
        PikaStructure();
    }
    
    //////////////////////////////////////////////////////////////////////////
    // Input
    
    void APikaqiuThirdTestCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
    {
        // Set up gameplay key bindings
        check(PlayerInputComponent);
        /*PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
        PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
    
        PlayerInputComponent->BindAxis("MoveForward", this, &APikaqiuThirdTestCharacter::MoveForward);
        PlayerInputComponent->BindAxis("MoveRight", this, &APikaqiuThirdTestCharacter::MoveRight);
    
        // We have 2 versions of the rotation bindings to handle different kinds of devices differently
        // "turn" handles devices that provide an absolute delta, such as a mouse.
        // "turnrate" is for devices that we choose to treat as a rate of change, such as an analog joystick
        PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
        PlayerInputComponent->BindAxis("TurnRate", this, &APikaqiuThirdTestCharacter::TurnAtRate);
        PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
        PlayerInputComponent->BindAxis("LookUpRate", this, &APikaqiuThirdTestCharacter::LookUpAtRate);
    
        // handle touch devices
        PlayerInputComponent->BindTouch(IE_Pressed, this, &APikaqiuThirdTestCharacter::TouchStarted);
        PlayerInputComponent->BindTouch(IE_Released, this, &APikaqiuThirdTestCharacter::TouchStopped);
    
        // VR headset functionality
        PlayerInputComponent->BindAction("ResetVR", IE_Pressed, this, &APikaqiuThirdTestCharacter::OnResetVR);*/
    
        //皮卡丘按键响应
        PikaSetupPlayerInputComponent(PlayerInputComponent);
    }
    
    
    void APikaqiuThirdTestCharacter::OnResetVR()
    {
        UHeadMountedDisplayFunctionLibrary::ResetOrientationAndPosition();
    }
    
    void APikaqiuThirdTestCharacter::TouchStarted(ETouchIndex::Type FingerIndex, FVector Location)
    {
            Jump();
    }
    
    void APikaqiuThirdTestCharacter::TouchStopped(ETouchIndex::Type FingerIndex, FVector Location)
    {
            StopJumping();
    }
    
    void APikaqiuThirdTestCharacter::TurnAtRate(float Rate)
    {
        // calculate delta for this frame from the rate information
        AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds());
    }
    
    void APikaqiuThirdTestCharacter::LookUpAtRate(float Rate)
    {
        // calculate delta for this frame from the rate information
        AddControllerPitchInput(Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds());
    }
    
    void APikaqiuThirdTestCharacter::MoveForward(float Value)
    {
        if ((Controller != NULL) && (Value != 0.0f))
        {
            // find out which way is forward
            const FRotator Rotation = Controller->GetControlRotation();
            const FRotator YawRotation(0, Rotation.Yaw, 0);
    
            // get forward vector
            const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
            AddMovementInput(Direction, Value);
        }
    }
    
    void APikaqiuThirdTestCharacter::MoveRight(float Value)
    {
        if ( (Controller != NULL) && (Value != 0.0f) )
        {
            // find out which way is right
            const FRotator Rotation = Controller->GetControlRotation();
            const FRotator YawRotation(0, Rotation.Yaw, 0);
        
            // get right vector 
            const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
            // add movement in that direction
            AddMovementInput(Direction, Value);
        }
    }
    
    /********************************系统生成的代码分割线**********************************/
    
    //模拟的构造函数
    void APikaqiuThirdTestCharacter::PikaStructure() 
    {
        //初始化基础变量
        //右手状态
        rightState = false;
        //左手状态
        leftState = false;
        //能否旋转
        canTrun = true;
        //死亡状态
        deathState = false;
        //导向旋转
        desireRotation = FRotator(0);
    }
    
    //重载BeginPlay和Tick函数
    void APikaqiuThirdTestCharacter::BeginPlay() 
    {
        Super::BeginPlay();
    }
    void APikaqiuThirdTestCharacter::Tick(float DeltaSeconds) 
    {
        Super::Tick(DeltaSeconds);
    
        if (deathState) 
        {
        
        }
        else 
        {
            PikaCharacterTurn();
            KeepMoving();
        }
    }
    
    //自动向前跑
    void APikaqiuThirdTestCharacter::KeepMoving() 
    {
        AddMovementInput(JudgeRAndL(desireRotation) , 1);
    }
    
    FVector APikaqiuThirdTestCharacter::JudgeRAndL(FRotator pikaRotation)
    {
        if(rightState)
        {
            rightState = false;
    
            return AddInputMoveForworld();
        }
        else if (leftState) 
        {
            leftState = false;
    
            return AddInputMoveForworld();
        }
        else 
        {
            return AddInputMoveForworld();
        }    
    }
    
    FVector APikaqiuThirdTestCharacter::AddInputMoveForworld()
    {
        //获取角色的旋转值
        const FRotator pikaRotation = Controller->GetControlRotation();
        //保证只有Yaw变化
        const FRotator yawRotation(0 , pikaRotation.Yaw , 0);
        const FVector desiron = FRotationMatrix(yawRotation).GetUnitAxis(EAxis::X);
        
        return desiron;
    
    }
    
    void APikaqiuThirdTestCharacter::PikaPirnt(FString  pikaStr)
    {
        if (GEngine) 
        {
            GEngine->AddOnScreenDebugMessage(-1 , 0.5f , FColor::Red , pikaStr);
        }
    }
    
    //按键响应
    void APikaqiuThirdTestCharacter::PikaSetupPlayerInputComponent(class UInputComponent *InputComponent)
    {
        //键盘按键
        InputComponent->BindAction("pikaRight" , IE_Pressed , this , &APikaqiuThirdTestCharacter::RightTurn);
        InputComponent->BindAction("pikaLeft", IE_Pressed, this, &APikaqiuThirdTestCharacter::LeftTurn);
    }
    
    FRotator APikaqiuThirdTestCharacter::PikaCombinRotation(FRotator rotation1, FRotator rotation2) 
    {
        FQuat aQuat = FQuat(rotation1);
        FQuat bQuat = FQuat(rotation2);
    
        return FRotator(aQuat * bQuat);
    }
    
    //右转身函数
    void APikaqiuThirdTestCharacter::RightTurn()
    {
        if (canTrun)
        {
            //顺时针旋转90度
            FRotator pikaRotation = FRotator(0 , 90 , 0);
            desireRotation = PikaCombinRotation(desireRotation, pikaRotation);
            rightState = true;
        }
        PikaPirnt("RightTurn");
    }
    //左转身函数
    void APikaqiuThirdTestCharacter::LeftTurn()
    {
        if (canTrun)
        {
            //逆时针旋转90度
            FRotator pikaRotation = FRotator(0, -90, 0);
            desireRotation = PikaCombinRotation(desireRotation, pikaRotation);
            leftState = true;
        }
        PikaPirnt("LeftTurn");
    }
    
    // 设置角色的转向
    void APikaqiuThirdTestCharacter::PikaCharacterTurn()
    {
        GetController()->SetControlRotation(FMath::RInterpTo(GetControlRotation() , desireRotation , GetWorld()->GetRealTimeSeconds() , 10));
    }