質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.49%

Unityのスマホタッチ操作に関して(1本目に置いた指を2本目に引っ張られたくない)

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 620

score 8

前提・実現したいこと

https://teratail.com/questions/167825
こちらと全く同じ問題が出ています。

発生している問題・エラーメッセージ

回答のようにScriptを変更してもエラーが起きてしまい自力で解決することができません。どなたかよろしくお願いします。

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// ジョイスティック
/// </summary>
public class Joystick : MonoBehaviour
{

    //実際に動くスティック部分
    [SerializeField]
    [Header("実際に動くスティック部分(自動設定)")]
    private GameObject _stick = null;
    private const string STICK_NAME = "Stick";

    //スティックが動く範囲の半径
    [SerializeField]
    [Header("スティックが動く範囲の半径")]
    private float _radius = 100;

    //指を離した時にスティックが中心に戻るか
    [SerializeField]
    [Header("指を離した時にスティックが中心に戻るか")]
    private bool _shouldResetPosition = true;

    //現在地(x,y共に値が-1~1の範囲になる)
    [SerializeField]
    [Header("現在地(自動更新)")]
    private Vector2 _position = Vector2.zero;
    public Vector2 Position { get { return _position; } }

    //スティックの位置(Setter)
    private Vector3 _stickPosition
    {
        set
        {
            _stick.transform.localPosition = value;
            _position = new Vector2(
              _stick.transform.localPosition.x / _radius,
              _stick.transform.localPosition.y / _radius
            );
        }
    }

    //=================================================================================
    //初期化
    //=================================================================================

    protected void Awake()
    {
        Awake();
        Init();
    }

    //初期化
    private void Init()
    {
        //スティックを生成する必要があれば生成し、位置を中心に設定
        CreateStickIfneeded();
        _stickPosition = Vector3.zero;

        //スティックのImage取得(なければ追加)、タッチ判定を取られないようにraycastTargetをfalseに
        Image stickImage = _stick.GetComponent<Image>();
        if (stickImage == null)
        {
            stickImage = _stick.AddComponent<Image>();
        }
        stickImage.raycastTarget = false;
    }

    //スティックを生成する必要があれば生成
    private void CreateStickIfneeded()
    {
        //スティックが設定されていれば終了
        if (_stick != null)
        {
            return;
        }

        //スティックが子にあるか検索、あれば取得し終了
        if (transform.Find(STICK_NAME) != null)
        {
            _stick = transform.Find(STICK_NAME).gameObject;
            return;
        }

        //スティック生成
        _stick = new GameObject(STICK_NAME);
        _stick.transform.SetParent(gameObject.transform);
        _stick.transform.localRotation = Quaternion.identity;
    }

    float _radius2 = 150;//ジョイスティックの最大半径
    public bool OnDrag(Vector2 touch)
    {
        //タップ位置を画面内の座標に変換し、スティックを移動
        Vector2 screenPos = Vector2.zero;
        //Debug.Log(Input.mousePosition);
        RectTransformUtility.ScreenPointToLocalPointInRectangle(GetComponent<RectTransform>(),
        new Vector2(Input.mousePosition.x, Input.mousePosition.y),
        null,
        out screenPos
        );

        _stickPosition = screenPos;

        //移動場所が設定した半径を超えてる場合は制限内に抑える
        float currentRadius = Vector3.Distance(Vector3.zero, _stick.transform.localPosition);

        if (currentRadius > _radius)
        {
            return false;
        }

        if (currentRadius > _radius)
        {
            //角度計算
            float radian = Mathf.Atan2(_stick.transform.localPosition.y, _stick.transform.localPosition.x);

            //円上にXとYを設定
            Vector3 limitedPosition = Vector3.zero;
            limitedPosition.x = _radius * Mathf.Cos(radian);
            limitedPosition.y = _radius * Mathf.Sin(radian);

            _stickPosition = limitedPosition;
        }
    }

    private T GetComponent<T>()
    {
        throw new NotImplementedException();
    }
    bool isInsideBoundary;

    public void Update(PointerEventData eventData)
    {
        Touch[] touches = Input.touches;
        for (int i = 0; i < Input.touchCount; i++)
        {
            Touch touch = touches[i];
            if (touch.phase == TouchPhase.Began || touch.ohase == TouchPhase.Moved)
            {
                isInsideBoundary = OnDrag(touch.position);
                if (isInsideBoundary) break;
            }
        }
        if (!isInsideBoundary)
        {
            if (_shouldResetPosition)
            {
                //スティックを中心に戻す
                _stickPosition = Vector3.zero;
            }
        }
    }

    //=================================================================================
    //更新
    //=================================================================================

#if UNITY_EDITOR
    //Gizmoを表示する
    private void OnDrawGizmos()
    {
        //スティックが移動できる範囲をScene上に表示
        UnityEditor.Handles.color = Color.green;
        UnityEditor.Handles.DrawWireDisc(transform.position, transform.forward, _radius * 0.5f);
    }
#endif

}

エラー

'Joystick.OnDrag(Vector2)': 値を返さないコード パスがあります。(97行目)

型または名前空間の名前 'NotImplementedException' が見つかりませんでした (using ディレクティブまたはアセンブリ参照が指定されていることを確認してください)。(134行目)
140行目、141行目、144行目、146行目ー>定義がありません系のエラー

試したこと

回答のようにソースコードを変更した。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • sakura_hana

    2019/10/13 13:12

    エラーの内容を質問に追記してください。

    キャンセル

  • Ruchi1237

    2019/10/13 13:51

    追記しました

    キャンセル

  • sakura_hana

    2019/10/16 10:59 編集

    OnDragメソッドは必ずboolを返す必要があります。
    現在は「currentRadius > _radius」を満たす場合だけしかboolを返していないのでエラーになります。

    if (currentRadius > _radius) の中やメソッドの最後などに
    return trueかfalse;
    すればいいのですが、ちゃんとコード読んでないしif文がおかしい気がする
    (if (currentRadius > _radius)が2つある。原文では片方「_radius2」にしているが理由がよく分からない)
    ので意味の把握と確認を行ってください。

    キャンセル

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る