虚幻引擎中的面向对象编程:核心概念与实践

作为业界内广泛使用的一款游戏引擎,虚幻引擎(Unreal Engine)以其优秀的图形表现力和强大的物理模拟能力而为人所知。但除此之外,以C++为基础,结合其专属扩展功能,实现高效、灵活的面向对象编程(OOP)方式,也是虚幻引擎的一大特色。本文将会详细探讨虚幻引擎中的面向对象编程理念,并给出实际示例,让大家更快地掌握相关技巧。


1. 面向对象的核心概念

        面向对象编程(OOP)是虚幻引擎的核心基础,其核心概念包括封装、继承和多态。

a. 封装 

封装简单来说,就是将数据和函数捆绑成一个封闭的单元,并限制对数据的直接访问权限,确保程序模块之间的独立性与安全性。在虚幻引擎中,封装通常体现为:

  • 数据隐藏: 通过访问修饰符(public、private、protected)控制类内部数据的可见性。
  • 属性定义: 引擎提供了强大的属性宏,例如UPROPERTY宏,可以轻松控制编写的游戏属性是否暴露给Unreal编辑器,极大提高了界面与逻辑之间的交互性。

b. 继承

继承允许开发者定义一个类时,复用另一个类的属性和功能,并能够扩展它们。虚幻引擎结构中最常见的例子是:

  • 单继承体系: 基本上所有的游戏主要类(Actor、Component等)都是直接或间接继承自基础类 UObject。
  • 替代多继承的方案: 虚幻引擎虽然主推单继承,但通过灵活使用组件机制,能在一定程度上实现类似多重继承的效果,增强代码的灵活性。

c. 多态

  • 多态是指程序运行时能够根据实际对象类型的不同,选择合适调用的方法。在虚幻引擎中,这主要是通过虚函数(Virtual Function)的重写实现。

2. 虚幻引擎特有的扩展

        虚幻引擎为了更好支持游戏开发的需求,在C++标准语法基础上开发了一系列独特扩展和宏工具,最关键的扩展技术包含:

a. 宏 

  • UCLASS: 用于定义得到引擎垃圾回收、反射功能支持的UObject派生类;
  • UPROPERTY: 定义游戏属性,可在编辑器直接查看或配置;
  • UFUNCTION: 定义可以通过蓝图调用的方法或绑定可触发的事件。

b. 组件化开发

     虚幻引擎更加推荐使用组件而非单纯的复杂继承树。组件(例如UActorComponentUSceneComponent)能够新建、在运行时动态添加或删除,极大便利了功能的重用与扩展。


以下通过简单的项目来进行演示:

面向对象特性示例:

1、首先定义一个BaseActor基类,其中封装了两个属性和两个方法:

BaseActor.h:

protected:
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "test")
	float testvalue1;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "test")
	float testvalue2;


	UFUNCTION(BlueprintCallable, Category = "test")
	void TestFunc(float a,float b,float& c);//a,b作为输入,c作为函数输出


	UFUNCTION(BlueprintCallable, Category = "test")
	virtual void TestFunc2(float a, float b, float& c);

BaseActor.cpp

void ABaseActor::TestFunc(float a, float b, float& c)
{
	c = a + b;
}

void ABaseActor::TestFunc2(float a, float b, float& c)
{
	c = a - b;
}

2、通过BaseActor类创建蓝图类BP_BaseActor

在事件图表中对函数进行实现:

输出结果如下:

3、通过BaseActor类创建派生类DerivedActor,在派生类DerivedActor中对虚函数TestFunc2进行重写。

DerivedActor.h:

	virtual void TestFunc2(float a, float b, float& c) override;

DerivedActor.cpp:

void ADerivedActor::TestFunc2(float a, float b, float& c)
{
	c = a * b;
}

4、通过派生类创建蓝图类BP_DerivedActor,在BP_DerivedActor事件图表中对TestFunc和TestFunc2进行实现。

输出结果如下:

以上示例简单演示了在虚幻引擎中如何进行类和函的封装,如何继承父类的方法和属性,以及通过重写虚函数来实现多态。


组件化开发示例:

1、创建MyCharacter类,通过添加组件来实现添加相机和弹簧臂的功能。

MyCharacter.h:

//前置声明
class USpringArmComponent;
class UCameraComponent;

MyCharacter.h:

private:
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"));
	TObjectPtr<USpringArmComponent>CameraBoom;
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"));
	TObjectPtr<UCameraComponent>PlayerCamera;

MyCharacter.cpp:

#include "Camera/CameraComponent.h"

MyCharacter.cpp:

AMyCharacter::AMyCharacter()
{
 	// 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;

	CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
	CameraBoom->SetupAttachment(RootComponent);//相机杆附着到根组件
	CameraBoom->TargetArmLength = 600.0f;//相机杆长度
	CameraBoom->SetRelativeRotation(FRotator(-40.f, 0.f, 0.f));//相机杆旋转pitch,yaw,roll
    //相机附着到相机杆
	PlayerCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("PlayerCamera1"));
	PlayerCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName);
}

以上示例通过组件化开发,无需进行继承即可使对象的功能变得可配置和模块化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值