////////////////////////////////////////////////////////////////////////////////////////////////
        /*--------------------------------------------------------------------------------------------*/
        public virtual void Build(ProjectionState pProjectionState,
																IProjectionVisualSettings pSettings)
        {
            vProjectionState = pProjectionState;
            vSettings = (ProjectionVisualSettingsStandard)pSettings;

            ////

            vSpotObj = new GameObject("Spot");
            vSpotObj.transform.SetParent(gameObject.transform, false);
            vSpotObj.transform.localScale = Vector3.zero;

            MeshFilter spotFilt = vSpotObj.AddComponent<MeshFilter>();
            MeshUtil.BuildCircleMesh(spotFilt.mesh, 0.5f, 32);
            vSpotMesh = spotFilt.mesh;

            MeshRenderer spotRend = vSpotObj.AddComponent<MeshRenderer>();
            spotRend.sharedMaterial =
                Materials.GetLayer(Materials.Layer.AboveText, Materials.DepthHintMax);

            ////

            vLineObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
            vLineObj.name = "Line";
            vLineObj.transform.SetParent(gameObject.transform, false);
            vLineObj.transform.localScale = Vector3.zero;
            vLineMesh = vLineObj.GetComponent<MeshFilter>().mesh;

            MeshRenderer lineRend = vLineObj.GetComponent<MeshRenderer>();
            lineRend.sharedMaterial =
                Materials.GetLayer(Materials.Layer.AboveText, Materials.DepthHintMax);
        }
        /*--------------------------------------------------------------------------------------------*/
        public ProjectionState GetProjection(CursorType pCursorType)
        {
            if (!vProjectionMap.ContainsKey(pCursorType))
            {
                ICursorState state = Hovercursor.GetCursorState(pCursorType);

                var proj = new ProjectionState(state, vInteractSett, vBaseTx);
                vProjectionMap.Add(pCursorType, proj);
            }

            return(vProjectionMap[pCursorType]);
        }
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		internal void Build(ProjectionState pProjectionState, IProjectionVisualSettings pSettings) {
			vProjectionState = pProjectionState;
			vSettings = pSettings;

			////

			vRendererHold = new GameObject("ProjectionRendererHold");
			vRendererHold.transform.SetParent(gameObject.transform, false);

			vRendererObj = new GameObject("ProjectionRenderer");
			vRendererObj.transform.SetParent(vRendererHold.transform, false);

			vRenderer = (IUiProjectionRenderer)vRendererObj.AddComponent(vSettings.Renderer);
			vRenderer.Build(vProjectionState, vSettings);
		}
        ////////////////////////////////////////////////////////////////////////////////////////////////
        /*--------------------------------------------------------------------------------------------*/
        private void UpdateProjection(ProjectionState pProj)
        {
            ICursorState cursor         = pProj.Cursor;
            CursorType   cursorType     = cursor.Type;
            bool         allowSelect    = (cursor.IsInputAvailable && pProj.IsActive);
            Vector3?     cursorWorldPos = (allowSelect ? cursor.GetWorldPosition() : (Vector3?)null);
            ItemTree     nearestTree    = new ItemTree();
            float        nearestDist    = float.MaxValue;

            foreach (ItemTree itemTree in vAllItems)
            {
                itemTree.Item.UpdateWithCursor(cursorType, cursorWorldPos);

                if (!allowSelect)
                {
                    continue;
                }

                float itemDist = itemTree.Item.GetHighlightDistance(cursorType);

                if (itemDist >= nearestDist)
                {
                    continue;
                }

                nearestTree = itemTree;
                nearestDist = itemDist;
            }

            foreach (ItemTree itemTree in vAllItems)
            {
                BaseItemState item = itemTree.Item;
                item.SetAsNearestItem(cursorType, (item == nearestTree.Item));
            }

            if (nearestTree.Panel == null || nearestTree.Item.MaxHighlightProgress <= 0)
            {
                pProj.SetNearestPanelTransform(null);
                pProj.NearestItemHighlightProgress = 0;
                return;
            }

            GameObject panelObj = (GameObject)nearestTree.Panel.ItemPanel.DisplayContainer;

            pProj.SetNearestPanelTransform(panelObj.transform);
            pProj.NearestItemHighlightProgress = nearestTree.Item.GetHighlightProgress(cursorType);
        }
		/*--------------------------------------------------------------------------------------------*/
		private void UpdateProjection(ProjectionState pProj) {
			ICursorState cursor = pProj.Cursor;
			CursorType cursorType = cursor.Type;
			bool allowSelect = (cursor.IsInputAvailable && pProj.IsActive);
			Vector3? cursorWorldPos = (allowSelect ? cursor.GetWorldPosition() : (Vector3?)null);
			ItemTree nearestTree = new ItemTree();
			float nearestDist = float.MaxValue;

			foreach ( ItemTree itemTree in vActiveItems ) {
				itemTree.Item.UpdateWithCursor(cursorType, cursorWorldPos);

				if ( !allowSelect ) {
					continue;
				}

				float itemDist = itemTree.Item.GetHighlightDistance(cursorType);

				if ( itemDist >= nearestDist ) {
					continue;
				}

				nearestTree = itemTree;
				nearestDist = itemDist;
			}

			foreach ( ItemTree itemTree in vAllItems ) {
				BaseItemState item = itemTree.Item;
				item.SetAsNearestItem(cursorType, (item == nearestTree.Item));
			}

			if ( nearestTree.Panel == null || nearestTree.Item.MaxHighlightProgress <= 0 ) {
				pProj.SetNearestPanelTransform(null);
				pProj.NearestItemHighlightProgress = 0;
				return;
			}

			GameObject panelObj = (GameObject)nearestTree.Panel.ItemPanel.DisplayContainer;
			pProj.SetNearestPanelTransform(panelObj.transform);
			pProj.NearestItemHighlightProgress = nearestTree.Item.GetHighlightProgress(cursorType);
		}
		/*--------------------------------------------------------------------------------------------*/
		public ProjectionState GetProjection(CursorType pCursorType) {
			if ( !vProjectionMap.ContainsKey(pCursorType) ) {
				ICursorState state = Hovercursor.GetCursorState(pCursorType);

				var proj = new ProjectionState(state, vInteractSett, vBaseTx);
				vProjectionMap.Add(pCursorType, proj);
			}

			return vProjectionMap[pCursorType];
		}