2016-10-26 20 views
0

私は、クリックしたときに選択できる多数のエージェントを持つ2D Unityゲームを持っています。これが起こると、彼らはプレーヤーになります(プレーヤーのエージェント変数はそれらに置き換えられ、エージェントはプレーヤーの親になります)。私はあなたの目的地を別のエージェントにドラッグして "ターゲット"するシステムを実装しようとしています。Input.GetMouseButtonUpがUnityで期待どおりに動作しない

これを行うには、ターゲットのMyクラス(すべてのプレーヤーのコンポーネントと変数への参照を保持するクラス)から実際にターゲティングしているので、エージェントの現在のエージェントによって操作される関数にエージェントを配置します。これは理論的にはうまくいくようですが、Unityでは、階層内の最初のエージェントを対象にすることしかできません。しかし、すべてのエージェントは、ゲームの開始時に生成されたエージェントプレハブの同一のインスタンスです。

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

public class Agent : Grammar { 
    public Physical physical; 
    public Agent agent; 

    void Update() { 

     float distanceFromMouse = the.Distance(this.transform.position, Camera.main.ScreenToWorldPoint(Input.mousePosition)); 

     if (Input.GetMouseButtonDown(0)) { 

      if (distanceFromMouse < 1f) { 
       the.player.agent = this; 
       the.player.transform.parent = this.transform; 
      } 
     } 

     if (Input.GetMouseButtonUp (0)) { 

      if (distanceFromMouse < 1f) { 
       if (the.player.agent != this && the.player.agent is Agent) { 
        the.player.agent.Target (agent); 
       } 
      } 

      the.player.agent = null; 
     } 

     if (the.player.agent == agent) 
      physical.goal = Camera.main.ScreenToWorldPoint (Input.mousePosition); 
     else if (physical.hasTarget) 
      physical.goal = physical.target.transform.position; 
    } 
} 

public void Target (My target) { 

    my.physical.target = target; 
    my.physical.hasTarget = true; 

    foreach (My other in the.agents.GetComponentsInChildren<My>()) { 

     if (other.physical.targetters.Contains (my)) 
      other.physical.targetters.Remove (my); 
    } 

    target.physical.targetters.Add (my); 
    target.physical.targetted = true; 
} 

ここではすべてが継承する私のGrammarクラスがあり、グローバルクラスにアクセスできます。ここで

using UnityEngine; 
using System.Collections; 

public class Grammar : MonoBehaviour { 

    public A a; 
    public The the; 
} 

はあなたのエージェントクラスにクリックを検出する方法が少しオフになっている私の(グローバルユーティリティ)クラス

using UnityEngine; 
using System.Collections; 

public class The : MonoBehaviour { 

    public Grid grid; 
    public GameObject world; 

    public Player player; 

    public GameObject squareParent; 
    public GameObject linkParent; 
    public GameObject nodeParent; 
    public GameObject agents; 

    public Vector2 HeadingFrom(float angle) { return new Vector2(Mathf.Cos(angle * Mathf.Deg2Rad), Mathf.Sin(angle * Mathf.Deg2Rad)); } 
    public float AngleFrom(Vector2 heading) { return Mathf.Atan2 (heading.y, heading.x) * Mathf.Rad2Deg; } 
    public Vector2 RelativeHeadingFrom(Vector2 heading, float rotation) { return (Vector2)(HeadingFrom(AngleFrom(heading) - rotation)); } 
    public float Distance(Vector2 from, Vector2 to) { return (Heading(from,to)).magnitude; } 
    public Vector2 Heading (Vector2 from, Vector2 to) { return to - from; } 
    public Vector2 MidPoint (GameObject my, GameObject their) { return (my.transform.position + their.transform.position)/2; } 
} 

答えて

0

です。 Input.mousePositionプロパティはVector3を返しますが、Zコンポーネントは常にゼロです。 Camera.ScreenToWorldPointdocumentationは、提供されたベクトルのZ成分がカメラからのワールド単位の距離であることに注意してください。これは、エージェントクラスの「クリック」のワールド位置が常にカメラのすぐ隣にあることを意味します。

通常は、OnMouseDown()メソッドとOnMouseUp()(エージェントクラス)を定義するか、Camera.ScreenPointToRayを使用してレイを作成し、それをシーンにレイキャストした後、レイヒットを使用します-resultは、マウスポインタの「実際の世界」の位置として返されます。これについての詳細は、answerUnity Answersでご覧ください。

エージェントがクリックされたかどうかを検出する新しいイベントシステム(新しいUnity GUIシステムの一部)を使用することをお勧めします。エージェントがクリックされたかどうかを検出するには、モバイルでゲームをしたい場合デバイス。あなたがそれを行うために実行する必要がありますどのような

は次のとおりです。

  • あなたのエージェントクラスにインターフェースIPointerUpHandlerIPointerDownHandlerを実装し、インタフェースを定義する必要が方法でクリックを扱います。
  • エージェントにコライダー(またはトリガー)があることを確認してください。
  • カメラオブジェクトにPhysicsRaycasterコンポーネントを追加してください。

また、これらのインターフェイスに興味があるかもしれません:

+0

感謝。私はレイキャスティングを試みましたが、私のプロジェクトは2Dなので、エラーが発生してしまいました.LayCast2Dを使ってそれをどうやってやっているのかは分かりません。 私はOnMouseUpとOnMouseDown関数も試しましたが、OnMouseUpはOnMouseDownのオブジェクトのみを参照するようです。明らかに、私はターゲティングエージェントをターゲットにしたくないので、うまくいきません。マウスボタンが押されたオブジェクトを気にしないOnMouseUp関数を持つ方法はありませんか? –

+0

私はOnMouseUp内でforeachループを使用して問題を解決しましたが、あまりエレガントではありません。追加ループなしでそれを行う別の方法がある場合は、まだ興味があります。 –

+0

私は上記のインターフェイス、特にドラッグインターフェイスを使用してみることをお勧めします。なぜなら、これらのインターフェイスは、「ドラッグ」を停止したときに「マウスアップ」イベントを記述し、受け取るためです。 –

関連する問題