【Unity2D】コピペOK!ゲームオブジェクトをドラッグ&ドロップして非アクティブ化する方法(マルチタッチ対応)。Raycastを使います。

2024年1月6日

どうも、だらはです。
今回はゲームオブジェクトをドラッグ&ドロップした後に、非アクティブ化する方法を紹介します。
マルチタップ対応、しかもコピペでOKなので是非参考にして頂けたらと思います!
※本記事は2Dオブジェクトの操作を対象としています。

スポンサーリンク

仕様

後述するスクリプトの仕様は以下の通りとなります。

  • ManageEnemy.cs
    • アタッチされるオブジェクトは等速にて移動する。
    • ドラッグ中はタッチ個所に追従する。
    • DelAreaにドロップされると非アクティブ化する。
  • PlayerCtlr.cs:
    • ゲームオブジェクトをドラッグ&ドロップ可能。
    • マウスポインタには非対応(マルチタッチはスマホ実機にて検出可能)

実装手順

実装手順は以下の通りです。

  1. Main CameraProjectionOrhographicに設定する。
  2. [Hierarchy -> Create Empty]から空のゲームオブジェクトを3つ作成する。
  3. 3つのゲームオブジェクト名をそれぞれPlayerEnemyDelAreaと命名する。
  4. 以下の通り機能をアタッチする。
    1. Player:PlayerCtrl.cs(後述)
    2. Enemy:ManageEnemy.cs(後述)、SpriteRenderer(適当な画像を割り当て)、CapsleCollider2D(Is TriggerをON)、Rigidbody2D(Body TypeはKinematic)
    3. DelArea:BoxCollider2D(Is TriggerをON)

以上です。

以下の画像は実行イメージとなります。

◆PlayerCtrl.cs(Playerオブジェクトにアタッチ)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerCtrl : MonoBehaviour
{
    void Update()
    {
        if (Input.touchCount < 1)
        {
            return;
        }

        foreach (var touch in Input.touches)
        {
            Ray ray = Camera.main.ScreenPointToRay(touch.position);
            RaycastHit2D hit = Physics2D.Raycast((Vector2)ray.origin, (Vector2)ray.direction);

            if (hit.collider != null)
            {
                ManageEnemy manageEnemy = hit.collider.gameObject.GetComponent<ManageEnemy>();
                manageEnemy.stateEnemy = 1;

                Vector3 screenPoint = Camera.main.WorldToScreenPoint(transform.position);
                float posX = touch.position.x + Random.Range(-5, 5);
                float posY = touch.position.y + Random.Range(-5, 5);
                float posZ = screenPoint.z;
                Vector3 pos = new Vector3(posX, posY, posZ);
                hit.collider.gameObject.transform.position = Camera.main.ScreenToWorldPoint(pos);
            }

            if (touch.phase == TouchPhase.Ended)
            {
                ManageEnemy manageEnemy = hit.collider.gameObject.GetComponent<ManageEnemy>();
                manageEnemy.stateEnemy = 2;
            }
        }
    }
}

◆ManageEnemy.cs(Enemyオブジェクトにアタッチ)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ManageEnemy : MonoBehaviour
{
    private float dx = 0f;
    private float dy = 0f;
    private float spdY = -1f;
    private bool flgDelObj = false;
    public int moveType = 1;
    public int stateEnemy = 0;
    private bool near = false;

    void Update()
    {
        //行動パタン選択
        switch (moveType)
        {
            case 1:
                Straight();
                break;
            case 2:
                Straight();
                break;
        }

        //移動方法選択
        if (stateEnemy == 0) //通常
        {
            if (flgDelObj == true)
            {
                dx = transform.position.x;
                dy = transform.position.y;
            }
            transform.position = new Vector3(dx, dy, 0);
        }
        else if (stateEnemy == 1) //ドラッグ中
        {

        }
        else if (stateEnemy == 2) //ドラッグ解除
        {
            if ((near == true) && (flgDelObj == false))
            {
                gameObject.SetActive(false);
            }
            stateEnemy = 0;
        }
    }
    
    void Straight()
    {
        //Straightの移動設定
        dx = 0f * Time.deltaTime;
        dy = spdY * Time.deltaTime;

        dx += transform.position.x;
        dy += transform.position.y;
    }
    
    void OnTriggerStay2D(Collider2D collider)
    {
        if (collider.gameObject.name == "DelArea")
        {
            near = true;
        }
    }
    void OnTriggerExit2D(Collider2D collider)
    {
        if (collider.gameObject.name == "DelArea")
        {
            near = false;
        }
    }
}

スポンサーリンク

応用

Posted by daraha_gm