////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public virtual void Build(MenuState pMenuState, IItemVisualSettings pSettings, 
																		float pAngle0, float pAngle1) {
			vMenuState = pMenuState;
			vSettings = (ItemVisualSettingsStandard)pSettings;
			vAngle0 = pAngle0;
			vAngle1 = pAngle1;
			vMeshSteps = (int)Math.Round(Math.Max(2, (vAngle1-vAngle0)/Math.PI*60));

			////

			vBackground = new GameObject("Background");
			vBackground.transform.SetParent(gameObject.transform, false);
			vBackground.AddComponent<MeshRenderer>();
			
			MeshFilter bgFilt = vBackground.AddComponent<MeshFilter>();
			vBackgroundMeshBuilder = new MeshBuilder();
			BuildMesh(vBackgroundMeshBuilder);
			vBackgroundMeshBuilder.Commit();
			vBackgroundMeshBuilder.CommitColors(Color.clear);
			bgFilt.sharedMesh = vBackgroundMeshBuilder.Mesh;

			////

			var labelObj = new GameObject("Label");
			labelObj.transform.SetParent(gameObject.transform, false);
			labelObj.transform.localPosition = new Vector3(0, 0, InnerRadius);
			labelObj.transform.localRotation = Quaternion.FromToRotation(Vector3.back, Vector3.right);
			labelObj.transform.localScale = new Vector3((vMenuState.IsOnLeftSide ? 1 : -1), 1, 1);

			vLabel = labelObj.AddComponent<UiLabel>();
			vLabel.AlignLeft = vMenuState.IsOnLeftSide;
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		internal void Build(MenuState pMenu, IItemVisualSettingsProvider pVisualSettingsProv) {
			vMenuState = pMenu;
			vVisualSettingsProv = pVisualSettingsProv;

			vMenuState.OnLevelChange += HandleLevelChange;
			UpdateAfterSideChange();
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		internal void Build(MenuState pMenuState, IItemVisualSettingsProvider pVisualSettingsProv) {
			vMenuState = pMenuState;
			vItemObjList = new List<GameObject>();

			ReadOnlyCollection<BaseItemState> itemStates = vMenuState.GetItems();
			int itemCount = itemStates.Count;
			float degree = 170 + DegreeFull/2f;
			float sizeSum = 0;

			for ( int i = 0 ; i < itemCount ; i++ ) {
				sizeSum += itemStates[i].Item.Height;
			}

			for ( int i = 0 ; i < itemCount ; i++ ) {
				BaseItemState itemState = itemStates[i];
				float itemPerc = itemState.Item.Height/sizeSum;
				float itemAngle = AngleFull*itemPerc;
				float itemDegHalf = itemAngle*ToDegrees/2f;
				IItemVisualSettings visualSett = pVisualSettingsProv.GetSettings(itemState.Item);

				var itemObj = new GameObject("Item"+vItemObjList.Count);
				itemObj.transform.SetParent(gameObject.transform, false);
				vItemObjList.Add(itemObj);

				UiItem uiItem = itemObj.AddComponent<UiItem>();
				uiItem.Build(vMenuState, itemState, itemAngle, visualSett);

				degree -= itemDegHalf;
				itemObj.transform.localRotation = Quaternion.AngleAxis(degree, Vector3.up);
				degree -= itemDegHalf;
			}
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public HovercastState(IItemHierarchy pItemHierarchy, HovercursorSetup pHovercusorSetup, 
				InteractionSettings pInterSett, IInput pInput, Transform pBaseTx) {
			vInteractSettings = pInterSett;
			vHovercursorSetup = pHovercusorSetup;
			vInput = pInput;
			BaseTransform = pBaseTx;

			FullMenu = new MenuState(pItemHierarchy, vInteractSettings);

			vActiveCursorInteractions = new ReadList<IBaseItemInteractionState>();
			vMenuPlanes = new ReadList<PlaneData>();
			vActiveCursorTypes = new ReadList<CursorType>();

			ActiveCursorTypes = vActiveCursorTypes.ReadOnly;

			vLeftCursorConvertMap = 
				new Dictionary<HovercastCursorType, CursorType>(HovercastCursorTypeComparer);
			vLeftCursorConvertMap.Add(HovercastCursorType.Palm, CursorType.LeftPalm);
			vLeftCursorConvertMap.Add(HovercastCursorType.Thumb, CursorType.LeftThumb);
			vLeftCursorConvertMap.Add(HovercastCursorType.Index, CursorType.LeftIndex);
			vLeftCursorConvertMap.Add(HovercastCursorType.Middle, CursorType.LeftMiddle);
			vLeftCursorConvertMap.Add(HovercastCursorType.Ring, CursorType.LeftRing);
			vLeftCursorConvertMap.Add(HovercastCursorType.Pinky, CursorType.LeftPinky);
			vLeftCursorConvertMap.Add(HovercastCursorType.Look, CursorType.Look);

			vRightCursorConvertMap =
				new Dictionary<HovercastCursorType, CursorType>(HovercastCursorTypeComparer);
			vRightCursorConvertMap.Add(HovercastCursorType.Palm, CursorType.RightPalm);
			vRightCursorConvertMap.Add(HovercastCursorType.Thumb, CursorType.RightThumb);
			vRightCursorConvertMap.Add(HovercastCursorType.Index, CursorType.RightIndex);
			vRightCursorConvertMap.Add(HovercastCursorType.Middle, CursorType.RightMiddle);
			vRightCursorConvertMap.Add(HovercastCursorType.Ring, CursorType.RightRing);
			vRightCursorConvertMap.Add(HovercastCursorType.Pinky, CursorType.RightPinky);
			vRightCursorConvertMap.Add(HovercastCursorType.Look, CursorType.Look);

			OnSideChange += (() => {});
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		internal void Build(MenuState pMenu, IItemVisualSettingsProvider pVisualSettingsProv) {
			vMenuState = pMenu;
			vVisualSettingsProv = pVisualSettingsProv;

			vRendererHold = new GameObject("RendererHold");
			vRendererHold.transform.SetParent(gameObject.transform, false);
			vRendererHold.transform.localRotation = Quaternion.AngleAxis(170, Vector3.up);

			////

			BaseItemState itemState = pMenu.GetPalmItem();
			IItemVisualSettings visualSett = pVisualSettingsProv.GetSettings(itemState.Item);

			var itemObj = new GameObject("BackItem");
			itemObj.transform.SetParent(vRendererHold.transform, false);

			UiItem uiItem = itemObj.AddComponent<UiItem>();
			uiItem.Build(vMenuState, itemState, (float)Math.PI*2, visualSett);

			////

			vMenuState.OnLevelChange += HandleLevelChange;
			Rebuild();
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		internal void Build(MenuState pMenuState, BaseItemState pItemState, float pArcAngle, 
																IItemVisualSettings pVisualSettings) {
			vMenuState = pMenuState;
			vItemState = pItemState;
			ArcAngle = pArcAngle;

			const float pi = (float)Math.PI;
			const float slideBufferAngle = pi/80f;

			vSlideDegrees = (pArcAngle-slideBufferAngle*2)/(float)Math.PI*180;
			vSlideDir0 = MeshUtil.GetRingPoint(1, -pArcAngle/2f+slideBufferAngle);

			////

			vRendererObj = new GameObject("Renderer");
			vRendererObj.transform.SetParent(gameObject.transform, false);

			vRenderer = (IUiItemRenderer)vRendererObj.AddComponent(pVisualSettings.Renderer);
			vRenderer.Build(vMenuState, vItemState, pArcAngle, pVisualSettings);
			vRenderer.SetDepthHint(vMenuState.DisplayDepthHint);
			vPrevDepth = vMenuState.DisplayDepthHint;

			vItemState.HoverPointUpdater = vRenderer.UpdateHoverPoints;
		}