lazhさんの3つの案に加えて、今回のような状況ではRaycast
案のバリエーションとして下記スクリプトのような手が使えるかもしれません。
C#
1using System;
2using System.Linq;
3using UnityEngine;
4
5public class PlayerController : MonoBehaviour
6{
7 // エリアの定義
8 [SerializeField] private AreaDefinition[] areaDefinitions =
9 {
10 new AreaDefinition {name = "Area R", color = new Color32(255, 0, 0, 255)},
11 new AreaDefinition {name = "Area Y", color = new Color32(255, 255, 0, 255)},
12 new AreaDefinition {name = "Area G", color = new Color32(0, 255, 0, 255)},
13 new AreaDefinition {name = "Area C", color = new Color32(0, 255, 255, 255)},
14 new AreaDefinition {name = "Area B", color = new Color32(0, 0, 255, 255)},
15 new AreaDefinition {name = "Area M", color = new Color32(255, 0, 255, 255)}
16 };
17
18 // ここに上記areaDefinitionsの各エリアの色と同じ色を使って描いた
19 // エリアマップテクスチャをセットしておく
20 // なお、GetPixels32を使いたいので「Read/Write Enabled」を
21 // オンにしておく必要がある
22 [SerializeField] private Texture2D areaMapTexture;
23
24 // ここにPlaneオブジェクトをセットしておく
25 // なお、textureCoordを取得したいので「Convex」はオフにしておく
26 [SerializeField] private MeshCollider areaMapCollider;
27
28 // 後述のRaycastのときに、プレイヤーの座標からレイ起点をどれだけずらすかを設定する
29 [SerializeField] private Vector3 raycastOriginOffset = new Vector3(0.0f, 10.0f, 0.0f);
30
31 private int[] areaMap;
32 private Vector2Int areaSize;
33 private int currentAreaIndex;
34
35 private void Start()
36 {
37 // 色からエリア番号を求める対応表を作り...
38 var colorToIndex = this.areaDefinitions.Select((area, i) => (area, i)).ToDictionary(area => area.area.color, area => area.i);
39
40 // エリアマップテクスチャの色をエリア番号に置き換えた配列を作っておく
41 this.areaMap = this.areaMapTexture.GetPixels32().Select(color => colorToIndex[color]).ToArray();
42
43 // エリアマップの大きさを覚えておく
44 this.areaSize = new Vector2Int(this.areaMapTexture.width, this.areaMapTexture.height);
45 }
46
47 private int GetAreaIndex(Vector3 position)
48 {
49 // Planeに対してRaycastを行い...
50 if (this.areaMapCollider.Raycast(
51 new Ray(position + this.raycastOriginOffset, Vector3.down),
52 out var hitInfo,
53 float.PositiveInfinity))
54 {
55 // hitInfo.textureCoordをもとにareaMapからエリア番号を引いてきて返す
56 var pixelCoord = hitInfo.textureCoord * this.areaSize;
57 var x = Mathf.Clamp(Mathf.FloorToInt(pixelCoord.x), 0, this.areaSize.x - 1);
58 var y = Mathf.Clamp(Mathf.FloorToInt(pixelCoord.y), 0, this.areaSize.y - 1);
59 return this.areaMap[(y * this.areaSize.x) + x];
60 }
61
62 // ヒットしなければ-1とする
63 return -1;
64 }
65
66 private void Update()
67 {
68 this.currentAreaIndex = this.GetAreaIndex(this.transform.position);
69 }
70
71 private void OnGUI()
72 {
73 GUI.color = Color.black;
74 GUILayout.Label(this.currentAreaIndex < 0 ? "???" : this.areaDefinitions[this.currentAreaIndex].name);
75 }
76
77 [Serializable]
78 public struct AreaDefinition
79 {
80 public string name;
81 public Color32 color;
82 }
83}
areaMapTexture
として下図テクスチャを使ったところ...
下図のように現在プレイヤーがいるエリアを判定することができました。
念のため申し上げますと、上図ではエリアをわかりやすくするためPlaneに色付けしていますが、Planeのマテリアルは何であってもかまいません。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。