Unity で非同期の whenAny を使用して達成する: シャベルの任意の部分をクリックすると、シャベル全体を拾う

1.シャベルの構成

シャベルは多くのパーツで構成されており、シャベルを持ち上げるときは、シャベルの任意の部分をクリックするだけです。
図のように、[木製ハンドル]、[ナット]、[シャベル]をクリックしてオブジェクトを持ち上げます。
写真の説明を追加してください
(1) ハイライトをオンにする
(2) ソイルシャベルがクリックされるのを待つ: どの部分でもクリック可能
(3) ハイライトをオフにしてソイルシャベルを取り除く

第二に、実現のアイデア

非同期に実装: ウィジェットがクリックされるのを待つ

  • 1. whenAny のキーコード: 任意のサブコンポーネントがクリックされるのを待つ
    select でタスクリストをラップする方法に注意してください
var allTasks = mamoty.GetComponentsInChildren<Transform>().Select(t => t.gameObject.OnClickAsync());
await UniTask.WhenAny(allTasks);
  • 2. クリックされるオブジェクトの非同期実装
    (1) Collider コリジョン ボディで使用する
    (2) コンポーネントとデリゲートのクリーニングに注意する
    /// <summary>
    /// 3D物体的异步点击方法
    /// </summary>
    /// <param name="gameObject"></param>
    /// <returns></returns>
    public static async UniTask OnClickAsync(this GameObject gameObject, EventTriggerType eventType = EventTriggerType.PointerClick)
    {
    
    
        //碰撞体判断
        if (!gameObject.GetComponent<Collider>()) Debug.LogWarning($"{
      
      gameObject}建议加上相应形状的collider组件");

        //添加组件
        var hasEventTrigger = gameObject.GetComponent<EventTrigger>() != null;
        if (!hasEventTrigger) gameObject.AddComponent<EventTrigger>();
        bool triggered = false;
        
        //委托及实例方法
        Action myAction = null;
        Action fn = () =>
        {
    
    
            triggered = true;
        };

        //委托绑定
        myAction += fn;

        //事件触发
        gameObject.GetComponent<EventTrigger>().AddListener(eventType, (PointerEventData eventData) =>
        {
    
    
            if (myAction != null)
            {
    
    
                myAction.Invoke();
            }
        });

        //等待事件触发
        await UniTask.WaitUntil(() => triggered == true);
        Debug.Log("");

        //取消绑定
        myAction -= fn;

        //资源清理:如果代码是并发执行,可能会把别人动态添加的eventTrigger销毁掉,所以建议不销毁
        //if (!hasEventTrigger) GameObject.DestroyImmediate(gameObject.GetComponent<EventTrigger>());
        
        return;
    }

3. 土ショベルピッキングの主な工程

 //取土铲
 FlowGetMamoty = async () =>
  {
    
    
      //打开高亮
      if (mamoty.GetComponent<Highlighter>() == null) mamoty.AddComponent<Highlighter>();
      mamoty.GetComponent<Highlighter>().tween = true;

      //等待土铲被点击:任一部件被点击
      var allTasks = mamoty.GetComponentsInChildren<Transform>().Select(t => t.gameObject.OnClickAsync());
      await UniTask.WhenAny(allTasks);
      
      //关闭高亮,取走土铲 
      mamoty.GetComponent<Highlighter>().tween = false;
      await mamoty.DoMove(openedPos, closedPos, closeDuration);
  };

おすすめ

転載: blog.csdn.net/dzj2021/article/details/130504320