x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Walk on walls Function

I've seen variants of this question asked around the fourms but sitll not entirely sure how to implment it. I'm trying to create the ability for the player to walk on walls, however, I want this to be controlled by a key function. What is the best way to go about applying this?

Thanks, Hans

Product Version: UE 4.9
Tags:
more ▼

asked Sep 24 '15 at 01:39 PM in C++ Programming

avatar image

hansstormtrooper
1 1 2 1

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

In Unreal 3, in the EPhysics enum, there was a PHYS_Spider. I never used it myself, so it might not be helpful to you, but it's a place to start. On that note, here's a video about walking on walls and spider physics in Unreal 4. I can't watch the video to see how helpful it is because I'm at work, but it might be of use to you. https://www.youtube.com/watch?v=jeU9AxtSMbA

more ▼

answered Mar 07 '16 at 02:01 PM

avatar image

sseufert
54 5 20 20

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

I had similar problem and I decided to write my own character class to solve this. My idea was to create whole game with switchable gravity, I thought it would be quite cool concept. After I saw Broken Dimensions gameplay I thought that it's not something as innovative - and actually it works with specific types of genres. My concept changed with time, maybe I'll try to implement it somewhere else. For now, you are free to use it.

I'll post here some of my source code to make it use to you and others. One big flaw - since I had to write from the beginning whole Character class (I called it GravityCharacter), I have quite broken collision detection. It works, but not as well as original ACharacter class.

(GravityCharacter.h file)

 #pragma once
 
 #include "GameFramework/Character.h"
 #include "ObjectMovementComponent.h"
 #include "GravityCharacter.generated.h"
 
 class UGravityMovementComponent;
 
 UCLASS()
 class GRAVITY_API AGravityCharacter : public ACharacter
 {
     GENERATED_BODY()
 
     UPROPERTY(EditAnywhere)
         UCameraComponent *CameraComponent;
     UPROPERTY(EditAnywhere)
         UGravityMovementComponent *CharacterMovementComponent;
 
 
 public:
 
     UGravityMovementComponent* GetCharacterMovementComponent() { return CharacterMovementComponent; }
 
     UCameraComponent* GetCameraComponent() { return CameraComponent; }
     FVector GetCameraLocation() { return CameraComponent->GetComponentLocation(); }
     FRotator GetCameraRotation() { return CameraComponent->GetComponentRotation(); }
     void HitLaser(ALaserBeam *Laser) {}
 
     AGravityCharacter();
 
     virtual void BeginPlay() override;
     virtual void Tick(float DeltaSeconds) override;
     virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
 
     virtual void MoveForward(float Val);
     virtual void MoveRight(float Val);
     virtual void ChangeGravity(float Val);
 
     virtual void Jump();
 
 };


(GravityCharacter.cpp file)

 #include "Gravity.h"
 #include "Runtime/Engine/Classes/Kismet/KismetSystemLibrary.h"
 #include "GravityMovementComponent.h"
 #include "Runtime/Engine/Classes/Engine/Player.h"
 #include "GravityCharacter.h"
 
 
 
 AGravityCharacter::AGravityCharacter() {

     //to obtain this I had to change one keyword in Character.h from private to protected. Pretty sick, huh?
     CharacterMovement->DestroyComponent();
     ACharacter::Mesh->DestroyComponent();
 
     RootComponent = CapsuleComponent;
     CapsuleComponent->SetSimulatePhysics(false);
     CapsuleComponent->SetEnableGravity(false);
     PrimaryActorTick.bCanEverTick = true;
     CameraComponent = CreateDefaultSubobject<UCameraComponent>("Camera Component");
     CameraComponent->SetupAttachment(CapsuleComponent);
     CameraComponent->SetRelativeLocation(FVector(0, 0, CapsuleComponent->GetScaledCapsuleHalfHeight() / 2));
 
     CharacterMovementComponent = CreateDefaultSubobject<UGravityMovementComponent>("Character Movement Component");
     CharacterMovementComponent->SetCharacterOwner(this);
 
     //AutoPossessPlayer = EAutoReceiveInput::Player0;
     //APawn::bUseControllerRotationPitch = false;
     //APawn::bUseControllerRotationYaw = false;
 }
 
 void AGravityCharacter::Tick(float DeltaTime) {
 
     Super::Tick(DeltaTime);
 
 }
 
 void AGravityCharacter::BeginPlay() {
     Super::BeginPlay();
 }
 
 void AGravityCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) {
     check(PlayerInputComponent);
     Super::SetupPlayerInputComponent(PlayerInputComponent);
 
     PlayerInputComponent->BindAxis("MoveForward", this, &AGravityCharacter::MoveForward);
     PlayerInputComponent->BindAxis("MoveRight", this, &AGravityCharacter::MoveRight);
     PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
     PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
     PlayerInputComponent->BindAxis("ChangeGravity", this, &AGravityCharacter::ChangeGravity);
 
     PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AGravityCharacter::Jump);
 
 }
 
 
 void AGravityCharacter::MoveForward(float Value) {
     if (Value != 0.0f)CharacterMovementComponent->MoveForwardInput(Value);
 }
 void AGravityCharacter::MoveRight(float Value) {
     if (Value != 0.0f)CharacterMovementComponent->MoveRightInput(Value);
 }
 void AGravityCharacter::ChangeGravity(float Value) {
     if (Value != 0.0f)CharacterMovementComponent->ChangeGravityInput(Value);
 }
 void AGravityCharacter::Jump() {
     CharacterMovementComponent->JumpInput();
 }

