├── .gitattributes
├── .gitignore
├── Assets
└── Trisibo
│ └── Delayed asset
│ ├── DelayedAsset.cs
│ ├── DelayedAssetProxy.cs
│ ├── DelayedAssetTypeAttribute.cs
│ ├── Editor
│ ├── DelayedAssetDrawer.cs
│ └── DelayedAssetProxyEditor.cs
│ ├── LICENSE.txt
│ └── Readme.txt
├── Delayed asset.unitypackage
├── LICENSE
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Visual Studio 2015 cache/options directory
2 | /.vs/
3 |
4 | # Autogenerated VS/MD solution and project files
5 | /*.csproj
6 | /*.unityproj
7 | /*.sln
8 | /*.suo
9 | /*.tmp
10 | /*.user
11 | /*.userprefs
12 | /*.pidb
13 | /*.booproj
14 | /*.svd
15 |
16 | # OS generated
17 | *.DS_[Ss]tore
18 | *.DS_[Ss]tore?
19 | *.Spotlight-V100
20 | *.[Tt]rashes
21 | [Ee]hthumbs.db
22 | [Tt]humbs.db
23 | *.pidb.meta
24 | [Tt]humbs.db.meta
25 | sysinfo.txt
26 |
27 | # Usually unneeded Unity stuff
28 | /[Ll]ibrary/
29 | /[Tt]emp/
30 | /[Oo]bj/
31 | /[Ee]xported[Oo]bj/
32 |
33 | # Unity stuff not needed for this repository
34 | /ProjectSettings/
35 | *.meta
36 | /[Aa]ssets/[Tt]est/
37 | /UnityPackageManager
38 | /Logs/
39 | /Packages/
40 |
41 | # Test builds
42 | /Builds/
43 |
--------------------------------------------------------------------------------
/Assets/Trisibo/Delayed asset/DelayedAsset.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (C) 2017 Trinidad Sibajas Bodoque
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | using UnityEngine;
23 | using System;
24 | #if UNITY_EDITOR
25 | using UnityEditor;
26 | #endif
27 |
28 | namespace Trisibo
29 | {
30 | ///
31 | /// Use on a serialized field of another MonoBehaviour object to allow loading an asset on demand,
32 | /// instead of when the container object is loaded.
33 | ///
34 |
35 | [Serializable]
36 | public class DelayedAsset
37 | #if UNITY_EDITOR
38 | : ISerializationCallbackReceiver
39 | #endif
40 | {
41 | #region Serialized data
42 |
43 |
44 | // The asset, only available on the editor to be able to set it from the inspector:
45 | #if UNITY_EDITOR
46 | [SerializeField, HideInInspector] UnityEngine.Object asset = null;
47 | #endif
48 |
49 |
50 | // The data needed to load the asset:
51 | [SerializeField, HideInInspector] string assetRelativePath = null;
52 | [SerializeField, HideInInspector] string assetTypeString = null;
53 |
54 |
55 | #endregion
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | #region Overloaded operators
65 |
66 |
67 | ///
68 | /// "==" operator.
69 | ///
70 |
71 | public static bool operator ==(DelayedAsset a, DelayedAsset b)
72 | {
73 | if (ReferenceEquals(a, null))
74 | return ReferenceEquals(b, null) || string.IsNullOrEmpty(b.assetRelativePath);
75 |
76 | if (ReferenceEquals(b, null))
77 | return ReferenceEquals(a, null) || string.IsNullOrEmpty(a.assetRelativePath);
78 |
79 | if (a.Equals(b))
80 | return true;
81 |
82 | if (string.IsNullOrEmpty(a.assetRelativePath))
83 | return string.IsNullOrEmpty(b.assetRelativePath);
84 |
85 | return a.assetRelativePath.Equals(b.assetRelativePath, StringComparison.InvariantCulture) && a.AssetType == b.AssetType;
86 | }
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | ///
96 | /// "!=" operator.
97 | ///
98 |
99 | public static bool operator !=(DelayedAsset a, DelayedAsset b)
100 | {
101 | return !(a == b);
102 | }
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | ///
112 | /// Inplicit bool operator.
113 | ///
114 |
115 | public static implicit operator bool(DelayedAsset a)
116 | {
117 | return !(a == null);
118 | }
119 |
120 |
121 | #endregion
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 | #region Object methods overrides
131 |
132 |
133 | ///
134 | /// Implementation of .
135 | ///
136 |
137 | public override bool Equals(object obj)
138 | {
139 | return base.Equals(obj);
140 | }
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 | ///
150 | /// Implementation of .
151 | ///
152 |
153 | public override int GetHashCode()
154 | {
155 | return base.GetHashCode();
156 | }
157 |
158 |
159 | #endregion
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 | #region Runtime data
169 |
170 |
171 | // The asset type:
172 | Type _assetType;
173 | Type AssetType
174 | {
175 | get { return _assetType ?? (_assetType = string.IsNullOrEmpty(assetTypeString) ? null : Type.GetType(assetTypeString)); }
176 | }
177 |
178 |
179 | // The asset once loaded at runtime:
180 | UnityEngine.Object _loadedAsset;
181 |
182 | UnityEngine.Object LoadedAsset
183 | {
184 | get
185 | {
186 | if (_loadedAsset == null && asyncLoadedAssetGetter != null)
187 | _loadedAsset = asyncLoadedAssetGetter();
188 | return _loadedAsset;
189 | }
190 |
191 | set
192 | {
193 | _loadedAsset = value;
194 | }
195 | }
196 |
197 |
198 | // The async load request, if any:
199 | AsyncLoadRequest asyncLoadRequest;
200 | Func asyncLoadedAssetGetter;
201 |
202 |
203 | #endregion
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 | #region Data types
213 |
214 |
215 | ///
216 | /// Represents an async request to load the original asset.
217 | /// Behaves in a similar way to Unity's .
218 | ///
219 |
220 | public class AsyncLoadRequest : CustomYieldInstruction
221 | {
222 | // The original resource request. Can be null if no resource request was done:
223 | readonly ResourceRequest resourceRequest;
224 |
225 |
226 | // The already loaded asset if there was no resource request, null otherwise:
227 | readonly UnityEngine.Object assetIfNoResourceRequest;
228 |
229 |
230 |
231 |
232 | ///
233 | /// Constructor.
234 | ///
235 | /// The resource request used to load the asset. Cannot be null; if no resource request was done, use the constructor that accepts an already loaded asset.
236 | /// Receives a method that returns the loaded asset (not the original asset).
237 |
238 | public AsyncLoadRequest(ResourceRequest resourceRequest, out Func actualLoadedAssetGetter)
239 | {
240 | this.resourceRequest = resourceRequest;
241 | actualLoadedAssetGetter = GetActualLoadedAsset;
242 | }
243 |
244 |
245 |
246 |
247 | ///
248 | /// Constructor.
249 | ///
250 | /// This must contain an already loaded asset. Use this constructor only if there was no resource request done.
251 | /// Receives a method that returns the loaded asset (not the original asset).
252 |
253 | public AsyncLoadRequest(UnityEngine.Object alreadyLoadedAsset, out Func actualLoadedAssetGetter)
254 | {
255 | assetIfNoResourceRequest = alreadyLoadedAsset;
256 | actualLoadedAssetGetter = GetActualLoadedAsset;
257 | }
258 |
259 |
260 |
261 |
262 | ///
263 | /// Has the asset loading finished?
264 | /// See documentation for more details.
265 | ///
266 |
267 | public bool IsDone
268 | {
269 | get
270 | {
271 | return resourceRequest != null ? resourceRequest.isDone : true;
272 | }
273 | }
274 |
275 |
276 |
277 |
278 | ///
279 | /// Allows tweaking the order in which async operations will be performed.
280 | /// See documentation for more details.
281 | /// If no actual loading was necessary, assigning a value will have no effect, and will always return -1.
282 | ///
283 |
284 | public int Priority
285 | {
286 | get
287 | {
288 | return resourceRequest != null ? resourceRequest.priority : -1;
289 | }
290 |
291 | set
292 | {
293 | if (resourceRequest != null)
294 | resourceRequest.priority = value;
295 | }
296 | }
297 |
298 |
299 |
300 |
301 | ///
302 | /// The progress of the operation.
303 | /// See documentation for more details.
304 | ///
305 |
306 | public float Progress
307 | {
308 | get
309 | {
310 | return resourceRequest != null ? resourceRequest.progress : 1;
311 | }
312 | }
313 |
314 |
315 |
316 |
317 | ///
318 | /// Asset object being loaded.
319 | /// See documentation for more details. The difference is that trying to get the value before is true won't stall the loading process, but will cause an .
320 | ///
321 | /// Thrown if is false when trying to access the asset.
322 |
323 | public UnityEngine.Object Asset
324 | {
325 | get
326 | {
327 | if (!IsDone)
328 | throw new InvalidOperationException("Tried to access the asset when IsDone was false");
329 |
330 | return GetOriginalAsset(GetActualLoadedAsset());
331 | }
332 | }
333 |
334 |
335 |
336 |
337 | ///
338 | /// implementation.
339 | ///
340 |
341 | public override bool keepWaiting
342 | {
343 | get
344 | {
345 | return !IsDone;
346 | }
347 | }
348 |
349 |
350 |
351 |
352 | ///
353 | /// Returns the loaded asset (which will be different to the original asset in case the loaded asset is a ).
354 | /// Will return null if is false.
355 | ///
356 | /// The loaded asset.
357 |
358 | UnityEngine.Object GetActualLoadedAsset()
359 | {
360 | if (IsDone)
361 | return resourceRequest != null ? resourceRequest.asset : assetIfNoResourceRequest;
362 | else
363 | return null;
364 | }
365 | }
366 |
367 |
368 | #endregion
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 | #region Asset loading methods
378 |
379 |
380 | ///
381 | /// Loads the original asset. Does not attempt to load it again if it was already loaded.
382 | /// To unload it do not use , use instead.
383 | ///
384 | /// The loaded asset, or null if it wasn't found or hadn't been assigned.
385 |
386 | public UnityEngine.Object Load()
387 | {
388 | #if UNITY_EDITOR
389 | {
390 | UpdateRuntimeSerializedData();
391 | }
392 | #endif
393 |
394 |
395 | if (LoadedAsset == null && !string.IsNullOrEmpty(assetRelativePath))
396 | {
397 | LoadedAsset = Resources.Load(assetRelativePath, AssetType);
398 | }
399 |
400 | return GetOriginalAsset(LoadedAsset);
401 | }
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 | ///
411 | /// Asynchronously loads the original asset. Does not attempt to load it again if it was already loaded.
412 | /// To unload it do not use , use instead.
413 | ///
414 | /// An object, from which the asset can be retrieved once the operation is completed. Will be null if the original asset couldn't be found, or hadn't been assigned.
415 |
416 | public AsyncLoadRequest LoadAsync()
417 | {
418 | #if UNITY_EDITOR
419 | {
420 | UpdateRuntimeSerializedData();
421 | }
422 | #endif
423 |
424 |
425 | if (asyncLoadRequest == null)
426 | {
427 | if (LoadedAsset != null)
428 | {
429 | asyncLoadRequest = new AsyncLoadRequest(LoadedAsset, out asyncLoadedAssetGetter);
430 | }
431 | else if (!string.IsNullOrEmpty(assetRelativePath))
432 | {
433 | ResourceRequest resourceRequest = Resources.LoadAsync(assetRelativePath, AssetType);
434 | asyncLoadRequest = new AsyncLoadRequest(resourceRequest, out asyncLoadedAssetGetter);
435 | }
436 | }
437 |
438 | return asyncLoadRequest;
439 | }
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 | ///
449 | /// Returns the original asset from the specified loaded asset, checking if the loaded asset is a instance.
450 | ///
451 | /// The loaded asset.
452 | /// The original asset.
453 |
454 | static UnityEngine.Object GetOriginalAsset(UnityEngine.Object loadedAsset)
455 | {
456 | return (loadedAsset is DelayedAssetProxy) ? ((DelayedAssetProxy)loadedAsset).Asset : loadedAsset;
457 | }
458 |
459 |
460 | #endregion
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 | #region Asset unloading methods
470 |
471 |
472 | ///
473 | /// Unloads the original asset if it's currently loaded.
474 | /// Must not be called if there's an unfinished operation (generated from a previous call to ).
475 | ///
476 | /// If the original asset is of a type that cannot be directly unloaded by Unity (, , or ), force a call to instead. Use it with care, since it may be slow.
477 | /// Thrown if there's an unfinished operation when this method is called.
478 |
479 | public void Unload(bool forceUnloadAllUnusedAssetsIfAssetNotUnloadable = false)
480 | {
481 | if (asyncLoadRequest != null && !asyncLoadRequest.IsDone)
482 | throw new InvalidOperationException("Called DelayedAsset.Unload() when there was an AsyncLoadRequest operation in progress");
483 |
484 |
485 | if (LoadedAsset != null)
486 | {
487 | // If the original asset is inside a proxy, unload it. Only if not in the editor, since otherwise it won't allow to load the asset again:
488 | #if !UNITY_EDITOR
489 | {
490 | var originalAsset = GetOriginalAsset(LoadedAsset);
491 | if (originalAsset != null && originalAsset != LoadedAsset)
492 | {
493 | if (CanBeDirectlyUnloaded(originalAsset))
494 | {
495 | Resources.UnloadAsset(originalAsset);
496 | }
497 | else if (forceUnloadAllUnusedAssetsIfAssetNotUnloadable)
498 | {
499 | originalAsset = null;
500 | Resources.UnloadUnusedAssets();
501 | }
502 | }
503 | }
504 | #endif
505 |
506 |
507 | // Unload the loaded asset:
508 | if (CanBeDirectlyUnloaded(LoadedAsset))
509 | {
510 | Resources.UnloadAsset(LoadedAsset);
511 | }
512 | else if (forceUnloadAllUnusedAssetsIfAssetNotUnloadable)
513 | {
514 | LoadedAsset = null;
515 | Resources.UnloadUnusedAssets();
516 | }
517 | }
518 |
519 | LoadedAsset = null;
520 | asyncLoadRequest = null;
521 | asyncLoadedAssetGetter = null;
522 | }
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 | ///
532 | /// Checks whether the specified asset can be directly unloaded with .
533 | /// Some assets can't (, , and ).
534 | ///
535 | /// The asset to check.
536 | /// Whether the specified asset can be directly unloaded with .
537 |
538 | static bool CanBeDirectlyUnloaded(UnityEngine.Object asset)
539 | {
540 | Type assetType = asset.GetType();
541 | return !typeof(Component).IsAssignableFrom(assetType) && !typeof(GameObject).IsAssignableFrom(assetType) && !typeof(AssetBundle).IsAssignableFrom(assetType);
542 | }
543 |
544 |
545 | #endregion
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 | #region ISerializationCallbackReceiver implementation
555 | #if UNITY_EDITOR
556 |
557 |
558 | ///
559 | /// implementation.
560 | ///
561 |
562 | void ISerializationCallbackReceiver.OnBeforeSerialize()
563 | {
564 | UpdateRuntimeSerializedData();
565 | }
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 | ///
575 | /// implementation.
576 | ///
577 |
578 | void ISerializationCallbackReceiver.OnAfterDeserialize()
579 | {
580 | LoadedAsset = null;
581 | _assetType = null;
582 | asyncLoadRequest = null;
583 | asyncLoadedAssetGetter = null;
584 | }
585 |
586 |
587 | #endif
588 | #endregion
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 | #region Editor members
598 | #if UNITY_EDITOR
599 |
600 |
601 | ///
602 | /// Only in the editor.
603 | /// The original asset object.
604 | ///
605 |
606 | public UnityEngine.Object Editor_OriginalAsset
607 | {
608 | get
609 | {
610 | return asset;
611 | }
612 | }
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 | ///
622 | /// Only in editor.
623 | /// Updates the serialized data used at runtime, using the current assigned asset.
624 | ///
625 |
626 | void UpdateRuntimeSerializedData()
627 | {
628 | assetRelativePath = null;
629 | assetTypeString = null;
630 |
631 | if ((object)asset != null && asset.GetInstanceID() != 0) //-> We cast to object because in some situations the asset instance may be some kind of "special" one that Unity considers null.
632 | {
633 | string assetAbsolutePath = AssetDatabase.GetAssetPath(asset.GetInstanceID());
634 | assetRelativePath = GetResourcesRelativeAssetPath(assetAbsolutePath);
635 |
636 | string error = CheckForErrors(asset, assetRelativePath);
637 | if (error != null)
638 | {
639 | assetRelativePath = null;
640 | assetTypeString = null;
641 | Debug.LogError("Delayed asset error: " + error);
642 | }
643 | else
644 | {
645 | assetTypeString = asset.GetType().AssemblyQualifiedName;
646 | }
647 | }
648 | }
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 | ///
658 | /// Only in the editor.
659 | /// Retrieves the asset path relative to a resources folder.
660 | ///
661 | /// The absolute path of the asset.
662 | /// The path relative to a resources folder, null if the asset is not inside a resources folder, either directly or inside a subfolder in the hierarchy.
663 |
664 | public static string GetResourcesRelativeAssetPath(string assetAbsolutePath)
665 | {
666 | const string resourcesPathString = "/Resources/";
667 |
668 | int resourcesStringIndex = assetAbsolutePath.IndexOf(resourcesPathString);
669 | if (resourcesStringIndex == -1)
670 | {
671 | return null;
672 | }
673 |
674 | int start = resourcesStringIndex + resourcesPathString.Length;
675 | int dot = assetAbsolutePath.LastIndexOf('.');
676 | return assetAbsolutePath.Substring(start, (dot >= 0 ? dot : assetAbsolutePath.Length) - start);
677 | }
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 | ///
687 | /// Only in the editor.
688 | /// Searches for any asset with the same path relative to a resources folder and the same type as the supplied asset.
689 | ///
690 | /// The asset.
691 | /// The path relative to a resources folder.
692 | /// One of the assets found, null if none.
693 |
694 | public static UnityEngine.Object FindAssetWithSameTypeAndRelativePath(UnityEngine.Object asset, string resourcesRelativePath)
695 | {
696 | int assetId = asset.GetInstanceID();
697 |
698 | UnityEngine.Object[] allAssets = Resources.LoadAll(resourcesRelativePath, asset.GetType());
699 | for (int i = 0; i < allAssets.Length; i++)
700 | {
701 | if (allAssets[i].GetInstanceID() != assetId)
702 | return allAssets[i];
703 | }
704 |
705 | return null;
706 | }
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 | ///
716 | /// Only in the editor.
717 | /// Checks for errors in an assigned asset.
718 | ///
719 | /// The asset.
720 | /// The path relative to a resources folder, if any.
721 | /// The error text for the first error found, null if there were no errors.
722 |
723 |
724 | public static string CheckForErrors(UnityEngine.Object asset, string resourcesRelativePath)
725 | {
726 | string error = null;
727 |
728 | if (string.IsNullOrEmpty(resourcesRelativePath))
729 | {
730 | error = "The asset \"" + AssetDatabase.GetAssetPath(asset.GetInstanceID()) + "\" is not inside a \"Resources\" folder.";
731 | }
732 | else
733 | {
734 | UnityEngine.Object otherAsset = FindAssetWithSameTypeAndRelativePath(asset, resourcesRelativePath);
735 | if (otherAsset != null)
736 | {
737 | error = "The asset \"" + AssetDatabase.GetAssetPath(asset.GetInstanceID()) + "\" doesn't have a unique type and path relative to a \"Resources\" folder, this other asset has the same ones: \"" + AssetDatabase.GetAssetPath(otherAsset) + "\".";
738 | }
739 | }
740 |
741 | return error;
742 | }
743 |
744 |
745 | #endif
746 | #endregion
747 | }
748 | }
749 |
--------------------------------------------------------------------------------
/Assets/Trisibo/Delayed asset/DelayedAssetProxy.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (C) 2017 Trinidad Sibajas Bodoque
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | using UnityEngine;
23 |
24 | namespace Trisibo
25 | {
26 | ///
27 | /// Makes it possible to use assets from any folder on a ,
28 | /// assigning the original asset to the , which must be inside a "Resources" folder.
29 | ///
30 |
31 | [CreateAssetMenu(menuName = "Trisibo/Delayed Asset/Delayed Asset Proxy")]
32 | public class DelayedAssetProxy : ScriptableObject
33 | {
34 | // The original asset, which can be inside any folder:
35 | [SerializeField, HideInInspector] UnityEngine.Object asset = null;
36 |
37 |
38 | /// The original asset.
39 | public UnityEngine.Object Asset
40 | {
41 | get { return asset; }
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Assets/Trisibo/Delayed asset/DelayedAssetTypeAttribute.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (C) 2017 Trinidad Sibajas Bodoque
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | using UnityEngine;
23 | using System;
24 |
25 | namespace Trisibo
26 | {
27 | ///
28 | /// Allows to specify the wrapped type for a .
29 | ///
30 |
31 | [AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
32 | public sealed class DelayedAssetTypeAttribute : PropertyAttribute
33 | {
34 | public readonly Type Type;
35 |
36 | public DelayedAssetTypeAttribute(Type type)
37 | {
38 | if (!typeof(UnityEngine.Object).IsAssignableFrom(type))
39 | throw new ArgumentException("The type argument for a DelayedAssetTypeAttribute must be derived from Unity.Object");
40 |
41 | this.Type = type;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Assets/Trisibo/Delayed asset/Editor/DelayedAssetDrawer.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (C) 2017 Trinidad Sibajas Bodoque
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | using UnityEngine;
23 | using UnityEditor;
24 | using System;
25 |
26 | namespace Trisibo
27 | {
28 | [CustomPropertyDrawer(typeof(DelayedAsset))]
29 | public class DelayedAssetDrawer : PropertyDrawer
30 | {
31 | bool isDraggingValidProxy;
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | ///
41 | /// implementation.
42 | ///
43 |
44 | public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
45 | {
46 | // Check if the field has a type attribute, and get the type:
47 | DelayedAssetTypeAttribute typeAttribute = (DelayedAssetTypeAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(DelayedAssetTypeAttribute));
48 | Type desiredType = typeAttribute != null ? typeAttribute.Type : typeof(UnityEngine.Object);
49 |
50 |
51 | // If a DelayedAssetProxy is being dragged into the slot, and the type of the referenced asset matches the desired type, allow to set it:
52 | if (Event.current.type == EventType.DragUpdated)
53 | {
54 | UnityEngine.Object draggedObject = DragAndDrop.objectReferences.Length == 0 ? null : DragAndDrop.objectReferences[0];
55 | isDraggingValidProxy = draggedObject is DelayedAssetProxy && ((DelayedAssetProxy)draggedObject).Asset != null && desiredType.IsAssignableFrom(((DelayedAssetProxy)draggedObject).Asset.GetType()) && position.Contains(Event.current.mousePosition);
56 | }
57 | else if (Event.current.type == EventType.DragExited)
58 | {
59 | isDraggingValidProxy = false;
60 | }
61 |
62 |
63 | if (isDraggingValidProxy)
64 | desiredType = typeof(DelayedAssetProxy);
65 |
66 |
67 | // Begin the property:
68 | EditorGUI.BeginProperty(position, label, property);
69 | EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
70 |
71 |
72 | // Draw the property:
73 | SerializedProperty assetProperty = property.FindPropertyRelative("asset");
74 | label.text = GetFormattedLabel(label.text);
75 |
76 | EditorGUI.BeginChangeCheck();
77 | EditorGUI.showMixedValue = property.hasMultipleDifferentValues;
78 | UnityEngine.Object newAsset = EditorGUI.ObjectField(position, label, assetProperty.objectReferenceValue, desiredType, false);
79 | EditorGUI.showMixedValue = false;
80 |
81 | bool hasChanged = EditorGUI.EndChangeCheck();
82 | if (hasChanged)
83 | assetProperty.objectReferenceValue = newAsset;
84 |
85 |
86 | // If an object has been assigned, check if there is some problem with it:
87 | if (hasChanged && newAsset != null)
88 | {
89 | string error = DelayedAsset.CheckForErrors(newAsset, DelayedAsset.GetResourcesRelativeAssetPath(AssetDatabase.GetAssetPath(newAsset)));
90 | if (error != null)
91 | {
92 | assetProperty.objectReferenceValue = null;
93 | EditorUtility.DisplayDialog("Delayed asset error", error, "OK");
94 | Debug.LogError("Delayed asset error: " + error);
95 | }
96 | }
97 |
98 |
99 | // End of the property:
100 | EditorGUI.EndDisabledGroup();
101 | EditorGUI.EndProperty();
102 | }
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | ///
112 | /// Gets a formatted label for the field.
113 | ///
114 | /// The original label.
115 | /// The formatted label.
116 |
117 | static string GetFormattedLabel(string originalLabel)
118 | {
119 | return "{" + originalLabel + "}";
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/Assets/Trisibo/Delayed asset/Editor/DelayedAssetProxyEditor.cs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (C) 2017 Trinidad Sibajas Bodoque
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | using UnityEditor;
23 |
24 | namespace Trisibo
25 | {
26 | [CustomEditor(typeof(DelayedAssetProxy))]
27 | public class DelayedAssetProxyEditor : Editor
28 | {
29 | SerializedProperty assetProp;
30 |
31 |
32 |
33 |
34 | ///
35 | /// Implementation of Editor.OnEnable().
36 | ///
37 |
38 | void OnEnable()
39 | {
40 | if (assetProp == null)
41 | assetProp = serializedObject.FindProperty("asset");
42 | }
43 |
44 |
45 |
46 |
47 | ///
48 | /// Implementation of .
49 | ///
50 |
51 | public override void OnInspectorGUI()
52 | {
53 | serializedObject.Update();
54 |
55 | EditorGUI.BeginDisabledGroup(EditorApplication.isPlayingOrWillChangePlaymode);
56 | EditorGUILayout.PropertyField(assetProp);
57 | EditorGUI.EndDisabledGroup();
58 |
59 | serializedObject.ApplyModifiedProperties();
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Assets/Trisibo/Delayed asset/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (C) 2017 Trinidad Sibajas Bodoque
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/Assets/Trisibo/Delayed asset/Readme.txt:
--------------------------------------------------------------------------------
1 | DEPRECATED: Causes issues with Unity at least from 2019.4
2 | =============================================================
3 |
4 | From Unity 2019.4 (may happen in earlier versions), this plugin can cause important edit-time issues in some situations, so don't use. It may not be updated to fix the issues. Please, use Unity's "Addressable Asset System" instead (https://blogs.unity3d.com/2019/07/15/addressable-asset-system/).
5 |
6 |
7 |
8 | License
9 | -------
10 |
11 | Copyright (C) 2017 Trinidad Sibajas Bodoque
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 |
--------------------------------------------------------------------------------
/Delayed asset.unitypackage:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Trisibo/Unity-delayed-asset/c6bf8bbd730f8b6d7dc4ebbdfb5493e888d02185/Delayed asset.unitypackage
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2017 Trinidad Sibajas Bodoque
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | DEPRECATED: Causes issues with Unity at least from 2019.4
2 | =============================================================
3 |
4 | From Unity 2019.4 (may happen in earlier versions), this plugin can cause important edit-time issues in some situations, so don't use. It may not be updated to fix the issues. Please, use Unity's "Addressable Asset System" instead (https://blogs.unity3d.com/2019/07/15/addressable-asset-system/).
5 |
6 |
7 |
8 | License
9 | -------
10 |
11 | Copyright (C) 2017 Trinidad Sibajas Bodoque
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18 |
--------------------------------------------------------------------------------