-
Notifications
You must be signed in to change notification settings - Fork 1
/
Utils.cs
113 lines (102 loc) · 4.45 KB
/
Utils.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// This class contains some helper functions.
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Networking;
using UnityEngine.EventSystems;
using System.Text.RegularExpressions;
using System.Linq;
public class Utils {
// Mathf.Clamp only works for float and int. we need some more versions:
public static long Clamp(long value, long min, long max) {
if (value < min) return min;
if (value > max) return max;
return value;
}
// is any of the keys UP?
public static bool AnyKeyUp(KeyCode[] keys) {
return keys.Any(k => Input.GetKeyUp(k));
}
// is any of the keys DOWN?
public static bool AnyKeyDown(KeyCode[] keys) {
return keys.Any(k => Input.GetKeyDown(k));
}
// detect headless mode (which has graphicsDeviceType Null)
public static bool IsHeadless() {
return SystemInfo.graphicsDeviceType == GraphicsDeviceType.Null;
}
// String.IsNullOrWhiteSpace that exists in NET4.5
// note: can't be an extension because then it can't detect null strings
// like null.IsNullOrWhitespace
public static bool IsNullOrWhiteSpace(string value) {
return System.String.IsNullOrEmpty(value) || value.Trim().Length == 0;
}
// Distance between two ClosestPointOnBounds
// this is needed in cases where entites are really big. in those cases,
// we can't just move to entity.transform.position, because it will be
// unreachable. instead we have to go the closest point on the boundary.
//
// Vector3.Distance(a.transform.position, b.transform.position):
// _____ _____
// | | | |
// | x==|======|==x |
// |_____| |_____|
//
//
// Utils.ClosestDistance(a.collider, b.collider):
// _____ _____
// | | | |
// | |x====x| |
// |_____| |_____|
//
public static float ClosestDistance(Collider a, Collider b) {
return Vector3.Distance(a.ClosestPointOnBounds(b.transform.position),
b.ClosestPointOnBounds(a.transform.position));
}
// pretty print seconds as hours:minutes:seconds
public static string PrettyTime(float seconds) {
var t = System.TimeSpan.FromSeconds(seconds);
string res = "";
if (t.Days > 0) res += t.Days + "d";
if (t.Hours > 0) res += " " + t.Hours + "h";
if (t.Minutes > 0) res += " " + t.Minutes + "m";
if (t.Seconds > 0) res += " " + t.Seconds + "s";
// if the string is still empty because the value was '0', then at least
// return the seconds instead of returning an empty string
return res != "" ? res : "0s";
}
// hard mouse scrolling that is consistent between all platforms
// Input.GetAxis("Mouse ScrollWheel") and
// Input.GetAxisRaw("Mouse ScrollWheel")
// both return values like 0.01 on standalone and 0.5 on WebGL, which
// causes too fast zooming on WebGL etc.
// normally GetAxisRaw should return -1,0,1, but it doesn't for scrolling
public static float GetAxisRawScrollUniversal() {
float scroll = Input.GetAxisRaw("Mouse ScrollWheel");
if (scroll < 0) return -1;
if (scroll > 0) return 1;
return 0;
}
// find local player (clientsided)
public static Player ClientLocalPlayer() {
// note: ClientScene.localPlayers.Count cant be used as check because
// nothing is removed from that list, even after disconnect. It still
// contains entries like: ID=0 NetworkIdentity NetID=null Player=null
// (which might be a UNET bug)
var p = ClientScene.localPlayers.Find(pc => pc.gameObject != null);
return p != null ? p.gameObject.GetComponent<Player>() : null;
}
// parse last upper cased noun from a string, e.g.
// EquipmentWeaponBow => Bow
// EquipmentShield => Shield
public static string ParseLastNoun(string text) {
var matches = new Regex(@"([A-Z][a-z]*)").Matches(text);
return matches.Count > 0 ? matches[matches.Count-1].Value : "";
}
// check if the cursor is over a UI or OnGUI element right now
// note: for UI, this only works if the UI's CanvasGroup blocks Raycasts
// note: for OnGUI: hotControl is only set while clicking, not while zooming
public static bool IsCursorOverUserInterface() {
return EventSystem.current.IsPointerOverGameObject() ||
GUIUtility.hotControl != 0;
}
}