【Unity开发】TryGetComponent的踩坑记录

在做项目时遇到了一个需求,是需要从碰撞体中获取某个组件,并对该组件做一些操作,因此我编写了如下代码:

private void OnTriggerEnter2D(Collider2D collision)
{
    var csr = collision.GetComponent<SpriteRenderer>();
    if (csr != null)
    {
        // Do Something
    }
}

不过,csr作为一个临时变量会引发GC,Visual Studio就为我提供了这样的建议:

原来,Unity中提供了TryGetComponent()这一方法,可以尝试从目标gameobject获取一个组件,如果获取失败,就不会为其申请空间,这样一来就减少了GC的发生,我的代码于是变成了这样:

private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.TryGetComponent<SpriteRenderer>(out var csr))
    {
        // Do Something
    }
}

我就想,即便是这样,我仍旧会产生一个临时变量csr用来存储get到的组件,那么如果我把这个csr声明为一个全局变量,会不会直接就避免了GC?(当然也不合理,因为这样一来在我们没有使用这个变量的大部分时间里,这部分内存都要被占用着)当时没想这么多,就这么做了,于是代码又变成了这样:

private SpriteRenderer csr;
private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.TryGetComponent(out csr))
    {
        // Do Something
    }
}

这下连泛型都省了,因为变量的类型已经被指定了。

马上我就继续去写其他的业务代码,结果发现事情没有那么简单,在我从别处调用了csr后,发现它居然是空的!

事实证明,out的返回值并不是用于长期留存的,Unity可能在这个方法执行完后就会把这块内存给清空,进而导致了csr成了一个空引用。。。

最后,我还是接受了创建临时变量的事实,把临时变量的值赋给了csr:

private SpriteRenderer csr;
private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.TryGetComponent(out SpriteRenderer tsr))
    {
        csr = tsr;
        // Do Something
    }
}

再次尝试,csr的引用内容终于正常了。以后在处理out参数的时候,肯定会多留个心眼了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值