我是靠谱客的博主 真实大船,最近开发中收集的这篇文章主要介绍Unity中的trigger,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前言

最近在一家公司实习,公司用unity做项目,所以开始抛弃cocos,步入unity的深坑,笔主在研究unity时,发现网上很少有人会去分析引擎内部的实现,更加偏向于“是什么”而不是“为什么”,笔主接下来的一段时间可能都会写一些关于unity的个人理解,由于看不到源码,笔主只能通过类比cocos和UE来猜想unity的实现。

trigger的概念

trigger被称之为触发器,但其实这个翻译不太准确,trigger是一种tick方法,它会在每一帧被检测,触发在程序里的概念更合适于消息传递这种场景,比如win32底层的信号量机制。

trigger的表现

在学习了unity官方的几个教程之后,我总结了一下各种类所带有的trigger方法中,基本符合如下的情况:

  • 在满足一定条件时指定函数被调用
  • 在一个周期(此处不是指update)中只会被调用一次,在进入下一次周期时标志被重置

trigger的实现

此处我会贴上我写的一小段代码,来讲述一下我对trigger的理解(由于底层代码都是由c++实现的,此处也是c++代码):

class Trigger
{
public:
    Trigger():
        _name = "",
        _last = false,
        _current = false
    {
    }

    ~Trigger() = default;

    void tick()
    {
        if(!_last)
            return;

        if(_current)
        {
            if(onTrigged != nullptr)
                onTrigged();
        }

        _last = _current;
    }

    void set()
    {
        this->_current = true;
    }

    void reset()
    {
        this->_current = false;
    }

    void onTimeLineEnd()
    {
        reset();
    }

    static Trigger* create();//此处实现很多,省略

private:

    string _name;
    bool _current;
    bool _last;
public:
    function<void()> onTrigged;
}

class  TriggerMgr
{
public:
     TriggerMgr();
    ~ TriggerMgr();

    void SetTrigger(const string& triggerName)
    {
        _triggers[triggerName]->set();
    }

    virtual void add(const string& triggerName,const function<void()>& func)
    {
        auto ret = Trigger::create();
        ret->onTrigged = func;
        _triggers.insert(make_pair<string,Trigger*>(triggerName,ret));
    }
private:
    unordered_map<string,Trigger*> _triggers;
};

我的理解是,unity中凡是有trigger的类,一定是实现了对底层trigger类的继承,然后能调用trigger的类,比如Collider,Animator等,内部都有一个hash表(c#中的Dictionary)来管理这些trigger,我们在添加trigger时,就是在表中加元素,然后通过多个标记来达到每个周期只执行一次的效果。

关于周期

此处的周期指的是完成一个事件的时间,比如在Collider中,这个周期指从“和碰撞体相交”到“不想交”的这段时间,我们可以在离开时这样调用:

virtual void onColliderOut()
{
    ...
    this->TriggerMgr[triggerName]->onTimeLineEnd();
    ...
}

当然,主流的做法是把此处代码放到事件的回调中,在结束时调用。

关于set true

在trigger中,我们被允许使用set方法将trigger显式调用,但是却不允许将trigger取消,set false被禁用了(或许可以实现,但是没看到这样的用法),这样可能是为了有更好的封装性,trigger这样就变成了一个具有自我恢复周期,而非外部控制的bool量。

关于冲突

据我观察,unity中的trigger应该是互相独立的(一个trigger周期内可触发多个其他trigger),所以互相冲突的可能性很小,现在还没遇到过,不过一般可以用优先级和权重的方案解决,遇到了再细细研究。

最后

以上就是真实大船为你收集整理的Unity中的trigger的全部内容,希望文章能够帮你解决Unity中的trigger所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(68)

评论列表共有 0 条评论

立即
投稿
返回
顶部