com.wallstop-studios.unity-helpers 2.0.0-rc61 → 2.0.0-rc62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Editor/AnimationCopier.cs +4 -11
- package/Editor/AnimationCreator.cs +5 -9
- package/Editor/AnimatorControllerCopier.cs +4 -10
- package/Editor/CustomEditors/MatchColliderToSpriteEditor.cs +1 -3
- package/Editor/FitTextureSizeWizard.cs +2 -2
- package/Editor/PrefabCheckWizard.cs +7 -10
- package/Editor/SpriteSettingsApplier.cs +1 -1
- package/Editor/TextureResizerWizard.cs +2 -7
- package/Editor/TextureSettingsApplier.cs +1 -1
- package/Runtime/Core/Extension/ColorExtensions.cs +15 -0
- package/Runtime/Core/Extension/LoggingExtensions.cs +68 -121
- package/Runtime/Core/Helper/Helpers.cs +3 -3
- package/Runtime/Core/Helper/Logging/UnityLogTagFormatter.cs +489 -0
- package/Runtime/Core/Helper/Logging/UnityLogTagFormatter.cs.meta +3 -0
- package/Runtime/Core/Helper/Logging.meta +3 -0
- package/Runtime/Core/Helper/Partials/LogHelpers.cs +1 -1
- package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +2 -6
- package/Runtime/Core/Helper/ReflectionHelpers.cs +149 -35
- package/Runtime/Core/Helper/SpriteHelpers.cs +2 -2
- package/Runtime/Utils/CircleLineRenderer.cs +3 -5
- package/Tests/Runtime/Extensions/LoggingExtensionTests.cs +718 -0
- package/Tests/Runtime/Extensions/LoggingExtensionTests.cs.meta +3 -0
- package/Tests/Runtime/Helper/WallMathTests.cs +1 -1
- package/Tests/Runtime/Random/RandomTestBase.cs +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
namespace UnityHelpers.Core.Helper.Logging
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
using System.Linq;
|
|
6
|
+
using System.Text;
|
|
7
|
+
using Extension;
|
|
8
|
+
using UnityEngine;
|
|
9
|
+
using Debug = UnityEngine.Debug;
|
|
10
|
+
using Object = UnityEngine.Object;
|
|
11
|
+
|
|
12
|
+
public sealed class UnityLogTagFormatter : IFormatProvider, ICustomFormatter
|
|
13
|
+
{
|
|
14
|
+
public const char Separator = ',';
|
|
15
|
+
|
|
16
|
+
private static readonly string NewLine = Environment.NewLine;
|
|
17
|
+
|
|
18
|
+
private static readonly Dictionary<string, string> ColorNamesToHex = ReflectionHelpers
|
|
19
|
+
.LoadStaticPropertiesForType<Color>()
|
|
20
|
+
.Where(kvp => kvp.Value.PropertyType == typeof(Color))
|
|
21
|
+
.Select(kvp => (kvp.Key, ((Color)kvp.Value.GetValue(null)).ToHex()))
|
|
22
|
+
.ToDictionary(StringComparer.OrdinalIgnoreCase);
|
|
23
|
+
|
|
24
|
+
/// <summary>
|
|
25
|
+
/// All currently registered decorations by tag.
|
|
26
|
+
/// </summary>
|
|
27
|
+
public IEnumerable<string> Decorations =>
|
|
28
|
+
_matchingDecorations.Values.SelectMany(x => x).Select(value => value.tag);
|
|
29
|
+
|
|
30
|
+
public IReadOnlyCollection<
|
|
31
|
+
IReadOnlyList<(
|
|
32
|
+
string tag,
|
|
33
|
+
bool editorOnly,
|
|
34
|
+
Func<string, bool> predicate,
|
|
35
|
+
Func<string, object, string> formatter
|
|
36
|
+
)>
|
|
37
|
+
> MatchingDecorations => _matchingDecorations.Values;
|
|
38
|
+
|
|
39
|
+
private readonly SortedDictionary<
|
|
40
|
+
int,
|
|
41
|
+
List<(
|
|
42
|
+
string tag,
|
|
43
|
+
bool editorOnly,
|
|
44
|
+
Func<string, bool> predicate,
|
|
45
|
+
Func<string, object, string> formatter
|
|
46
|
+
)>
|
|
47
|
+
> _matchingDecorations = new();
|
|
48
|
+
private readonly StringBuilder _cachedStringBuilder = new();
|
|
49
|
+
private readonly List<string> _cachedDecorators = new();
|
|
50
|
+
private readonly HashSet<string> _appliedTags = new(StringComparer.OrdinalIgnoreCase);
|
|
51
|
+
|
|
52
|
+
public UnityLogTagFormatter()
|
|
53
|
+
: this(true) { }
|
|
54
|
+
|
|
55
|
+
/// <summary>
|
|
56
|
+
/// Creates a new UnityLogTagFormatter.
|
|
57
|
+
/// </summary>
|
|
58
|
+
/// <param name="createDefaultDecorators">If true, applies default decorators (bold, italic, color, size, and json).</param>
|
|
59
|
+
public UnityLogTagFormatter(bool createDefaultDecorators)
|
|
60
|
+
{
|
|
61
|
+
if (!createDefaultDecorators)
|
|
62
|
+
{
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
AddDecoration(
|
|
67
|
+
format =>
|
|
68
|
+
string.Equals(format, "b", StringComparison.OrdinalIgnoreCase)
|
|
69
|
+
|| string.Equals(format, "bold", StringComparison.OrdinalIgnoreCase)
|
|
70
|
+
|| string.Equals(format, "!", StringComparison.OrdinalIgnoreCase),
|
|
71
|
+
format: (_, value) => $"<b>{value}</b>",
|
|
72
|
+
tag: "Bold",
|
|
73
|
+
editorOnly: true,
|
|
74
|
+
force: true
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
AddDecoration(
|
|
78
|
+
format =>
|
|
79
|
+
string.Equals(format, "i", StringComparison.OrdinalIgnoreCase)
|
|
80
|
+
|| string.Equals(format, "italic", StringComparison.OrdinalIgnoreCase)
|
|
81
|
+
|| string.Equals(format, "_", StringComparison.OrdinalIgnoreCase),
|
|
82
|
+
format: (_, value) => $"<i>{value}</i>",
|
|
83
|
+
tag: "Italic",
|
|
84
|
+
editorOnly: true,
|
|
85
|
+
force: true
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
AddDecoration(
|
|
89
|
+
match: "json",
|
|
90
|
+
format: value => value?.ToJson() ?? "{}",
|
|
91
|
+
tag: "JSON",
|
|
92
|
+
editorOnly: false,
|
|
93
|
+
force: true
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const char colorCharCheck = '#';
|
|
97
|
+
const string colorStringCheck = "color=";
|
|
98
|
+
AddDecoration(
|
|
99
|
+
format =>
|
|
100
|
+
format.StartsWith(colorCharCheck)
|
|
101
|
+
|| format.StartsWith(colorStringCheck, StringComparison.OrdinalIgnoreCase),
|
|
102
|
+
format: (format, value) =>
|
|
103
|
+
{
|
|
104
|
+
string baseColor = format.StartsWith(
|
|
105
|
+
colorStringCheck,
|
|
106
|
+
StringComparison.OrdinalIgnoreCase
|
|
107
|
+
)
|
|
108
|
+
? format.Substring(colorStringCheck.Length)
|
|
109
|
+
: format;
|
|
110
|
+
|
|
111
|
+
string hexCode = ColorNamesToHex.GetValueOrDefault(
|
|
112
|
+
format.StartsWith(colorCharCheck) ? format.Substring(1) : baseColor,
|
|
113
|
+
baseColor
|
|
114
|
+
);
|
|
115
|
+
return $"<color={hexCode}>{value}</color>";
|
|
116
|
+
},
|
|
117
|
+
tag: "Color",
|
|
118
|
+
editorOnly: true,
|
|
119
|
+
force: true
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const string sizeCheck = "size=";
|
|
123
|
+
AddDecoration(
|
|
124
|
+
format =>
|
|
125
|
+
(
|
|
126
|
+
format.StartsWith(sizeCheck, StringComparison.OrdinalIgnoreCase)
|
|
127
|
+
&& int.TryParse(format.Substring(sizeCheck.Length), out _)
|
|
128
|
+
|| int.TryParse(format, out _)
|
|
129
|
+
),
|
|
130
|
+
format: (format, value) =>
|
|
131
|
+
{
|
|
132
|
+
if (!int.TryParse(format, out int size))
|
|
133
|
+
{
|
|
134
|
+
size = int.Parse(format.Substring(sizeCheck.Length));
|
|
135
|
+
}
|
|
136
|
+
return $"<size={size}>{value}</size>";
|
|
137
|
+
},
|
|
138
|
+
tag: "Size",
|
|
139
|
+
editorOnly: true,
|
|
140
|
+
force: true
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
[HideInCallstack]
|
|
145
|
+
public object GetFormat(Type formatType)
|
|
146
|
+
{
|
|
147
|
+
return formatType.IsAssignableFrom(typeof(ICustomFormatter)) ? this : null;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
[HideInCallstack]
|
|
151
|
+
public string Format(string format, object arg, IFormatProvider formatProvider)
|
|
152
|
+
{
|
|
153
|
+
if (string.IsNullOrWhiteSpace(format))
|
|
154
|
+
{
|
|
155
|
+
return arg?.ToString() ?? string.Empty;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
_cachedDecorators.Clear();
|
|
159
|
+
if (!format.Contains(Separator))
|
|
160
|
+
{
|
|
161
|
+
_cachedDecorators.Add(format);
|
|
162
|
+
}
|
|
163
|
+
else
|
|
164
|
+
{
|
|
165
|
+
_cachedStringBuilder.Clear();
|
|
166
|
+
foreach (char element in format)
|
|
167
|
+
{
|
|
168
|
+
if (element == Separator)
|
|
169
|
+
{
|
|
170
|
+
if (0 < _cachedStringBuilder.Length)
|
|
171
|
+
{
|
|
172
|
+
_cachedDecorators.Add(_cachedStringBuilder.ToString());
|
|
173
|
+
_cachedStringBuilder.Clear();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
else
|
|
177
|
+
{
|
|
178
|
+
_cachedStringBuilder.Append(element);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (0 < _cachedStringBuilder.Length)
|
|
182
|
+
{
|
|
183
|
+
_cachedDecorators.Add(_cachedStringBuilder.ToString());
|
|
184
|
+
_cachedStringBuilder.Clear();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
_appliedTags.Clear();
|
|
189
|
+
object formatted = arg;
|
|
190
|
+
foreach (string key in _cachedDecorators)
|
|
191
|
+
{
|
|
192
|
+
foreach (
|
|
193
|
+
List<(
|
|
194
|
+
string tag,
|
|
195
|
+
bool editorOnly,
|
|
196
|
+
Func<string, bool> predicate,
|
|
197
|
+
Func<string, object, string> formatter
|
|
198
|
+
)> matchingDecoration in _matchingDecorations.Values
|
|
199
|
+
)
|
|
200
|
+
{
|
|
201
|
+
foreach (
|
|
202
|
+
(
|
|
203
|
+
string tag,
|
|
204
|
+
bool editorOnly,
|
|
205
|
+
Func<string, bool> predicate,
|
|
206
|
+
Func<string, object, string> matchingFormatter
|
|
207
|
+
) in matchingDecoration
|
|
208
|
+
)
|
|
209
|
+
{
|
|
210
|
+
if (
|
|
211
|
+
(Application.isEditor || !editorOnly)
|
|
212
|
+
&& predicate(key)
|
|
213
|
+
&& _appliedTags.Add(tag)
|
|
214
|
+
)
|
|
215
|
+
{
|
|
216
|
+
formatted = matchingFormatter(key, formatted);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (0 < _appliedTags.Count)
|
|
223
|
+
{
|
|
224
|
+
return formatted.ToString();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (arg is not string && arg is IFormattable formattable)
|
|
228
|
+
{
|
|
229
|
+
return formattable.ToString(format, this);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return arg?.ToString() ?? string.Empty;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
[HideInCallstack]
|
|
236
|
+
public string Log(
|
|
237
|
+
FormattableString message,
|
|
238
|
+
Object context = null,
|
|
239
|
+
Exception e = null,
|
|
240
|
+
bool pretty = true
|
|
241
|
+
)
|
|
242
|
+
{
|
|
243
|
+
string rendered = Render(message, context, e, pretty);
|
|
244
|
+
if (context != null)
|
|
245
|
+
{
|
|
246
|
+
Debug.Log(rendered, context);
|
|
247
|
+
}
|
|
248
|
+
else
|
|
249
|
+
{
|
|
250
|
+
Debug.Log(rendered);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return rendered;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
[HideInCallstack]
|
|
257
|
+
public string LogWarn(
|
|
258
|
+
FormattableString message,
|
|
259
|
+
Object context = null,
|
|
260
|
+
Exception e = null,
|
|
261
|
+
bool pretty = true
|
|
262
|
+
)
|
|
263
|
+
{
|
|
264
|
+
string rendered = Render(message, context, e, pretty);
|
|
265
|
+
if (context != null)
|
|
266
|
+
{
|
|
267
|
+
Debug.LogWarning(rendered, context);
|
|
268
|
+
}
|
|
269
|
+
else
|
|
270
|
+
{
|
|
271
|
+
Debug.LogWarning(rendered);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return rendered;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
[HideInCallstack]
|
|
278
|
+
public string LogError(
|
|
279
|
+
FormattableString message,
|
|
280
|
+
Object context = null,
|
|
281
|
+
Exception e = null,
|
|
282
|
+
bool pretty = true
|
|
283
|
+
)
|
|
284
|
+
{
|
|
285
|
+
string rendered = Render(message, context, e, pretty);
|
|
286
|
+
if (context != null)
|
|
287
|
+
{
|
|
288
|
+
Debug.LogError(rendered, context);
|
|
289
|
+
}
|
|
290
|
+
else
|
|
291
|
+
{
|
|
292
|
+
Debug.LogError(rendered);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return rendered;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/// <summary>
|
|
299
|
+
/// Attempts to add a decoration.
|
|
300
|
+
/// </summary>
|
|
301
|
+
/// <param name="match">An exact match for tag ("a" would correspond to ${value:a})</param>
|
|
302
|
+
/// <param name="format">A formatter to apply to the matched object (typically something like value => $"<newFormat>{value}</newFormat>"){</param>
|
|
303
|
+
/// <param name="tag">A descriptive, unique identifier for the decoration (for example, "Bold", or "Color")</param>
|
|
304
|
+
/// <param name="priority">The priority to register the decoration at. Lower values will be evaluated first.</param>
|
|
305
|
+
/// <param name="editorOnly">If true, will only be applied when the game is running in the Unity Editor.</param>
|
|
306
|
+
/// <param name="force">
|
|
307
|
+
/// If true, will override any existing decorations for the same tag, regardless of priority.
|
|
308
|
+
/// If false, decorations with the same tag (compared OrdinalIgnoreCase) will cause the registration to fail.
|
|
309
|
+
/// </param>
|
|
310
|
+
/// <returns>True if the decoration was added, false if the decoration was not added.</returns>
|
|
311
|
+
public bool AddDecoration(
|
|
312
|
+
string match,
|
|
313
|
+
Func<object, string> format,
|
|
314
|
+
string tag = null,
|
|
315
|
+
int priority = 0,
|
|
316
|
+
bool editorOnly = false,
|
|
317
|
+
bool force = false
|
|
318
|
+
)
|
|
319
|
+
{
|
|
320
|
+
return AddDecoration(
|
|
321
|
+
check => string.Equals(check, match, StringComparison.OrdinalIgnoreCase),
|
|
322
|
+
format: (_, value) => format(value),
|
|
323
|
+
tag: tag ?? match,
|
|
324
|
+
priority: priority,
|
|
325
|
+
editorOnly: editorOnly,
|
|
326
|
+
force: force
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/// <summary>
|
|
331
|
+
/// Attempts to add a decoration.
|
|
332
|
+
/// </summary>
|
|
333
|
+
/// <param name="predicate">
|
|
334
|
+
/// Tag matcher. Can be as complex as you want. For example, the default color matcher
|
|
335
|
+
/// is implemented something like tag => tag.StartsWith('#') || tag.StartsWith("color=")
|
|
336
|
+
/// </param>
|
|
337
|
+
/// <param name="format">
|
|
338
|
+
/// Custom formatting function. Takes in both the matched tag as well the current object to format. In
|
|
339
|
+
/// the same case of color matching, the implementation needs to be smart enough to handle the case where
|
|
340
|
+
/// the tag is "#red" or "color=red" or "color=#FF0000".
|
|
341
|
+
/// </param>
|
|
342
|
+
/// <param name="tag">A descriptive, unique identifier for the decoration (for example, "Bold", or "Color")</param>
|
|
343
|
+
/// <param name="priority">The priority to register the decoration at. Lower values will be evaluated first.</param>
|
|
344
|
+
/// <param name="editorOnly">If true, will only be applied when the game is running in the Unity Editor.</param>
|
|
345
|
+
/// <param name="force">
|
|
346
|
+
/// If true, will override any existing decorations for the same tag, regardless of priority.
|
|
347
|
+
/// If false, decorations with the same tag (compared OrdinalIgnoreCase) will cause the registration to fail.
|
|
348
|
+
/// </param>
|
|
349
|
+
/// <returns>True if the decoration was added, false if the decoration was not added.</returns>
|
|
350
|
+
|
|
351
|
+
public bool AddDecoration(
|
|
352
|
+
Func<string, bool> predicate,
|
|
353
|
+
Func<string, object, string> format,
|
|
354
|
+
string tag,
|
|
355
|
+
int priority = 0,
|
|
356
|
+
bool editorOnly = false,
|
|
357
|
+
bool force = false
|
|
358
|
+
)
|
|
359
|
+
{
|
|
360
|
+
foreach (var entry in _matchingDecorations)
|
|
361
|
+
{
|
|
362
|
+
for (int i = 0; i < entry.Value.Count; i++)
|
|
363
|
+
{
|
|
364
|
+
var existingDecoration = entry.Value[i];
|
|
365
|
+
if (
|
|
366
|
+
!string.Equals(
|
|
367
|
+
existingDecoration.tag,
|
|
368
|
+
tag,
|
|
369
|
+
StringComparison.OrdinalIgnoreCase
|
|
370
|
+
)
|
|
371
|
+
)
|
|
372
|
+
{
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (force)
|
|
377
|
+
{
|
|
378
|
+
if (priority != entry.Key)
|
|
379
|
+
{
|
|
380
|
+
entry.Value.RemoveAt(i);
|
|
381
|
+
break;
|
|
382
|
+
}
|
|
383
|
+
entry.Value[i] = (tag, editorOnly, predicate, format);
|
|
384
|
+
return true;
|
|
385
|
+
}
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
if (
|
|
391
|
+
!_matchingDecorations.TryGetValue(
|
|
392
|
+
priority,
|
|
393
|
+
out List<(
|
|
394
|
+
string tag,
|
|
395
|
+
bool editorOnly,
|
|
396
|
+
Func<string, bool> predicate,
|
|
397
|
+
Func<string, object, string> formatter
|
|
398
|
+
)> matchingDecorations
|
|
399
|
+
)
|
|
400
|
+
)
|
|
401
|
+
{
|
|
402
|
+
_matchingDecorations[priority] = new List<(
|
|
403
|
+
string tag,
|
|
404
|
+
bool editorOnly,
|
|
405
|
+
Func<string, bool> predicate,
|
|
406
|
+
Func<string, object, string> formatter
|
|
407
|
+
)>
|
|
408
|
+
{
|
|
409
|
+
(tag, editorOnly, predicate, format),
|
|
410
|
+
};
|
|
411
|
+
return true;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
matchingDecorations.Add((tag, editorOnly, predicate, format));
|
|
415
|
+
return true;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/// <summary>
|
|
419
|
+
/// Attempts to remove a decoration by its tag.
|
|
420
|
+
/// </summary>
|
|
421
|
+
/// <param name="tag">Tag for the decoration ("Bold", "Color", etc.)</param>
|
|
422
|
+
/// <param name="decoration">The removed decoration, if one was found.</param>
|
|
423
|
+
/// <returns>True if a decoration was found for that tag and removed, false otherwise.</returns>
|
|
424
|
+
public bool RemoveDecoration(
|
|
425
|
+
string tag,
|
|
426
|
+
out (
|
|
427
|
+
string tag,
|
|
428
|
+
bool editorOnly,
|
|
429
|
+
Func<string, bool> predicate,
|
|
430
|
+
Func<string, object, string> formatter
|
|
431
|
+
) decoration
|
|
432
|
+
)
|
|
433
|
+
{
|
|
434
|
+
foreach (var entry in _matchingDecorations)
|
|
435
|
+
{
|
|
436
|
+
for (int i = 0; i < entry.Value.Count; ++i)
|
|
437
|
+
{
|
|
438
|
+
decoration = entry.Value[i];
|
|
439
|
+
if (string.Equals(tag, decoration.tag, StringComparison.OrdinalIgnoreCase))
|
|
440
|
+
{
|
|
441
|
+
entry.Value.RemoveAt(i);
|
|
442
|
+
if (entry.Value.Count == 0)
|
|
443
|
+
{
|
|
444
|
+
_matchingDecorations.Remove(entry.Key);
|
|
445
|
+
}
|
|
446
|
+
return true;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
decoration = default;
|
|
452
|
+
return false;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
[HideInCallstack]
|
|
456
|
+
private string Render(
|
|
457
|
+
FormattableString message,
|
|
458
|
+
Object unityObject,
|
|
459
|
+
Exception e,
|
|
460
|
+
bool pretty
|
|
461
|
+
)
|
|
462
|
+
{
|
|
463
|
+
if (!pretty)
|
|
464
|
+
{
|
|
465
|
+
return e != null
|
|
466
|
+
? $"{message.ToString(this)}{NewLine} {e}"
|
|
467
|
+
: message.ToString(this);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
float now = Time.time;
|
|
471
|
+
string componentType;
|
|
472
|
+
string gameObjectName;
|
|
473
|
+
if (unityObject != null)
|
|
474
|
+
{
|
|
475
|
+
componentType = unityObject.GetType().Name;
|
|
476
|
+
gameObjectName = unityObject.name;
|
|
477
|
+
}
|
|
478
|
+
else
|
|
479
|
+
{
|
|
480
|
+
componentType = "NO_TYPE";
|
|
481
|
+
gameObjectName = "NO_NAME";
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
return e != null
|
|
485
|
+
? $"{now}|{gameObjectName}[{componentType}]|{message.ToString(this)}{NewLine} {e}"
|
|
486
|
+
: $"{now}|{gameObjectName}[{componentType}]|{message.ToString(this)}";
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
{
|
|
31
31
|
if (log)
|
|
32
32
|
{
|
|
33
|
-
component.LogWarn("Could not find {
|
|
33
|
+
component.LogWarn($"Could not find {tag}.");
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
return default;
|
|
@@ -45,11 +45,7 @@
|
|
|
45
45
|
if (log)
|
|
46
46
|
{
|
|
47
47
|
component.LogWarn(
|
|
48
|
-
"Failed to find {
|
|
49
|
-
typeof(T).Name,
|
|
50
|
-
tag,
|
|
51
|
-
gameObject.name,
|
|
52
|
-
gameObject.GetInstanceID()
|
|
48
|
+
$"Failed to find {typeof(T).Name} on {tag} (name: {gameObject.name}), id [{gameObject.GetInstanceID()}]."
|
|
53
49
|
);
|
|
54
50
|
}
|
|
55
51
|
|