🦋

Flutterでの検索結果をUnityで表示する

2023/12/12に公開

目指していること

分野を問わない「いつ、どこで、なにがあった」Databaseを構築中。
userが協働してDataを蓄積する。
DataのInputはFlutter製のアプリケーションで行う。
backendはServerpodを介して、DatabaseはPostgreSQL。
Flutterのアプリケーション上で検索もできるし、検索結果も表示するが、
同時にUnityで構築した三次元空間内で
Databaseの全体像と、さらに検索結果も表示する。
FlutterとUnityは、Serverpodに附属するWebServerを介して接続する。

本日のMenu

これまでUnityでは、Databaseの全体像の表示、までできていた。
これに、検索結果の追記をする。
方法としては、Data全件のうち、選択されたものを光らせる、
または、選択されなかったものの明度を落とす、
というのが希望だけれど、
処理が複雑になる(私にとって)ので、もう少し簡易にした。
つまり、選択されたものについて、markerをプラスする。
まあ、フラグを立てる、みたいな感じ。
Dataは三次元空間座標を持っているので、
全件表示の同じ座標にmarkerをくっつけると、「これが選択されてますよ」になる。
markerは単純で小さいけど、輝度が高い。
さらに、markerをlineで繋いで、「順路」が示されるようにしてみた。
広大な資料庫で迷子にならないように。

markerのprefabを作る

DataのPointerはProBuilderで方向指示性(過去・未来・北)のある形状を工夫したが、
今回は単純に球を採用。直径がPointerよりちょっと小さいぐらい。
はっきりと白く光る。
Pointerのcollisionをじゃましないように、markerはcollisionなし。
これをprefabにして、検索結果を読み込んで表示はPointerのときと同じ。
Pointerに付いていたデータ表示機能もつけない。
単純に、「ここ!」と光るだけ。
MainCameraにPostProcessLayer,
空のobjectにPostProcessVolumeをつけ、
PointerのMaterialでEmissionをonにすることで光る、
というのだが、イマイチ違いがわからない。
でもともかく目立つことは目立つ。
で、このmarkerをAsset領域に引っぱってprefabにする。

分身の術のScriptを書く

検索結果は今回もCSVにしてresourceに入れてある。
ので、まだ、リアルタイム表示、というわけにはいかない。

  • Dataを読む。
  • objectを生成。
  • objectをList化。
  • List順にlineでつないでいく。
using UnityEngine;
using System.Collections.Generic; //Required for making List.

public class GlobeSelectedManager : MonoBehaviour
{
    
    // Specifies Prefab.
    public GameObject selectedPrefab; 
    public Material lineMaterial;

    private List<GameObject> spawnedObjects = new List<GameObject>();
   
    // CSV file's name.
    public string fileName = "SelectedGlobe"; 


    void Start ()
    {
        // Reads CSV file and split by row.
        TextAsset csvData = Resources.Load<TextAsset>(fileName);
        string[] lines = csvData.text.Split('\n');
        for (int i = 1; i < lines.Length; i++)
        {
            string[] parts = lines[i].Split(',');
            if(parts.Length < 5) continue;

            float coord_x = float.Parse(parts[0])/25;
            float coord_y = float.Parse(parts[1])/25;
            float coord_z = float.Parse(parts[2])/25;
            //float coefficient = parts[3];

            //Creates object and sets position.
            GameObject selectedMarker = Instantiate(selectedPrefab, new Vector3(coord_x, coord_y, coord_z), Quaternion.identity);
            spawnedObjects.Add(selectedMarker);
        }

        DrawLinesBetweenObjects();
    }

    void DrawLinesBetweenObjects()
    {
        for (int i = 0; i < spawnedObjects.Count - 1; i++)
        {
            GameObject startObject = spawnedObjects[i];
            GameObject endObject = spawnedObjects[i + 1];

            LineRenderer lineRenderer = new GameObject("Line").AddComponent<LineRenderer>();
            lineRenderer.material = lineMaterial;
            lineRenderer.positionCount = 2;
            lineRenderer.SetPosition(0, startObject.transform.position);
            lineRenderer.SetPosition(1, endObject.transform.position);
            lineRenderer.startWidth = 0.1f;
            lineRenderer.endWidth = 0.1f;

        }
    }
}

このScriptを空のobjectにattachしてManagerにし、prefab元としてmarkerを指定する。
黄色が全件表示のPointer、
白がmarker、Pointerが中からちょっとだけ見えている。

そして最終問題はDataの受け渡し

Flutter大学

Discussion