前言
发现了Unity的Transform组件有意思的地方,所以这里准备记录一下。
1.抛出问题
先给各位展示一下有问题的代码,具体代码如下:
Transform treanTransform = new GameObject("Test").transform;
treanTransform.gameObject.AddComponent<BoxCollider>();
treanTransform.gameObject.AddComponent<Canvas>();
treanTransform.gameObject.AddComponent<BoxCollider>();
可能看了很长时间也没有发现问题在那里,其实一开始也不知道...,但是打断点出来的结果是这样的,执行到这行代码才出现的问题gameObject.AddComponent<Canvas>(),导致引用直接变成null了,这是新工程什么东西都没有,就只有这个脚本,所以其他因素就不用考虑...
2.尝试解决问题
调用AddComponent其他组件没有任何问题,但是添加Canvas组件是有问题的,准备修改代码再尝试一下看看,具体代码如下:
GameObject tmpGameObject = new GameObject("Test");
tmpGameObject.AddComponent<BoxCollider>();
tmpGameObject.AddComponent<Canvas>();
tmpGameObject.AddComponent<BoxCollider>();
经过尝试可以正常的执行,准备尝试一下其他情况,代码如下:
void Start()
{
transform.gameObject.AddComponent<BoxCollider>();
transform.gameObject.AddComponent<Canvas>();
transform.gameObject.AddComponent<BoxCollider>();
}
发现也是没有问题,这样为什么会丢引用呢?突然想到一件事件,就是添加了Canvas以后,Unity将原来Transform组件变幻成了RectTransform组件,这样才导致引用丢失的,接下来就要抛砖引玉了。
3.抛砖引玉
那文章第三处代码段为什么可以正常执行呢?把鼠标移动到transform一探究竟吧,具体如下图所示:
原来transform它是一个属性,也就是说它是及时获取到组件返回的,并非是一个引用,所以优化游戏的时候就可以这样去做,具体代码如下:
private new Transform transform;
private new GameObject gameObject;
void Awake()
{
transform = base.transform;
gameObject = base.gameObject;
}
但是要小心一点,这样做可能会导致出现意外情况,从而丢失引用,比如什么情况呢???添加Canvas组件时。
第二点就是RectTransform和Transform组件有什么区别呢?
3D面板上显示的是位置坐标组件Transform,2D面板上显示的是位置坐标组件RectTransform
RectTransform是Transform的子类,可以这样强制转换(RectTransform rectTrans = (RectTransform)this.transform;)但是反过来就不行啦,RectTransform是可以看到源代码的,具体代码如下: