//////////////////////////////////////////////////////////////////////////////////////////////// /*--------------------------------------------------------------------------------------------*/ private void UpdateRenderer(ICursorData pCursorData) { IdleRenderer.Controllers.Set(HoverRendererIdle.CenterPositionName, this); IdleRenderer.Controllers.Set(HoverRendererIdle.DistanceThresholdName, this); IdleRenderer.Controllers.Set(HoverRendererIdle.TimerProgressName, this); IdleRenderer.Controllers.Set(HoverRendererIdle.IsRaycastName, this); IdleRenderer.Controllers.Set(SettingsControllerMap.GameObjectActiveSelf, this); IdleRenderer.CenterOffset = transform.InverseTransformPoint(pCursorData.Idle.WorldPosition); IdleRenderer.DistanceThreshold = pCursorData.Idle.DistanceThreshold; IdleRenderer.TimerProgress = pCursorData.Idle.Progress; IdleRenderer.IsRaycast = pCursorData.IsRaycast; RendererUtil.SetActiveWithUpdate(IdleRenderer.gameObject, pCursorData.Idle.IsActive); /*Transform itemPointHold = IdleRenderer.Fill.ItemPointer.transform.parent; * Transform cursPointHold = IdleRenderer.Fill.CursorPointer.transform.parent; * * Vector3 itemCenter = GetComponent<HoverRendererUpdater>() * .ActiveRenderer.GetCenterWorldPosition(); * Vector3 itemCenterLocalPos = IdleRenderer.transform * .InverseTransformPoint(itemCenter); * Vector3 cursorLocalPos = IdleRenderer.transform * .InverseTransformPoint(pCursorData.WorldPosition); * * itemPointHold.localRotation = Quaternion.FromToRotation(Vector3.right, itemCenterLocalPos); * cursPointHold.localRotation = Quaternion.FromToRotation(Vector3.right, cursorLocalPos);*/ }
/*--------------------------------------------------------------------------------------------*/ private void UpdateItems() { List <ICursorData> cursors = CursorDataProvider.Cursors; int cursorCount = cursors.Count; for (int i = 0; i < cursorCount; i++) { ICursorData cursor = cursors[i]; cursor.MaxItemHighlightProgress = 0; cursor.MaxItemSelectionProgress = 0; if (!cursor.CanCauseSelections) { continue; } HoverItemHighlightState.Highlight?high; HoverItemHighlightState highState = FindNearestItemToCursor(cursor.Type, out high); if (highState == null || high == null) { continue; } highState.SetNearestAcrossAllItemsForCursor(cursor.Type); cursor.MaxItemHighlightProgress = high.Value.Progress; } }
/*--------------------------------------------------------------------------------------------*/ private void FillCursorLists() { for (int i = 0; i < vItems.Count; i++) { HoverItemData data = vItems[i].Data; IItemDataSelectable selData = (IItemDataSelectable)data; HoverItemHighlightState highState = data.GetComponent <HoverItemHighlightState>(); ICursorData cursorData = highState.NearestHighlight.Value.Cursor; if (cursorData.Idle.Progress >= 1) { selData.DeselectStickySelections(); continue; } HoverItemSelectionState selState = data.GetComponent <HoverItemSelectionState>(); HoverRenderer rend = data.GetComponent <HoverItemRendererUpdater>().ActiveRenderer; var info = new StickySelectionInfo { ItemWorldPosition = rend.GetCenterWorldPosition(), SelectionProgress = selState.SelectionProgress }; cursorData.ActiveStickySelections.Add(info); } }
/*--------------------------------------------------------------------------------------------*/ protected virtual void AddLatestHighlightsAndFindNearest() { float minDist = float.MaxValue; List <ICursorData> cursors = CursorDataProvider.Cursors; int cursorCount = cursors.Count; for (int i = 0; i < cursorCount; i++) { ICursorData cursor = cursors[i]; if (!cursor.CanCauseSelections) { continue; } Highlight high = CalculateHighlight(cursor); high.IsNearestAcrossAllItems = vIsNearestForCursorTypeMap.Contains(cursor.Type); Highlights.Add(high); if (high.Distance >= minDist) { continue; } minDist = high.Distance; NearestHighlight = high; } IsNearestAcrossAllItemsForAnyCursor = (vIsNearestForCursorTypeMap.Count > 0); }
/*--------------------------------------------------------------------------------------------*/ private void AddLatestHighlightsAndFindNearest() { float minDist = float.MaxValue; List <ICursorData> cursors = CursorDataProvider.Cursors; int cursorCount = cursors.Count; for (int i = 0; i < cursorCount; i++) { ICursorData cursor = cursors[i]; if (!cursor.CanCauseSelections) { continue; } Highlight high = CalculateHighlight(cursor); Highlights.Add(high); if (high.Distance >= minDist) { continue; } minDist = high.Distance; NearestHighlight = high; } }
/*--------------------------------------------------------------------------------------------*/ private void BuildCursor(HoverCursorDataProvider pProv, ICursorData pData) { var curGo = new GameObject(pData.Type + ""); curGo.transform.SetParent(gameObject.transform, false); TreeUpdater treeUp = curGo.AddComponent <TreeUpdater>(); HoverCursorFollower follow = curGo.AddComponent <HoverCursorFollower>(); follow.CursorDataProvider = pProv; follow.CursorType = pData.Type; follow.FollowCursorActive = false; follow.ScaleUsingCursorSize = true; HoverCursorRendererUpdater cursRendUp = curGo.AddComponent <HoverCursorRendererUpdater>(); cursRendUp.CursorRendererPrefab = CursorRendererPrefab; if (pData.Idle != null) { HoverIdleRendererUpdater idleRendUp = curGo.AddComponent <HoverIdleRendererUpdater>(); idleRendUp.IdleRendererPrefab = IdleRendererPrefab; } follow.Update(); //moves interface to the correct cursor transform treeUp.UpdateAtAndBelowThisLevel(); //force renderer creation }
//////////////////////////////////////////////////////////////////////////////////////////////// /*--------------------------------------------------------------------------------------------*/ private void CalcNearestRaycastResults() { List <ICursorData> cursors = CursorDataProvider.SelectableCursors; int cursorCount = cursors.Count; bool didFillList = false; for (int i = 0; i < cursorCount; i++) { ICursorData cursor = cursors[i]; if (!cursor.IsRaycast) { continue; } if (!didFillList) { GetComponent <HoverItemsManager>().FillListWithActiveItemComponents(vHighStates); didFillList = true; } cursor.BestRaycastResult = CalcNearestRaycastResult(cursor); /*if ( cursor.BestRaycastResult != null ) { * Color col = (cursor.BestRaycastResult.Value.IsHit ? Color.green : Color.red); * Debug.DrawLine(cursor.BestRaycastResult.Value.WorldPosition, * cursor.WorldPosition, col); * }*/ } }
/*--------------------------------------------------------------------------------------------*/ private RaycastResult?CalcNearestRaycastResult(ICursorData pCursor) { if (!pCursor.IsRaycast || !pCursor.CanCauseSelections) { return(null); } float minHighSqrDist = float.MaxValue; float minCastSqrDist = float.MaxValue; var worldRay = new Ray(pCursor.WorldPosition, pCursor.WorldRotation * pCursor.RaycastLocalDirection); RaycastResult result = new RaycastResult(); result.WorldPosition = worldRay.GetPoint(10000); result.WorldRotation = pCursor.WorldRotation; for (int i = 0; i < vHighStates.Count; i++) { HoverItemHighlightState item = vHighStates[i]; if (item.IsHighlightPreventedViaAnyDisplay()) { continue; } RaycastResult raycast; Vector3 nearHighWorldPos = item.ProximityProvider .GetNearestWorldPosition(worldRay, out raycast); if (!raycast.IsHit) { continue; } float highSqrDist = (raycast.WorldPosition - nearHighWorldPos).sqrMagnitude; float castSqrDist = (raycast.WorldPosition - pCursor.WorldPosition).sqrMagnitude; //float hitSqrDist = Mathf.Pow(item.InteractionSettings.HighlightDistanceMin, 2); float hitSqrDist = 0.0000001f; highSqrDist = Mathf.Max(highSqrDist, hitSqrDist); bool isHighlightWorse = (highSqrDist > minHighSqrDist); bool isComparingHits = (highSqrDist <= hitSqrDist && minHighSqrDist <= hitSqrDist); bool isRaycastNearer = (castSqrDist < minCastSqrDist); if (isHighlightWorse || (isComparingHits && !isRaycastNearer)) { continue; } minHighSqrDist = highSqrDist; minCastSqrDist = castSqrDist; result = raycast; } return(result); }
/*--------------------------------------------------------------------------------------------*/ public virtual void TreeUpdate() { DestroyRendererIfNecessary(); IdleRenderer = (IdleRenderer ?? FindOrBuildIdle()); ICursorData cursorData = GetComponent <HoverCursorFollower>().GetCursorData(); UpdateRenderer(cursorData); }
//////////////////////////////////////////////////////////////////////////////////////////////// /*--------------------------------------------------------------------------------------------*/ private void DrawCursorList(string pLabel, List <ICursorData> pCursors) { EditorGUILayout.LabelField(pLabel, EditorStyles.boldLabel); GUI.enabled = false; for (int i = 0; i < pCursors.Count; i++) { ICursorData cursor = pCursors[i]; EditorGUILayout.ObjectField(cursor.Type + "", (Object)cursor, cursor.GetType(), true); } GUI.enabled = true; }
/*--------------------------------------------------------------------------------------------*/ private void UpdateItems() { List <ICursorData> cursors = CursorDataProvider.Cursors; int cursorCount = cursors.Count; for (int i = 0; i < cursorCount; i++) { ICursorData cursor = cursors[i]; cursor.MaxItemHighlightProgress = 0; cursor.MaxItemSelectionProgress = 0; if (!cursor.CanCauseSelections) { continue; } HoverItemHighlightState highState = FindNearestItemWithinProxOfCursor( cursor.Type, out HoverItemHighlightState.Highlight? high); if (highState == null || high == null) { continue; } highState.SetNearestAcrossAllItemsForCursor(cursor.Type); cursor.MaxItemHighlightProgress = high.Value.Progress; } for (int i = 0; i < vActiveHighStates.Count; i++) { HoverItemHighlightState highState = vActiveHighStates[i]; HoverItemSelectionState selState = highState.GetComponent <HoverItemSelectionState>(); highState.UpdateViaManager(); if (selState == null) { continue; } selState.UpdateViaManager(); if (selState.WasSelectedThisFrame) { ICursorData selCursor = highState.NearestHighlight?.Cursor; //Debug.Log("Item selected: "+selState.transform.ToDebugPath()+" / "+ // selCursor?.Type, selState); OnItemSelected.Invoke(highState.GetComponent <HoverItem>(), selCursor); } } }
/*--------------------------------------------------------------------------------------------*/ private void UpdateNearestCursor(HoverItemHighlightState pHighState) { HoverItemHighlightState.Highlight?nearestHigh = pHighState.NearestHighlight; if (nearestHigh == null) { return; } ICursorData cursor = nearestHigh.Value.Cursor; cursor.MaxItemSelectionProgress = Mathf.Max( cursor.MaxItemSelectionProgress, SelectionProgress); }
/*--------------------------------------------------------------------------------------------*/ public void TreeUpdate() { HovercastInterface cast = gameObject.GetComponent <HovercastInterface>(); if (!cast.BackItem.IsEnabled) { return; } ICursorData cursorData = cast.GetComponent <HoverCursorFollower>() .CursorDataProvider.GetCursorData(BackTriggerCursorType); float triggerStrength = cursorData.TriggerStrength; UpdateTrigger(cast, triggerStrength); UpdateOverrider(cast.BackItem, triggerStrength); }
/*--------------------------------------------------------------------------------------------*/ private void UpdateNearestCursor() { HoverItemHighlightState highState = GetComponent <HoverItemHighlightState>(); HoverItemHighlightState.Highlight?nearestHigh = highState.NearestHighlight; if (nearestHigh == null) { return; } ICursorData cursor = nearestHigh.Value.Cursor; cursor.MaxItemSelectionProgress = Mathf.Max( cursor.MaxItemSelectionProgress, SelectionProgress); }
//////////////////////////////////////////////////////////////////////////////////////////////// /*--------------------------------------------------------------------------------------------*/ private void CalcNearestRaycastResults() { List <ICursorData> cursors = CursorDataProvider.Cursors; int cursorCount = cursors.Count; for (int i = 0; i < cursorCount; i++) { ICursorData cursor = cursors[i]; cursor.BestRaycastResult = CalcNearestRaycastResult(cursor); /*if ( cursor.BestRaycastResult != null ) { * Color col = (cursor.BestRaycastResult.Value.IsHit ? Color.green : Color.red); * Debug.DrawLine(cursor.BestRaycastResult.Value.WorldPosition, * cursor.WorldPosition, col); * }*/ } }
/*--------------------------------------------------------------------------------------------*/ private void UpdateRenderer(HoverCursorFollower pFollower) { ICursorData cursorData = pFollower.GetCursorData(); HoverIndicator cursorInd = CursorRenderer.GetIndicator(); CursorRenderer.Controllers.Set(SettingsControllerMap.GameObjectActiveSelf, this); CursorRenderer.Controllers.Set(HoverRendererCursor.IsRaycastName, this); CursorRenderer.Controllers.Set(HoverRendererCursor.RaycastWorldOriginName, this); cursorInd.Controllers.Set(HoverIndicator.HighlightProgressName, this); cursorInd.Controllers.Set(HoverIndicator.SelectionProgressName, this); RendererUtil.SetActiveWithUpdate(CursorRenderer, cursorData.IsActive); CursorRenderer.IsRaycast = cursorData.IsRaycast; CursorRenderer.RaycastWorldOrigin = cursorData.WorldPosition; cursorInd.HighlightProgress = cursorData.MaxItemHighlightProgress; cursorInd.SelectionProgress = cursorData.MaxItemSelectionProgress; }
/*--------------------------------------------------------------------------------------------*/ public void TreeUpdate() { HovercastInterface cast = gameObject.GetComponent <HovercastInterface>(); HoverCursorFollower follow = cast.GetComponent <HoverCursorFollower>(); UpdateCursorType(follow); if (cast.BackItem.IsEnabled) { ICursorData cursorData = follow.CursorDataProvider.GetCursorData(CursorType); float triggerStrength = cursorData.TriggerStrength; UpdateTrigger(cast, triggerStrength); UpdateOverrider(cast.BackItem, triggerStrength); } Controllers.TryExpireControllers(); }
/*--------------------------------------------------------------------------------------------*/ protected Highlight CalculateHighlight(ICursorData pCursor) { var high = new Highlight(); high.Cursor = pCursor; if (!Application.isPlaying) { return(high); } Vector3 cursorWorldPos = (pCursor.BestRaycastResult == null ? pCursor.WorldPosition : pCursor.BestRaycastResult.Value.WorldPosition); high.NearestWorldPos = ProximityProvider.GetNearestWorldPosition(cursorWorldPos); high.Distance = (cursorWorldPos - high.NearestWorldPos).magnitude; high.Progress = Mathf.InverseLerp(InteractionSettings.HighlightDistanceMax, InteractionSettings.HighlightDistanceMin, high.Distance); return(high); }
/*--------------------------------------------------------------------------------------------*/ private void UpdateRenderer(HoverCursorFollower pFollower) { ICursorData cursorData = pFollower.GetCursorData(); HoverIndicator cursorInd = CursorRenderer.GetIndicator(); CursorRenderer.Controllers.Set(SettingsControllerMap.GameObjectActiveSelf, this); CursorRenderer.Controllers.Set(HoverRendererCursor.IsRaycastName, this); CursorRenderer.Controllers.Set(HoverRendererCursor.ShowRaycastLineName, this); CursorRenderer.Controllers.Set(HoverRendererCursor.RaycastWorldOriginName, this); cursorInd.Controllers.Set(HoverIndicator.HighlightProgressName, this); cursorInd.Controllers.Set(HoverIndicator.SelectionProgressName, this); RendererUtil.SetActiveWithUpdate(CursorRenderer, (cursorData.IsActive && cursorData.Capability != CursorCapabilityType.None)); CursorRenderer.IsRaycast = cursorData.IsRaycast; CursorRenderer.ShowRaycastLine = (cursorData.CanCauseSelections && cursorData.Type != CursorType.Look); CursorRenderer.RaycastWorldOrigin = cursorData.WorldPosition; cursorInd.HighlightProgress = cursorData.MaxItemHighlightProgress; cursorInd.SelectionProgress = cursorData.MaxItemSelectionProgress; }
/*--------------------------------------------------------------------------------------------*/ public void Update() { Controllers.TryExpireControllers(); if (CursorDataProvider == null) { Debug.LogError("Reference to " + typeof(HoverCursorDataProvider).Name + " must be set.", this); return; } ICursorData cursor = GetCursorData(); RaycastResult?raycast = cursor.BestRaycastResult; Transform tx = gameObject.transform; if (FollowCursorActive) { foreach (GameObject go in ObjectsToActivate) { go.SetActive(cursor.IsActive); } } if (FollowCursorPosition) { Controllers.Set(SettingsControllerMap.TransformPosition, this, 0); tx.position = (raycast == null ? cursor.WorldPosition : raycast.Value.WorldPosition); } if (FollowCursorRotation) { Controllers.Set(SettingsControllerMap.TransformRotation, this, 0); if (raycast == null) { tx.rotation = cursor.WorldRotation; } else { RaycastResult rc = raycast.Value; Vector3 perpDir = (cursor.RaycastLocalDirection == Vector3.up ? Vector3.right : Vector3.up); //TODO: does this work in all cases? Vector3 castUpPos = rc.WorldPosition + rc.WorldRotation * perpDir; Vector3 cursorUpPos = rc.WorldPosition + cursor.WorldRotation * perpDir; float upToPlaneDist = rc.WorldPlane.GetDistanceToPoint(cursorUpPos); Vector3 cursorUpOnPlanePos = cursorUpPos - rc.WorldPlane.normal * upToPlaneDist; Quaternion invCastRot = Quaternion.Inverse(rc.WorldRotation); Vector3 fromLocalVec = invCastRot * (castUpPos - rc.WorldPosition); Vector3 toLocalVec = invCastRot * (cursorUpOnPlanePos - rc.WorldPosition); Quaternion applyRot = Quaternion.FromToRotation(fromLocalVec, toLocalVec); //Debug.DrawLine(rc.WorldPosition, castUpPos, Color.red); //Debug.DrawLine(rc.WorldPosition, cursorUpOnPlanePos, Color.blue); tx.rotation = rc.WorldRotation * applyRot; } } if (ScaleUsingCursorSize) { Controllers.Set(SettingsControllerMap.TransformLocalScale, this, 0); tx.localScale = Vector3.one * (cursor.Size * CursorSizeMultiplier); } }