Introducción

Unreal Engine es uno de los motores de videojuegos más potentes y versátiles disponibles en la industria. Ofrece un conjunto robusto de herramientas para simular física realista en juegos, desde colisiones y movimientos hasta interacciones complejas entre objetos. En este módulo, exploraremos cómo implementar y manejar la física en Unreal Engine.

Contenido

  1. Configuración Inicial
  2. Componentes de Física en Unreal Engine
  3. Simulación de Rigid Bodies
  4. Colisiones y Respuestas
  5. Constraints y Joints
  6. Ejercicios Prácticos

  1. Configuración Inicial

Instalación de Unreal Engine

Para comenzar, asegúrate de tener Unreal Engine instalado en tu sistema. Puedes descargarlo desde el Epic Games Launcher.

Crear un Nuevo Proyecto

  1. Abre el Epic Games Launcher y selecciona Unreal Engine.
  2. Haz clic en "Launch" para abrir Unreal Engine.
  3. Selecciona "New Project" y elige una plantilla adecuada (por ejemplo, "Blank" o "Third Person").
  4. Configura las opciones del proyecto y haz clic en "Create".

  1. Componentes de Física en Unreal Engine

Actor y Componentes de Física

En Unreal Engine, los actores son los objetos básicos que puedes colocar en tu nivel. Los componentes de física se añaden a estos actores para habilitar la simulación física.

  • Static Mesh Component: Representa la geometría del objeto.
  • Physics Asset: Define las propiedades físicas del objeto.
  • Collision Component: Maneja la detección de colisiones.

Ejemplo de Configuración de un Actor con Física

// MyActor.h
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"

UCLASS()
class MYPROJECT_API AMyActor : public AActor
{
    GENERATED_BODY()
    
public:    
    AMyActor();

protected:
    virtual void BeginPlay() override;

public:    
    virtual void Tick(float DeltaTime) override;

    UPROPERTY(VisibleAnywhere)
    UStaticMeshComponent* MeshComponent;

    UPROPERTY(VisibleAnywhere)
    UPhysicsConstraintComponent* PhysicsConstraint;
};
// MyActor.cpp
#include "MyActor.h"

AMyActor::AMyActor()
{
    PrimaryActorTick.bCanEverTick = true;

    MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComponent"));
    RootComponent = MeshComponent;

    PhysicsConstraint = CreateDefaultSubobject<UPhysicsConstraintComponent>(TEXT("PhysicsConstraint"));
    PhysicsConstraint->SetupAttachment(RootComponent);

    MeshComponent->SetSimulatePhysics(true);
}

void AMyActor::BeginPlay()
{
    Super::BeginPlay();
}

void AMyActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}

  1. Simulación de Rigid Bodies

Habilitar Física en un Mesh

Para habilitar la simulación de física en un Static Mesh:

  1. Selecciona el Static Mesh en el editor.
  2. En el panel de detalles, marca la opción "Simulate Physics".

Propiedades de Física

  • Mass: Masa del objeto.
  • Linear Damping: Resistencia al movimiento lineal.
  • Angular Damping: Resistencia al movimiento angular.
  • Gravity: Habilitar o deshabilitar la gravedad.

Ejemplo de Configuración de Propiedades

MeshComponent->SetMassOverrideInKg(NAME_None, 50.0f);
MeshComponent->SetLinearDamping(0.1f);
MeshComponent->SetAngularDamping(0.1f);
MeshComponent->SetEnableGravity(true);

  1. Colisiones y Respuestas

Tipos de Colisiones

  • Block: El objeto bloquea otros objetos.
  • Overlap: El objeto puede solaparse con otros objetos.
  • Ignore: El objeto ignora otros objetos.

Configuración de Colisiones

MeshComponent->SetCollisionProfileName(TEXT("BlockAll"));
MeshComponent->SetNotifyRigidBodyCollision(true);

Manejo de Eventos de Colisión

MeshComponent->OnComponentHit.AddDynamic(this, &AMyActor::OnHit);

void AMyActor::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
    UE_LOG(LogTemp, Warning, TEXT("Hit detected!"));
}

  1. Constraints y Joints

Tipos de Constraints

  • Physics Constraint: Restringe el movimiento entre dos objetos.
  • Spring Arm: Simula un brazo con resorte.

Configuración de Constraints

PhysicsConstraint->SetConstrainedComponents(MeshComponent, NAME_None, OtherMeshComponent, NAME_None);
PhysicsConstraint->SetLinearXLimit(ELinearConstraintMotion::LCM_Locked, 0);
PhysicsConstraint->SetLinearYLimit(ELinearConstraintMotion::LCM_Locked, 0);
PhysicsConstraint->SetLinearZLimit(ELinearConstraintMotion::LCM_Free, 0);

  1. Ejercicios Prácticos

