

私は現在、Unityを用いてクロンダイクというソリティアの一種を実装しています。  
今はゲームロジックを後回しにして、テーブル上のカードをドラッグ＆ドロップによって動かす機能を実装しています。テーブル上にはカードを置くことができる領域（山札・場札・組札など）がいくつか存在し、領域内ではカードは領域の種類によって異なる方法で整列されます。領域内のカードはドラッグすることでテーブル上を自由に動かすことができ、ドロップすると、その時点で衝突している領域に置かれます。

この実装では、カード１枚を単一のゲームオブジェクトとして表現し、これにMovingCard.csというスクリプトをアタッチしています。MovingCard.csは以下のようになっています。

[code]

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class MovingCard : MonoBehaviour
    {
        [SerializeField] KlondikeController controller;
    
        Collider2D _collider;
        public Collider2D GetCollider()
        {
            return _collider;
        }
        
        // ICardContainerはカードを置くことができる領域オブジェクトにアタッチされるスクリプト
        // _currContainerは、現在カードが配置されている領域オブジェクトにアタッチされている
        ICardContainer _currContainer;
        bool _isDragged;
    
        public void MoveTo(ICardContainer container)
        {
            if (_currContainer != null)
            {
                _currContainer.Unregister(this);
            }
            _currContainer = container;
            _currContainer.Register(this);
        }
    
        private void OnMouseDrag()
        {
            _isDragged = true;
    
            // カードをつかむ
            Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            Vector3 newPos = new Vector3(pos.x, pos.y, transform.position.z);
            transform.position = newPos;
        }
    
        private void OnMouseUp()
        {
            _isDragged = false;
    
            // カードを離す
            controller.DropCard(this);
        }
    
        private void Start()
        {
            _collider = GetComponent<BoxCollider2D>();
            _isDragged = false;
        }
    
        // デバッグ用
        private void OnGUI()
        {
            GUILayout.Label($"_isDragged: {_isDragged}");
        }
    }
    
[/code]

この実装は概ね期待通りに動くのですが、困った振る舞いをします。  
それは、カードをある領域にドロップしたとき、そのカードが領域に配置されたあと、ドラッグすることができなくなってしまう **ことがある**
という点です。以下、その症状の詳細です。

  * ドラッグできない状態になるのが確認できたタイミングは、カードが領域に配置されたときのみ。
  * カードを領域に配置したとき、常にこの現象が起こるわけではない。最初に領域を移ったときに起こる場合もあれば、何度カードを動かしても起こらない場合もある。
  * OnGUIの出力から、ドラッグできなくなっているオブジェクトはOnMouseDragが呼ばれなくなったことを確認できる。
  * カードを２つシーンに配置した状態で実行すると、片方がドラッグできない状態になっても、もう片方はドラッグできる状態のままである。

現象が起こったり起こらなかったりする事について、私は「特定のフレームでカードをドロップした場合に不具合が起こる」のではないかと怪しんでいます。OnMouseDragを使うにはゲームオブジェクトにColliderとRigidbodyがアタッチされている必要があり、一方でOnMouseXXX系のメソッドはUpdateに同期して呼び出されるので、このタイミングの違いが問題を生んでいるのではないかと思います。しかし、それだけでは「ドラッグできない状態が継続する」という症状が説明できず、困っています。

もし原因がわからなくても、似た事例を教えていただけたりすると助かります。


CC BY-SA 4.0
2022-06-26T06:48:38.217
89601
2022-06-28T09:03:14.233
2022-06-28T09:03:14.233
49045
49045
question
c# unity3d unity2d
Unityでのデバッグ中にゲームオブジェクトがクリックできなくなる事がある