mapbox / mapbox-unity-sdk

Mapbox Unity SDK - https://www.mapbox.com/unity/
Other
720 stars 213 forks source link

Trying to access the properties #364

Closed HausOfAlejandro closed 6 years ago

HausOfAlejandro commented 6 years ago

Is it necessary to have a "FeatureBehaviour" component in the gameobject to access the properties? or there is something I still do not understand about the VectorFeatureUnity :-(

Currently working:

using UnityEngine;
using System.Linq;
using Mapbox.Unity.MeshGeneration.Data;
using System;
using Mapbox.Unity.MeshGeneration.Components;

public class Interactable : MonoBehaviour
{
    public VectorFeatureUnity fb;

    public void Start()
    {
        fb = gameObject.GetComponent<FeatureBehaviour> ().Data;
        Debug.Log (fb.Data.GetValue("extrude"));
    }

}
david-rhodes commented 6 years ago

@AlexFactory It depends on what you intend to do with that data. Are you using this at runtime, or to change visuals/behavior at generation time?

The intent of FeatureBehaviour was to make this accessible from game objects (via GetComponent), but there may be more efficient mechanisms, depending on your use case.

HausOfAlejandro commented 6 years ago

Thanks for your quick response, David :-)

The purpose is to use it at runtime, get the data and properties of an object when it is clicked.

It works this way, but I was worried that maybe there is a more efficient way to do it.

For example, executing the previous code from a single instance and that it directly points to the other elements, and avoid to adding this class to more than 600 buildings that are generated in real time in the application.

david-rhodes commented 6 years ago

Well, you could have a single component (manager) that you add each feature to (with a modifier) and then when you raycast with a mouse click do a look up inside that manager (dictionary?). Your key could be the gameobject or collider and the value could be the data dictionary.

Edit: this will remove need of FeatureBehaviour and Interactable.

HausOfAlejandro commented 6 years ago

It's an excellent idea David!

I have created GlobalController that detects through raycast when I click on the generated buildings (VectorLayerVisualizer),

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

public class GlobalController : MonoBehaviour {

    public Transform Transform { get; set; }
    public VectorFeatureUnity Data;

    public void Init(VectorFeatureUnity feature)
    {
        Transform = transform;
        Data = feature;
    }
    void Update () {
        if (Input.GetMouseButtonDown (0))
        {
            Ray ray = cam.ScreenPointToRay (Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast (ray, out hit))
            {
                Debug.Log (string.Join ("\r\n", Data.Properties.Select (x => x.Key + " - " + x.Value.ToString ()).ToArray ()));

            }
        }
    } //-- Update()

}

The problem is that I can not get the properties this way because I get the following error:

NullReferenceException: Object reference not set to an instance of an object

Please excuse me if what I'm trying to do is pointless or I'm omitting something fundamental, recently I'm using the Mapbox SDK for Unity and I've read all the documentation I can most because I think it's great and it's perfect for the project I'm developing .

david-rhodes commented 6 years ago

First, you'll want to have a singleton/static object that has a dictionary of <GameObject, VectorFeatureUnity>. Then, you'll create a GameObjectModifier that adds its relevant data to that singleton instance. Example:

// this is inside the Run method . . .
MyFeatureManager.Instance.AddFeature(ve.GameObject, ve.Feature);

You then do raycasting in the singleton component and just look up your vector feature from the dictionary.

david-rhodes commented 6 years ago

Closing for now. Let us know if you need additional help.