(GravityMovementComponent.h - after some time I realised it would be better to write UActorComponent inherited class instead of keeping everyting in one file)

 #pragma once
 
 #include "Components/ActorComponent.h"
 #include "GravityCharacter.h"
 #include "GravityMovementComponent.generated.h"
 
 class AGravityCharacter;
 
 UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
 class GRAVITY_API UGravityMovementComponent : public UActorComponent
 {
     GENERATED_BODY()
 
 protected:
     AGravityCharacter *OwnerCharacter;
 
 public:    
     UGravityMovementComponent();
     virtual void BeginPlay() override;
     virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override;
     
     void SetCharacterOwner(AGravityCharacter *InOwnerCharacter) { OwnerCharacter = InOwnerCharacter; }
 
     FVector GetActorLocation() { return OwnerCharacter->GetActorLocation(); }
     FRotator GetActorRotation() { return OwnerCharacter->GetActorRotation(); }
 
     AController* GetController() { return OwnerCharacter->GetController(); }
     UCapsuleComponent* GetCapsuleComponent() { return OwnerCharacter->GetCapsuleComponent(); }
     UCameraComponent* GetCameraComponent() { return OwnerCharacter->GetCameraComponent(); }
 
     UPROPERTY(EditAnywhere)
         float GravityValue = 4000;
     UPROPERTY(EditAnywhere)
         float MovementSpeed = 5000;
     UPROPERTY(EditAnywhere)
         float FrictionParameter = 0.9f;
     UPROPERTY(EditAnywhere)
         float JumpVelocity = 2000;
 
     int GValue = 0;
 
     FVector Xaxis = FVector(1, 0, 0);
     FVector Yaxis = FVector(0, 1, 0);
     FVector Zaxis = FVector(0, 0, 1);
 
     FVector& operator[](int i) {
         if (i % 3 == 0)return Xaxis;
         if (i % 3 == 1)return Yaxis;
         return Zaxis;
     }
 
     EMovementMode MovementMode = MOVE_Flying;
 
     FVector Acceleration = FVector(0, 0, 0);
     FVector Velocity = FVector(0, 0, 0);
 
     AOptics *HoldedItem = NULL;
     bool bIsHoldingItem = false;
 
     bool bIsDroppingItem = false;
 
     FVector StartingItemLocation;
     FRotator StartingItemRotation;
 
     EMovementMode GetMovementMode() { return MovementMode; }
     void SetMovementMode(EMovementMode InMovementMode) { MovementMode = InMovementMode; }
 
     void ChangeGravityInput(float Val) {
         if (Val > 0)GValue++;
         if (Val < 0)GValue--;
         if (Val == 0)return;
 
         GValue = (GValue + 6) % 6;
         int j = GValue / 2;
         int k = 1 - GValue % 2 * 2;
         auto &Vec = *this;
         Vec[j] = FVector(k, 0, 0);
         Vec[j + 1] = FVector(0, k, 0);
         Vec[j + 2] = FVector(0, 0, k);
     }
 
 
 
     void MoveForwardInput(float Value) {
         FVector Vec = GetActorRotation().Vector();
         Vec -= Zaxis * FVector::DotProduct(Zaxis, Vec);
         Vec.Normalize();
         AddMovementInput(Vec, Value, true);
     }
 
     void MoveRightInput(float Value) {
         FVector Vec = GetActorRotation().Vector();
         Vec -= Zaxis * FVector::DotProduct(Zaxis, Vec);
         Vec.Normalize();
         AddMovementInput(FVector::CrossProduct(Zaxis, Vec), Value, true);
     }
 
     void AddMovementInput(FVector Direction, float Value, bool bForce) {
         Acceleration += Direction*Value*MovementSpeed;
     }
 
 
 
 
     float CheckCollision(FVector InVec, float D) {
         if (D <= 0)return 1;
         FVector TraceStart = GetActorLocation();
         FVector TraceEnd = TraceStart + InVec*D;
         FHitResult OutHit;
 
         FCollisionObjectQueryParams CollisionType = FCollisionObjectQueryParams(ECC_TO_BITFIELD(ECC_WorldStatic) | ECC_TO_BITFIELD(ECC_WorldDynamic));
 
 
         GetWorld()->LineTraceSingleByObjectType(OutHit, TraceStart, TraceEnd, CollisionType);
         if (OutHit.bBlockingHit) return OutHit.Distance;
         else return 2 * D;
     }
 
     void UpdateRotation() {
         if (!GetController()) return;
 
         OwnerCharacter->SetActorRotation(Zaxis.ToOrientationRotator());
         OwnerCharacter->AddActorLocalRotation(FRotator(-90, 0, 0));
         FRotator Rot = GetController()->GetControlRotation();
         OwnerCharacter->AddActorLocalRotation(FRotator(0, Rot.Yaw, 0));
         GetCameraComponent()->SetRelativeRotation(FRotator(Rot.Pitch, 0, 0));
     }
 
 
 
     void JumpInput() {
         Velocity += Zaxis * JumpVelocity;
     }
 
     void UpdatePhysics(float DeltaTime) {
         UWorld *World = GetWorld();
         if (World == NULL || DeltaTime == 0.f)return;
         Acceleration += -Zaxis * GravityValue; // part where I apply gravity
 
         Velocity += Acceleration*DeltaTime;
         Velocity *= FrictionParameter;
         Acceleration = FVector::ZeroVector;
 
         float H = GetCapsuleComponent()->GetScaledCapsuleHalfHeight();
         float R = GetCapsuleComponent()->GetScaledCapsuleRadius();
 
         float z0 = CheckCollision(-Zaxis, H);
         float z1 = CheckCollision(Zaxis, H);
 
         float dot = FVector::DotProduct(Velocity, Zaxis);
         if (z1 < H && dot > 0) Velocity -= dot*Zaxis; //ceiling
 
         if (dot < 0) {
             bool IsStandingOnFloor = z0 < H;
 
             if (IsStandingOnFloor) {
                 Velocity -= dot*Zaxis;
                 SetMovementMode(MOVE_Walking);
             }
             else SetMovementMode(MOVE_Falling);
         }
 
         for (FVector Axis : {Xaxis, Yaxis}) { //check for walls
             float x0 = CheckCollision(-Axis, R);
             float x1 = CheckCollision(Axis, R);
             dot = FVector::DotProduct(Velocity, Axis);
             if (x0 < R && dot < 0) Velocity -= dot*Axis;
             if (x1 < R && dot > 0) Velocity -= dot*Axis;
         }
 
 
         OwnerCharacter->AddActorWorldOffset(Velocity*DeltaTime);
 
     }
 };


(GravityMovementComponent.cpp file)

 #include "Gravity.h"
 #include "GravityCharacter.h"
 #include "GravityMovementComponent.h"
 
 
 UGravityMovementComponent::UGravityMovementComponent(){
     PrimaryComponentTick.bCanEverTick = true;
 
     Xaxis = FVector(1, 0, 0);
     Yaxis = FVector(0, 1, 0);
     Zaxis = FVector(0, 0, 1);
 }
 
 
 void UGravityMovementComponent::BeginPlay(){
     Super::BeginPlay();
 }
 
 
 void UGravityMovementComponent::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ){
     Super::TickComponent( DeltaTime, TickType, ThisTickFunction );
     UpdateRotation();
     UpdatePhysics(DeltaTime);
 }



Ah, I could also include somewhere call to external GravityGameInstance, i thought it would be ok to keep here some global variable. Feel free to write here some const value.

more ▼

answered Feb 02 '17 at 12:07 PM

avatar image

Ch3shireCat
186 19 21 26

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question