该怎么样用C++来实现类Unity3d的AddComponent

19 篇文章 0 订阅

Unity3d 越来越完善,朝着它学习的人也越来越多。一是因为Unity3d是一整套开发工具,使用起来简单快捷。二是 Mono C#的快速开发上手简单。


在Unity编辑器中,添加一个GameObject , 然后把一个继承自MonoBehavior的脚本拖到GameObject上,即可对GameObject进行操作。或者在代码中new 一个GameObject,然后用AddComponet 挂载一个脚本到GameObject上。


AddComponet 这个函数,可以通过传递 String 来实例化一个类。该如何用C++来实现类似的功能呢?


首先介绍一下Unity 的一些原理:

(1) 我们编写一个类继承自MonoBehavior ,然后添加 Start 、Update 这些函数。但是这些函数其实是私有的,并不是从MonoBehavior中继承而来,那这几个函数是在哪里调用的?

Unity中通过反射来判断一个类中有没有对应的函数,引自知乎中的一个回答:


Unity的确是通过反射来调用脚本的方法的,并且这一过程会在运行时不停对所有MonoBehaviour遍历进行。

Unity之所以统一地使用这一套固定的函数命名方案,便于明确地划出了每个函数需要做些什么。

这样做的目的我猜测是有利用保留脚本的灵活性。

这种做法被惯称为“事件机制”,一旦某个脚本被执行完成之后,它的控制权会重新回到调度管理处,可以轻松地再去执行下一个,

并且也能在运行时通过反射方式让其它脚本使用Component.SendMessage进行调用。

如果采用了抽象方式让子类去实现这样的方法,那么对于Unity本身的对象管理是没有任何好处的,并且对于拥有多个脚本组件的对象来说,维护成本不但增加了,

还可能让脚本之间的管理变得混乱。

使用反射也许会丢失一些性能,但却能让每个不同的MonoBehaviour之间看起来都是独立的,只需要在它提供的几个内置方法中关注自己的逻辑就可以了。 

那 C++ 呢?C++判断类是否有某个函数不好弄,所以还是采用继承的方式来简单实现 AddComponet 。

这种方法的关键就是如何使用类名来创建类实例


其中一种方式就是 , 让通过类名实例化的类 继承自 基类 ,然后通过静态函数在程序最开始运行的时候,向基类注册,然后在调用 AddComponet 的时候,通过基类的函数在最开始注册的子类中寻找是否有对应名字的子类,如果有的话就实例化子类。


最终简单实现Unity3d中的AddComponet 函数。

int main()
{
	GameObject* obj=new GameObject("Cube");
	NewMonoBehaviour* newmono=(NewMonoBehaviour*)obj->AddComponent("NewMonoBehaviour");
	MyMonoBehaviour* mymono=(MyMonoBehaviour*)obj->AddComponent("MyMonoBehaviour");

	for (int i=0;i<obj->m_componentVec.size();i++)
	{
		std::pair<string,Component*> compmap=obj->m_componentVec[i];
		MonoBehaviour* mono=(MonoBehaviour*)compmap.second;
		mono->Awake();
	}

	system("pause");
	return 0;
}

代码下载:

http://pan.baidu.com/s/1i3rcYPZ




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值