如果您知道实体组件架构的工作原理,请跳过说明!
解释
好的,所以我试图创建一个实体组件系统,并且我遇到了一个非常奇怪的问题,直到现在才发生过,基本上我有一个包含一些变量的Entity类(比如name,tag,id)和一个指针向量,它跟踪所有添加到实体的组件,即实体类,所有组件都派生自Component类,它具有一个类型(char * ),以及虚拟功能,如开始,更新等。这是您创建组件的方式:
a[0]
我的问题:
好吧所以我的问题只有在我尝试获取Rigidbody2d类型的组件时才会发生,这是" PhysicalObject.cpp",physicalobject是一种已经有一些组件的实体,比如预制件,所以我不必总是将相同的组件添加到实体类型,如物理对象:
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[:-1]
[0, 1, 2, 3, 4, 5, 6, 7, 8]
>>> a[-2::-1]
[8, 7, 6, 5, 4, 3, 2, 1, 0]
错误指向" entity.h" getcomponent函数 Entity.h:
//添加组件,构造函数和其他函数。
#pragma once
class printcomponent : public Component {
printcomponent() : Component("printcomponent"){} // the printcomponent constructor derives from the component constructor which takes a char* as parameter, and sets the component's type to that char*
void Start(){
cout << "This is printed on start" << endl;
}
void Update(){
cout << "This gets printed every frame" << endl;
}
~printcomponent();//destructor
}
最后是RigidBody2d.h文件,它包含刚体组件,与其他组件没有什么不同,但仍然会出错。
RigidBody2D.h://我将显示所有代码,因为我不确定导致问题的原因,所以如果这个帖子变得非常长,我会道歉,同时请注意我和#39;在我的引擎中实现了box2d库,因此有一些变量和函数,我认为这不会导致任何错误。
#include "stdafx.h"
#include "Public.h" // all the public variables are in here, and declared in Public.cpp
#include "PhysicalObject.h"
PhysicalObject::PhysicalObject(float boxwidth, float boxheight, float gscale, bool fixedr, float nDnsity, float nFricton, string name, string tag, bool isactive, bool isstatic) : Entity(name, tag, isactive, isstatic) // so basically the constructor creates an entity
{
this->AddComponent<Transfrm>(b2Vec2(0.f, 0.f), 0.f, b2Vec2(1.f, 1.f)); // i add a transform component
this->AddComponent<RigidBody2D>(gscale, fixedr); // i add a rigidbody2d component, there is no problem when adding components
this->AddComponent<SprtRend>(this); // again spriterenderer component
trans = this->GetComponent<Transfrm>(); // okay so i have 2 variables for easily accessing specific components, i have one trans for transform, and one rigidb for rigidbody2d, basically calling this instead of getting component is much more efficient !
rigidb = this->GetComponent<RigidBody2D>(); // this is the line causing me problems, the previous line doesn't cause any problem, but this causes an Unhandled exception, in the function GetComponent of Entity.h
}
最后是RigidBody2D.cpp:
template <typename T>
T* GetComponent() {
T t; // so basically this function creates a new given type T and loops through all the components until it finds a matching type
for (unsigned i = 0; i < AllComponents.size(); i++) {
if (AllComponents.at(i)->Type == t.Type) { // when debugging in this line, in the 'autos' window, it shows the type as "RigidBody2D", which is fine, but after i continue to the other line, it gives me the unhandled exception and the type of 't' is something like: "/x" and some numbers, which makes no sense, and doesn't occur when getting other components.
return dynamic_cast<T*>(AllComponents.at(i));
break;
}
}
cout << "Entity: " << Name << " Does Not Have Component of Type: " << t.Type << endl;
}
// desctructor
我非常抱歉这篇巨大的帖子让我花了2个小时写作,但我已经进行了3天的搜索和调试,仍然无法找到解决方案,因为我从未遇到过这样的问题,提前谢谢。
答案 0 :(得分:1)
对我来说这部分看起来很奇怪:
RigidBody2D::RigidBody2D(float gscale, bool fixedr) : Component("RigidBody2D")
^^^^^^^ gscale is a float
{
Trans = new Transfrm(b2Vec2(0.f, 0.f), 0.f, b2Vec2(1.f, 1.f));
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(Trans->Position.x, Trans->Position.y);
bodyDef.gravityScale = gscale;
^^^^
Used for initialization of bodyDef.gravityScale
bodyDef.fixedRotation = fixedr;
GScale = &bodyDef.gravityScale;
^^^^^^
Pointer to bodyDef.gravityScale
FreezeRot = &bodyDef.fixedRotation;
Body = CurrentPhysicsWorld->CreateBody(&bodyDef);
}
RigidBody2D::~RigidBody2D() {
delete Trans;
delete GScale;
^^^^^^^^
Delete of bodyDef member which wasn't created by new
delete FreezeRot;
CurrentPhysicsWorld->DestroyBody(Body);
};
因此,我认为您正在尝试delete
某些非new
答案 1 :(得分:1)
有一些突出的事情:
GetComponent
并不总是返回任何内容,这很容易导致未定义的行为。
在~RigidBody2D()
中,您{{}} {{}}两个对象 - delete
和GScale
- 这些对象不是使用FreezeRot
创建的,而是拥有的按new
。
当然,这是未定义的。
这两个是否足以解决你的问题很难猜到 根据您发布的代码,我怀疑还有很多其他类似问题可以追捕。
答案 2 :(得分:0)
我认为问题在于您手动删除GScale
和FreezeRot
的方式。在GetComponent
中,您创建了一个临时对象T,它将在函数末尾超出范围。如果你搜索一个RigidBody类型,它将在函数完成时调用析构函数,删除一些应留给Box2D来管理的指针。
作为修复,我建议删除代码帽删除这两个成员,并为每种类型创建一个名为Type的静态成员,以便您可以这样做:
T::Type
而不是必须创建一个临时对象:
T t;
T.type