// header:
private:
//UPROPERTY(VisibleAnywhere)
class UCameraComponent* Camera;
//class:
#include "Camera/CameraComponent.h"
// Sets default values
AVRCharacter::AVRCharacter()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
Camera->SetupAttachment(GetRootComponent());
}
Blueprints > GameMode: GameModeBase > Create > GameModeBase
Change default pawn class to my character class
//header:
private:
void MoveForward(float throttle);
void MoveRight(float throttle);
//class:
// Called to bind functionality to input
void AVRCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis(TEXT("Forward"), this, &AVRCharacter::MoveForward);
PlayerInputComponent->BindAxis(TEXT("Right"), this, &AVRCharacter::MoveRight);
}
void AVRCharacter::MoveForward(float throttle)
{
AddMovementInput(throttle * Camera->GetForwardVector());
}
void AVRCharacter::MoveRight(float throttle)
{
AddMovementInput(throttle * Camera->GetRightVector());
}
- Create axis mapping on UE interface.
settings -> Project settings -> Engine/Input -> Create axis mapping*
-
There's a restriction basically with characters you cant move their capsules.
-
Character must move acording the VR head, but because of the childing the player will move together.
- To solve this: Move the VR root to opposite direction, so it will center character and Camera on desired location.
VRRoot = CreateDefaultSubobject<USceneComponent>(TEXT("VRRoot")); VRRoot->SetupAttachment(GetRootComponent()); Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera")); Camera->SetupAttachment(VRRoot); //Camera attach VR root
- To solve this: Move the VR root to opposite direction, so it will center character and Camera on desired location.
- Find the teleport destination
- Show the destination to the player
- Fade out the viewport
- Move the player to the destination
- Fade back in
//In Editor create an primitive object attached on player (Use blueprints to it, apparently is required go very deep in UE classes hyerarch to create primitives in c++)
//header:
private:
void UpdateDestinationMarker();
UPROPERTY(VisibleAnywhere)
class UStaticMeshComponent* DestinationMarker;
UPROPERTY(VisibleAnywhere)
float MaxTeleportDistance = 1000; //10 meters
//class:
//Calls on AVRCharacter attaching the destination marker position to Root Component (The BP_VRCharacter) :
DestinationMarker = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DestinationMarker"));
DestinationMarker->SetupAttachment(GetRootComponent());
void AVRCharacter::UpdateDestinationMarker()
{
FVector Start = Camera->GetComponentLocation();
FVector End = Start + Camera->GetForwardVector() * MaxTeleportDistance;
FHitResult HitResult;
bool bHit = GetWorld()->LineTraceSingleByChannel(HitResult, Start, End, ECC_Visibility);
if (bHit) {
DestinationMarker->SetWorldLocation(HitResult.Location);
}
}
// Problem: If there's collision our primitive will be hit by the ray that is being projected to the worod.
// Solution: BP Editor -> DestinationMarker -> Details Panel -> Collision -> Collision Presets -> Set to NoCollision
#include "Camera/PlayerCameraManager.h"
#include "TimerManager.h"
#include "Components/CapsuleComponent.h"
//Bind Action to user input:
PlayerInputComponent->BindAction(TEXT("StartFade"), IE_Released ,this, &AVRCharacter::FadeIn);
//Fade and timer logic:
void AVRCharacter::FadeIn()
{
APlayerController* PC = Cast<APlayerController>(GetController());
if (PC != nullptr) {
PC->PlayerCameraManager->StartCameraFade(0,1, FadeTime, FLinearColor::Black);
}
FTimerHandle Handle;
GetWorldTimerManager().SetTimer(Handle, this, &AVRCharacter::FadeOut, FadeTime, false);
}
void AVRCharacter::FadeOut()
{
APlayerController* PC = Cast<APlayerController>(GetController());
if (PC != nullptr) {
PC->PlayerCameraManager->StartCameraFade(1, 0, FadeTime, FLinearColor::Black);
}
}
Model panel -> Nav Mesh Bounds Volume
Press P to show/hide
In YourProjectNameBuild.cs, insert "NavigationSystem" Module in PublicDependencyModuleNames List:
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "NavigationSystem" });
//Adding navMesh reference
//Header:
private:
UPROPERTY(EditAnywhere)
FVector TeleportProjectionExtent = FVector(100, 100, 100);
//File:
#include "NavigationSystem.h"
FNavLocation NavLocation;
//Returns true if is poiting to navMesh
UNavigationSystemV1::GetCurrent(GetWorld())->ProjectPointToNavigation(HitResult.Location, NavLocation, TeleportProjectionExtent);
Unity | Unreal | API Reference |
---|---|---|
Mesh | UStaticMeshComponent | https://docs.unrealengine.com/en-US/API/Runtime/Engine/Components/UStaticMeshComponent/index.html |
RayCast | UWorld::LineTraceSingleByChannel | https://docs.unrealengine.com/en-US/API/Runtime/Engine/Engine/UWorld/LineTraceSingleByChannel/index.html |
Manipulating deltatime | FTimerManager::SetTimer | https://docs.unrealengine.com/en-US/API/Runtime/Engine/FTimerManager/SetTimer/index.html |
Transform = new Vector3(Transform) | SetActorLocation(OtherComponent->GetComponentLocation()); | https://docs.unrealengine.com/en-US/API/Runtime/Engine/GameFramework/AActor/SetActorLocation/index.html |
Debug.Log("") print("") | UE_LOG(Category, Verbosity, (TEXT("")) | https://docs.unrealengine.com/en-US/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/StringHandling/index.html |
OnTriggerXXXX(collider other) | TriggerVolume->IsOverlappingActor(ActorEvent) | https://docs.unrealengine.com/en-US/API/Runtime/Engine/GameFramework/AActor/IsOverlappingActor/index.html |
//Raycst in code example:
bool LineTraceSingleByChannel
(
struct FHitResult & OutHit, // Empty hit result
const FVector & Start, // Pass a reference toi the memory but cant edit that memory. When we dont put const in memory type parameter we indicate that value mighty be changed
const FVector & End,
ECollisionChannel TraceChannel,
const FCollisionQueryParams & Params, //Optional
const FCollisionResponseParams & ResponseParam //Optional
) const
//TimeDeltaTime
FTimerHandle Handle;
GetWorldTimerManager().SetTimer(Handle, this, &ClientCall::FinishFade, FadeTime, false);
//Hello example
FString Log = TEXT("Hello");
FString* PrtLog = &Log;
Log.Len();
PrtLog->Len();
UE_LOG(LogTemp, Warning, TEXT("%s"), **PrtLog /* Derefencing and using overload operator */)
//Acces object name
*GetOwner()->GetName();
//Access object transform
GetOwner()->GetTransform()
//Rotation Sample
float InitialYaw;
float CurrentYaw;
float TargetYaw;
CurrentYaw = FMath::Lerp(CurrentYaw, TargetYaw, 0.02f);
FRotator Rotation = GetOwner()->GetActorRotation();
Rotation.Yaw = CurrentYaw;
GetOwner()->SetActorRotation(Rotation);
//Collision Trigger
//h
#include "Engine/TriggerVolume.h"
UPROPERTY(EditAnywhere)
ATriggerVolume* TriggerPointer;
UPROPERTY(EditAnywhere)
AActor* ActorEvent;
-
In Blank Scene notes:
-
PlayerController.AbsoluteRotation: Has VR rotation update.
-
PlayerController.location: does not update
-
PlayerCameraManager.Rotation: VR Update
-
PlayerCameraManager.location: update acording move input
-