Tanoda
HoverTooltip.cs
Go to the documentation of this file.
1
3
5{
6 [AddComponentMenu("UI/Extensions/HoverTooltip")]
7 public class HoverTooltip : MonoBehaviour
8 {
9 //manually selectable padding for the background image
11 public int verticalPadding;
12
13 //tooltip text
14 public Text thisText;
15
16 //horizontal layout of the tooltip
17 public HorizontalLayoutGroup hlG;
18
19 //tooltip background image
20 public RectTransform bgImage;
21 Image bgImageSource;
22
23 //needed as the layout refreshes only on the first Update() call
24 bool firstUpdate;
25
26 //if the tooltip is inside a UI element
27 bool inside;
28
29 //size of the tooltip, needed to track if out of screen
30 // public float width;
31 // public float height;
32
33 //detect canvas mode so to apply different behaviors to different canvas modes, currently only RenderMode.ScreenSpaceCamera implemented
34 //int canvasMode;
35 RenderMode GUIMode;
36
37 //the scene GUI camera
38 Camera GUICamera;
39
40 //the default tooltip object has the following pivots, so that the offset from the mouse is always proportional to the screen resolution (the y pivot)
41 //Pivot(0.5,-0.5)
42
43 //screen viewport corners for out of screen detection
44 Vector3 lowerLeft;
45 Vector3 upperRight;
46
47 //scale factor of proportionality to the reference resolution (1280x720)
48 float currentYScaleFactor;
49 float currentXScaleFactor;
50
51 //standard X and Y offsets of the new tooltip
52 float defaultYOffset;
53 float defaultXOffset;
54
55 //real on screen sizes of the tooltip object
56 float tooltipRealHeight;
57 float tooltipRealWidth;
58
59 // Use this for initialization
60 void Start()
61 {
62 //in this line you need to change the string in order to get your Camera //TODO MAYBE DO IT FROM THE INSPECTOR
63 GUICamera = GameObject.Find("GUICamera").GetComponent<Camera>();
64 GUIMode = this.transform.parent.parent.GetComponent<Canvas>().renderMode;
65
66 bgImageSource = bgImage.GetComponent<Image>();
67
68 //at start the pointer is never to be considered over and UI element
69 inside = false;
70
71 //assign the tooltip to the singleton GUI class manager for fast access
72 //TacticalGUIManager.tgm.mmttp = this;
73
74 //hide the tooltip
76 this.transform.parent.gameObject.SetActive(false);
77 }
78
79
80 //single string input tooltip
81 public void SetTooltip(string text)
82 {
83 NewTooltip();
84
85 //init tooltip string
86 thisText.text = text;
87
88 //call the position function
90 }
91
92
93 //multi string/line input tooltip (each string of the input array is a new line)
94 public void SetTooltip(string[] texts)
95 {
96 NewTooltip();
97
98 //build up the tooltip line after line with the input
99 string tooltipText = "";
100 int index = 0;
101 foreach (string newLine in texts)
102 {
103 if (index == 0)
104 {
105 tooltipText += newLine;
106 }
107 else
108 {
109 tooltipText += ("\n" + newLine);
110 }
111 index++;
112 }
113
114 //init tooltip string
115 thisText.text = tooltipText;
116
117 //call the position function
119 }
120
121 //temporary call to not mess up old code, will be removed
122 public void SetTooltip(string text, bool test)
123 {
124 NewTooltip();
125
126 //init tooltip string
127 thisText.text = text;
128
129 //call the position function
131 }
132
133
134 //position function, currently not working correctly due to the use of pivots and not manual offsets, soon to be fixed
136 {
137 //get the dynamic position of the pos in viewport coordinates
138 Vector3 newPos = GUICamera.ScreenToViewportPoint(Input.mousePosition);
139
140 // store in val the updated position (x or y) of the tooltip edge of interest
141 float val;
142
143 //store the new offset to impose in case of out of screen
144 float yOffSet = 0f;
145 float xOffSet = 0f;
146
147 //check for right edge of screen
148 //obtain the x coordinate of the right edge of the tooltip
149 val = ((GUICamera.ViewportToScreenPoint(newPos).x) + (tooltipRealWidth * bgImage.pivot.x));
150
151 //evaluate if the right edge of the tooltip goes out of screen
152 if (val > (upperRight.x))
153 {
154 float distFromRight = upperRight.x - val;
155
156 if (distFromRight > (defaultXOffset * 0.75))
157 {
158 //shorten the temporary offset up to a certain distance from the tooltip
159 xOffSet = distFromRight;
160 }
161 else
162 {
163 //if the distance becomes too short flip the tooltip to below the pointer (by offset+twice the height of the tooltip)
164 xOffSet = ((defaultXOffset) - (tooltipRealWidth) * 2f);
165 }
166
167 //assign the new modified coordinates to the tooltip and convert to screen coordinates
168 Vector3 newTooltipPos = new Vector3(GUICamera.ViewportToScreenPoint(newPos).x + xOffSet, 0f, 0f);
169
170 newPos.x = GUICamera.ScreenToViewportPoint(newTooltipPos).x;
171 }
172
173 //check for left edge of screen
174 //obtain the x coordinate of the left edge of the tooltip
175 val = ((GUICamera.ViewportToScreenPoint(newPos).x) - (tooltipRealWidth * bgImage.pivot.x));
176
177 //evaluate if the left edge of the tooltip goes out of screen
178 if (val < (lowerLeft.x))
179 {
180 float distFromLeft = lowerLeft.x - val;
181
182 if (distFromLeft < (defaultXOffset * 0.75 - tooltipRealWidth))
183 {
184 //shorten the temporary offset up to a certain distance from the tooltip
185 xOffSet = -distFromLeft;
186 }
187 else
188 {
189 //if the distance becomes too short flip the tooltip to above the pointer (by twice the height of the tooltip)
190 xOffSet = ((tooltipRealWidth) * 2f);
191 }
192
193 //assign the new modified coordinates to the tooltip and convert to screen coordinates
194 Vector3 newTooltipPos = new Vector3(GUICamera.ViewportToScreenPoint(newPos).x - xOffSet, 0f, 0f);
195
196 newPos.x = GUICamera.ScreenToViewportPoint(newTooltipPos).x;
197 }
198
199 //check for upper edge of the screen
200 //obtain the y coordinate of the upper edge of the tooltip
201 val = ((GUICamera.ViewportToScreenPoint(newPos).y) - ((bgImage.sizeDelta.y * currentYScaleFactor * (bgImage.pivot.y)) - (tooltipRealHeight)));
202 //evaluate if the upper edge of the tooltip goes out of screen
203 if (val > (upperRight.y))
204 {
205 float distFromUpper = upperRight.y - val;
206 yOffSet = (bgImage.sizeDelta.y * currentYScaleFactor * (bgImage.pivot.y));
207
208 if (distFromUpper > (defaultYOffset * 0.75))
209 {
210 //shorten the temporary offset up to a certain distance from the tooltip
211 yOffSet = distFromUpper;
212 }
213 else
214 {
215 //if the distance becomes too short flip the tooltip to below the pointer (by offset+twice the height of the tooltip)
216 yOffSet = ((defaultYOffset) - (tooltipRealHeight) * 2f);
217 }
218
219 //assign the new modified coordinates to the tooltip and convert to screen coordinates
220 Vector3 newTooltipPos = new Vector3(newPos.x, GUICamera.ViewportToScreenPoint(newPos).y + yOffSet, 0f);
221 newPos.y = GUICamera.ScreenToViewportPoint(newTooltipPos).y;
222 }
223
224 //check for lower edge of the screen
225 //obtain the y coordinate of the lower edge of the tooltip
226 val = ((GUICamera.ViewportToScreenPoint(newPos).y) - ((bgImage.sizeDelta.y * currentYScaleFactor * (bgImage.pivot.y))));
227
228 //evaluate if the upper edge of the tooltip goes out of screen
229 if (val < (lowerLeft.y))
230 {
231 float distFromLower = lowerLeft.y - val;
232 yOffSet = (bgImage.sizeDelta.y * currentYScaleFactor * (bgImage.pivot.y));
233
234 if (distFromLower < (defaultYOffset * 0.75 - tooltipRealHeight))
235 {
236 //shorten the temporary offset up to a certain distance from the tooltip
237 yOffSet = distFromLower;
238 }
239 else
240 {
241 //if the distance becomes too short flip the tooltip to above the pointer (by twice the height of the tooltip)
242 yOffSet = ((tooltipRealHeight) * 2f);
243 }
244
245 //assign the new modified coordinates to the tooltip and convert to screen coordinates
246 Vector3 newTooltipPos = new Vector3(newPos.x, GUICamera.ViewportToScreenPoint(newPos).y + yOffSet, 0f);
247 newPos.y = GUICamera.ScreenToViewportPoint(newTooltipPos).y;
248 }
249
250 this.transform.parent.transform.position = new Vector3(GUICamera.ViewportToWorldPoint(newPos).x, GUICamera.ViewportToWorldPoint(newPos).y, 0f);
251 this.transform.parent.gameObject.SetActive(true);
252 inside = true;
253 }
254
255 //call to hide tooltip when hovering out from the object
256 public void HideTooltip()
257 {
258 if (GUIMode == RenderMode.ScreenSpaceCamera)
259 {
260 if (this != null)
261 {
262 this.transform.parent.gameObject.SetActive(false);
263 inside = false;
265 }
266 }
267 }
268
269 // Update is called once per frame
270 void Update()
271 {
272 LayoutInit();
273 if (inside)
274 {
275 if (GUIMode == RenderMode.ScreenSpaceCamera)
276 {
278 }
279 }
280 }
281
282 //this function is used in order to setup the size of the tooltip by cheating on the HorizontalLayoutBehavior. The resize is done in the first update.
283 void LayoutInit()
284 {
285 if (firstUpdate)
286 {
287 firstUpdate = false;
288
289 bgImage.sizeDelta = new Vector2(hlG.preferredWidth + horizontalPadding, hlG.preferredHeight + verticalPadding);
290
291 defaultYOffset = (bgImage.sizeDelta.y * currentYScaleFactor * (bgImage.pivot.y));
292 defaultXOffset = (bgImage.sizeDelta.x * currentXScaleFactor * (bgImage.pivot.x));
293
294 tooltipRealHeight = bgImage.sizeDelta.y * currentYScaleFactor;
295 tooltipRealWidth = bgImage.sizeDelta.x * currentXScaleFactor;
296
298 }
299 }
300
301 //init basic variables on a new tooltip set
302 void NewTooltip()
303 {
304 firstUpdate = true;
305
306 lowerLeft = GUICamera.ViewportToScreenPoint(new Vector3(0.0f, 0.0f, 0.0f));
307 upperRight = GUICamera.ViewportToScreenPoint(new Vector3(1.0f, 1.0f, 0.0f));
308
309 currentYScaleFactor = Screen.height / this.transform.root.GetComponent<CanvasScaler>().referenceResolution.y;
310 currentXScaleFactor = Screen.width / this.transform.root.GetComponent<CanvasScaler>().referenceResolution.x;
311
312 }
313
314 //used to visualize the tooltip one update call after it has been built (to avoid flickers)
316 {
317 Color textColor = thisText.color;
318 thisText.color = new Color(textColor.r, textColor.g, textColor.b, 1f);
319 bgImageSource.color = new Color(bgImageSource.color.r, bgImageSource.color.g, bgImageSource.color.b, 0.8f);
320 }
321
322 //used to hide the tooltip so that it can be made visible one update call after it has been built (to avoid flickers)
324 {
325 Color textColor = thisText.color;
326 thisText.color = new Color(textColor.r, textColor.g, textColor.b, 0f);
327 bgImageSource.color = new Color(bgImageSource.color.r, bgImageSource.color.g, bgImageSource.color.b, 0f);
328 }
329
330 }
331}
System.Drawing.Image Image
Definition: TestScript.cs:37
UnityEngine.Color Color
Definition: TestScript.cs:32
void SetTooltip(string text, bool test)
Credit Erdener Gonenc - @PixelEnvision.