using System; using System.Collections.Generic; using UnityEngine.UI; using UnityEngine; namespace Poco { public class UnityNode : AbstractNode { public static Dictionary TypeNames = new Dictionary() { { "Text", "Text" }, { "Gradient Text", "Gradient.Text" }, { "Image", "Image" }, { "RawImage", "Raw.Image" }, { "Mask", "Mask" }, { "2DRectMask", "2D-Rect.Mask" }, { "Button", "Button" }, { "InputField", "InputField" }, { "Toggle", "Toggle" }, { "Toggle Group", "ToggleGroup" }, { "Slider", "Slider" }, { "ScrollBar", "ScrollBar" }, { "DropDown", "DropDown" }, { "ScrollRect", "ScrollRect" }, { "Selectable", "Selectable" }, { "Camera", "Camera" }, { "RectTransform", "Node" }, }; public static string DefaultTypeName = "GameObject"; private GameObject gameObject; private Renderer renderer; private RectTransform rectTransform; private Rect rect; private Vector2 objectPos; private List components; private Camera camera; public UnityNode(GameObject obj) { gameObject = obj; camera = Camera.main; foreach (var cam in Camera.allCameras) { // skip the main camera // we want to use specified camera first then fallback to main camera if no other cameras // for further advanced cases, we could test whether the game object is visible within the camera if (cam == Camera.main) { continue; } if ((cam.cullingMask & (1 << gameObject.layer)) != 0) { camera = cam; } } renderer = gameObject.GetComponent(); rectTransform = gameObject.GetComponent(); rect = GameObjectRect(renderer, rectTransform); objectPos = renderer ? WorldToGUIPoint(camera, renderer.bounds.center) : Vector2.zero; components = GameObjectAllComponents(); } public override AbstractNode getParent() { GameObject parentObj = gameObject.transform.parent.gameObject; return new UnityNode(parentObj); } public override List getChildren() { List children = new List(); foreach (Transform child in gameObject.transform) { children.Add(new UnityNode(child.gameObject)); } return children; } public override object getAttr(string attrName) { switch (attrName) { case "name": return gameObject.name; case "type": return GuessObjectTypeFromComponentNames(components); case "visible": return GameObjectVisible(renderer, components); case "pos": return GameObjectPosInScreen(objectPos, renderer, rectTransform, rect); case "size": return GameObjectSizeInScreen(rect, rectTransform); case "scale": return new List() { 1.0f, 1.0f }; case "anchorPoint": return GameObjectAnchorInScreen(renderer, rect, objectPos); case "zOrders": return GameObjectzOrders(); case "clickable": return GameObjectClickable(components); case "text": return GameObjectText(); case "components": return components; case "texture": return GetImageSourceTexture(); case "tag": return GameObjectTag(); case "layer": return GameObjectLayerName(); case "_ilayer": return GameObjectLayer(); case "_instanceId": return gameObject.GetInstanceID(); default: return null; } } public override Dictionary enumerateAttrs() { Dictionary payload = GetPayload(); Dictionary ret = new Dictionary(); foreach (KeyValuePair p in payload) { if (p.Value != null) { ret.Add(p.Key, p.Value); } } return ret; } private Dictionary GetPayload() { Dictionary payload = new Dictionary() { { "name", gameObject.name }, { "type", GuessObjectTypeFromComponentNames (components) }, { "visible", GameObjectVisible (renderer, components) }, { "pos", GameObjectPosInScreen (objectPos, renderer, rectTransform, rect) }, { "size", GameObjectSizeInScreen (rect, rectTransform) }, { "scale", new List (){ 1.0f, 1.0f } }, { "anchorPoint", GameObjectAnchorInScreen (renderer, rect, objectPos) }, { "zOrders", GameObjectzOrders () }, { "clickable", GameObjectClickable (components) }, { "text", GameObjectText () }, { "components", components }, { "texture", GetImageSourceTexture () }, { "tag", GameObjectTag () }, { "_ilayer", GameObjectLayer() }, { "layer", GameObjectLayerName() }, { "_instanceId", gameObject.GetInstanceID () }, }; return payload; } private string GuessObjectTypeFromComponentNames(List components) { List cns = new List(components); cns.Reverse(); foreach (string name in cns) { if (TypeNames.ContainsKey(name)) { return TypeNames[name]; } } return DefaultTypeName; } private bool GameObjectVisible(Renderer renderer, List components) { if (gameObject.activeInHierarchy) { bool light = components.Contains("Light"); // bool mesh = components.Contains ("MeshRenderer") && components.Contains ("MeshFilter"); bool particle = components.Contains("ParticleSystem") && components.Contains("ParticleSystemRenderer"); if (light || particle) { return false; } else { return renderer ? renderer.isVisible : true; } } else { return false; } } private int GameObjectLayer() { return gameObject.layer; } private string GameObjectLayerName() { return LayerMask.LayerToName(gameObject.layer); } private bool GameObjectClickable(List components) { Button button = gameObject.GetComponent