マウス座標を3Dのワールド座標に変換してキャラクターを動かす

投稿者: | 2019-12-11

マウスでクリックした場所にナビメッシュエージェントを移動させてみます。

空のゲームオブジェクトに新しいスクリプトを付けます。
Textオブジェクトも作ります。

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5.  
  6. public class gameScript : MonoBehaviour
  7. {
  8.  
  9. public Text text;
  10. Vector3 cursorPosition;
  11.  
  12. // Start is called before the first frame update
  13. void Start()
  14. {
  15. text.text = "";
  16. }
  17.  
  18. // Update is called once per frame
  19. void Update()
  20. {
  21. cursorPosition = Input.mousePosition; // 画面上のカーソルの位置
  22. text.text = cursorPosition.ToString();
  23. }
  24. }


マウスカーソルの画面上の座標が表示されます。左下が(0,0)です。平面なのでZ座標は常に0です。

メインカメラのScreenToWorldPoint()メソッドを使うと、これをワールド座標に変換できます。
デフォルトのメインカメラには始めから「MainCamera」タグが付いていて、このタグが付いているカメラは、Camera.main で取得できます。

参考:https://docs.unity3d.com/ja/current/ScriptReference/Camera-main.html

Z座標が0のままだとうまく行かないので、その前にZ座標に適当な値を入れます。

  1. cursorPosition = Input.mousePosition; // 画面上のカーソルの位置
  2. cursorPosition.z = 10.0f; // z座標に適当な値を入れる
  3. cursorPosition3d = Camera.main.ScreenToWorldPoint(cursorPosition); // 3Dの座標になおす
  4.  
  5. Debug.DrawRay(Camera.main.transform.position, (cursorPosition3d - Camera.main.transform.position) * 100f, Color.red); // デバッグのレイを飛ばす

カメラからマウスカーソルが指す方向へレイを飛ばし、そのレイが他のオブジェクトとぶつかったポイントの座標を取得してみます。
デバッグ用のでなくゲームで使う普通のレイを飛ばします。

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5.  
  6. public class gameScript : MonoBehaviour
  7. {
  8.  
  9. public Text text;
  10. Vector3 cursorPosition;
  11. Vector3 cursorPosition3d;
  12. RaycastHit hit;
  13.  
  14. // Start is called before the first frame update
  15. void Start()
  16. {
  17. text.text = "";
  18. }
  19.  
  20. // Update is called once per frame
  21. void Update()
  22. {
  23. cursorPosition = Input.mousePosition; // 画面上のカーソルの位置
  24. cursorPosition.z = 10.0f; // z座標に適当な値を入れる
  25. cursorPosition3d = Camera.main.ScreenToWorldPoint(cursorPosition); // 3Dの座標になおす
  26.  
  27. // カメラから cursorPosition3d の方向へレイを飛ばす
  28. if (Physics.Raycast(Camera.main.transform.position, (cursorPosition3d - Camera.main.transform.position), out hit, Mathf.Infinity))
  29. {
  30. Debug.DrawRay(Camera.main.transform.position, (cursorPosition3d - Camera.main.transform.position) * hit.distance, Color.red);
  31.  
  32. text.text = hit.point.ToString();
  33. }
  34. }
  35. }

参考:https://docs.unity3d.com/jp/current/ScriptReference/RaycastHit.html


Planeの座標が(0, 0, 0)なので、カーソルがPlaneを指しているときのY座標は常に0です。グレーのCubeは高さが1なので、その上ではY座標は1になって、その側面はその中間の値になっています。
オブジェクトの表面の、マウスカーソルで指し示したポイントの座標が取れていることがわかります。

キャラクターを動かす

スタンダードアセットにあるAI TPSキャラクターをシーンにドラッグアンドドロップします。

床やCubeをまとめて選択します。

NavigationウィンドウでNavigation Staticにチェックを入れます。

Bake -> Bakeボタンを押します。

これでAI TPSキャラクターを動かせるようになりました。

AI TPSキャラクターには Nav Mesh Agentコンポーネントが予め付いているので、目的地を指定するとその場所へ移動してくれます。

目的地を教えるには、スクリプトでdestinationプロパティに目的地の座標を入れるだけです。

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. using UnityEngine.AI;
  6.  
  7. public class gameScript : MonoBehaviour
  8. {
  9.  
  10. public Text text;
  11. Vector3 cursorPosition;
  12. Vector3 cursorPosition3d;
  13. RaycastHit hit;
  14.  
  15. public GameObject aiCharacter;
  16. NavMeshAgent agent;
  17.  
  18. // Start is called before the first frame update
  19. void Start()
  20. {
  21. text.text = "";
  22. agent = aiCharacter.GetComponent<NavMeshAgent>();
  23. }
  24.  
  25. // Update is called once per frame
  26. void Update()
  27. {
  28. cursorPosition = Input.mousePosition; // 画面上のカーソルの位置
  29. cursorPosition.z = 10.0f; // z座標に適当な値を入れる
  30. cursorPosition3d = Camera.main.ScreenToWorldPoint(cursorPosition); // 3Dの座標になおす
  31.  
  32. if (Input.GetMouseButtonDown(0)) // マウスの左クリックをしたとき
  33. {
  34. // カメラから cursorPosition3d の方向へレイを飛ばす
  35. if (Physics.Raycast(Camera.main.transform.position, (cursorPosition3d - Camera.main.transform.position), out hit, Mathf.Infinity))
  36. {
  37. Debug.DrawRay(Camera.main.transform.position, (cursorPosition3d - Camera.main.transform.position) * hit.distance, Color.red);
  38.  
  39. //text.text = hit.point.ToString();
  40.  
  41. agent.destination = hit.point; // エージェントに目的地を教える
  42. }
  43. }
  44. }
  45. }

マウスでクリックしたポイントにキャラクターが移動します。

コメントを残す

メールアドレスが公開されることはありません。