1.UE5学习笔记 Unreal Engine Reflection System
2.django简单来说是什么(Django是什么)
3.ActionRPG的存档与物品系统笔记
4.TSubclassOfåUClassçåºå«
UE5学习笔记 Unreal Engine Reflection System
The Unreal Engine Reflection System encapsulates your classes with various macros that provide engine and editor functionality.
1. Objects
The base class for objects in Unreal is UObject.
1.1 The UCLASS Macro
The UCLASS macro gives the UObject a reference to a UCLASS that describes its Unreal-based type. Each UCLASS maintains one Object called the Class Default Object (CDO).
1.2 UObject Creation
UObjects do not support constructor arguments. All C++ UObjects are initialized on engine startup, and the engine calls their default constructor. If there is no default constructor, your UObject will not compile.
UObject constructors should be lightweight and only used to set up default values and subobjects, no other functionality should be called at construction time. For Actors and Actor Components, initialization functionality should be put into the BeginPlay() method instead.
UObjects should only be constructed using NewObject at runtime, or CreateDefaultSubobject for constructors.
UObjects should never use the new operator. All UObjects are memory managed by Unreal Engine and garbage collected.
1.3 Destroying Objects
Object destruction is handled automatically by the garbage collection system when an Object is no longer referenced. This means that no UPROPERTY pointers, engine containers, TStrongObjectPtr, or class instances should have any strong references to them.
Weak Pointers have no impact on whether an Object is garbage collected or not.
When the garbage collector runs, unreferenced Objects found are removed from memory. In addition, the function MarkPendingKill() can be called directly on an Object. This function sets all pointers to the Object to NULL and removes the Object from global searches. The Object is fully deleted on the next garbage collection pass.
1.4 Automatic Updating of References
When an AActor or UActorComponent is destroyed or otherwise removed from play, all references to it that are visible to the reflection system (UProperty pointers and pointers stored in Unreal Engine container classes such as TArray) are automatically nulled.
Note this does not mean that all UObject* variables must be UProperties. If you want an Object pointer that is not a UProperty, consider using TWeakObjectPtr.
2. Properties
2.1 Property Declaration
2.2 Core Data Types
As Bitmasks
You can also make integer parameters to Blueprint-callable functions behave as bitmasks, by adding the Bitmask meta tag (no value necessary) to a UPARAM specifier for the parameter.
In order to customize the bitflags' names, we must first create a UENUM with the "bitflags" meta tag:
As an alternate declaration style, we can use the ENUM_CLASS_FLAGS to turn your enumerated type into a bitmask after defining it.
Here is the test sample:
2.3 Strings
Unreal Engine 5 supports three core types of strings.
2.4 Structs
Unreal Engine's reflection system recognizes structs as a UStruct, but they are not part of the UObject ecosystem, and cannot be used inside of UClasses.
Struct Specifiers
Best Practices & Tips
Below are some helpful tips to remember when you use UStruct:
2.5 TSubclassOf
TSubclassOf is a template class that provides UClass type safety.
2.6 Property Specifiers
2.7 Metadata Specifiers
Metadata only exists in the editor; do not write game logic that accesses metadata.
Property Metadata Specifiers
More Metadata Specifiers Details :
Metadata Specifiers
3. Interfaces
Interface classes are used for ensuring that a set of potentially unrelated classes implement a common set of functions.
3.1 Interface Declaration
Declaring an interface class is similar to declaring a normal Unreal class, but with two main differences.
The "U-prefixed" class needs no constructor or any other functions, while the "I-prefixed" class will contain all interface functions and is the one that will actually be inherited by your other classes.
3.2 Interface Specifiers
BlueprintType
DependsOn
MinimalAPI
3.3 Blueprint Callable Interface Functions
To make a Blueprint callable interface function, you must provide a UFUNCTION macro in the function's declaration with the BlueprintCallable specifier. You must also use either the BlueprintImplementableEvent or BlueprintNativeEvent specifiers, and the function must not be virtual.
3.4 Determining If a Class Implements Your Interface
3.5 Casting To Other Unreal Types
3.6 Blueprint Implementable Classes
If you want Blueprints to be able to implement this interface, you must use the Blueprintable metadata specifier.
Every interface function that your Blueprint class is intended to override, must be a BlueprintNativeEvent or a BlueprintImplementableEvent.
Functions marked as BlueprintCallable will still be able to be called, but not overridden. All other functions will be inaccessible from Blueprints.
4. UFunctions
4.1 Function Specifiers
Full Doc: UFunctions
4.2 Function Parameter Specifiers
5. Unreal Smart Pointer Library
The Unreal Smart Pointer Library is a custom implementation of C++ smart pointers designed to ease the burden of memory allocation and tracking.
These classes cannot be used with the UObject system because Unreal Objects use a separate memory-tracking system that is better-tuned for game code.
More Details: Unreal Smart Pointer Library
django简单来说是什么(Django是什么)
导读:本篇文章首席CTO笔记来给大家介绍有关django简单来说是什么的相关内容,希望对大家有所帮助,一起来看看吧。为什么很多人都喜欢Django的ORM而不是SQLAlchemy,是因为简单...sqlalchemy使用上有两个层次,1是使用sqlexpression,说白可以让你用python写sql,2是dracut源码分析它的orm,orm是使用session的,自行管理session生存期,自行在多个过程中传递session,自行管理事务。写法上是通常的transactionscript(java常说的贫血的domainmodel)模式。实际编码通常1和2混合编程。
django通过中间件部分隐藏了连接/事务管理的概念,写法上也比较简单,接近java常说的充血的domainmodel.内容上也没有sqlalchemy的sqlexpression层次。易用性就体现出来了。
不过用过的orm中,能达到sqlalchemy这样高度的orm,还没有在其他语言中看到。ruby有sequal,java的jooq都有部分sqlalchemy思想的影子。
Django和Flask这两个框架在设计上各方面有什么优缺点
(1)Flask
Flask确实很“轻”,不愧是MicroFramework,从Django转向Flask的开发者一定会如此感慨,除非二者均为深入使用过
Flask自由、灵活,可扩展性强,第三方库的梅州道闸源码选择面广,开发时可以结合自己最喜欢用的轮子,也能结合最流行最强大的Python库
入门简单,即便没有多少web开发经验,也能很快做出网站
非常适用于小型网站
非常适用于开发web服务的API
开发大型网站无压力,但代码架构需要自己设计,开发成本取决于开发者的能力和经验
各方面性能均等于或优于Django
Django自带的或第三方的好评如潮的功能,Flask上总会找到与之类似第三方库
Flask灵活开发,Python高手基本都会喜欢Flask,但对Django却可能褒贬不一
Flask与关系型数据库的配合使用不弱于Django,而其与NoSQL数据库的配合远远优于Django
Flask比Django更加Pythonic,与Python的philosophy更加吻合
(2)Django
Django太重了,除了web框架,自带ORM和模板引擎,灵活和自由度不够高
Django能开发小应用,但总会有“杀鸡焉用牛刀”的感觉
Django的自带ORM非常优秀,综合评价略高于SQLAlchemy
Django自带的模板引擎简单好用,但其强大程度和综合评价略低于Jinja
Django自带ORM也使Django与关系型数据库耦合度过高,如果想使用MongoDB等NoSQL数据,需要选取合适的第三方库,且总感觉Django+SQL才是天生一对的搭配,Django+NoSQL砍掉了Django的半壁江山
Django目前支持Jinja等非官方模板引擎
Django自带的数据库管理app好评如潮
Django非常适合企业级网站的开发:快速、靠谱、稳定
Django成熟、稳定、简单小说php源码完善,但相比于Flask,Django的整体生态相对封闭
Django是Pythonweb框架的先驱,用户多,第三方库最丰富,最好的Python库,如果不能直接用到Django中,也一定能找到与之对应的移植
Django上手也比较容易,开发文档详细、完善,相关资料丰富
django和django-cms的区别知乎与其说Django-cms是一个内容管理系统,不如说其实一个基础的开发平台。与常规的cms不同,Django-cms并不是一个开箱即用的产品,也没有提供很多内置的模板和主题,让用户快速的搭建一个网站出来。相反,要想使用Django-cms要求用户必须熟悉Django,其搭建的的过程很"像"一个是用Django开发的过程。
本文根据一天的文档阅读心得总结而来。
从结构上来说Django-cms包含以下内容:
1、一个基础框架:
多站点支持——好吧,其实是Django的
多语言支持。没个页面可以有不同语言的源码学堂健康饮食版本。
Page管理。后台可视化支持,包括Page结构和Page中插件(Plugin)的配置等
可扩展的菜单系统
集成/继承自Django的模板系统。增加placeholder。
基于plugin的扩展机制——与Django应用(app)的集成。
2、一组插件
file
text
googlemap
flash
video
3、一组模板标签
show_menu
show_breadcrumb
show_submenu
placeholder
......
4、其他
SEO支持
虚拟根(softroot)
sitemap
(内容)版本历史记录功能
...
从使用上来说,Django-cms的首要客户应该是程序员,而不是最终用户或设计师。这是由其部署过程决定的,在使用Django-cms开发一个网站的时候,大体上要遵循如下步骤:
使用标准的django-admin.pystartproject建立标准Django项目
修改settings.py,INSTALLED_APPS增加cms、menu及其他的插件,TEMPLATE_CONTEXT_PROCESSORS、LANGUAGES、及其他CMS_开头的配置信息
使用manage.pysyncdb生成数据库
开发模板和样式
manage.pyrunserver启动
然后才是使用后台系统构建目标网站结构
如果发现需求无法满足,可以去Django-cms网站查询插件库或者根据其扩展机制开发自己的plugin。这纯粹是在标准Django应用(app)开发的基础上,外加一个与Django-cms的集成。
虽然Django-cms提供的开箱即用功能不多,但是新世界平台源码它却提供了一个非常好的基础结构,让开发人员可以快速构建产品。所以从这个角度来说称其为enhanced-django似乎更合适。
Django什么情况在朋友和同事的极力推荐下最近开始看上了python,其实主要是还是因为python是年度语言,怎么的也要与时俱进呀.最近一路看来有些心得,希望能与大家分享,小弟其实也只接触不到一周的python,有说错的地方还望大家指出改正.
不打算从py的语法基础说起了,直接说说对django的心得:
接触django首先需要了解可能就是他那个model,建立一个model就什么都有了,这对于搞java得人员来说还是挺有吸引力的(当然貌似对于动态语言这都是小儿科),那么让我们先看一个model的例子:
偷懒了,直接拿django-admin里面的User出来了
classUser(models.Model):
username=models.CharField(_('username'),maxlength=,unique=True,validator_list=[validators.isAlphaNumeric]))
first_name=models.CharField(_('firstname'),maxlength=,blank=True)
last_name=models.CharField(_('lastname'),maxlength=,blank=True)
email=models.EmailField(_('e-mailaddress'),blank=True)
password=models.CharField(_('password'),maxlength=))
classMeta:
ordering=('username',)
每个属性就是一个库表的字段,定义起来非常简单明了,models里面提供了很多种类的Field类似上面的EmailField。不同的Field有不同的设置,可以看相应的原来来了解相关的设置.
在modelclass内部还有一个classMeta,这个Class的属性制定了这个表的一些存取策略,例如这里的ordering。MetaClass里面的属性可以用model的_meta属性取得。OK,那么这样一个model怎么就能实现对数据库表的灵活操作了呢。让我们来看看吧。
首先先分析一下/django/django/db/models/base.py这个文件,其中包含了models.Model这类的定义:
看看class定义的第一行吧,第一行就够我琢磨一阵子的了:
classModel(object):
__metaclass__=ModelBase
Model采用了newstyleclass定义,关于这个内容大家可以放狗看一下,第一行是一个__metaclass__属性的定义,该属性的值是ModelBase,这是一个类。__metaclass__的意思是,指定一个class,这个class的实例就是本class,相信您已经晕了。那么就拿这个Model的例子来说明一下,如果没有__metaclass__这个属性,产生一个实例就是正常的流程,有了这个属性流程会有改变:
首先调用BaseModel.__new__(cls,name,bases,attrs)这个方法,回返回的值是一个class类型,然后用这个class来创建实例。其实BaseModel就是Model的元类,来制定Model这个类的最终样子。关于元类的更多信息请看这里
那么我们的目光一下转移到BaseModel这个类上,我有种直觉,Meta这个class最后可以用_meta来取就是在这里做的手脚,看一下BaseModel的定义吧,有点长:
classModelBase(type):
"Metaclassforallmodels"
def__new__(cls,name,bases,attrs):
#Ifthisisn'tasubclassofModel,don'tdoanythingspecial.
ifname=='Model'ornotfilter(lambdab:issubclass(b,Model),bases):#1
returnsuper(ModelBase,cls).__new__(cls,name,bases,attrs)
#Createtheclass.
new_class=type.__new__(cls,name,bases,{ '__module__':attrs.pop('__module__')})#2
new_class.add_to_class('_meta',Options(attrs.pop('Meta',None)))#3
new_class.add_to_class('DoesNotExist',types.ClassType('DoesNotExist',(ObjectDoesNotExist,),{ }))
#Buildcompletelistofparents#4
forbaseinbases:
#TODO:Checkingforthepresenceof'_meta'ishackish.
if'_meta'indir(base):
new_class._meta.parents.append(base)
new_class._meta.parents.extend(base._meta.parents)
model_module=sys.modules[new_class.__module__]
ifgetattr(new_class._meta,'app_label',None)isNone:
#Figureouttheapp_labelbylookingonelevelup.
#For'django.contrib.sites.models',thiswouldbe'sites'.
new_class._meta.app_label=model_module.__name__.split('.')[-2]#5
#Bailoutearlyifwehavealreadycreatedthisclass.
m=get_model(new_class._meta.app_label,name,False)#6
ifmisnotNone:
returnm
#Addallattributestotheclass.
forobj_name,objinattrs.items():
new_class.add_to_class(obj_name,obj)#7
#AddFieldsinheritedfromparents
forparentinnew_class._meta.parents:
forfieldinparent._meta.fields:
#Onlyaddparentfieldsiftheyaren'tdefinedforthisclass.
try:
new_class._meta.get_field(field.name)
exceptFieldDoesNotExist:
field.contribute_to_class(new_class,field.name)#8
new_class._prepare()
register_models(new_class._meta.app_label,new_class)#9
#Becauseofthewayimportshappen(recursively),wemayormaynotbe
#thefirstclassforthismodeltoregisterwiththeframework.There
#shouldonlybeoneclassforeachmodel,sowemustalwaysreturnthe
#registeredversion.
returnget_model(new_class._meta.app_label,name,False)#
简单分析一下这个代码:
1.检查class是否为Model的子类,不是的话,不做任何处理,直接传给父类处理,也就相当于正常的处理了class,注意super在多重继承的时候应该严格使用
2.用type来创建类,创建的就是正常的ModelClass
3.这句很重要,add_to_class是Model里面的class方法,这个方法其实就是传入name和value,给Model添加class属性.看到了,原来神奇的_meta就是这么来的.提到add_to_class方法,简单看一下它的代码:
defadd_to_class(cls,name,value):
ifname=='Admin':
asserttype(value)==types.ClassType,"%rattributeof%smodelmustbeaclass,nota%sobject"%(name,cls.__name__,type(value))
value=AdminOptions(**dict([(k,v)fork,vinvalue.__dict__.items()ifnotk.startswith('_')]))
ifhasattr(value,'contribute_to_class'):
value.contribute_to_class(cls,name)
else:
setattr(cls,name,value)
add_to_class=classmethod(add_to_class)
最后一句是制定这个方法是class方法,特点就是方法的第一个参数是本class,其实classmethod就是一个装饰器,在2。4之后可以使用@来简写。这里不得不提的是他对Admin的特殊处理,虽然AdminOption不是在admin模块里面的,但是这么做还是跟一个Admin的东东绑定起来了,在java的世界解耦是一件大事,看到下面还有对'contribute_to_class'这个方法的特殊处理,django为啥不弄的解耦点呢。而且同样是包装成Option,一个是在BaseModel里面弄(那个Meta的包装),一个在add_to_class方法里面弄,实在有点不优雅,可能还没了解太多,不知道他的深度用意吧。
4.Meta的集成,Option的这个类提供继承方法
5.取得applabel,就是把model的名字分割取到数第二个,我很喜欢-2这样的设定
6.get_model方法取得缓存里面的东西。
7.把所有的classattr拿出来搞一遍,一般的属性就setattr弄回去了,要是这个属性有contribute_to_class这个callable属性,那就执行之(Admin的处理完全也可以这样,其实我们常用的objects就是用这个方法弄的)
8.每个Field调用自己的contribute_to_class方法来进行特殊的处理
9.进入缓存,,暂且叫缓存吧,里面的东西大家看看很简单文件在/django/django/db/models/loading.py里面还是有很多内容的
.看注释说的很清楚了,我们一定要在缓存里面拿model。
结语:以上就是首席CTO笔记为大家介绍的关于django简单来说是什么的全部内容了,希望对大家有所帮助,如果你还想了解更多这方面的信息,记得收藏关注本站。
ActionRPG的存档与物品系统笔记
ActionRPG在RPGType.h文件中定义了各个类型,在RPGControllerBase类中定义了背包逻辑。而存档逻辑则分布在RPGGameInstance与RPGSaveGame中。
对于个人项目,建议直接使用这里的代码,无需修改。但为了方便后续的Ue4项目使用,最好将共用部分封装成插件。这也是官方GameplayAbility视频教程所推荐的。
物品类型定义在RPGItem.h文件中,包括物品名称、描述、图标、价格、最大数量、最高等级、附带的Ability等级变量等。同时,TSubclassOf GrantedAbility定义了物品附带的Ability对象。
GetIdentifierString()函数用于返回主资源的Id字符串,FPrimaryAssetId GetPrimaryAssetId()函数用于返回主资源的Id。
FRPGItemSlot位于RPGType.h中,类似于黑魂中的快捷物品栏、装备武器栏等。你可以通过指定类型来区分不同的物品格子。
FRPGItemData包含了背包中的物品数量、物品等级等信息。其中UpdateItemData函数用于处理物品变动时的容错问题。
在RPGPlayerControllerBase.h中,我倾向于将背包逻辑封装成一个Component,通过继承UActorComponent来实现Inventory方面的代码移植。
由于本人制作的Demo为魂like游戏,Token类型的Item作为“魂”来定义。魂不会影响UI显示,因此项目里增加了一个委托:FOnInventoryItemChanged OnInventoryTokenItemChanged。
在通知函数FillEmptySlotWithItem中,会判断Token类型,并只对OnInventoryTokenItemChanged进行多播。
RPGSaveGame.h定义了一个用于存储游戏数据的存储对象。
RPGGameInstanceBase.h中包含了主要的存档逻辑,如HandleSaveGameLoaded、WriteSaveGame、LoadOrCreateSaveGame、HandleAsyncSave等函数。
在游戏中,ItemSlot的设置与魂系列游戏不同,建议删除所有自动填充ItemSlot的逻辑,并重写SetSlottedItem、FillEmptySlots、FillEmptySlotWithItem等函数。
物品系统的SlottedItems需要手动添加Key,否则无法通过SetSlotedItem设置SlotItem。建议在UI中完成这项工作,例如在Slot UI的Construct函数中向SlottedItems添加Key,以实现注册槽的目的。
TSubclassOfåUClassçåºå«
UObjectä½ä¸ºè¢«å建ç 对象 çå¤é¨åæ°ã
UClasså®ä¹å¾ å建ç 对象 ç±»ã