Tanoda
ToolTip.cs
Go to the documentation of this file.
1
6
7//ToolTip is written by Emiliano Pastorelli, H&R Tallinn (Estonia), http://www.hammerandravens.com
8//Copyright (c) 2015 Emiliano Pastorelli, H&R - Hammer&Ravens, Tallinn, Estonia.
9//All rights reserved.
10
11//Redistribution and use in source and binary forms are permitted
12//provided that the above copyright notice and this paragraph are
13//duplicated in all such forms and that any documentation,
14//advertising materials, and other materials related to such
15//distribution and use acknowledge that the software was developed
16//by H&R, Hammer&Ravens. The name of the
17//H&R, Hammer&Ravens may not be used to endorse or promote products derived
18//from this software without specific prior written permission.
19//THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
20//IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
21//WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22
24{
25 [RequireComponent(typeof(RectTransform))]
26 [AddComponentMenu("UI/Extensions/Tooltip/Tooltip")]
27 public class ToolTip : MonoBehaviour
28 {
29 //text of the tooltip
30 private Text _text;
31 private RectTransform _rectTransform, canvasRectTransform;
32
33 [Tooltip("The canvas used by the tooltip as positioning and scaling reference. Should usually be the root Canvas of the hierarchy this component is in")]
34 public Canvas canvas;
35
36 [Tooltip("Sets if tooltip triggers will run ForceUpdateCanvases and refresh the tooltip's layout group " +
37 "(if any) when hovered, in order to prevent momentousness misplacement sometimes caused by ContentSizeFitters")]
39
43 private LayoutGroup _layoutGroup;
44
45 //if the tooltip is inside a UI element
46 private bool _inside;
47
48 private float width, height;//, canvasWidth, canvasHeight;
49
50 public float YShift,xShift;
51
52 [HideInInspector]
53 public RenderMode guiMode;
54
55 private Camera _guiCamera;
56
57 public Camera GuiCamera
58 {
59 get
60 {
61 if (!_guiCamera) {
62 _guiCamera = Camera.main;
63 }
64
65 return _guiCamera;
66 }
67 }
68
69 private Vector3 screenLowerLeft, screenUpperRight, shiftingVector;
70
74 private Vector3 baseTooltipPos;
75
76 private Vector3 newTTPos;
77 private Vector3 adjustedNewTTPos;
78 private Vector3 adjustedTTLocalPos;
79 private Vector3 shifterForBorders;
80
81 private float borderTest;
82
83 // Standard Singleton Access
84 private static ToolTip instance;
85
86 public static ToolTip Instance
87 {
88 get
89 {
90 if (instance == null)
91 instance = FindObjectOfType<ToolTip>();
92 return instance;
93 }
94 }
95
96
97 void Reset() {
98 canvas = GetComponentInParent<Canvas>();
99 canvas = canvas.rootCanvas;
100 }
101
102 // Use this for initialization
103 public void Awake()
104 {
105 instance = this;
106 if (!canvas) {
107 canvas = GetComponentInParent<Canvas>();
108 canvas = canvas.rootCanvas;
109 }
110
111 _guiCamera = canvas.worldCamera;
112 guiMode = canvas.renderMode;
113 _rectTransform = GetComponent<RectTransform>();
114 canvasRectTransform = canvas.GetComponent<RectTransform>();
115 _layoutGroup = GetComponentInChildren<LayoutGroup>();
116
117 _text = GetComponentInChildren<Text>();
118
119 _inside = false;
120
121 this.gameObject.SetActive(false);
122 }
123
124 //Call this function externally to set the text of the template and activate the tooltip
125 public void SetTooltip(string ttext, Vector3 basePos, bool refreshCanvasesBeforeGetSize = false)
126 {
127
128 baseTooltipPos = basePos;
129
130 //set the text
131 if (_text) {
132 _text.text = ttext;
133 }
134 else {
135 Debug.LogWarning("[ToolTip] Couldn't set tooltip text, tooltip has no child Text component");
136 }
137
138 ContextualTooltipUpdate(refreshCanvasesBeforeGetSize);
139
140 }
141
142 //call this function on mouse exit to deactivate the template
143 public void HideTooltip()
144 {
145 gameObject.SetActive(false);
146 _inside = false;
147 }
148
149 // Update is called once per frame
150 void Update()
151 {
152 if (_inside)
153 {
155 }
156 }
157
163 public void RefreshTooltipSize() {
165 Canvas.ForceUpdateCanvases();
166
167 if (_layoutGroup) {
168 _layoutGroup.enabled = false;
169 _layoutGroup.enabled = true;
170 }
171
172 }
173
174 }
175
180 public void ContextualTooltipUpdate(bool refreshCanvasesBeforeGettingSize = false) {
181 switch (guiMode) {
182 case RenderMode.ScreenSpaceCamera:
183 OnScreenSpaceCamera(refreshCanvasesBeforeGettingSize);
184 break;
185 case RenderMode.ScreenSpaceOverlay:
186 OnScreenSpaceOverlay(refreshCanvasesBeforeGettingSize);
187 break;
188 }
189 }
190
191 //main tooltip edge of screen guard and movement - camera
192 public void OnScreenSpaceCamera(bool refreshCanvasesBeforeGettingSize = false)
193 {
194 shiftingVector.x = xShift;
195 shiftingVector.y = YShift;
196
197 baseTooltipPos.z = canvas.planeDistance;
198
199 newTTPos = GuiCamera.ScreenToViewportPoint(baseTooltipPos - shiftingVector);
200 adjustedNewTTPos = GuiCamera.ViewportToWorldPoint(newTTPos);
201
202 gameObject.SetActive(true);
203
204 if (refreshCanvasesBeforeGettingSize) RefreshTooltipSize();
205
206 //consider scaled dimensions when comparing against the edges
207 width = transform.lossyScale.x * _rectTransform.sizeDelta[0];
208 height = transform.lossyScale.y * _rectTransform.sizeDelta[1];
209
210 // check and solve problems for the tooltip that goes out of the screen on the horizontal axis
211
212 RectTransformUtility.ScreenPointToWorldPointInRectangle(canvasRectTransform, Vector2.zero, GuiCamera, out screenLowerLeft);
213 RectTransformUtility.ScreenPointToWorldPointInRectangle(canvasRectTransform, new Vector2(Screen.width, Screen.height), GuiCamera, out screenUpperRight);
214
215
216 //check for right edge of screen
217 borderTest = (adjustedNewTTPos.x + width / 2);
218 if (borderTest > screenUpperRight.x)
219 {
220 shifterForBorders.x = borderTest - screenUpperRight.x;
221 adjustedNewTTPos.x -= shifterForBorders.x;
222 }
223 //check for left edge of screen
224 borderTest = (adjustedNewTTPos.x - width / 2);
225 if (borderTest < screenLowerLeft.x)
226 {
227 shifterForBorders.x = screenLowerLeft.x - borderTest;
228 adjustedNewTTPos.x += shifterForBorders.x;
229 }
230
231 // check and solve problems for the tooltip that goes out of the screen on the vertical axis
232
233 //check for lower edge of the screen
234 borderTest = (adjustedNewTTPos.y - height / 2);
235 if (borderTest < screenLowerLeft.y) {
236 shifterForBorders.y = screenLowerLeft.y - borderTest;
237 adjustedNewTTPos.y += shifterForBorders.y;
238 }
239
240 //check for upper edge of the screen
241 borderTest = (adjustedNewTTPos.y + height / 2);
242 if (borderTest > screenUpperRight.y)
243 {
244 shifterForBorders.y = borderTest - screenUpperRight.y;
245 adjustedNewTTPos.y -= shifterForBorders.y;
246 }
247
248 //failed attempt to circumvent issues caused when rotating the camera
249 adjustedNewTTPos = transform.rotation * adjustedNewTTPos;
250
251 transform.position = adjustedNewTTPos;
252 adjustedTTLocalPos = transform.localPosition;
253 adjustedTTLocalPos.z = 0;
254 transform.localPosition = adjustedTTLocalPos;
255
256 _inside = true;
257 }
258
259
260 //main tooltip edge of screen guard and movement - overlay
261 public void OnScreenSpaceOverlay(bool refreshCanvasesBeforeGettingSize = false) {
262 shiftingVector.x = xShift;
263 shiftingVector.y = YShift;
264 newTTPos = (baseTooltipPos - shiftingVector) / canvas.scaleFactor;
265 adjustedNewTTPos = newTTPos;
266
267 gameObject.SetActive(true);
268
269 if (refreshCanvasesBeforeGettingSize) RefreshTooltipSize();
270
271 width = _rectTransform.sizeDelta[0];
272 height = _rectTransform.sizeDelta[1];
273
274 // check and solve problems for the tooltip that goes out of the screen on the horizontal axis
275 //screen's 0 = overlay canvas's 0 (always?)
276 screenLowerLeft = Vector3.zero;
277 screenUpperRight = canvasRectTransform.sizeDelta;
278
279 //check for right edge of screen
280 borderTest = (newTTPos.x + width / 2);
281 if (borderTest > screenUpperRight.x) {
282 shifterForBorders.x = borderTest - screenUpperRight.x;
283 adjustedNewTTPos.x -= shifterForBorders.x;
284 }
285 //check for left edge of screen
286 borderTest = (adjustedNewTTPos.x - width / 2);
287 if (borderTest < screenLowerLeft.x) {
288 shifterForBorders.x = screenLowerLeft.x - borderTest;
289 adjustedNewTTPos.x += shifterForBorders.x;
290 }
291
292 // check and solve problems for the tooltip that goes out of the screen on the vertical axis
293
294 //check for lower edge of the screen
295 borderTest = (adjustedNewTTPos.y - height / 2);
296 if (borderTest < screenLowerLeft.y) {
297 shifterForBorders.y = screenLowerLeft.y - borderTest;
298 adjustedNewTTPos.y += shifterForBorders.y;
299 }
300
301 //check for upper edge of the screen
302 borderTest = (adjustedNewTTPos.y + height / 2);
303 if (borderTest > screenUpperRight.y) {
304 shifterForBorders.y = borderTest - screenUpperRight.y;
305 adjustedNewTTPos.y -= shifterForBorders.y;
306 }
307
308 //remove scale factor for the actual positioning of the TT
309 adjustedNewTTPos *= canvas.scaleFactor;
310 transform.position = adjustedNewTTPos;
311
312 _inside = true;
313 }
314 }
315}
UnityEngine.Debug Debug
Definition: TanodaServer.cs:19
void OnScreenSpaceCamera(bool refreshCanvasesBeforeGettingSize=false)
Definition: ToolTip.cs:192
void OnScreenSpaceOverlay(bool refreshCanvasesBeforeGettingSize=false)
Definition: ToolTip.cs:261
void SetTooltip(string ttext, Vector3 basePos, bool refreshCanvasesBeforeGetSize=false)
Definition: ToolTip.cs:125
void RefreshTooltipSize()
forces rebuilding of Canvases in order to update the tooltip's content size fitting....
Definition: ToolTip.cs:163
void ContextualTooltipUpdate(bool refreshCanvasesBeforeGettingSize=false)
Runs the appropriate tooltip placement method, according to the parent canvas's render mode
Definition: ToolTip.cs:180
Credit Erdener Gonenc - @PixelEnvision.