Ejercicio 1: Crear un Actor con Física

  1. Crea un nuevo actor en Unreal Engine.
  2. Añade un Static Mesh Component y habilita la simulación de física.
  3. Configura las propiedades de masa, damping y gravedad.
  4. Añade un Physics Constraint para restringir el movimiento en un eje.

Ejercicio 2: Manejar Colisiones

  1. Configura el Static Mesh Component para detectar colisiones.
  2. Implementa un evento de colisión que imprima un mensaje en la consola.

Soluciones

Ejercicio 1

// MyPhysicsActor.h
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyPhysicsActor.generated.h"

UCLASS()
class MYPROJECT_API AMyPhysicsActor : public AActor
{
    GENERATED_BODY()
    
public:    
    AMyPhysicsActor();

protected:
    virtual void BeginPlay() override;

public:    
    virtual void Tick(float DeltaTime) override;

    UPROPERTY(VisibleAnywhere)
    UStaticMeshComponent* MeshComponent;

    UPROPERTY(VisibleAnywhere)
    UPhysicsConstraintComponent* PhysicsConstraint;
};
// MyPhysicsActor.cpp
#include "MyPhysicsActor.h"

AMyPhysicsActor::AMyPhysicsActor()
{
    PrimaryActorTick.bCanEverTick = true;

    MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComponent"));
    RootComponent = MeshComponent;

    PhysicsConstraint = CreateDefaultSubobject<UPhysicsConstraintComponent>(TEXT("PhysicsConstraint"));
    PhysicsConstraint->SetupAttachment(RootComponent);

    MeshComponent->SetSimulatePhysics(true);
    MeshComponent->SetMassOverrideInKg(NAME_None, 50.0f);
    MeshComponent->SetLinearDamping(0.1f);
    MeshComponent->SetAngularDamping(0.1f);
    MeshComponent->SetEnableGravity(true);

    PhysicsConstraint->SetConstrainedComponents(MeshComponent, NAME_None, nullptr, NAME_None);
    PhysicsConstraint->SetLinearXLimit(ELinearConstraintMotion::LCM_Locked, 0);
    PhysicsConstraint->SetLinearYLimit(ELinearConstraintMotion::LCM_Locked, 0);
    PhysicsConstraint->SetLinearZLimit(ELinearConstraintMotion::LCM_Free, 0);
}

void AMyPhysicsActor::BeginPlay()
{
    Super::BeginPlay();
}

void AMyPhysicsActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}

Ejercicio 2

// MyCollisionActor.h
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyCollisionActor.generated.h"

UCLASS()
class MYPROJECT_API AMyCollisionActor : public AActor
{
    GENERATED_BODY()
    
public:    
    AMyCollisionActor();

protected:
    virtual void BeginPlay() override;

public:    
    virtual void Tick(float DeltaTime) override;

    UPROPERTY(VisibleAnywhere)
    UStaticMeshComponent* MeshComponent;

    UFUNCTION()
    void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
};
// MyCollisionActor.cpp
#include "MyCollisionActor.h"

AMyCollisionActor::AMyCollisionActor()
{
    PrimaryActorTick.bCanEverTick = true;

    MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComponent"));
    RootComponent = MeshComponent;

    MeshComponent->SetSimulatePhysics(true);
    MeshComponent->SetCollisionProfileName(TEXT("BlockAll"));
    MeshComponent->SetNotifyRigidBodyCollision(true);

    MeshComponent->OnComponentHit.AddDynamic(this, &AMyCollisionActor::OnHit);
}

void AMyCollisionActor::BeginPlay()
{
    Super::BeginPlay();
}

void AMyCollisionActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}

void AMyCollisionActor::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
    UE_LOG(LogTemp, Warning, TEXT("Hit detected!"));
}

Conclusión

En este módulo, hemos cubierto los fundamentos de la física en Unreal Engine, incluyendo la configuración inicial, los componentes de física, la simulación de rigid bodies, la gestión de colisiones y la configuración de constraints. Con estos conocimientos, estarás bien equipado para implementar física realista en tus proyectos de Unreal Engine.

Próximos Pasos

En el siguiente módulo, exploraremos cómo comparar diferentes motores de física y sus capacidades, lo que te permitirá tomar decisiones informadas sobre qué motor utilizar para tus proyectos específicos.

© Copyright 2024. Todos los derechos reservados