diff --git a/Assets/Plugins/DOTween.meta b/Assets/Plugins/DOTween.meta
new file mode 100644
index 0000000..f2d9f57
--- /dev/null
+++ b/Assets/Plugins/DOTween.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: bb76236d4a7e17944ae1e59b77c5b561
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/DOTween.XML b/Assets/Plugins/DOTween/DOTween.XML
new file mode 100644
index 0000000..46e79c4
--- /dev/null
+++ b/Assets/Plugins/DOTween/DOTween.XML
@@ -0,0 +1,3089 @@
+
+
+
+ DOTween
+
+
+
+
+ Types of autoPlay behaviours
+
+
+
+ No tween is automatically played
+
+
+ Only Sequences are automatically played
+
+
+ Only Tweeners are automatically played
+
+
+ All tweens are automatically played
+
+
+
+ What axis to constrain in case of Vector tweens
+
+
+
+ Called the first time the tween is set in a playing state, after any eventual delay
+
+
+
+ Used in place of System.Func, which is not available in mscorlib.
+
+
+
+
+ Used in place of System.Action.
+
+
+
+
+ Public so it can be used by lose scripts related to DOTween (like DOTweenAnimation)
+
+
+
+
+ Used to separate DOTween class from the MonoBehaviour instance (in order to use static constructors on DOTween).
+ Contains all instance-based methods
+
+
+
+ Used internally inside Unity Editor, as a trick to update DOTween's inspector at every frame
+
+
+
+ Directly sets the current max capacity of Tweeners and Sequences
+ (meaning how many Tweeners and Sequences can be running at the same time),
+ so that DOTween doesn't need to automatically increase them in case the max is reached
+ (which might lead to hiccups when that happens).
+ Sequences capacity must be less or equal to Tweeners capacity
+ (if you pass a low Tweener capacity it will be automatically increased to match the Sequence's).
+ Beware: use this method only when there are no tweens running.
+
+ Max Tweeners capacity.
+ Default: 200
+ Max Sequences capacity.
+ Default: 50
+
+
+
+ This class contains a C# port of the easing equations created by Robert Penner (http://robertpenner.com/easing).
+
+
+
+
+ Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in: accelerating from zero velocity.
+
+
+ Current time (in frames or seconds).
+
+
+ Expected easing duration (in frames or seconds).
+
+ Unused: here to keep same delegate for all ease types.
+ Unused: here to keep same delegate for all ease types.
+
+ The eased value.
+
+
+
+
+ Easing equation function for a bounce (exponentially decaying parabolic bounce) easing out: decelerating from zero velocity.
+
+
+ Current time (in frames or seconds).
+
+
+ Expected easing duration (in frames or seconds).
+
+ Unused: here to keep same delegate for all ease types.
+ Unused: here to keep same delegate for all ease types.
+
+ The eased value.
+
+
+
+
+ Easing equation function for a bounce (exponentially decaying parabolic bounce) easing in/out: acceleration until halfway, then deceleration.
+
+
+ Current time (in frames or seconds).
+
+
+ Expected easing duration (in frames or seconds).
+
+ Unused: here to keep same delegate for all ease types.
+ Unused: here to keep same delegate for all ease types.
+
+ The eased value.
+
+
+
+
+ Returns a value between 0 and 1 (inclusive) based on the elapsed time and ease selected
+
+
+
+
+ Returns a value between 0 and 1 (inclusive) based on the elapsed time and ease selected
+
+
+
+
+ Used to interpret AnimationCurves as eases.
+ Public so it can be used by external ease factories
+
+
+
+
+ Behaviour in case a tween nested inside a Sequence fails and is captured by safe mode
+
+
+
+ If the Sequence contains other elements, kill the failed tween but preserve the rest
+
+
+ Kill the whole Sequence
+
+
+
+ Log types thrown by errors captured and prevented by safe mode
+
+
+
+ No logs. NOT RECOMMENDED
+
+
+ Throw a normal log
+
+
+ Throw a warning log (default)
+
+
+ Throw an error log
+
+
+
+ Additional notices passed to plugins when updating.
+ Public so it can be used by custom plugins. Internally, only PathPlugin uses it
+
+
+
+
+ None
+
+
+
+
+ Lets the plugin know that we restarted or rewinded
+
+
+
+
+ OnRewind callback behaviour (can only be set via DOTween's Utility Panel)
+
+
+
+
+ When calling Rewind or PlayBackwards/SmoothRewind, OnRewind callbacks will be fired only if the tween isn't already rewinded
+
+
+
+
+ When calling Rewind, OnRewind callbacks will always be fired, even if the tween is already rewinded.
+ When calling PlayBackwards/SmoothRewind instead, OnRewind callbacks will be fired only if the tween isn't already rewinded
+
+
+
+
+ When calling Rewind or PlayBackwards/SmoothRewind, OnRewind callbacks will always be fired, even if the tween is already rewinded
+
+
+
+
+ Public only so custom shortcuts can access some of these methods
+
+
+
+
+ INTERNAL: used by DO shortcuts and Modules to set special startup mode
+
+
+
+
+ INTERNAL: used by DO shortcuts and Modules to set the tween as blendable
+
+
+
+
+ INTERNAL: used by DO shortcuts and Modules to prevent a tween from using a From setup even if passed
+
+
+
+
+ Used to dispatch commands that need to be captured externally, usually by Modules
+
+
+
+
+ Various utils
+
+
+
+
+ Returns a Vector3 with z = 0
+
+
+
+
+ Returns the 2D angle between two vectors
+
+
+
+
+ Returns a point on a circle with the given center and radius,
+ using Unity's circle coordinates (0° points up and increases clockwise)
+
+
+
+
+ Uses approximate equality on each axis instead of Unity's Vector3 equality,
+ because the latter fails (in some cases) when assigning a Vector3 to a transform.position and then checking it.
+
+
+
+
+ Looks for the type within all possible project assembly names
+
+
+
+ NO-GC METHOD: changes the start value of a tween and rewinds it (without pausing it).
+ Has no effect with tweens that are inside Sequences
+ The new start value
+ If bigger than 0 applies it as the new tween duration
+
+
+ NO-GC METHOD: changes the end value of a tween and rewinds it (without pausing it).
+ Has no effect with tweens that are inside Sequences
+ The new end value
+ If TRUE the start value will become the current target's value, otherwise it will stay the same
+
+
+ NO-GC METHOD: changes the end value of a tween and rewinds it (without pausing it).
+ Has no effect with tweens that are inside Sequences
+ The new end value
+ If bigger than 0 applies it as the new tween duration
+ If TRUE the start value will become the current target's value, otherwise it will stay the same
+
+
+ NO-GC METHOD: changes the start and end value of a tween and rewinds it (without pausing it).
+ Has no effect with tweens that are inside Sequences
+ The new start value
+ The new end value
+ If bigger than 0 applies it as the new tween duration
+
+
+
+ Struct that stores two colors (used for LineRenderer tweens)
+
+
+
+
+ Used for tween callbacks
+
+
+
+
+ Used for tween callbacks
+
+
+
+
+ Used for custom and animationCurve-based ease functions. Must return a value between 0 and 1.
+
+
+
+
+ Straight Quaternion plugin. Instead of using Vector3 values accepts Quaternion values directly.
+ Beware: doesn't work with LoopType.Incremental (neither directly nor if inside a LoopType.Incremental Sequence).
+ To use it, call DOTween.To with the plugin parameter overload, passing it PureQuaternionPlugin.Plug() as first parameter
+ (do not use any of the other public PureQuaternionPlugin methods):
+ DOTween.To(PureQuaternionPlugin.Plug(), ()=> myQuaternionProperty, x=> myQuaternionProperty = x, myQuaternionEndValue, duration);
+
+
+
+
+ Plug this plugin inside a DOTween.To call.
+ Example:
+ DOTween.To(PureQuaternionPlugin.Plug(), ()=> myQuaternionProperty, x=> myQuaternionProperty = x, myQuaternionEndValue, duration);
+
+
+
+ INTERNAL: do not use
+
+
+ INTERNAL: do not use
+
+
+ INTERNAL: do not use
+
+
+ INTERNAL: do not use
+
+
+ INTERNAL: do not use
+
+
+ INTERNAL: do not use
+
+
+ INTERNAL: do not use
+
+
+ INTERNAL: do not use
+
+
+
+ Extra non-tweening-related curve methods
+
+
+
+
+ Cubic bezier curve methods
+
+
+
+
+ Calculates a point along the given Cubic Bezier segment-curve.
+
+ Segment start point
+ Start point's control point/handle
+ Segment end point
+ End point's control point/handle
+ 0-1 percentage along which to retrieve point
+
+
+
+ Returns an array containing a series of points along the given Cubic Bezier segment-curve.
+
+ Start point
+ Start point's control point/handle
+ End point
+ End point's control point/handle
+ Cloud resolution (min: 2)
+
+
+
+ Calculates a series of points along the given Cubic Bezier segment-curve and adds them to the given list.
+
+ Start point
+ Start point's control point/handle
+ End point
+ End point's control point/handle
+ Cloud resolution (min: 2)
+
+
+
+ Main DOTween class. Contains static methods to create and control tweens in a generic way
+
+
+
+ DOTween's version
+
+
+ If TRUE (default) makes tweens slightly slower but safer, automatically taking care of a series of things
+ (like targets becoming null while a tween is playing).
+ Default: TRUE
+
+
+ Log type when safe mode reports capturing an error and preventing it
+
+
+ Behaviour in case a tween nested inside a Sequence fails (and is caught by safe mode).
+ Default: NestedTweenFailureBehaviour.TryToPreserveSequence
+
+
+ If TRUE you will get a DOTween report when exiting play mode (only in the Editor).
+ Useful to know how many max Tweeners and Sequences you reached and optimize your final project accordingly.
+ Beware, this will slightly slow down your tweens while inside Unity Editor.
+ Default: FALSE
+
+
+ Global DOTween global timeScale (default: 1).
+ The final timeScale of a non-timeScaleIndependent tween is:
+ Unity's Time.timeScale * DOTween.timeScale * tween.timeScale
+ while the final timeScale of a timeScaleIndependent tween is:
+ DOTween.unscaledTimeScale * DOTween.timeScale * tween.timeScale
+
+
+ DOTween timeScale applied only to timeScaleIndependent tweens (default: 1).
+ The final timeScale of a timeScaleIndependent tween is:
+ DOTween.unscaledTimeScale * DOTween.timeScale * tween.timeScale
+
+
+ If TRUE, DOTween will use Time.smoothDeltaTime instead of Time.deltaTime for UpdateType.Normal and UpdateType.Late tweens
+ (unless they're set as timeScaleIndependent, in which case a value between the last timestep
+ and will be used instead).
+ Setting this to TRUE will lead to smoother animations.
+ Default: FALSE
+
+
+ If is TRUE, this indicates the max timeStep that an independent update call can last.
+ Setting this to TRUE will lead to smoother animations.
+ Default: FALSE
+
+
+ DOTween's log behaviour.
+ Default: LogBehaviour.ErrorsOnly
+
+
+ Used to intercept DOTween's logs. If this method isn't NULL, DOTween will call it before writing a log via Unity's own Debug log methods.
+ Return TRUE if you want DOTween to proceed with the log, FALSE otherwise.
+ This method must return a bool
and accept two parameters:
+ - LogType
: the type of Unity log that DOTween is trying to log
+ - object
: the log message that DOTween wants to log
+
+
+ If TRUE draws path gizmos in Unity Editor (if the gizmos button is active).
+ Deactivate this if you want to avoid gizmos overhead while in Unity Editor
+
+
+ If TRUE activates various debug options
+
+
+ Stores the target id so it can be used to give more info in case of safeMode error capturing.
+ Only active if both debugMode
and useSafeMode
are TRUE
+
+
+ Default updateType for new tweens.
+ Default: UpdateType.Normal
+
+
+ Sets whether Unity's timeScale should be taken into account by default or not.
+ Default: false
+
+
+ Default autoPlay behaviour for new tweens.
+ Default: AutoPlay.All
+
+
+ Default autoKillOnComplete behaviour for new tweens.
+ Default: TRUE
+
+
+ Default loopType applied to all new tweens.
+ Default: LoopType.Restart
+
+
+ If TRUE all newly created tweens are set as recyclable, otherwise not.
+ Default: FALSE
+
+
+ Default ease applied to all new Tweeners (not to Sequences which always have Ease.Linear as default).
+ Default: Ease.InOutQuad
+
+
+ Default overshoot/amplitude used for eases
+ Default: 1.70158f
+
+
+ Default period used for eases
+ Default: 0
+
+
+ Used internally. Assigned/removed by DOTweenComponent.Create/DestroyInstance
+
+
+
+ Must be called once, before the first ever DOTween call/reference,
+ otherwise it will be called automatically and will use default options.
+ Calling it a second time won't have any effect.
+ You can chain SetCapacity
to this method, to directly set the max starting size of Tweeners and Sequences:
+ DOTween.Init(false, false, LogBehaviour.Default).SetCapacity(100, 20);
+
+ If TRUE all new tweens will be set for recycling, meaning that when killed,
+ instead of being destroyed, they will be put in a pool and reused instead of creating new tweens. This option allows you to avoid
+ GC allocations by reusing tweens, but you will have to take care of tween references, since they might result active
+ even if they were killed (since they might have been respawned and are now being used for other tweens).
+ If you want to automatically set your tween references to NULL when a tween is killed
+ you can use the OnKill callback like this:
+ .OnKill(()=> myTweenReference = null)
+ You can change this setting at any time by changing the static property,
+ or you can set the recycling behaviour for each tween separately, using:
+ SetRecyclable(bool recyclable)
+ Default: FALSE
+ If TRUE makes tweens slightly slower but safer, automatically taking care of a series of things
+ (like targets becoming null while a tween is playing).
+ You can change this setting at any time by changing the static property.
+ Default: FALSE
+ Type of logging to use.
+ You can change this setting at any time by changing the static property.
+ Default: ErrorsOnly
+
+
+
+ Directly sets the current max capacity of Tweeners and Sequences
+ (meaning how many Tweeners and Sequences can be running at the same time),
+ so that DOTween doesn't need to automatically increase them in case the max is reached
+ (which might lead to hiccups when that happens).
+ Sequences capacity must be less or equal to Tweeners capacity
+ (if you pass a low Tweener capacity it will be automatically increased to match the Sequence's).
+ Beware: use this method only when there are no tweens running.
+
+ Max Tweeners capacity.
+ Default: 200
+ Max Sequences capacity.
+ Default: 50
+
+
+
+ Kills all tweens, clears all cached tween pools and plugins and resets the max Tweeners/Sequences capacities to the default values.
+
+ If TRUE also destroys DOTween's gameObject and resets its initializiation, default settings and everything else
+ (so that next time you use it it will need to be re-initialized)
+
+
+
+ Clears all cached tween pools.
+
+
+
+
+ Checks all active tweens to find and remove eventually invalid ones (usually because their targets became NULL)
+ and returns the total number of invalid tweens found and removed.
+ IMPORTANT: this will cause an error on UWP platform, so don't use it there
+ BEWARE: this is a slightly expensive operation so use it with care
+
+
+
+
+ Updates all tweens that are set to .
+
+ Manual deltaTime
+ Unscaled delta time (used with tweens set as timeScaleIndependent)
+
+
+ Tweens a property or field to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a property or field to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a property or field to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a property or field to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a property or field to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a property or field to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a property or field to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a property or field to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a property or field to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a property or field to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a property or field to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a property or field to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a property or field to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a property or field to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a property or field to the given value using a custom plugin
+ The plugin to use. Each custom plugin implements a static Get()
method
+ you'll need to call to assign the correct plugin in the correct way, like this:
+ CustomPlugin.Get()
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens only one axis of a Vector3 to the given value using default plugins.
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+ The axis to tween
+
+
+ Tweens only the alpha of a Color to the given value using default plugins
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end value to reachThe tween's duration
+
+
+ Tweens a virtual property from the given start to the given end value
+ and implements a setter that allows to use that value with an external method or a lambda
+ Example:
+ To(MyMethod, 0, 12, 0.5f);
+ Where MyMethod is a function that accepts a float parameter (which will be the result of the virtual tween)
+ The action to perform with the tweened value
+ The value to start from
+ The end value to reach
+ The duration of the virtual tween
+
+
+
+ Punches a Vector3 towards the given direction and then back to the starting one
+ as if it was connected to the starting position via an elastic.
+ This tween type generates some GC allocations at startup
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The direction and strength of the punch
+ The duration of the tween
+ Indicates how much will the punch vibrate
+ Represents how much (0 to 1) the vector will go beyond the starting position when bouncing backwards.
+ 1 creates a full oscillation between the direction and the opposite decaying direction,
+ while 0 oscillates only between the starting position and the decaying direction
+
+
+ Shakes a Vector3 with the given values.
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The duration of the tween
+ The shake strength
+ Indicates how much will the shake vibrate
+ Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware).
+ Setting it to 0 will shake along a single direction and behave like a random punch.
+ If TRUE only shakes on the X Y axis (looks better with things like cameras).
+ If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not
+ Randomness mode
+
+
+ Shakes a Vector3 with the given values.
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The duration of the tween
+ The shake strength on each axis
+ Indicates how much will the shake vibrate
+ Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware).
+ Setting it to 0 will shake along a single direction and behave like a random punch.
+ If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not
+ Randomness mode
+
+
+ Tweens a property or field to the given values using default plugins.
+ Ease is applied between each segment and not as a whole.
+ This tween type generates some GC allocations at startup
+ A getter for the field or property to tween.
+ Example usage with lambda:()=> myProperty
+ A setter for the field or property to tween
+ Example usage with lambda:x=> myProperty = x
+ The end values to reach for each segment. This array must have the same length as durations
+ The duration of each segment. This array must have the same length as endValues
+
+
+
+ Returns a new to be used for tween groups.
+ Mind that Sequences don't have a target applied automatically like Tweener creation shortcuts,
+ so if you want to be able to kill this Sequence when calling DOTween.Kill(target) you'll have to add
+ the target manually; you can do that directly by using the overload instead of this one
+
+
+
+
+ Returns a new to be used for tween groups, and allows to set a target
+ (because Sequences don't have their target set automatically like Tweener creation shortcuts).
+ That way killing/controlling tweens by target will apply to this Sequence too.
+
+ The target of the Sequence. Relevant only for static target-based methods like DOTween.Kill(target),
+ useless otherwise
+
+
+ Completes all tweens and returns the number of actual tweens completed
+ (meaning tweens that don't have infinite loops and were not already complete)
+ For Sequences only: if TRUE also internal Sequence callbacks will be fired,
+ otherwise they will be ignored
+
+
+ Completes all tweens with the given ID or target and returns the number of actual tweens completed
+ (meaning the tweens that don't have infinite loops and were not already complete)
+ For Sequences only: if TRUE internal Sequence callbacks will be fired,
+ otherwise they will be ignored
+
+
+ Flips all tweens (changing their direction to forward if it was backwards and viceversa),
+ then returns the number of actual tweens flipped
+
+
+ Flips the tweens with the given ID or target (changing their direction to forward if it was backwards and viceversa),
+ then returns the number of actual tweens flipped
+
+
+ Sends all tweens to the given position (calculating also eventual loop cycles) and returns the actual tweens involved
+
+
+ Sends all tweens with the given ID or target to the given position (calculating also eventual loop cycles)
+ and returns the actual tweens involved
+
+
+ Kills all tweens and returns the number of actual tweens killed
+ If TRUE completes the tweens before killing them
+
+
+ Kills all tweens and returns the number of actual tweens killed
+ If TRUE completes the tweens before killing them
+ Eventual IDs or targets to exclude from the killing
+
+
+ Kills all tweens with the given ID or target and returns the number of actual tweens killed
+ If TRUE completes the tweens before killing them
+
+
+ Kills all tweens with the given target and the given ID, and returns the number of actual tweens killed
+ If TRUE completes the tweens before killing them
+
+
+ Pauses all tweens and returns the number of actual tweens paused
+
+
+ Pauses all tweens with the given ID or target and returns the number of actual tweens paused
+ (meaning the tweens that were actually playing and have been paused)
+
+
+ Plays all tweens and returns the number of actual tweens played
+ (meaning tweens that were not already playing or complete)
+
+
+ Plays all tweens with the given ID or target and returns the number of actual tweens played
+ (meaning the tweens that were not already playing or complete)
+
+
+ Plays all tweens with the given target and the given ID, and returns the number of actual tweens played
+ (meaning the tweens that were not already playing or complete)
+
+
+ Plays backwards all tweens and returns the number of actual tweens played
+ (meaning tweens that were not already started, playing backwards or rewinded)
+
+
+ Plays backwards all tweens with the given ID or target and returns the number of actual tweens played
+ (meaning the tweens that were not already started, playing backwards or rewinded)
+
+
+ Plays backwards all tweens with the given target and ID and returns the number of actual tweens played
+ (meaning the tweens that were not already started, playing backwards or rewinded)
+
+
+ Plays forward all tweens and returns the number of actual tweens played
+ (meaning tweens that were not already playing forward or complete)
+
+
+ Plays forward all tweens with the given ID or target and returns the number of actual tweens played
+ (meaning the tweens that were not already playing forward or complete)
+
+
+ Plays forward all tweens with the given target and ID and returns the number of actual tweens played
+ (meaning the tweens that were not already started, playing backwards or rewinded)
+
+
+ Restarts all tweens, then returns the number of actual tweens restarted
+
+
+ Restarts all tweens with the given ID or target, then returns the number of actual tweens restarted
+ If TRUE includes the eventual tweens delays, otherwise skips them
+ If >= 0 changes the startup delay of all involved tweens to this value, otherwise doesn't touch it
+
+
+ Restarts all tweens with the given target and the given ID, and returns the number of actual tweens played
+ (meaning the tweens that were not already playing or complete)
+ If TRUE includes the eventual tweens delays, otherwise skips them
+ If >= 0 changes the startup delay of all involved tweens to this value, otherwise doesn't touch it
+
+
+ Rewinds and pauses all tweens, then returns the number of actual tweens rewinded
+ (meaning tweens that were not already rewinded)
+
+
+ Rewinds and pauses all tweens with the given ID or target, then returns the number of actual tweens rewinded
+ (meaning the tweens that were not already rewinded)
+
+
+ Smoothly rewinds all tweens (delays excluded), then returns the number of actual tweens rewinding/rewinded
+ (meaning tweens that were not already rewinded).
+ A "smooth rewind" animates the tween to its start position,
+ skipping all elapsed loops (except in case of LoopType.Incremental) while keeping the animation fluent.
+ Note that a tween that was smoothly rewinded will have its play direction flipped
+
+
+ Smoothly rewinds all tweens (delays excluded) with the given ID or target, then returns the number of actual tweens rewinding/rewinded
+ (meaning the tweens that were not already rewinded).
+ A "smooth rewind" animates the tween to its start position,
+ skipping all elapsed loops (except in case of LoopType.Incremental) while keeping the animation fluent.
+ Note that a tween that was smoothly rewinded will have its play direction flipped
+
+
+ Toggles the play state of all tweens and returns the number of actual tweens toggled
+ (meaning tweens that could be played or paused, depending on the toggle state)
+
+
+ Toggles the play state of all tweens with the given ID or target and returns the number of actual tweens toggled
+ (meaning the tweens that could be played or paused, depending on the toggle state)
+
+
+
+ Returns TRUE if a tween with the given ID or target is active.
+ You can also use this to know if a shortcut tween is active for a given target.
+ Example:
+ transform.DOMoveX(45, 1); // transform is automatically added as the tween target
+ DOTween.IsTweening(transform); // Returns true
+
+ The target or ID to look for
+ If FALSE (default) returns TRUE as long as a tween for the given target/ID is active,
+ otherwise also requires it to be playing
+
+
+
+ Returns the total number of active tweens (so both Tweeners and Sequences).
+ A tween is considered active if it wasn't killed, regardless if it's playing or paused
+
+
+
+
+ Returns the total number of active Tweeners.
+ A Tweener is considered active if it wasn't killed, regardless if it's playing or paused
+
+
+
+
+ Returns the total number of active Sequences.
+ A Sequence is considered active if it wasn't killed, regardless if it's playing or paused
+
+
+
+
+ Returns the total number of active and playing tweens.
+ A tween is considered as playing even if its delay is actually playing
+
+
+
+
+ Returns a the total number of active tweens with the given id.
+
+ If TRUE returns only the tweens with the given ID that are currently playing
+
+
+
+ Returns a list of all active tweens in a playing state.
+ Returns NULL if there are no active playing tweens.
+ Beware: each time you call this method a new list is generated, so use it for debug only
+
+ If NULL creates a new list, otherwise clears and fills this one (and thus saves allocations)
+
+
+
+ Returns a list of all active tweens in a paused state.
+ Returns NULL if there are no active paused tweens.
+ Beware: each time you call this method a new list is generated, so use it for debug only
+
+ If NULL creates a new list, otherwise clears and fills this one (and thus saves allocations)
+
+
+
+ Returns a list of all active tweens with the given id.
+ Returns NULL if there are no active tweens with the given id.
+ Beware: each time you call this method a new list is generated
+
+ If TRUE returns only the tweens with the given ID that are currently playing
+ If NULL creates a new list, otherwise clears and fills this one (and thus saves allocations)
+
+
+
+ Returns a list of all active tweens with the given target.
+ Returns NULL if there are no active tweens with the given target.
+ Beware: each time you call this method a new list is generated
+ If TRUE returns only the tweens with the given target that are currently playing
+ If NULL creates a new list, otherwise clears and fills this one (and thus saves allocations)
+
+
+
+
+ Creates virtual tweens that can be used to change other elements via their OnUpdate calls
+
+
+
+
+ Tweens a virtual float.
+ You can add regular settings to the generated tween,
+ but do not use OnUpdate
or you will overwrite the onVirtualUpdate parameter
+
+ The value to start from
+ The value to tween to
+ The duration of the tween
+ A callback which must accept a parameter of type float, called at each update
+
+
+
+ Tweens a virtual int.
+ You can add regular settings to the generated tween,
+ but do not use OnUpdate
or you will overwrite the onVirtualUpdate parameter
+
+ The value to start from
+ The value to tween to
+ The duration of the tween
+ A callback which must accept a parameter of type int, called at each update
+
+
+
+ Tweens a virtual Vector2.
+ You can add regular settings to the generated tween,
+ but do not use OnUpdate
or you will overwrite the onVirtualUpdate parameter
+
+ The value to start from
+ The value to tween to
+ The duration of the tween
+ A callback which must accept a parameter of type Vector3, called at each update
+
+
+
+ Tweens a virtual Vector3.
+ You can add regular settings to the generated tween,
+ but do not use OnUpdate
or you will overwrite the onVirtualUpdate parameter
+
+ The value to start from
+ The value to tween to
+ The duration of the tween
+ A callback which must accept a parameter of type Vector3, called at each update
+
+
+
+ Tweens a virtual Color.
+ You can add regular settings to the generated tween,
+ but do not use OnUpdate
or you will overwrite the onVirtualUpdate parameter
+
+ The value to start from
+ The value to tween to
+ The duration of the tween
+ A callback which must accept a parameter of type Color, called at each update
+
+
+ Returns a value based on the given ease and lifetime percentage (0 to 1)
+ The value to start from when lifetimePercentage is 0
+ The value to reach when lifetimePercentage is 1
+ The time percentage (0 to 1) at which the value should be taken
+ The type of ease
+
+
+ Returns a value based on the given ease and lifetime percentage (0 to 1)
+ The value to start from when lifetimePercentage is 0
+ The value to reach when lifetimePercentage is 1
+ The time percentage (0 to 1) at which the value should be taken
+ The type of ease
+ Eventual overshoot to use with Back ease
+
+
+ Returns a value based on the given ease and lifetime percentage (0 to 1)
+ The value to start from when lifetimePercentage is 0
+ The value to reach when lifetimePercentage is 1
+ The time percentage (0 to 1) at which the value should be taken
+ The type of ease
+ Eventual amplitude to use with Elastic easeType
+ Eventual period to use with Elastic easeType
+
+
+ Returns a value based on the given ease and lifetime percentage (0 to 1)
+ The value to start from when lifetimePercentage is 0
+ The value to reach when lifetimePercentage is 1
+ The time percentage (0 to 1) at which the value should be taken
+ The AnimationCurve to use for ease
+
+
+ Returns a value based on the given ease and lifetime percentage (0 to 1)
+ The value to start from when lifetimePercentage is 0
+ The value to reach when lifetimePercentage is 1
+ The time percentage (0 to 1) at which the value should be taken
+ The type of ease
+
+
+ Returns a value based on the given ease and lifetime percentage (0 to 1)
+ The value to start from when lifetimePercentage is 0
+ The value to reach when lifetimePercentage is 1
+ The time percentage (0 to 1) at which the value should be taken
+ The type of ease
+ Eventual overshoot to use with Back ease
+
+
+ Returns a value based on the given ease and lifetime percentage (0 to 1)
+ The value to start from when lifetimePercentage is 0
+ The value to reach when lifetimePercentage is 1
+ The time percentage (0 to 1) at which the value should be taken
+ The type of ease
+ Eventual amplitude to use with Elastic easeType
+ Eventual period to use with Elastic easeType
+
+
+ Returns a value based on the given ease and lifetime percentage (0 to 1)
+ The value to start from when lifetimePercentage is 0
+ The value to reach when lifetimePercentage is 1
+ The time percentage (0 to 1) at which the value should be taken
+ The AnimationCurve to use for ease
+
+
+ Fires the given callback after the given time.
+ Callback delay
+ Callback to fire when the delay has expired
+ If TRUE (default) ignores Unity's timeScale
+
+
+
+ Don't assign this! It's assigned automatically when creating 0 duration tweens
+
+
+
+
+ Don't assign this! It's assigned automatically when setting the ease to an AnimationCurve or to a custom ease function
+
+
+
+
+ Allows to wrap ease method in special ways, adding extra features
+
+
+
+
+ Converts the given ease so that it also creates a stop-motion effect, by playing the tween at the given FPS
+
+ FPS at which the tween should be played
+ Ease type
+
+
+
+ Converts the given ease so that it also creates a stop-motion effect, by playing the tween at the given FPS
+
+ FPS at which the tween should be played
+ AnimationCurve to use for the ease
+
+
+
+ Converts the given ease so that it also creates a stop-motion effect, by playing the tween at the given FPS
+
+ FPS at which the tween should be played
+ Custom ease function to use
+
+
+
+ Used to allow method chaining with DOTween.Init
+
+
+
+
+ Directly sets the current max capacity of Tweeners and Sequences
+ (meaning how many Tweeners and Sequences can be running at the same time),
+ so that DOTween doesn't need to automatically increase them in case the max is reached
+ (which might lead to hiccups when that happens).
+ Sequences capacity must be less or equal to Tweeners capacity
+ (if you pass a low Tweener capacity it will be automatically increased to match the Sequence's).
+ Beware: use this method only when there are no tweens running.
+
+ Max Tweeners capacity.
+ Default: 200
+ Max Sequences capacity.
+ Default: 50
+
+
+
+ Behaviour that can be assigned when chaining a SetLink to a tween
+
+
+
+ Pauses the tween when the link target is disabled
+
+
+ Pauses the tween when the link target is disabled, plays it when it's enabled
+
+
+ Pauses the tween when the link target is disabled, restarts it when it's enabled
+
+
+ Plays the tween when the link target is enabled
+
+
+ Restarts the tween when the link target is enabled
+
+
+ Kills the tween when the link target is disabled
+
+
+ Kills the tween when the link target is destroyed (becomes NULL). This is always active even if another behaviour is chosen
+
+
+ Completes the tween when the link target is disabled
+
+
+ Completes and kills the tween when the link target is disabled
+
+
+ Rewinds the tween (delay excluded) when the link target is disabled
+
+
+ Rewinds and kills the tween when the link target is disabled
+
+
+
+ Path mode (used to determine correct LookAt orientation)
+
+
+
+ Ignores the path mode (and thus LookAt behaviour)
+
+
+ Regular 3D path
+
+
+ 2D top-down path
+
+
+ 2D side-scroller path
+
+
+
+ Type of path to use with DOPath tweens
+
+
+
+ Linear, composed of straight segments between each waypoint
+
+
+ Curved path (which uses Catmull-Rom curves)
+
+
+ EXPERIMENTAL:
Curved path (which uses Cubic Bezier curves, where each point requires two extra control points)
+
+
+
+ Tweens a Vector2 along a circle.
+ EndValue represents the center of the circle, start and end value degrees are inside options
+ ChangeValue x is changeValue°, y is unused
+
+
+
+
+ Path control point
+
+
+
+
+ Path waypoints (modified by PathPlugin when setting relative end/change value or by CubicBezierDecoder) and by DOTweenPathInspector
+
+
+
+
+ Minimum input points necessary to create the path (doesn't correspond to actual waypoints required)
+
+
+
+
+ Gets the point on the path at the given percentage (0 to 1)
+
+ The percentage (0 to 1) at which to get the point
+ If TRUE constant speed is taken into account, otherwise not
+
+
+
+ Base interface for all tween plugins options
+
+
+
+ Resets the plugin
+
+
+
+ This plugin generates some GC allocations at startup
+
+
+
+
+ Path plugin works exclusively with Transforms
+
+
+
+
+ Rotation mode used with DORotate methods
+
+
+
+
+ Fastest way that never rotates beyond 360°
+
+
+
+
+ Fastest way that rotates beyond 360°
+
+
+
+
+ Adds the given rotation to the transform using world axis and an advanced precision mode
+ (like when using transform.Rotate(Space.World)).
+ In this mode the end value is is always considered relative
+
+
+
+
+ Adds the given rotation to the transform's local axis
+ (like when rotating an object with the "local" switch enabled in Unity's editor or using transform.Rotate(Space.Self)).
+ In this mode the end value is is always considered relative
+
+
+
+
+ Type of scramble to apply to string tweens
+
+
+
+
+ No scrambling of characters
+
+
+
+
+ A-Z + a-z + 0-9 characters
+
+
+
+
+ A-Z characters
+
+
+
+
+ a-z characters
+
+
+
+
+ 0-9 characters
+
+
+
+
+ Custom characters
+
+
+
+
+ Type of randomness to apply to a shake tween
+
+
+
+ Default, full randomness
+
+
+ Creates a more balanced randomness that looks more harmonic
+
+
+
+ Methods that extend Tween objects and allow to control or get data from them
+
+
+
+ Completes the tween
+
+
+ Completes the tween
+ For Sequences only: if TRUE also internal Sequence callbacks will be fired,
+ otherwise they will be ignored
+
+
+ Optional: indicates that the tween creation has ended, to be used (optionally) as the last element of tween chaining creation.
+ This method won't do anything except in case of 0-duration tweens,
+ where it will complete them immediately instead of waiting for the next internal update routine
+ (unless they're nested in a Sequence, in which case the Sequence will still be the one in control and this method will be ignored)
+
+
+ Flips the direction of this tween (backwards if it was going forward or viceversa)
+
+
+ Forces the tween to initialize its settings immediately
+
+
+ Send the tween to the given position in time
+ Time position to reach
+ (if higher than the whole tween duration the tween will simply reach its end)
+ If TRUE will play the tween after reaching the given position, otherwise it will pause it
+
+
+ Send the tween to the given position in time while also executing any callback between the previous time position and the new one
+ Time position to reach
+ (if higher than the whole tween duration the tween will simply reach its end)
+ If TRUE will play the tween after reaching the given position, otherwise it will pause it
+
+
+ Kills the tween
+ If TRUE completes the tween before killing it
+
+
+
+ Forces this tween to update manually, regardless of the set via SetUpdate.
+ Note that the tween will still be subject to normal tween rules, so if for example it's paused this method will do nothing.
+ Also note that if you only want to update this tween instance manually you'll have to set it to anyway,
+ so that it's not updated automatically.
+
+ Manual deltaTime
+ Unscaled delta time (used with tweens set as timeScaleIndependent)
+
+
+ Pauses the tween
+
+
+ Plays the tween
+
+
+ Sets the tween in a backwards direction and plays it
+
+
+ Sets the tween in a forward direction and plays it
+
+
+ Restarts the tween from the beginning
+ Ignored in case of Sequences. If TRUE includes the eventual tween delay, otherwise skips it
+ Ignored in case of Sequences. If >= 0 changes the startup delay to this value, otherwise doesn't touch it
+
+
+ Rewinds and pauses the tween
+ Ignored in case of Sequences. If TRUE includes the eventual tween delay, otherwise skips it
+
+
+ Smoothly rewinds the tween (delays excluded).
+ A "smooth rewind" animates the tween to its start position,
+ skipping all elapsed loops (except in case of LoopType.Incremental) while keeping the animation fluent.
+ If called on a tween who is still waiting for its delay to happen, it will simply set the delay to 0 and pause the tween.
+ Note that a tween that was smoothly rewinded will have its play direction flipped
+
+
+ Plays the tween if it was paused, pauses it if it was playing
+
+
+ Send a path tween to the given waypoint.
+ Has no effect if this is not a path tween.
+ BEWARE, this is a special utility method:
+ it works only with Linear eases. Also, the lookAt direction might be wrong after calling this and might need to be set manually
+ (because it relies on a smooth path movement and doesn't work well with jumps that encompass dramatic direction changes)
+ Waypoint index to reach
+ (if higher than the max waypoint index the tween will simply go to the last one)
+ If TRUE will play the tween after reaching the given waypoint, otherwise it will pause it
+
+
+
+ Creates a yield instruction that waits until the tween is killed or complete.
+ It can be used inside a coroutine as a yield.
+ Example usage:yield return myTween.WaitForCompletion();
+
+
+
+
+ Creates a yield instruction that waits until the tween is killed or rewinded.
+ It can be used inside a coroutine as a yield.
+ Example usage:yield return myTween.WaitForRewind();
+
+
+
+
+ Creates a yield instruction that waits until the tween is killed.
+ It can be used inside a coroutine as a yield.
+ Example usage:yield return myTween.WaitForKill();
+
+
+
+
+ Creates a yield instruction that waits until the tween is killed or has gone through the given amount of loops.
+ It can be used inside a coroutine as a yield.
+ Example usage:yield return myTween.WaitForElapsedLoops(2);
+
+ Elapsed loops to wait for
+
+
+
+ Creates a yield instruction that waits until the tween is killed or has reached the given position (loops included, delays excluded).
+ It can be used inside a coroutine as a yield.
+ Example usage:yield return myTween.WaitForPosition(2.5f);
+
+ Position (loops included, delays excluded) to wait for
+
+
+
+ Creates a yield instruction that waits until the tween is killed or started
+ (meaning when the tween is set in a playing state the first time, after any eventual delay).
+ It can be used inside a coroutine as a yield.
+ Example usage:yield return myTween.WaitForStart();
+
+
+
+ Returns the total number of loops completed by this tween
+
+
+ Returns the eventual delay set for this tween
+
+
+ Returns the eventual elapsed delay set for this tween
+
+
+ Returns the duration of this tween (delays excluded).
+ NOTE: when using settings like SpeedBased, the duration will be recalculated when the tween starts
+ If TRUE returns the full duration loops included,
+ otherwise the duration of a single loop cycle
+
+
+ Returns the elapsed time for this tween (delays exluded)
+ If TRUE returns the elapsed time since startup loops included,
+ otherwise the elapsed time within the current loop cycle
+
+
+ Returns the elapsed percentage (0 to 1) of this tween (delays exluded)
+ If TRUE returns the elapsed percentage since startup loops included,
+ otherwise the elapsed percentage within the current loop cycle
+
+
+ Returns the elapsed percentage (0 to 1) of this tween (delays exluded),
+ based on a single loop, and calculating eventual backwards Yoyo loops as 1 to 0 instead of 0 to 1
+
+
+ Returns FALSE if this tween has been killed or is NULL, TRUE otherwise.
+ BEWARE: if this tween is recyclable it might have been spawned again for another use and thus return TRUE anyway.
+ When working with recyclable tweens you should take care to know when a tween has been killed and manually set your references to NULL.
+ If you want to be sure your references are set to NULL when a tween is killed you can use the OnKill
callback like this:
+ .OnKill(()=> myTweenReference = null)
+
+
+ Returns TRUE if this tween was reversed and is set to go backwards
+
+
+ NOTE: To check if a tween was simply set to go backwards see .
+ Returns TRUE if this tween is going backwards for any of these reasons:
+ - The tween was reversed and is going backwards on a straight loop
+ - The tween was reversed and is going backwards on an odd Yoyo loop
+ - The tween is going forward but on an even Yoyo loop
+ IMPORTANT: if used inside a tween's callback, this will return a result concerning the exact frame when it's asked,
+ so for example in a callback at the end of a Yoyo loop step this method will never return FALSE
+ because the frame will never end exactly there and the tween will already be going backwards when the callback is fired
+
+
+ Returns TRUE if the tween is complete
+ (silently fails and returns FALSE if the tween has been killed)
+
+
+ Returns TRUE if this tween has been initialized
+
+
+ Returns TRUE if this tween is playing
+
+
+ Returns the total number of loops set for this tween
+ (returns -1 if the loops are infinite)
+
+
+
+ Returns a point on a path based on the given path percentage.
+ Returns Vector3.zero
if this is not a path tween, if the tween is invalid, or if the path is not yet initialized.
+ A path is initialized after its tween starts, or immediately if the tween was created with the Path Editor (DOTween Pro feature).
+ You can force a path to be initialized by calling myTween.ForceInit()
.
+
+ Percentage of the path (0 to 1) on which to get the point
+
+
+
+ Returns an array of points that can be used to draw the path.
+ Note that this method generates allocations, because it creates a new array.
+ Returns NULL
if this is not a path tween, if the tween is invalid, or if the path is not yet initialized.
+ A path is initialized after its tween starts, or immediately if the tween was created with the Path Editor (DOTween Pro feature).
+ You can force a path to be initialized by calling myTween.ForceInit()
.
+
+ How many points to create for each path segment (waypoint to waypoint).
+ Only used in case of non-Linear paths
+
+
+
+ Returns the length of a path.
+ Returns -1 if this is not a path tween, if the tween is invalid, or if the path is not yet initialized.
+ A path is initialized after its tween starts, or immediately if the tween was created with the Path Editor (DOTween Pro feature).
+ You can force a path to be initialized by calling myTween.ForceInit()
.
+
+
+
+
+ Types of loop
+
+
+
+ Each loop cycle restarts from the beginning
+
+
+ The tween moves forward and backwards at alternate cycles
+
+
+ Continuously increments the tween at the end of each loop cycle (A to B, B to B+(A-B), and so on), thus always moving "onward".
+ In case of String tweens works only if the tween is set as relative
+
+
+
+ Controls other tweens as a group
+
+
+
+
+ Methods that extend known Unity objects and allow to directly create and control tweens from their instances
+
+
+
+ Tweens a Camera's aspect
to the given value.
+ Also stores the camera as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Camera's backgroundColor to the given value.
+ Also stores the camera as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Camera's farClipPlane
to the given value.
+ Also stores the camera as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Camera's fieldOfView
to the given value.
+ Also stores the camera as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Camera's nearClipPlane
to the given value.
+ Also stores the camera as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Camera's orthographicSize
to the given value.
+ Also stores the camera as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Camera's pixelRect
to the given value.
+ Also stores the camera as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Camera's rect
to the given value.
+ Also stores the camera as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Shakes a Camera's localPosition along its relative X Y axes with the given values.
+ Also stores the camera as the tween's target so it can be used for filtered operations
+ The duration of the tween
+ The shake strength
+ Indicates how much will the shake vibrate
+ Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware).
+ Setting it to 0 will shake along a single direction.
+ If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not
+ Randomness mode
+
+
+ Shakes a Camera's localPosition along its relative X Y axes with the given values.
+ Also stores the camera as the tween's target so it can be used for filtered operations
+ The duration of the tween
+ The shake strength on each axis
+ Indicates how much will the shake vibrate
+ Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware).
+ Setting it to 0 will shake along a single direction.
+ If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not
+ Randomness mode
+
+
+ Shakes a Camera's localRotation.
+ Also stores the camera as the tween's target so it can be used for filtered operations
+ The duration of the tween
+ The shake strength
+ Indicates how much will the shake vibrate
+ Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware).
+ Setting it to 0 will shake along a single direction.
+ If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not
+ Randomness mode
+
+
+ Shakes a Camera's localRotation.
+ Also stores the camera as the tween's target so it can be used for filtered operations
+ The duration of the tween
+ The shake strength on each axis
+ Indicates how much will the shake vibrate
+ Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware).
+ Setting it to 0 will shake along a single direction.
+ If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not
+ Randomness mode
+
+
+ Tweens a Light's color to the given value.
+ Also stores the light as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Light's intensity to the given value.
+ Also stores the light as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Light's shadowStrength to the given value.
+ Also stores the light as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a LineRenderer's color to the given value.
+ Also stores the LineRenderer as the tween's target so it can be used for filtered operations.
+ Note that this method requires to also insert the start colors for the tween,
+ since LineRenderers have no way to get them.
+ The start value to tween from
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Material's color to the given value.
+ Also stores the material as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Material's named color property to the given value.
+ Also stores the material as the tween's target so it can be used for filtered operations
+ The end value to reach
+ The name of the material property to tween (like _Tint or _SpecColor)
+ The duration of the tween
+
+
+ Tweens a Material's named color property with the given ID to the given value.
+ Also stores the material as the tween's target so it can be used for filtered operations
+ The end value to reach
+ The ID of the material property to tween (also called nameID in Unity's manual)
+ The duration of the tween
+
+
+ Tweens a Material's alpha color to the given value
+ (will have no effect unless your material supports transparency).
+ Also stores the material as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Material's alpha color to the given value
+ (will have no effect unless your material supports transparency).
+ Also stores the material as the tween's target so it can be used for filtered operations
+ The end value to reach
+ The name of the material property to tween (like _Tint or _SpecColor)
+ The duration of the tween
+
+
+ Tweens a Material's alpha color with the given ID to the given value
+ (will have no effect unless your material supports transparency).
+ Also stores the material as the tween's target so it can be used for filtered operations
+ The end value to reach
+ The ID of the material property to tween (also called nameID in Unity's manual)
+ The duration of the tween
+
+
+ Tweens a Material's named float property to the given value.
+ Also stores the material as the tween's target so it can be used for filtered operations
+ The end value to reach
+ The name of the material property to tween
+ The duration of the tween
+
+
+ Tweens a Material's named float property with the given ID to the given value.
+ Also stores the material as the tween's target so it can be used for filtered operations
+ The end value to reach
+ The ID of the material property to tween (also called nameID in Unity's manual)
+ The duration of the tween
+
+
+ Tweens a Material's texture offset to the given value.
+ Also stores the material as the tween's target so it can be used for filtered operations
+ The end value to reach
+ The duration of the tween
+
+
+ Tweens a Material's named texture offset property to the given value.
+ Also stores the material as the tween's target so it can be used for filtered operations
+ The end value to reach
+ The name of the material property to tween
+ The duration of the tween
+
+
+ Tweens a Material's texture scale to the given value.
+ Also stores the material as the tween's target so it can be used for filtered operations
+ The end value to reach
+ The duration of the tween
+
+
+ Tweens a Material's named texture scale property to the given value.
+ Also stores the material as the tween's target so it can be used for filtered operations
+ The end value to reach
+ The name of the material property to tween
+ The duration of the tween
+
+
+ Tweens a Material's named Vector property to the given value.
+ Also stores the material as the tween's target so it can be used for filtered operations
+ The end value to reach
+ The name of the material property to tween
+ The duration of the tween
+
+
+ Tweens a Material's named Vector property with the given ID to the given value.
+ Also stores the material as the tween's target so it can be used for filtered operations
+ The end value to reach
+ The ID of the material property to tween (also called nameID in Unity's manual)
+ The duration of the tween
+
+
+ Tweens a TrailRenderer's startWidth/endWidth to the given value.
+ Also stores the TrailRenderer as the tween's target so it can be used for filtered operations
+ The end startWidth to reachThe end endWidth to reach
+ The duration of the tween
+
+
+ Tweens a TrailRenderer's time to the given value.
+ Also stores the TrailRenderer as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Transform's position to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Tweens a Transform's X position to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Tweens a Transform's Y position to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Tweens a Transform's Z position to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Tweens a Transform's localPosition to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Tweens a Transform's X localPosition to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Tweens a Transform's Y localPosition to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Tweens a Transform's Z localPosition to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Tweens a Transform's rotation to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+ Rotation mode
+
+
+ Tweens a Transform's rotation to the given value using pure quaternion values.
+ Also stores the transform as the tween's target so it can be used for filtered operations.
+ PLEASE NOTE: DORotate, which takes Vector3 values, is the preferred rotation method.
+ This method was implemented for very special cases, and doesn't support LoopType.Incremental loops
+ (neither for itself nor if placed inside a LoopType.Incremental Sequence)
+
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Transform's localRotation to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+ Rotation mode
+
+
+ Tweens a Transform's rotation to the given value using pure quaternion values.
+ Also stores the transform as the tween's target so it can be used for filtered operations.
+ PLEASE NOTE: DOLocalRotate, which takes Vector3 values, is the preferred rotation method.
+ This method was implemented for very special cases, and doesn't support LoopType.Incremental loops
+ (neither for itself nor if placed inside a LoopType.Incremental Sequence)
+
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Transform's localScale to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Transform's localScale uniformly to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Transform's X localScale to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Transform's Y localScale to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Transform's Z localScale to the given value.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Transform's rotation so that it will look towards the given world position.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The position to look atThe duration of the tween
+ Eventual axis constraint for the rotation
+ The vector that defines in which direction up is (default: Vector3.up)
+
+
+ EXPERIMENTAL
Tweens a Transform's rotation so that it will look towards the given world position,
+ while also updating the lookAt position every frame
+ (contrary to which calculates the lookAt rotation only once, when the tween starts).
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The position to look atThe duration of the tween
+ Eventual axis constraint for the rotation
+ The vector that defines in which direction up is (default: Vector3.up)
+
+
+ Punches a Transform's localPosition towards the given direction and then back to the starting one
+ as if it was connected to the starting position via an elastic.
+ The direction and strength of the punch (added to the Transform's current position)
+ The duration of the tween
+ Indicates how much will the punch vibrate
+ Represents how much (0 to 1) the vector will go beyond the starting position when bouncing backwards.
+ 1 creates a full oscillation between the punch direction and the opposite direction,
+ while 0 oscillates only between the punch and the start position
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Punches a Transform's localScale towards the given size and then back to the starting one
+ as if it was connected to the starting scale via an elastic.
+ The punch strength (added to the Transform's current scale)
+ The duration of the tween
+ Indicates how much will the punch vibrate
+ Represents how much (0 to 1) the vector will go beyond the starting size when bouncing backwards.
+ 1 creates a full oscillation between the punch scale and the opposite scale,
+ while 0 oscillates only between the punch scale and the start scale
+
+
+ Punches a Transform's localRotation towards the given size and then back to the starting one
+ as if it was connected to the starting rotation via an elastic.
+ The punch strength (added to the Transform's current rotation)
+ The duration of the tween
+ Indicates how much will the punch vibrate
+ Represents how much (0 to 1) the vector will go beyond the starting rotation when bouncing backwards.
+ 1 creates a full oscillation between the punch rotation and the opposite rotation,
+ while 0 oscillates only between the punch and the start rotation
+
+
+ Shakes a Transform's localPosition with the given values.
+ The duration of the tween
+ The shake strength
+ Indicates how much will the shake vibrate
+ Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware).
+ Setting it to 0 will shake along a single direction.
+ If TRUE the tween will smoothly snap all values to integers
+ If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not
+ Randomness mode
+
+
+ Shakes a Transform's localPosition with the given values.
+ The duration of the tween
+ The shake strength on each axis
+ Indicates how much will the shake vibrate
+ Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware).
+ Setting it to 0 will shake along a single direction.
+ If TRUE the tween will smoothly snap all values to integers
+ If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not
+ Randomness mode
+
+
+ Shakes a Transform's localRotation.
+ The duration of the tween
+ The shake strength
+ Indicates how much will the shake vibrate
+ Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware).
+ Setting it to 0 will shake along a single direction.
+ If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not
+ Randomness mode
+
+
+ Shakes a Transform's localRotation.
+ The duration of the tween
+ The shake strength on each axis
+ Indicates how much will the shake vibrate
+ Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware).
+ Setting it to 0 will shake along a single direction.
+ If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not
+ Randomness mode
+
+
+ Shakes a Transform's localScale.
+ The duration of the tween
+ The shake strength
+ Indicates how much will the shake vibrate
+ Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware).
+ Setting it to 0 will shake along a single direction.
+ If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not
+ Randomness mode
+
+
+ Shakes a Transform's localScale.
+ The duration of the tween
+ The shake strength on each axis
+ Indicates how much will the shake vibrate
+ Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware).
+ Setting it to 0 will shake along a single direction.
+ If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not
+ Randomness mode
+
+
+ Tweens a Transform's position to the given value, while also applying a jump effect along the Y axis.
+ Returns a Sequence instead of a Tweener.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reach
+ Power of the jump (the max height of the jump is represented by this plus the final Y offset)
+ Total number of jumps
+ The duration of the tween
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Tweens a Transform's localPosition to the given value, while also applying a jump effect along the Y axis.
+ Returns a Sequence instead of a Tweener.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The end value to reach
+ Power of the jump (the max height of the jump is represented by this plus the final Y offset)
+ Total number of jumps
+ The duration of the tween
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Tweens a Transform's position through the given path waypoints, using the chosen path algorithm.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The waypoints to go through
+ The duration of the tween
+ The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points)
+ The path mode: 3D, side-scroller 2D, top-down 2D
+ The resolution of the path (useless in case of Linear paths): higher resolutions make for more detailed curved paths but are more expensive.
+ Defaults to 10, but a value of 5 is usually enough if you don't have dramatic long curves between waypoints
+ The color of the path (shown when gizmos are active in the Play panel and the tween is running)
+
+
+ Tweens a Transform's localPosition through the given path waypoints, using the chosen path algorithm.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The waypoint to go through
+ The duration of the tween
+ The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points)
+ The path mode: 3D, side-scroller 2D, top-down 2D
+ The resolution of the path: higher resolutions make for more detailed curved paths but are more expensive.
+ Defaults to 10, but a value of 5 is usually enough if you don't have dramatic long curves between waypoints
+ The color of the path (shown when gizmos are active in the Play panel and the tween is running)
+
+
+ IMPORTANT: Unless you really know what you're doing, you should use the overload that accepts a Vector3 array instead.
+ Tweens a Transform's position via the given path.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The path to use
+ The duration of the tween
+ The path mode: 3D, side-scroller 2D, top-down 2D
+
+
+ IMPORTANT: Unless you really know what you're doing, you should use the overload that accepts a Vector3 array instead.
+ Tweens a Transform's localPosition via the given path.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The path to use
+ The duration of the tween
+ The path mode: 3D, side-scroller 2D, top-down 2D
+
+
+ Tweens a Tween's timeScale to the given value.
+ Also stores the Tween as the tween's target so it can be used for filtered operations
+ The end value to reachThe duration of the tween
+
+
+ Tweens a Light's color to the given value,
+ in a way that allows other DOBlendableColor tweens to work together on the same target,
+ instead than fight each other as multiple DOColor would do.
+ Also stores the Light as the tween's target so it can be used for filtered operations
+ The value to tween toThe duration of the tween
+
+
+ Tweens a Material's color to the given value,
+ in a way that allows other DOBlendableColor tweens to work together on the same target,
+ instead than fight each other as multiple DOColor would do.
+ Also stores the Material as the tween's target so it can be used for filtered operations
+ The value to tween toThe duration of the tween
+
+
+ Tweens a Material's named color property to the given value,
+ in a way that allows other DOBlendableColor tweens to work together on the same target,
+ instead than fight each other as multiple DOColor would do.
+ Also stores the Material as the tween's target so it can be used for filtered operations
+ The value to tween to
+ The name of the material property to tween (like _Tint or _SpecColor)
+ The duration of the tween
+
+
+ Tweens a Material's named color property with the given ID to the given value,
+ in a way that allows other DOBlendableColor tweens to work together on the same target,
+ instead than fight each other as multiple DOColor would do.
+ Also stores the Material as the tween's target so it can be used for filtered operations
+ The value to tween to
+ The ID of the material property to tween (also called nameID in Unity's manual)
+ The duration of the tween
+
+
+ Tweens a Transform's position BY the given value (as if you chained a SetRelative
),
+ in a way that allows other DOBlendableMove tweens to work together on the same target,
+ instead than fight each other as multiple DOMove would do.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The value to tween byThe duration of the tween
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Tweens a Transform's localPosition BY the given value (as if you chained a SetRelative
),
+ in a way that allows other DOBlendableMove tweens to work together on the same target,
+ instead than fight each other as multiple DOMove would do.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The value to tween byThe duration of the tween
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ EXPERIMENTAL METHOD - Tweens a Transform's rotation BY the given value (as if you chained a SetRelative
),
+ in a way that allows other DOBlendableRotate tweens to work together on the same target,
+ instead than fight each other as multiple DORotate would do.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The value to tween byThe duration of the tween
+ Rotation mode
+
+
+ EXPERIMENTAL METHOD - Tweens a Transform's lcoalRotation BY the given value (as if you chained a SetRelative
),
+ in a way that allows other DOBlendableRotate tweens to work together on the same target,
+ instead than fight each other as multiple DORotate would do.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The value to tween byThe duration of the tween
+ Rotation mode
+
+
+ Punches a Transform's localRotation BY the given value and then back to the starting one
+ as if it was connected to the starting rotation via an elastic. Does it in a way that allows other
+ DOBlendableRotate tweens to work together on the same target
+ The punch strength (added to the Transform's current rotation)
+ The duration of the tween
+ Indicates how much will the punch vibrate
+ Represents how much (0 to 1) the vector will go beyond the starting rotation when bouncing backwards.
+ 1 creates a full oscillation between the punch rotation and the opposite rotation,
+ while 0 oscillates only between the punch and the start rotation
+
+
+ Tweens a Transform's localScale BY the given value (as if you chained a SetRelative
),
+ in a way that allows other DOBlendableScale tweens to work together on the same target,
+ instead than fight each other as multiple DOScale would do.
+ Also stores the transform as the tween's target so it can be used for filtered operations
+ The value to tween byThe duration of the tween
+
+
+
+ Completes all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens completed
+ (meaning the tweens that don't have infinite loops and were not already complete)
+
+ For Sequences only: if TRUE also internal Sequence callbacks will be fired,
+ otherwise they will be ignored
+
+
+
+ Completes all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens completed
+ (meaning the tweens that don't have infinite loops and were not already complete)
+
+ For Sequences only: if TRUE also internal Sequence callbacks will be fired,
+ otherwise they will be ignored
+
+
+
+ Kills all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens killed.
+
+ If TRUE completes the tween before killing it
+
+
+
+ Kills all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens killed.
+
+ If TRUE completes the tween before killing it
+
+
+
+ Flips the direction (backwards if it was going forward or viceversa) of all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens flipped.
+
+
+
+
+ Flips the direction (backwards if it was going forward or viceversa) of all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens flipped.
+
+
+
+
+ Sends to the given position all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens involved.
+
+ Time position to reach
+ (if higher than the whole tween duration the tween will simply reach its end)
+ If TRUE will play the tween after reaching the given position, otherwise it will pause it
+
+
+
+ Sends to the given position all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens involved.
+
+ Time position to reach
+ (if higher than the whole tween duration the tween will simply reach its end)
+ If TRUE will play the tween after reaching the given position, otherwise it will pause it
+
+
+
+ Pauses all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens paused.
+
+
+
+
+ Pauses all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens paused.
+
+
+
+
+ Plays all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens played.
+
+
+
+
+ Plays all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens played.
+
+
+
+
+ Plays backwards all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens played.
+
+
+
+
+ Plays backwards all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens played.
+
+
+
+
+ Plays forward all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens played.
+
+
+
+
+ Plays forward all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens played.
+
+
+
+
+ Restarts all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens restarted.
+
+
+
+
+ Restarts all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens restarted.
+
+
+
+
+ Rewinds all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens rewinded.
+
+
+
+
+ Rewinds all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens rewinded.
+
+
+
+
+ Smoothly rewinds all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens rewinded.
+
+
+
+
+ Smoothly rewinds all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens rewinded.
+
+
+
+
+ Toggles the paused state (plays if it was paused, pauses if it was playing) of all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens involved.
+
+
+
+
+ Toggles the paused state (plays if it was paused, pauses if it was playing) of all tweens that have this target as a reference
+ (meaning tweens that were started from this target, or that had this target added as an Id)
+ and returns the total number of tweens involved.
+
+
+
+
+ This class serves only as a utility class to store tween settings to apply on multiple tweens.
+ It is in no way needed otherwise, since you can directly apply tween settings to a tween via chaining
+
+
+
+ A variable you can eventually Clear and reuse when needed,
+ to avoid instantiating TweenParams objects
+
+
+ Creates a new TweenParams object, which you can use to store tween settings
+ to pass to multiple tweens via myTween.SetAs(myTweenParms)
+
+
+ Clears and resets this TweenParams instance using default values,
+ so it can be reused without instantiating another one
+
+
+ Sets the autoKill behaviour of the tween.
+ Has no effect if the tween has already started
+ If TRUE the tween will be automatically killed when complete
+
+
+ Sets an ID for the tween, which can then be used as a filter with DOTween's static methods.
+ The ID to assign to this tween. Can be an int, a string, an object or anything else.
+
+
+ Sets an ID for the tween, which can then be used as a filter with DOTween's static methods.
+ The ID to assign to this tween. Can be an int, a string, an object or anything else.
+
+
+ Sets an ID for the tween, which can then be used as a filter with DOTween's static methods.
+ The ID to assign to this tween. Can be an int, a string, an object or anything else.
+
+
+ Sets the target for the tween, which can then be used as a filter with DOTween's static methods.
+ IMPORTANT: use it with caution. If you just want to set an ID for the tween use SetId
instead.
+ When using shorcuts the shortcut target is already assigned as the tween's target,
+ so using this method will overwrite it and prevent shortcut-operations like myTarget.DOPause from working correctly.
+ The target to assign to this tween. Can be an int, a string, an object or anything else.
+
+
+ Sets the looping options for the tween.
+ Has no effect if the tween has already started
+ Number of cycles to play (-1 for infinite - will be converted to 1 in case the tween is nested in a Sequence)
+ Loop behaviour type (default: LoopType.Restart)
+
+
+ Sets the ease of the tween.
+ If applied to Sequences eases the whole sequence animation
+ Eventual overshoot or amplitude to use with Back or Elastic easeType (default is 1.70158)
+ Eventual period to use with Elastic easeType (default is 0)
+
+
+ Sets the ease of the tween using an AnimationCurve.
+ If applied to Sequences eases the whole sequence animation
+
+
+ Sets the ease of the tween using a custom ease function.
+ If applied to Sequences eases the whole sequence animation
+
+
+ Sets the recycling behaviour for the tween.
+ If TRUE the tween will be recycled after being killed, otherwise it will be destroyed.
+
+
+ Sets the update type to the one defined in DOTween.defaultUpdateType (UpdateType.Normal unless changed)
+ and lets you choose if it should be independent from Unity's Time.timeScale
+ If TRUE the tween will ignore Unity's Time.timeScale
+
+
+ Sets the type of update (default or independent) for the tween
+ The type of update (default: UpdateType.Normal)
+ If TRUE the tween will ignore Unity's Time.timeScale
+
+
+ Sets the onStart callback for the tween.
+ Called the first time the tween is set in a playing state, after any eventual delay
+
+
+ Sets the onPlay callback for the tween.
+ Called when the tween is set in a playing state, after any eventual delay.
+ Also called each time the tween resumes playing from a paused state
+
+
+ Sets the onRewind callback for the tween.
+ Called when the tween is rewinded,
+ either by calling Rewind
or by reaching the start position while playing backwards.
+ Rewinding a tween that is already rewinded will not fire this callback
+
+
+ Sets the onUpdate callback for the tween.
+ Called each time the tween updates
+
+
+ Sets the onStepComplete callback for the tween.
+ Called the moment the tween completes one loop cycle, even when going backwards
+
+
+ Sets the onComplete callback for the tween.
+ Called the moment the tween reaches its final forward position, loops included
+
+
+ Sets the onKill callback for the tween.
+ Called the moment the tween is killed
+
+
+ Sets the onWaypointChange callback for the tween.
+ Called when a path tween reaches a new waypoint
+
+
+ Sets a delayed startup for the tween.
+ Has no effect on Sequences or if the tween has already started
+
+
+ If isRelative is TRUE sets the tween as relative
+ (the endValue will be calculated as startValue + endValue
instead than being used directly).
+ Has no effect on Sequences or if the tween has already started
+
+
+ If isSpeedBased is TRUE sets the tween as speed based
+ (the duration will represent the number of units the tween moves x second).
+ Has no effect on Sequences, nested tweens, or if the tween has already started
+
+
+
+ Methods that extend Tween objects and allow to set their parameters
+
+
+
+ Sets the autoKill behaviour of the tween to TRUE.
+ Has no effect
if the tween has already started or if it's added to a Sequence
+
+
+ Sets the autoKill behaviour of the tween.
+ Has no effect
if the tween has already started or if it's added to a Sequence
+ If TRUE the tween will be automatically killed when complete
+
+
+ Sets an ID for the tween (), which can then be used as a filter with DOTween's static methods.
+ The ID to assign to this tween. Can be an int, a string, an object or anything else.
+
+
+ Sets a string ID for the tween (), which can then be used as a filter with DOTween's static methods.
+ Filtering via string is 2X faster than using an object as an ID (using the alternate obejct overload)
+ The string ID to assign to this tween.
+
+
+ Sets an int ID for the tween (), which can then be used as a filter with DOTween's static methods.
+ Filtering via int is 4X faster than via object, 2X faster than via string (using the alternate object/string overloads)
+ The int ID to assign to this tween.
+
+
+ Allows to link this tween to a GameObject
+ so that it will be automatically killed when the GameObject is destroyed.
+ Has no effect
if the tween is added to a Sequence
+ The link target (unrelated to the target set via SetTarget
)
+
+
+ Allows to link this tween to a GameObject and assign a behaviour depending on it.
+ This will also automatically kill the tween when the GameObject is destroyed.
+ Has no effect
if the tween is added to a Sequence
+ The link target (unrelated to the target set via SetTarget
)
+ The behaviour to use ( is always evaluated even if you choose another one)
+
+
+ Sets the target for the tween, which can then be used as a filter with DOTween's static methods.
+ IMPORTANT: use it with caution. If you just want to set an ID for the tween use SetId
instead.
+ When using shorcuts the shortcut target is already assigned as the tween's target,
+ so using this method will overwrite it and prevent shortcut-operations like myTarget.DOPause from working correctly.
+ The target to assign to this tween. Can be an int, a string, an object or anything else.
+
+
+ Sets the looping options for the tween.
+ Has no effect if the tween has already started
+ Number of cycles to play (-1 for infinite - will be converted to 1 in case the tween is nested in a Sequence)
+
+
+ Sets the looping options for the tween.
+ Has no effect if the tween has already started
+ Number of cycles to play (-1 for infinite - will be converted to 1 in case the tween is nested in a Sequence)
+ Loop behaviour type (default: LoopType.Restart)
+
+
+ Sets the ease of the tween.
+ If applied to Sequences eases the whole sequence animation
+
+
+ Sets the ease of the tween.
+ If applied to Sequences eases the whole sequence animation
+
+ Eventual overshoot to use with Back or Flash ease (default is 1.70158 - 1 for Flash).
+ In case of Flash ease it must be an intenger and sets the total number of flashes that will happen.
+ Using an even number will complete the tween on the starting value, while an odd one will complete it on the end value.
+
+
+
+ Sets the ease of the tween.
+ If applied to Sequences eases the whole sequence animation
+ Eventual amplitude to use with Elastic easeType or overshoot to use with Flash easeType (default is 1.70158 - 1 for Flash).
+ In case of Flash ease it must be an integer and sets the total number of flashes that will happen.
+ Using an even number will complete the tween on the starting value, while an odd one will complete it on the end value.
+
+ Eventual period to use with Elastic or Flash easeType (default is 0).
+ In case of Flash ease it indicates the power in time of the ease, and must be between -1 and 1.
+ 0 is balanced, 1 weakens the ease with time, -1 starts the ease weakened and gives it power towards the end.
+
+
+
+ Sets the ease of the tween using an AnimationCurve.
+ If applied to Sequences eases the whole sequence animation
+
+
+ Sets the ease of the tween using a custom ease function (which must return a value between 0 and 1).
+ If applied to Sequences eases the whole sequence animation
+
+
+ Allows the tween to be recycled after being killed.
+
+
+ Sets the recycling behaviour for the tween.
+ If TRUE the tween will be recycled after being killed, otherwise it will be destroyed.
+
+
+ Sets the update type to UpdateType.Normal and lets you choose if it should be independent from Unity's Time.timeScale
+ If TRUE the tween will ignore Unity's Time.timeScale
+
+
+ Sets the type of update for the tween
+ The type of update (defalt: UpdateType.Normal)
+
+
+ Sets the type of update for the tween and lets you choose if it should be independent from Unity's Time.timeScale
+ The type of update
+ If TRUE the tween will ignore Unity's Time.timeScale
+
+
+ EXPERIMENTAL: inverts this tween, so that it will play from the end to the beginning
+ (playing it backwards will actually play it from the beginning to the end).
+ Has no effect
if the tween has already started or if it's added to a Sequence
+
+
+ EXPERIMENTAL: inverts this tween, so that it will play from the end to the beginning
+ (playing it backwards will actually play it from the beginning to the end).
+ Has no effect
if the tween has already started or if it's added to a Sequence
+ If TRUE the tween will be inverted, otherwise it won't
+
+
+ Sets the onStart
callback for the tween, clearing any previous onStart
callback that was set.
+ Called the first time the tween is set in a playing state, after any eventual delay
+
+
+ Sets the onPlay
callback for the tween, clearing any previous onPlay
callback that was set.
+ Called when the tween is set in a playing state, after any eventual delay.
+ Also called each time the tween resumes playing from a paused state
+
+
+ Sets the onPause
callback for the tween, clearing any previous onPause
callback that was set.
+ Called when the tween state changes from playing to paused.
+ If the tween has autoKill set to FALSE, this is called also when the tween reaches completion.
+
+
+ Sets the onRewind
callback for the tween, clearing any previous onRewind
callback that was set.
+ Called when the tween is rewinded,
+ either by calling Rewind
or by reaching the start position while playing backwards.
+ Rewinding a tween that is already rewinded will not fire this callback
+
+
+ Sets the onUpdate
callback for the tween, clearing any previous onUpdate
callback that was set.
+ Called each time the tween updates
+
+
+ Sets the onStepComplete
callback for the tween, clearing any previous onStepComplete
callback that was set.
+ Called the moment the tween completes one loop cycle, even when going backwards
+
+
+ Sets the onComplete
callback for the tween, clearing any previous onComplete
callback that was set.
+ Called the moment the tween reaches its final forward position, loops included
+
+
+ Sets the onKill
callback for the tween, clearing any previous onKill
callback that was set.
+ Called the moment the tween is killed
+
+
+ Sets the onWaypointChange
callback for the tween, clearing any previous onWaypointChange
callback that was set.
+ Called when a path tween's current waypoint changes
+
+
+ Sets the parameters of the tween (id, ease, loops, delay, timeScale, callbacks, etc) as the parameters of the given one.
+ Doesn't copy specific SetOptions settings: those will need to be applied manually each time.
+ Has no effect if the tween has already started.
+ NOTE: the tween's target
will not be changed
+ Tween from which to copy the parameters
+
+
+ Sets the parameters of the tween (id, ease, loops, delay, timeScale, callbacks, etc) as the parameters of the given TweenParams.
+ Has no effect if the tween has already started.
+ TweenParams from which to copy the parameters
+
+
+ Adds the given tween to the end of the Sequence.
+ Has no effect if the Sequence has already started
+ The tween to append
+
+
+ Adds the given tween to the beginning of the Sequence, pushing forward the other nested content.
+ Has no effect if the Sequence has already started
+ The tween to prepend
+
+
+ Inserts the given tween at the same time position of the last tween, callback or interval added to the Sequence.
+ Note that, in case of a Join after an interval, the insertion time will be the time where the interval starts, not where it finishes.
+ Has no effect if the Sequence has already started
+
+
+ Inserts the given tween at the given time position in the Sequence,
+ automatically adding an interval if needed.
+ Has no effect if the Sequence has already started
+ The time position where the tween will be placed
+ The tween to insert
+
+
+ Adds the given interval to the end of the Sequence.
+ Has no effect if the Sequence has already started
+ The interval duration
+
+
+ Adds the given interval to the beginning of the Sequence, pushing forward the other nested content.
+ Has no effect if the Sequence has already started
+ The interval duration
+
+
+ Adds the given callback to the end of the Sequence.
+ Has no effect if the Sequence has already started
+ The callback to append
+
+
+ Adds the given callback to the beginning of the Sequence, pushing forward the other nested content.
+ Has no effect if the Sequence has already started
+ The callback to prepend
+
+
+ Inserts the given callback at the same time position of the last tween, callback or interval added to the Sequence.
+ Note that, in case of a Join after an interval, the insertion time will be the time where the interval starts, not where it finishes.
+ Has no effect if the Sequence has already started
+ /// <param name="callback">The callback to prepend</param>
+
+
+ Inserts the given callback at the given time position in the Sequence,
+ automatically adding an interval if needed.
+ Has no effect if the Sequence has already started
+ The time position where the callback will be placed
+ The callback to insert
+
+
+ Changes a TO tween into a FROM tween: sets the current target's position as the tween's endValue
+ then immediately sends the target to the previously set endValue.
+
+
+ Changes a TO tween into a FROM tween: sets the current target's position as the tween's endValue
+ then immediately sends the target to the previously set endValue.
+ If TRUE the FROM value will be calculated as relative to the current one
+
+
+ Changes a TO tween into a FROM tween: sets the current value of the target as the endValue,
+ and the previously passed endValue as the actual startValue.
+ If TRUE sets the target to from value immediately, otherwise waits for the tween to start
+ If TRUE the FROM value will be calculated as relative to the current one
+
+
+ Changes a TO tween into a FROM tween: sets the tween's starting value to the given one
+ and eventually sets the tween's target to that value immediately.
+ Value to start from
+ If TRUE sets the target to from value immediately, otherwise waits for the tween to start
+ If TRUE the FROM/TO values will be calculated as relative to the current ones
+
+
+ Changes a TO tween into a FROM tween: sets the tween's starting value to the given one
+ and eventually sets the tween's target to that value immediately.
+ Alpha value to start from (in case of Fade tweens)
+ If TRUE sets the target to from value immediately, otherwise waits for the tween to start
+ If TRUE the FROM/TO values will be calculated as relative to the current ones
+
+
+ Changes a TO tween into a FROM tween: sets the tween's starting value to the given one
+ and eventually sets the tween's target to that value immediately.
+ Value to start from (in case of Vector tweens that act on a single coordinate or scale tweens)
+ If TRUE sets the target to from value immediately, otherwise waits for the tween to start
+ If TRUE the FROM/TO values will be calculated as relative to the current ones
+
+
+ Changes a TO tween into a FROM tween: sets the tween's starting value to the given one
+ and eventually sets the tween's target to that value immediately.
+ Value to start from (in case of Vector tweens that act on a single coordinate or scale tweens)
+ If TRUE sets the target to from value immediately, otherwise waits for the tween to start
+ If TRUE the FROM/TO values will be calculated as relative to the current ones
+
+
+ Sets a delayed startup for the tween.
+ In case of Sequences behaves the same as ,
+ which means the delay will repeat in case of loops (while with tweens it's ignored after the first loop cycle).
+ Has no effect if the tween has already started
+
+
+ EXPERIMENTAL: implemented in v1.2.340.
+ Sets a delayed startup for the tween with options to choose how the delay is applied in case of Sequences.
+ Has no effect if the tween has already started
+ Only used by types: If FALSE sets the delay as a one-time occurrence
+ (defaults to this for types),
+ otherwise as a Sequence interval which will repeat at the beginning of every loop cycle
+
+
+ Sets the tween as relative
+ (the endValue will be calculated as startValue + endValue
instead than being used directly).
+ Has no effect on Sequences or if the tween has already started
+
+
+ If isRelative is TRUE sets the tween as relative
+ (the endValue will be calculated as startValue + endValue
instead than being used directly).
+ Has no effect on Sequences or if the tween has already started
+
+
+ If isSpeedBased is TRUE sets the tween as speed based
+ (the duration will represent the number of units the tween moves x second).
+ Has no effect on Sequences, nested tweens, or if the tween has already started
+
+
+ If isSpeedBased is TRUE sets the tween as speed based
+ (the duration will represent the number of units the tween moves x second).
+ Has no effect on Sequences, nested tweens, or if the tween has already started
+
+
+ Options for float tweens
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Options for Vector2 tweens
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Options for Vector2 tweens
+ Selecting an axis will tween the vector only on that axis, leaving the others untouched
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Options for Vector3 tweens
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Options for Vector3 tweens
+ Selecting an axis will tween the vector only on that axis, leaving the others untouched
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Options for Vector4 tweens
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Options for Vector4 tweens
+ Selecting an axis will tween the vector only on that axis, leaving the others untouched
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Options for Quaternion tweens
+ If TRUE (default) the rotation will take the shortest route, and will not rotate more than 360°.
+ If FALSE the rotation will be fully accounted. Is always FALSE if the tween is set as relative
+
+
+ Options for Color tweens
+ If TRUE only the alpha value of the color will be tweened
+
+
+ Options for Vector4 tweens
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Options for Vector4 tweens
+ If TRUE, rich text will be interpreted correctly while animated,
+ otherwise all tags will be considered as normal text
+ The type of scramble to use, if any
+ A string containing the characters to use for scrambling.
+ Use as many characters as possible (minimum 10) because DOTween uses a fast scramble mode which gives better results with more characters.
+ Leave it to NULL to use default ones
+
+
+ Options for Vector3Array tweens
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Options for Vector3Array tweens
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Options for ShapeCircle tweens
+ If TRUE the center you set in the DOTween.To method will be considered as relative
+ to the starting position of the target
+ If TRUE the tween will smoothly snap all values to integers
+
+
+ Options for Path tweens (created via the DOPath
shortcut)
+ The eventual movement axis to lock. You can input multiple axis if you separate them like this:
+ AxisConstrain.X | AxisConstraint.Y
+ The eventual rotation axis to lock. You can input multiple axis if you separate them like this:
+ AxisConstrain.X | AxisConstraint.Y
+
+
+ Options for Path tweens (created via the DOPath
shortcut)
+ If TRUE the path will be automatically closed
+ The eventual movement axis to lock. You can input multiple axis if you separate them like this:
+ AxisConstrain.X | AxisConstraint.Y
+ The eventual rotation axis to lock. You can input multiple axis if you separate them like this:
+ AxisConstrain.X | AxisConstraint.Y
+
+
+ Additional LookAt options for Path tweens (created via the DOPath
shortcut).
+ Orients the target towards the given position.
+ Must be chained directly to the tween creation method or to a SetOptions
+ The position to look at
+ The eventual direction to consider as "forward".
+ If left to NULL defaults to the regular forward side of the transform
+ The vector that defines in which direction up is (default: Vector3.up)
+
+
+ Additional LookAt options for Path tweens (created via the DOPath
shortcut).
+ Orients the target towards the given position with options to keep the Z rotation stable.
+ Must be chained directly to the tween creation method or to a SetOptions
+ The position to look at
+ If TRUE doesn't rotate the target along the Z axis
+
+
+ Additional LookAt options for Path tweens (created via the DOPath
shortcut).
+ Orients the target towards another transform.
+ Must be chained directly to the tween creation method or to a SetOptions
+ The transform to look at
+ The eventual direction to consider as "forward".
+ If left to NULL defaults to the regular forward side of the transform
+ The vector that defines in which direction up is (default: Vector3.up)
+
+
+ Additional LookAt options for Path tweens (created via the DOPath
shortcut).
+ Orients the target towards another transform with options to keep the Z rotation stable.
+ Must be chained directly to the tween creation method or to a SetOptions
+ The transform to look at
+ If TRUE doesn't rotate the target along the Z axis
+
+
+ Additional LookAt options for Path tweens (created via the DOPath
shortcut).
+ Orients the target to the path, with the given lookAhead.
+ Must be chained directly to the tween creation method or to a SetOptions
+ The percentage of lookAhead to use (0 to 1)
+ The eventual direction to consider as "forward".
+ If left to NULL defaults to the regular forward side of the transform
+ The vector that defines in which direction up is (default: Vector3.up)
+
+
+ Additional LookAt options for Path tweens (created via the DOPath
shortcut).
+ Orients the path with options to keep the Z rotation stable.
+ Must be chained directly to the tween creation method or to a SetOptions
+ The percentage of lookAhead to use (0 to 1)
+ If TRUE doesn't rotate the target along the Z axis
+
+
+
+ Types of log behaviours
+
+
+
+ Log only warnings and errors
+
+
+ Log warnings, errors and additional infos
+
+
+ Log only errors
+
+
+
+ Indicates either a Tweener or a Sequence
+
+
+
+ TimeScale for the tween
+
+
+ If TRUE the tween will play backwards
+
+
+ If TRUE the tween is completely inverted but without playing it backwards
+ (play backwards will actually play the tween in the original direction)
+
+
+ Object ID (usable for filtering with DOTween static methods). Can be anything except a string or an int
+ (use or for those)
+
+
+ String ID (usable for filtering with DOTween static methods). 2X faster than using an object id
+
+
+ Int ID (usable for filtering with DOTween static methods). 4X faster than using an object id, 2X faster than using a string id.
+ Default is -999 so avoid using an ID like that or it will capture all unset intIds
+
+
+ Tween target (usable for filtering with DOTween static methods). Automatically set by tween creation shortcuts
+
+
+ Called when the tween is set in a playing state, after any eventual delay.
+ Also called each time the tween resumes playing from a paused state
+
+
+ Called when the tween state changes from playing to paused.
+ If the tween has autoKill set to FALSE, this is called also when the tween reaches completion.
+
+
+ Called when the tween is rewinded,
+ either by calling Rewind
or by reaching the start position while playing backwards.
+ Rewinding a tween that is already rewinded will not fire this callback
+
+
+ Called each time the tween updates
+
+
+ Called the moment the tween completes one loop cycle
+
+
+ Called the moment the tween reaches completion (loops included)
+
+
+ Called the moment the tween is killed
+
+
+ Called when a path tween's current waypoint changes
+
+
+ Tweeners-only (ignored by Sequences), returns TRUE if the tween was set as relative
+
+
+
+ Set by SetTarget if DOTween's Debug Mode is on (see DOTween Utility Panel -> "Store GameObject's ID" debug option
+
+
+
+ FALSE when tween is (or should be) despawned - set only by TweenManager
+
+
+ Gets and sets the time position (loops included, delays excluded) of the tween
+
+
+ Returns TRUE if the tween is set to loop (either a set number of times or infinitely)
+
+
+ TRUE after the tween was set in a play state at least once, AFTER any delay is elapsed
+
+
+ Time position within a single loop cycle
+
+
+
+ Animates a single value
+
+
+
+ Changes the start value of a tween and rewinds it (without pausing it).
+ Has no effect with tweens that are inside Sequences
+ The new start value
+ If bigger than 0 applies it as the new tween duration
+
+
+ Changes the end value of a tween and rewinds it (without pausing it).
+ Has no effect with tweens that are inside Sequences
+ The new end value
+ If bigger than 0 applies it as the new tween duration
+ If TRUE the start value will become the current target's value, otherwise it will stay the same
+
+
+ Changes the end value of a tween and rewinds it (without pausing it).
+ Has no effect with tweens that are inside Sequences
+ The new end value
+ If TRUE the start value will become the current target's value, otherwise it will stay the same
+
+
+ Changes the start and end value of a tween and rewinds it (without pausing it).
+ Has no effect with tweens that are inside Sequences
+ The new start value
+ The new end value
+ If bigger than 0 applies it as the new tween duration
+
+
+
+ Used internally
+
+
+
+
+ Update type
+
+
+
+ Updates every frame during Update calls
+
+
+ Updates every frame during LateUpdate calls
+
+
+ Updates using FixedUpdate calls
+
+
+ Updates using manual update calls
+
+
+
diff --git a/Assets/Plugins/DOTween/DOTween.XML.meta b/Assets/Plugins/DOTween/DOTween.XML.meta
new file mode 100644
index 0000000..db88436
--- /dev/null
+++ b/Assets/Plugins/DOTween/DOTween.XML.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 0fa616d8a39d6934b8f5c2bab642ec00
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/DOTween.dll b/Assets/Plugins/DOTween/DOTween.dll
new file mode 100644
index 0000000..57112d3
Binary files /dev/null and b/Assets/Plugins/DOTween/DOTween.dll differ
diff --git a/Assets/Plugins/DOTween/DOTween.dll.mdb b/Assets/Plugins/DOTween/DOTween.dll.mdb
new file mode 100644
index 0000000..62da0a3
Binary files /dev/null and b/Assets/Plugins/DOTween/DOTween.dll.mdb differ
diff --git a/Assets/Plugins/DOTween/DOTween.dll.mdb.meta b/Assets/Plugins/DOTween/DOTween.dll.mdb.meta
new file mode 100644
index 0000000..c1a51ad
--- /dev/null
+++ b/Assets/Plugins/DOTween/DOTween.dll.mdb.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: c9670ac8dd6444942994a82589a32e56
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/DOTween.dll.meta b/Assets/Plugins/DOTween/DOTween.dll.meta
new file mode 100644
index 0000000..f8f3141
--- /dev/null
+++ b/Assets/Plugins/DOTween/DOTween.dll.meta
@@ -0,0 +1,33 @@
+fileFormatVersion: 2
+guid: 6e34401331a6989419fc6a45f3d726cd
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 0
+ isExplicitlyReferenced: 0
+ validateReferences: 1
+ platformData:
+ - first:
+ Any:
+ second:
+ enabled: 1
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ DefaultValueInitialized: true
+ - first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Editor.meta b/Assets/Plugins/DOTween/Editor.meta
new file mode 100644
index 0000000..ef8d150
--- /dev/null
+++ b/Assets/Plugins/DOTween/Editor.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: a5db00ddfeb5e1b4988f77a7a87e9a4b
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Editor/DOTweenEditor.XML b/Assets/Plugins/DOTween/Editor/DOTweenEditor.XML
new file mode 100644
index 0000000..690bfc4
--- /dev/null
+++ b/Assets/Plugins/DOTween/Editor/DOTweenEditor.XML
@@ -0,0 +1,144 @@
+
+
+
+ DOTweenEditor
+
+
+
+
+ Contains compatibility methods taken from DemiEditor (for when DOTween is without it)
+
+
+
+
+ Warning: some versions of this method don't have the includeInactive parameter so it won't be taken into account
+
+
+
+
+ Warning: some versions of this method don't have the includeInactive parameter so it won't be taken into account
+
+
+
+
+ Warning: some versions of this method don't have the includeInactive parameter so it won't be taken into account
+
+
+
+
+ Warning: some versions of this method don't have the includeInactive parameter so it won't be taken into account
+
+
+
+
+ Starts the update loop of tween in the editor. Has no effect during playMode.
+
+ Eventual callback to call after every update
+
+
+
+ Stops the update loop and clears the onPreviewUpdated callback.
+
+ If TRUE also resets the tweened objects to their original state.
+ Note that this works by calling Rewind on all tweens, so it will work correctly
+ only if you have a single tween type per object and it wasn't killed
+ If TRUE also kills any cached tween
+
+
+
+ Readies the tween for editor preview by setting its UpdateType to Manual plus eventual extra settings.
+
+ The tween to ready
+ If TRUE (recommended) removes all callbacks (OnComplete/Rewind/etc)
+ If TRUE prevents the tween from being auto-killed at completion
+ If TRUE starts playing the tween immediately
+
+
+ Full major version + first minor version (ex: 2018.1f)
+
+
+ Major version
+
+
+ First minor version (ex: in 2018.1 it would be 1)
+
+
+
+ Checks that the given editor texture use the correct import settings,
+ and applies them if they're incorrect.
+
+
+
+
+ Returns TRUE if setup is required
+
+
+
+
+ Returns TRUE if the file/directory at the given path exists.
+
+ Path, relative to Unity's project folder
+
+
+
+
+ Converts the given project-relative path to a full path,
+ with backward (\) slashes).
+
+
+
+
+ Converts the given full path to a path usable with AssetDatabase methods
+ (relative to Unity's project folder, and with the correct Unity forward (/) slashes).
+
+
+
+
+ Connects to a asset.
+ If the asset already exists at the given path, loads it and returns it.
+ Otherwise, either returns NULL or automatically creates it before loading and returning it
+ (depending on the given parameters).
+
+ Asset type
+ File path (relative to Unity's project folder)
+ If TRUE and the requested asset doesn't exist, forces its creation
+
+
+
+ Full path for the given loaded assembly, assembly file included
+
+
+
+
+ Adds the given global define if it's not already present
+
+
+
+
+ Removes the given global define if it's present
+
+
+
+
+ Returns TRUE if the given global define is present in all the
+ or only in the given , depending on passed parameters.
+
+
+ to use. Leave NULL to check in all of them.
+
+
+
+ Not used as menu item anymore, but as a utility function
+
+
+
+ Full major version + first minor version (ex: 2018.1f)
+
+
+ Major version
+
+
+ First minor version (ex: in 2018.1 it would be 1)
+
+
+
diff --git a/Assets/Plugins/DOTween/Editor/DOTweenEditor.XML.meta b/Assets/Plugins/DOTween/Editor/DOTweenEditor.XML.meta
new file mode 100644
index 0000000..e80b1dc
--- /dev/null
+++ b/Assets/Plugins/DOTween/Editor/DOTweenEditor.XML.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: a3b2ae74fd9a8e14ba009bf186d857b4
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Editor/DOTweenEditor.dll b/Assets/Plugins/DOTween/Editor/DOTweenEditor.dll
new file mode 100644
index 0000000..4911a86
Binary files /dev/null and b/Assets/Plugins/DOTween/Editor/DOTweenEditor.dll differ
diff --git a/Assets/Plugins/DOTween/Editor/DOTweenEditor.dll.mdb b/Assets/Plugins/DOTween/Editor/DOTweenEditor.dll.mdb
new file mode 100644
index 0000000..4cf61e0
Binary files /dev/null and b/Assets/Plugins/DOTween/Editor/DOTweenEditor.dll.mdb differ
diff --git a/Assets/Plugins/DOTween/Editor/DOTweenEditor.dll.mdb.meta b/Assets/Plugins/DOTween/Editor/DOTweenEditor.dll.mdb.meta
new file mode 100644
index 0000000..ef5535c
--- /dev/null
+++ b/Assets/Plugins/DOTween/Editor/DOTweenEditor.dll.mdb.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 3dcd4aa6b33279f4a8dee4d043d11fde
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Editor/DOTweenEditor.dll.meta b/Assets/Plugins/DOTween/Editor/DOTweenEditor.dll.meta
new file mode 100644
index 0000000..97fa394
--- /dev/null
+++ b/Assets/Plugins/DOTween/Editor/DOTweenEditor.dll.meta
@@ -0,0 +1,33 @@
+fileFormatVersion: 2
+guid: b8651264cfd330c429b7aba333184a46
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ defineConstraints: []
+ isPreloaded: 0
+ isOverridable: 0
+ isExplicitlyReferenced: 0
+ validateReferences: 1
+ platformData:
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 1
+ settings:
+ DefaultValueInitialized: true
+ - first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Editor/Imgs.meta b/Assets/Plugins/DOTween/Editor/Imgs.meta
new file mode 100644
index 0000000..6d5af59
--- /dev/null
+++ b/Assets/Plugins/DOTween/Editor/Imgs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 75ec2295e38406d4ca7d3da6e2490d62
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Editor/Imgs/DOTweenIcon.png b/Assets/Plugins/DOTween/Editor/Imgs/DOTweenIcon.png
new file mode 100644
index 0000000..d06fc7c
Binary files /dev/null and b/Assets/Plugins/DOTween/Editor/Imgs/DOTweenIcon.png differ
diff --git a/Assets/Plugins/DOTween/Editor/Imgs/DOTweenIcon.png.meta b/Assets/Plugins/DOTween/Editor/Imgs/DOTweenIcon.png.meta
new file mode 100644
index 0000000..4ef6874
--- /dev/null
+++ b/Assets/Plugins/DOTween/Editor/Imgs/DOTweenIcon.png.meta
@@ -0,0 +1,127 @@
+fileFormatVersion: 2
+guid: a468423a8d4d59549b9515009f68d479
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 13
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ flipGreenChannel: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ vTOnly: 0
+ ignoreMipmapLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 0
+ wrapV: 0
+ wrapW: 0
+ nPOTScale: 1
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 0
+ spriteTessellationDetail: -1
+ textureType: 0
+ textureShape: 1
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 0
+ applyGammaDecoding: 0
+ swizzle: 50462976
+ cookieLightType: 0
+ platformSettings:
+ - serializedVersion: 3
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: Standalone
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: WebGL
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ physicsShape: []
+ bones: []
+ spriteID:
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ nameFileIdTable: {}
+ mipmapLimitGroupName:
+ pSDRemoveMatte: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Editor/Imgs/DOTweenMiniIcon.png b/Assets/Plugins/DOTween/Editor/Imgs/DOTweenMiniIcon.png
new file mode 100644
index 0000000..7cd74c1
Binary files /dev/null and b/Assets/Plugins/DOTween/Editor/Imgs/DOTweenMiniIcon.png differ
diff --git a/Assets/Plugins/DOTween/Editor/Imgs/DOTweenMiniIcon.png.meta b/Assets/Plugins/DOTween/Editor/Imgs/DOTweenMiniIcon.png.meta
new file mode 100644
index 0000000..b8443b9
--- /dev/null
+++ b/Assets/Plugins/DOTween/Editor/Imgs/DOTweenMiniIcon.png.meta
@@ -0,0 +1,127 @@
+fileFormatVersion: 2
+guid: 431f682345954f64ea3f62b140b4af34
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 13
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ flipGreenChannel: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ vTOnly: 0
+ ignoreMipmapLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 0
+ wrapV: 0
+ wrapW: 0
+ nPOTScale: 1
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 0
+ spriteTessellationDetail: -1
+ textureType: 0
+ textureShape: 1
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 0
+ applyGammaDecoding: 0
+ swizzle: 50462976
+ cookieLightType: 0
+ platformSettings:
+ - serializedVersion: 3
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: Standalone
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: WebGL
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ physicsShape: []
+ bones: []
+ spriteID:
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ nameFileIdTable: {}
+ mipmapLimitGroupName:
+ pSDRemoveMatte: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Editor/Imgs/Footer.png b/Assets/Plugins/DOTween/Editor/Imgs/Footer.png
new file mode 100644
index 0000000..e29d02f
Binary files /dev/null and b/Assets/Plugins/DOTween/Editor/Imgs/Footer.png differ
diff --git a/Assets/Plugins/DOTween/Editor/Imgs/Footer.png.meta b/Assets/Plugins/DOTween/Editor/Imgs/Footer.png.meta
new file mode 100644
index 0000000..ce95f63
--- /dev/null
+++ b/Assets/Plugins/DOTween/Editor/Imgs/Footer.png.meta
@@ -0,0 +1,127 @@
+fileFormatVersion: 2
+guid: 4e6390733bd97be4fae0332289cca833
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 13
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ flipGreenChannel: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ vTOnly: 0
+ ignoreMipmapLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 1
+ spriteTessellationDetail: -1
+ textureType: 2
+ textureShape: 1
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 0
+ applyGammaDecoding: 0
+ swizzle: 50462976
+ cookieLightType: 0
+ platformSettings:
+ - serializedVersion: 3
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 256
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 0
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: Standalone
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: WebGL
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ physicsShape: []
+ bones: []
+ spriteID:
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ nameFileIdTable: {}
+ mipmapLimitGroupName:
+ pSDRemoveMatte: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Editor/Imgs/Footer_dark.png b/Assets/Plugins/DOTween/Editor/Imgs/Footer_dark.png
new file mode 100644
index 0000000..e48db5e
Binary files /dev/null and b/Assets/Plugins/DOTween/Editor/Imgs/Footer_dark.png differ
diff --git a/Assets/Plugins/DOTween/Editor/Imgs/Footer_dark.png.meta b/Assets/Plugins/DOTween/Editor/Imgs/Footer_dark.png.meta
new file mode 100644
index 0000000..fe8ddcf
--- /dev/null
+++ b/Assets/Plugins/DOTween/Editor/Imgs/Footer_dark.png.meta
@@ -0,0 +1,127 @@
+fileFormatVersion: 2
+guid: 87963014ad9d16b42a59eb99f850c255
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 13
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 1
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ flipGreenChannel: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ vTOnly: 0
+ ignoreMipmapLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 0
+ wrapV: 0
+ wrapW: 0
+ nPOTScale: 1
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 0
+ spriteTessellationDetail: -1
+ textureType: 0
+ textureShape: 1
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 0
+ applyGammaDecoding: 0
+ swizzle: 50462976
+ cookieLightType: 0
+ platformSettings:
+ - serializedVersion: 3
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: Standalone
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: WebGL
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ physicsShape: []
+ bones: []
+ spriteID:
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ nameFileIdTable: {}
+ mipmapLimitGroupName:
+ pSDRemoveMatte: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Editor/Imgs/Header.jpg b/Assets/Plugins/DOTween/Editor/Imgs/Header.jpg
new file mode 100644
index 0000000..4d710d7
Binary files /dev/null and b/Assets/Plugins/DOTween/Editor/Imgs/Header.jpg differ
diff --git a/Assets/Plugins/DOTween/Editor/Imgs/Header.jpg.meta b/Assets/Plugins/DOTween/Editor/Imgs/Header.jpg.meta
new file mode 100644
index 0000000..bdb11f8
--- /dev/null
+++ b/Assets/Plugins/DOTween/Editor/Imgs/Header.jpg.meta
@@ -0,0 +1,127 @@
+fileFormatVersion: 2
+guid: 032c2ac9096e25c4db0e8a4bf95bce47
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 13
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ flipGreenChannel: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ vTOnly: 0
+ ignoreMipmapLimit: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: 1
+ aniso: 1
+ mipBias: 0
+ wrapU: 1
+ wrapV: 1
+ wrapW: 1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 1
+ spriteTessellationDetail: -1
+ textureType: 2
+ textureShape: 1
+ singleChannelComponent: 0
+ flipbookRows: 1
+ flipbookColumns: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ ignorePngGamma: 0
+ applyGammaDecoding: 0
+ swizzle: 50462976
+ cookieLightType: 0
+ platformSettings:
+ - serializedVersion: 3
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 512
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 0
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: Standalone
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: WebGL
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ ignorePlatformSupport: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ physicsShape: []
+ bones: []
+ spriteID:
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ nameFileIdTable: {}
+ mipmapLimitGroupName:
+ pSDRemoveMatte: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Modules.meta b/Assets/Plugins/DOTween/Modules.meta
new file mode 100644
index 0000000..f392c3f
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: bea948af3f04ef34d90aac3117ac5fb5
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModuleAudio.cs b/Assets/Plugins/DOTween/Modules/DOTweenModuleAudio.cs
new file mode 100644
index 0000000..d958ae0
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModuleAudio.cs
@@ -0,0 +1,198 @@
+// Author: Daniele Giardini - http://www.demigiant.com
+// Created: 2018/07/13
+
+#if true // MODULE_MARKER
+using System;
+using DG.Tweening.Core;
+using DG.Tweening.Plugins.Options;
+using UnityEngine;
+using UnityEngine.Audio; // Required for AudioMixer
+
+#pragma warning disable 1591
+namespace DG.Tweening
+{
+ public static class DOTweenModuleAudio
+ {
+ #region Shortcuts
+
+ #region Audio
+
+ /// Tweens an AudioSource's volume to the given value.
+ /// Also stores the AudioSource as the tween's target so it can be used for filtered operations
+ /// The end value to reach (0 to 1)The duration of the tween
+ public static TweenerCore DOFade(this AudioSource target, float endValue, float duration)
+ {
+ if (endValue < 0) endValue = 0;
+ else if (endValue > 1) endValue = 1;
+ TweenerCore t = DOTween.To(() => target.volume, x => target.volume = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ /// Tweens an AudioSource's pitch to the given value.
+ /// Also stores the AudioSource as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOPitch(this AudioSource target, float endValue, float duration)
+ {
+ TweenerCore t = DOTween.To(() => target.pitch, x => target.pitch = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ #endregion
+
+ #region AudioMixer
+
+ /// Tweens an AudioMixer's exposed float to the given value.
+ /// Also stores the AudioMixer as the tween's target so it can be used for filtered operations.
+ /// Note that you need to manually expose a float in an AudioMixerGroup in order to be able to tween it from an AudioMixer.
+ /// Name given to the exposed float to set
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOSetFloat(this AudioMixer target, string floatName, float endValue, float duration)
+ {
+ TweenerCore t = DOTween.To(()=> {
+ float currVal;
+ target.GetFloat(floatName, out currVal);
+ return currVal;
+ }, x=> target.SetFloat(floatName, x), endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ #region Operation Shortcuts
+
+ ///
+ /// Completes all tweens that have this target as a reference
+ /// (meaning tweens that were started from this target, or that had this target added as an Id)
+ /// and returns the total number of tweens completed
+ /// (meaning the tweens that don't have infinite loops and were not already complete)
+ ///
+ /// For Sequences only: if TRUE also internal Sequence callbacks will be fired,
+ /// otherwise they will be ignored
+ public static int DOComplete(this AudioMixer target, bool withCallbacks = false)
+ {
+ return DOTween.Complete(target, withCallbacks);
+ }
+
+ ///
+ /// Kills all tweens that have this target as a reference
+ /// (meaning tweens that were started from this target, or that had this target added as an Id)
+ /// and returns the total number of tweens killed.
+ ///
+ /// If TRUE completes the tween before killing it
+ public static int DOKill(this AudioMixer target, bool complete = false)
+ {
+ return DOTween.Kill(target, complete);
+ }
+
+ ///
+ /// Flips the direction (backwards if it was going forward or viceversa) of all tweens that have this target as a reference
+ /// (meaning tweens that were started from this target, or that had this target added as an Id)
+ /// and returns the total number of tweens flipped.
+ ///
+ public static int DOFlip(this AudioMixer target)
+ {
+ return DOTween.Flip(target);
+ }
+
+ ///
+ /// Sends to the given position all tweens that have this target as a reference
+ /// (meaning tweens that were started from this target, or that had this target added as an Id)
+ /// and returns the total number of tweens involved.
+ ///
+ /// Time position to reach
+ /// (if higher than the whole tween duration the tween will simply reach its end)
+ /// If TRUE will play the tween after reaching the given position, otherwise it will pause it
+ public static int DOGoto(this AudioMixer target, float to, bool andPlay = false)
+ {
+ return DOTween.Goto(target, to, andPlay);
+ }
+
+ ///
+ /// Pauses all tweens that have this target as a reference
+ /// (meaning tweens that were started from this target, or that had this target added as an Id)
+ /// and returns the total number of tweens paused.
+ ///
+ public static int DOPause(this AudioMixer target)
+ {
+ return DOTween.Pause(target);
+ }
+
+ ///
+ /// Plays all tweens that have this target as a reference
+ /// (meaning tweens that were started from this target, or that had this target added as an Id)
+ /// and returns the total number of tweens played.
+ ///
+ public static int DOPlay(this AudioMixer target)
+ {
+ return DOTween.Play(target);
+ }
+
+ ///
+ /// Plays backwards all tweens that have this target as a reference
+ /// (meaning tweens that were started from this target, or that had this target added as an Id)
+ /// and returns the total number of tweens played.
+ ///
+ public static int DOPlayBackwards(this AudioMixer target)
+ {
+ return DOTween.PlayBackwards(target);
+ }
+
+ ///
+ /// Plays forward all tweens that have this target as a reference
+ /// (meaning tweens that were started from this target, or that had this target added as an Id)
+ /// and returns the total number of tweens played.
+ ///
+ public static int DOPlayForward(this AudioMixer target)
+ {
+ return DOTween.PlayForward(target);
+ }
+
+ ///
+ /// Restarts all tweens that have this target as a reference
+ /// (meaning tweens that were started from this target, or that had this target added as an Id)
+ /// and returns the total number of tweens restarted.
+ ///
+ public static int DORestart(this AudioMixer target)
+ {
+ return DOTween.Restart(target);
+ }
+
+ ///
+ /// Rewinds all tweens that have this target as a reference
+ /// (meaning tweens that were started from this target, or that had this target added as an Id)
+ /// and returns the total number of tweens rewinded.
+ ///
+ public static int DORewind(this AudioMixer target)
+ {
+ return DOTween.Rewind(target);
+ }
+
+ ///
+ /// Smoothly rewinds all tweens that have this target as a reference
+ /// (meaning tweens that were started from this target, or that had this target added as an Id)
+ /// and returns the total number of tweens rewinded.
+ ///
+ public static int DOSmoothRewind(this AudioMixer target)
+ {
+ return DOTween.SmoothRewind(target);
+ }
+
+ ///
+ /// Toggles the paused state (plays if it was paused, pauses if it was playing) of all tweens that have this target as a reference
+ /// (meaning tweens that were started from this target, or that had this target added as an Id)
+ /// and returns the total number of tweens involved.
+ ///
+ public static int DOTogglePause(this AudioMixer target)
+ {
+ return DOTween.TogglePause(target);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+ }
+}
+#endif
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModuleAudio.cs.meta b/Assets/Plugins/DOTween/Modules/DOTweenModuleAudio.cs.meta
new file mode 100644
index 0000000..7086233
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModuleAudio.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 08316b88882678c478f093087890cb74
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModuleEPOOutline.cs b/Assets/Plugins/DOTween/Modules/DOTweenModuleEPOOutline.cs
new file mode 100644
index 0000000..2ab3775
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModuleEPOOutline.cs
@@ -0,0 +1,146 @@
+using UnityEngine;
+
+#if false || EPO_DOTWEEN // MODULE_MARKER
+
+using EPOOutline;
+using DG.Tweening.Plugins.Options;
+using DG.Tweening;
+using DG.Tweening.Core;
+
+namespace DG.Tweening
+{
+ public static class DOTweenModuleEPOOutline
+ {
+ public static int DOKill(this SerializedPass target, bool complete)
+ {
+ return DOTween.Kill(target, complete);
+ }
+
+ public static TweenerCore DOFloat(this SerializedPass target, string propertyName, float endValue, float duration)
+ {
+ var tweener = DOTween.To(() => target.GetFloat(propertyName), x => target.SetFloat(propertyName, x), endValue, duration);
+ tweener.SetOptions(true).SetTarget(target);
+ return tweener;
+ }
+
+ public static TweenerCore DOFade(this SerializedPass target, string propertyName, float endValue, float duration)
+ {
+ var tweener = DOTween.ToAlpha(() => target.GetColor(propertyName), x => target.SetColor(propertyName, x), endValue, duration);
+ tweener.SetOptions(true).SetTarget(target);
+ return tweener;
+ }
+
+ public static TweenerCore DOColor(this SerializedPass target, string propertyName, Color endValue, float duration)
+ {
+ var tweener = DOTween.To(() => target.GetColor(propertyName), x => target.SetColor(propertyName, x), endValue, duration);
+ tweener.SetOptions(false).SetTarget(target);
+ return tweener;
+ }
+
+ public static TweenerCore DOVector(this SerializedPass target, string propertyName, Vector4 endValue, float duration)
+ {
+ var tweener = DOTween.To(() => target.GetVector(propertyName), x => target.SetVector(propertyName, x), endValue, duration);
+ tweener.SetOptions(false).SetTarget(target);
+ return tweener;
+ }
+
+ public static TweenerCore DOFloat(this SerializedPass target, int propertyId, float endValue, float duration)
+ {
+ var tweener = DOTween.To(() => target.GetFloat(propertyId), x => target.SetFloat(propertyId, x), endValue, duration);
+ tweener.SetOptions(true).SetTarget(target);
+ return tweener;
+ }
+
+ public static TweenerCore DOFade(this SerializedPass target, int propertyId, float endValue, float duration)
+ {
+ var tweener = DOTween.ToAlpha(() => target.GetColor(propertyId), x => target.SetColor(propertyId, x), endValue, duration);
+ tweener.SetOptions(true).SetTarget(target);
+ return tweener;
+ }
+
+ public static TweenerCore DOColor(this SerializedPass target, int propertyId, Color endValue, float duration)
+ {
+ var tweener = DOTween.To(() => target.GetColor(propertyId), x => target.SetColor(propertyId, x), endValue, duration);
+ tweener.SetOptions(false).SetTarget(target);
+ return tweener;
+ }
+
+ public static TweenerCore DOVector(this SerializedPass target, int propertyId, Vector4 endValue, float duration)
+ {
+ var tweener = DOTween.To(() => target.GetVector(propertyId), x => target.SetVector(propertyId, x), endValue, duration);
+ tweener.SetOptions(false).SetTarget(target);
+ return tweener;
+ }
+
+ public static int DOKill(this Outlinable.OutlineProperties target, bool complete = false)
+ {
+ return DOTween.Kill(target, complete);
+ }
+
+ public static int DOKill(this Outliner target, bool complete = false)
+ {
+ return DOTween.Kill(target, complete);
+ }
+
+ ///
+ /// Controls the alpha (transparency) of the outline
+ ///
+ public static TweenerCore DOFade(this Outlinable.OutlineProperties target, float endValue, float duration)
+ {
+ var tweener = DOTween.ToAlpha(() => target.Color, x => target.Color = x, endValue, duration);
+ tweener.SetOptions(true).SetTarget(target);
+ return tweener;
+ }
+
+ ///
+ /// Controls the color of the outline
+ ///
+ public static TweenerCore DOColor(this Outlinable.OutlineProperties target, Color endValue, float duration)
+ {
+ var tweener = DOTween.To(() => target.Color, x => target.Color = x, endValue, duration);
+ tweener.SetOptions(false).SetTarget(target);
+ return tweener;
+ }
+
+ ///
+ /// Controls the amount of blur applied to the outline
+ ///
+ public static TweenerCore DOBlurShift(this Outlinable.OutlineProperties target, float endValue, float duration, bool snapping = false)
+ {
+ var tweener = DOTween.To(() => target.BlurShift, x => target.BlurShift = x, endValue, duration);
+ tweener.SetOptions(snapping).SetTarget(target);
+ return tweener;
+ }
+
+ ///
+ /// Controls the amount of blur applied to the outline
+ ///
+ public static TweenerCore DOBlurShift(this Outliner target, float endValue, float duration, bool snapping = false)
+ {
+ var tweener = DOTween.To(() => target.BlurShift, x => target.BlurShift = x, endValue, duration);
+ tweener.SetOptions(snapping).SetTarget(target);
+ return tweener;
+ }
+
+ ///
+ /// Controls the amount of dilation applied to the outline
+ ///
+ public static TweenerCore DODilateShift(this Outlinable.OutlineProperties target, float endValue, float duration, bool snapping = false)
+ {
+ var tweener = DOTween.To(() => target.DilateShift, x => target.DilateShift = x, endValue, duration);
+ tweener.SetOptions(snapping).SetTarget(target);
+ return tweener;
+ }
+
+ ///
+ /// Controls the amount of dilation applied to the outline
+ ///
+ public static TweenerCore DODilateShift(this Outliner target, float endValue, float duration, bool snapping = false)
+ {
+ var tweener = DOTween.To(() => target.DilateShift, x => target.DilateShift = x, endValue, duration);
+ tweener.SetOptions(snapping).SetTarget(target);
+ return tweener;
+ }
+ }
+}
+#endif
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModuleEPOOutline.cs.meta b/Assets/Plugins/DOTween/Modules/DOTweenModuleEPOOutline.cs.meta
new file mode 100644
index 0000000..316b825
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModuleEPOOutline.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1ea379e2ae548dc4388fa2c5caad4de8
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModulePhysics.cs b/Assets/Plugins/DOTween/Modules/DOTweenModulePhysics.cs
new file mode 100644
index 0000000..08b0700
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModulePhysics.cs
@@ -0,0 +1,216 @@
+// Author: Daniele Giardini - http://www.demigiant.com
+// Created: 2018/07/13
+
+#if true // MODULE_MARKER
+using System;
+using DG.Tweening.Core;
+using DG.Tweening.Core.Enums;
+using DG.Tweening.Plugins;
+using DG.Tweening.Plugins.Core.PathCore;
+using DG.Tweening.Plugins.Options;
+using UnityEngine;
+
+#pragma warning disable 1591
+namespace DG.Tweening
+{
+ public static class DOTweenModulePhysics
+ {
+ #region Shortcuts
+
+ #region Rigidbody
+
+ /// Tweens a Rigidbody's position to the given value.
+ /// Also stores the rigidbody as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOMove(this Rigidbody target, Vector3 endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.position, target.MovePosition, endValue, duration);
+ t.SetOptions(snapping).SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a Rigidbody's X position to the given value.
+ /// Also stores the rigidbody as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOMoveX(this Rigidbody target, float endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.position, target.MovePosition, new Vector3(endValue, 0, 0), duration);
+ t.SetOptions(AxisConstraint.X, snapping).SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a Rigidbody's Y position to the given value.
+ /// Also stores the rigidbody as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOMoveY(this Rigidbody target, float endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.position, target.MovePosition, new Vector3(0, endValue, 0), duration);
+ t.SetOptions(AxisConstraint.Y, snapping).SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a Rigidbody's Z position to the given value.
+ /// Also stores the rigidbody as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOMoveZ(this Rigidbody target, float endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.position, target.MovePosition, new Vector3(0, 0, endValue), duration);
+ t.SetOptions(AxisConstraint.Z, snapping).SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a Rigidbody's rotation to the given value.
+ /// Also stores the rigidbody as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// Rotation mode
+ public static TweenerCore DORotate(this Rigidbody target, Vector3 endValue, float duration, RotateMode mode = RotateMode.Fast)
+ {
+ TweenerCore t = DOTween.To(() => target.rotation, target.MoveRotation, endValue, duration);
+ t.SetTarget(target);
+ t.plugOptions.rotateMode = mode;
+ return t;
+ }
+
+ /// Tweens a Rigidbody's rotation so that it will look towards the given position.
+ /// Also stores the rigidbody as the tween's target so it can be used for filtered operations
+ /// The position to look atThe duration of the tween
+ /// Eventual axis constraint for the rotation
+ /// The vector that defines in which direction up is (default: Vector3.up)
+ public static TweenerCore DOLookAt(this Rigidbody target, Vector3 towards, float duration, AxisConstraint axisConstraint = AxisConstraint.None, Vector3? up = null)
+ {
+ TweenerCore t = DOTween.To(() => target.rotation, target.MoveRotation, towards, duration)
+ .SetTarget(target).SetSpecialStartupMode(SpecialStartupMode.SetLookAt);
+ t.plugOptions.axisConstraint = axisConstraint;
+ t.plugOptions.up = (up == null) ? Vector3.up : (Vector3)up;
+ return t;
+ }
+
+ #region Special
+
+ /// Tweens a Rigidbody's position to the given value, while also applying a jump effect along the Y axis.
+ /// Returns a Sequence instead of a Tweener.
+ /// Also stores the Rigidbody as the tween's target so it can be used for filtered operations
+ /// The end value to reach
+ /// Power of the jump (the max height of the jump is represented by this plus the final Y offset)
+ /// Total number of jumps
+ /// The duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static Sequence DOJump(this Rigidbody target, Vector3 endValue, float jumpPower, int numJumps, float duration, bool snapping = false)
+ {
+ if (numJumps < 1) numJumps = 1;
+ float startPosY = 0;
+ float offsetY = -1;
+ bool offsetYSet = false;
+ Sequence s = DOTween.Sequence();
+ Tween yTween = DOTween.To(() => target.position, target.MovePosition, new Vector3(0, jumpPower, 0), duration / (numJumps * 2))
+ .SetOptions(AxisConstraint.Y, snapping).SetEase(Ease.OutQuad).SetRelative()
+ .SetLoops(numJumps * 2, LoopType.Yoyo)
+ .OnStart(() => startPosY = target.position.y);
+ s.Append(DOTween.To(() => target.position, target.MovePosition, new Vector3(endValue.x, 0, 0), duration)
+ .SetOptions(AxisConstraint.X, snapping).SetEase(Ease.Linear)
+ ).Join(DOTween.To(() => target.position, target.MovePosition, new Vector3(0, 0, endValue.z), duration)
+ .SetOptions(AxisConstraint.Z, snapping).SetEase(Ease.Linear)
+ ).Join(yTween)
+ .SetTarget(target).SetEase(DOTween.defaultEaseType);
+ yTween.OnUpdate(() => {
+ if (!offsetYSet) {
+ offsetYSet = true;
+ offsetY = s.isRelative ? endValue.y : endValue.y - startPosY;
+ }
+ Vector3 pos = target.position;
+ pos.y += DOVirtual.EasedValue(0, offsetY, yTween.ElapsedPercentage(), Ease.OutQuad);
+ target.MovePosition(pos);
+ });
+ return s;
+ }
+
+ /// Tweens a Rigidbody's position through the given path waypoints, using the chosen path algorithm.
+ /// Also stores the Rigidbody as the tween's target so it can be used for filtered operations.
+ /// NOTE: to tween a rigidbody correctly it should be set to kinematic at least while being tweened.
+ /// BEWARE: doesn't work on Windows Phone store (waiting for Unity to fix their own bug).
+ /// If you plan to publish there you should use a regular transform.DOPath.
+ /// The waypoints to go through
+ /// The duration of the tween
+ /// The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points)
+ /// The path mode: 3D, side-scroller 2D, top-down 2D
+ /// The resolution of the path (useless in case of Linear paths): higher resolutions make for more detailed curved paths but are more expensive.
+ /// Defaults to 10, but a value of 5 is usually enough if you don't have dramatic long curves between waypoints
+ /// The color of the path (shown when gizmos are active in the Play panel and the tween is running)
+ public static TweenerCore DOPath(
+ this Rigidbody target, Vector3[] path, float duration, PathType pathType = PathType.Linear,
+ PathMode pathMode = PathMode.Full3D, int resolution = 10, Color? gizmoColor = null
+ )
+ {
+ if (resolution < 1) resolution = 1;
+ TweenerCore t = DOTween.To(PathPlugin.Get(), () => target.position, target.MovePosition, new Path(pathType, path, resolution, gizmoColor), duration)
+ .SetTarget(target).SetUpdate(UpdateType.Fixed);
+
+ t.plugOptions.isRigidbody = true;
+ t.plugOptions.mode = pathMode;
+ return t;
+ }
+ /// Tweens a Rigidbody's localPosition through the given path waypoints, using the chosen path algorithm.
+ /// Also stores the Rigidbody as the tween's target so it can be used for filtered operations
+ /// NOTE: to tween a rigidbody correctly it should be set to kinematic at least while being tweened.
+ /// BEWARE: doesn't work on Windows Phone store (waiting for Unity to fix their own bug).
+ /// If you plan to publish there you should use a regular transform.DOLocalPath.
+ /// The waypoint to go through
+ /// The duration of the tween
+ /// The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points)
+ /// The path mode: 3D, side-scroller 2D, top-down 2D
+ /// The resolution of the path: higher resolutions make for more detailed curved paths but are more expensive.
+ /// Defaults to 10, but a value of 5 is usually enough if you don't have dramatic long curves between waypoints
+ /// The color of the path (shown when gizmos are active in the Play panel and the tween is running)
+ public static TweenerCore DOLocalPath(
+ this Rigidbody target, Vector3[] path, float duration, PathType pathType = PathType.Linear,
+ PathMode pathMode = PathMode.Full3D, int resolution = 10, Color? gizmoColor = null
+ )
+ {
+ if (resolution < 1) resolution = 1;
+ Transform trans = target.transform;
+ TweenerCore t = DOTween.To(PathPlugin.Get(), () => trans.localPosition, x => target.MovePosition(trans.parent == null ? x : trans.parent.TransformPoint(x)), new Path(pathType, path, resolution, gizmoColor), duration)
+ .SetTarget(target).SetUpdate(UpdateType.Fixed);
+
+ t.plugOptions.isRigidbody = true;
+ t.plugOptions.mode = pathMode;
+ t.plugOptions.useLocalPosition = true;
+ return t;
+ }
+ // Used by path editor when creating the actual tween, so it can pass a pre-compiled path
+ internal static TweenerCore DOPath(
+ this Rigidbody target, Path path, float duration, PathMode pathMode = PathMode.Full3D
+ )
+ {
+ TweenerCore t = DOTween.To(PathPlugin.Get(), () => target.position, target.MovePosition, path, duration)
+ .SetTarget(target);
+
+ t.plugOptions.isRigidbody = true;
+ t.plugOptions.mode = pathMode;
+ return t;
+ }
+ internal static TweenerCore DOLocalPath(
+ this Rigidbody target, Path path, float duration, PathMode pathMode = PathMode.Full3D
+ )
+ {
+ Transform trans = target.transform;
+ TweenerCore t = DOTween.To(PathPlugin.Get(), () => trans.localPosition, x => target.MovePosition(trans.parent == null ? x : trans.parent.TransformPoint(x)), path, duration)
+ .SetTarget(target);
+
+ t.plugOptions.isRigidbody = true;
+ t.plugOptions.mode = pathMode;
+ t.plugOptions.useLocalPosition = true;
+ return t;
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+ }
+}
+#endif
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModulePhysics.cs.meta b/Assets/Plugins/DOTween/Modules/DOTweenModulePhysics.cs.meta
new file mode 100644
index 0000000..d8c763c
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModulePhysics.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6686ce3275e2cdd4abbd5d5557cb249b
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModulePhysics2D.cs b/Assets/Plugins/DOTween/Modules/DOTweenModulePhysics2D.cs
new file mode 100644
index 0000000..8ce2b56
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModulePhysics2D.cs
@@ -0,0 +1,193 @@
+// Author: Daniele Giardini - http://www.demigiant.com
+// Created: 2018/07/13
+
+#if true // MODULE_MARKER
+using System;
+using DG.Tweening.Core;
+using DG.Tweening.Plugins;
+using DG.Tweening.Plugins.Core.PathCore;
+using DG.Tweening.Plugins.Options;
+using UnityEngine;
+
+#pragma warning disable 1591
+namespace DG.Tweening
+{
+ public static class DOTweenModulePhysics2D
+ {
+ #region Shortcuts
+
+ #region Rigidbody2D Shortcuts
+
+ /// Tweens a Rigidbody2D's position to the given value.
+ /// Also stores the Rigidbody2D as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOMove(this Rigidbody2D target, Vector2 endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.position, target.MovePosition, endValue, duration);
+ t.SetOptions(snapping).SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a Rigidbody2D's X position to the given value.
+ /// Also stores the Rigidbody2D as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOMoveX(this Rigidbody2D target, float endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.position, target.MovePosition, new Vector2(endValue, 0), duration);
+ t.SetOptions(AxisConstraint.X, snapping).SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a Rigidbody2D's Y position to the given value.
+ /// Also stores the Rigidbody2D as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOMoveY(this Rigidbody2D target, float endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.position, target.MovePosition, new Vector2(0, endValue), duration);
+ t.SetOptions(AxisConstraint.Y, snapping).SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a Rigidbody2D's rotation to the given value.
+ /// Also stores the Rigidbody2D as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DORotate(this Rigidbody2D target, float endValue, float duration)
+ {
+ TweenerCore t = DOTween.To(() => target.rotation, target.MoveRotation, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ #region Special
+
+ /// Tweens a Rigidbody2D's position to the given value, while also applying a jump effect along the Y axis.
+ /// Returns a Sequence instead of a Tweener.
+ /// Also stores the Rigidbody2D as the tween's target so it can be used for filtered operations.
+ /// IMPORTANT: a rigidbody2D can't be animated in a jump arc using MovePosition, so the tween will directly set the position
+ /// The end value to reach
+ /// Power of the jump (the max height of the jump is represented by this plus the final Y offset)
+ /// Total number of jumps
+ /// The duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static Sequence DOJump(this Rigidbody2D target, Vector2 endValue, float jumpPower, int numJumps, float duration, bool snapping = false)
+ {
+ if (numJumps < 1) numJumps = 1;
+ float startPosY = 0;
+ float offsetY = -1;
+ bool offsetYSet = false;
+ Sequence s = DOTween.Sequence();
+ Tween yTween = DOTween.To(() => target.position, x => target.position = x, new Vector2(0, jumpPower), duration / (numJumps * 2))
+ .SetOptions(AxisConstraint.Y, snapping).SetEase(Ease.OutQuad).SetRelative()
+ .SetLoops(numJumps * 2, LoopType.Yoyo)
+ .OnStart(() => startPosY = target.position.y);
+ s.Append(DOTween.To(() => target.position, x => target.position = x, new Vector2(endValue.x, 0), duration)
+ .SetOptions(AxisConstraint.X, snapping).SetEase(Ease.Linear)
+ ).Join(yTween)
+ .SetTarget(target).SetEase(DOTween.defaultEaseType);
+ yTween.OnUpdate(() => {
+ if (!offsetYSet) {
+ offsetYSet = true;
+ offsetY = s.isRelative ? endValue.y : endValue.y - startPosY;
+ }
+ Vector3 pos = target.position;
+ pos.y += DOVirtual.EasedValue(0, offsetY, yTween.ElapsedPercentage(), Ease.OutQuad);
+ target.MovePosition(pos);
+ });
+ return s;
+ }
+
+ /// Tweens a Rigidbody2D's position through the given path waypoints, using the chosen path algorithm.
+ /// Also stores the Rigidbody2D as the tween's target so it can be used for filtered operations.
+ /// NOTE: to tween a Rigidbody2D correctly it should be set to kinematic at least while being tweened.
+ /// BEWARE: doesn't work on Windows Phone store (waiting for Unity to fix their own bug).
+ /// If you plan to publish there you should use a regular transform.DOPath.
+ /// The waypoints to go through
+ /// The duration of the tween
+ /// The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points)
+ /// The path mode: 3D, side-scroller 2D, top-down 2D
+ /// The resolution of the path (useless in case of Linear paths): higher resolutions make for more detailed curved paths but are more expensive.
+ /// Defaults to 10, but a value of 5 is usually enough if you don't have dramatic long curves between waypoints
+ /// The color of the path (shown when gizmos are active in the Play panel and the tween is running)
+ public static TweenerCore DOPath(
+ this Rigidbody2D target, Vector2[] path, float duration, PathType pathType = PathType.Linear,
+ PathMode pathMode = PathMode.Full3D, int resolution = 10, Color? gizmoColor = null
+ )
+ {
+ if (resolution < 1) resolution = 1;
+ int len = path.Length;
+ Vector3[] path3D = new Vector3[len];
+ for (int i = 0; i < len; ++i) path3D[i] = path[i];
+ TweenerCore t = DOTween.To(PathPlugin.Get(), () => target.position, x => target.MovePosition(x), new Path(pathType, path3D, resolution, gizmoColor), duration)
+ .SetTarget(target).SetUpdate(UpdateType.Fixed);
+
+ t.plugOptions.isRigidbody2D = true;
+ t.plugOptions.mode = pathMode;
+ return t;
+ }
+ /// Tweens a Rigidbody2D's localPosition through the given path waypoints, using the chosen path algorithm.
+ /// Also stores the Rigidbody2D as the tween's target so it can be used for filtered operations
+ /// NOTE: to tween a Rigidbody2D correctly it should be set to kinematic at least while being tweened.
+ /// BEWARE: doesn't work on Windows Phone store (waiting for Unity to fix their own bug).
+ /// If you plan to publish there you should use a regular transform.DOLocalPath.
+ /// The waypoint to go through
+ /// The duration of the tween
+ /// The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points)
+ /// The path mode: 3D, side-scroller 2D, top-down 2D
+ /// The resolution of the path: higher resolutions make for more detailed curved paths but are more expensive.
+ /// Defaults to 10, but a value of 5 is usually enough if you don't have dramatic long curves between waypoints
+ /// The color of the path (shown when gizmos are active in the Play panel and the tween is running)
+ public static TweenerCore DOLocalPath(
+ this Rigidbody2D target, Vector2[] path, float duration, PathType pathType = PathType.Linear,
+ PathMode pathMode = PathMode.Full3D, int resolution = 10, Color? gizmoColor = null
+ )
+ {
+ if (resolution < 1) resolution = 1;
+ int len = path.Length;
+ Vector3[] path3D = new Vector3[len];
+ for (int i = 0; i < len; ++i) path3D[i] = path[i];
+ Transform trans = target.transform;
+ TweenerCore t = DOTween.To(PathPlugin.Get(), () => trans.localPosition, x => target.MovePosition(trans.parent == null ? x : trans.parent.TransformPoint(x)), new Path(pathType, path3D, resolution, gizmoColor), duration)
+ .SetTarget(target).SetUpdate(UpdateType.Fixed);
+
+ t.plugOptions.isRigidbody2D = true;
+ t.plugOptions.mode = pathMode;
+ t.plugOptions.useLocalPosition = true;
+ return t;
+ }
+ // Used by path editor when creating the actual tween, so it can pass a pre-compiled path
+ internal static TweenerCore DOPath(
+ this Rigidbody2D target, Path path, float duration, PathMode pathMode = PathMode.Full3D
+ )
+ {
+ TweenerCore t = DOTween.To(PathPlugin.Get(), () => target.position, x => target.MovePosition(x), path, duration)
+ .SetTarget(target);
+
+ t.plugOptions.isRigidbody2D = true;
+ t.plugOptions.mode = pathMode;
+ return t;
+ }
+ internal static TweenerCore DOLocalPath(
+ this Rigidbody2D target, Path path, float duration, PathMode pathMode = PathMode.Full3D
+ )
+ {
+ Transform trans = target.transform;
+ TweenerCore t = DOTween.To(PathPlugin.Get(), () => trans.localPosition, x => target.MovePosition(trans.parent == null ? x : trans.parent.TransformPoint(x)), path, duration)
+ .SetTarget(target);
+
+ t.plugOptions.isRigidbody2D = true;
+ t.plugOptions.mode = pathMode;
+ t.plugOptions.useLocalPosition = true;
+ return t;
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+ }
+}
+#endif
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModulePhysics2D.cs.meta b/Assets/Plugins/DOTween/Modules/DOTweenModulePhysics2D.cs.meta
new file mode 100644
index 0000000..1bf46d3
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModulePhysics2D.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 545da64eeffb52a498ad13f6390274e9
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModuleSprite.cs b/Assets/Plugins/DOTween/Modules/DOTweenModuleSprite.cs
new file mode 100644
index 0000000..72afb7b
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModuleSprite.cs
@@ -0,0 +1,93 @@
+// Author: Daniele Giardini - http://www.demigiant.com
+// Created: 2018/07/13
+
+#if true // MODULE_MARKER
+using System;
+using UnityEngine;
+using DG.Tweening.Core;
+using DG.Tweening.Plugins.Options;
+
+#pragma warning disable 1591
+namespace DG.Tweening
+{
+ public static class DOTweenModuleSprite
+ {
+ #region Shortcuts
+
+ #region SpriteRenderer
+
+ /// Tweens a SpriteRenderer's color to the given value.
+ /// Also stores the spriteRenderer as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOColor(this SpriteRenderer target, Color endValue, float duration)
+ {
+ TweenerCore t = DOTween.To(() => target.color, x => target.color = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a Material's alpha color to the given value.
+ /// Also stores the spriteRenderer as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOFade(this SpriteRenderer target, float endValue, float duration)
+ {
+ TweenerCore t = DOTween.ToAlpha(() => target.color, x => target.color = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a SpriteRenderer's color using the given gradient
+ /// (NOTE 1: only uses the colors of the gradient, not the alphas - NOTE 2: creates a Sequence, not a Tweener).
+ /// Also stores the image as the tween's target so it can be used for filtered operations
+ /// The gradient to useThe duration of the tween
+ public static Sequence DOGradientColor(this SpriteRenderer target, Gradient gradient, float duration)
+ {
+ Sequence s = DOTween.Sequence();
+ GradientColorKey[] colors = gradient.colorKeys;
+ int len = colors.Length;
+ for (int i = 0; i < len; ++i) {
+ GradientColorKey c = colors[i];
+ if (i == 0 && c.time <= 0) {
+ target.color = c.color;
+ continue;
+ }
+ float colorDuration = i == len - 1
+ ? duration - s.Duration(false) // Verifies that total duration is correct
+ : duration * (i == 0 ? c.time : c.time - colors[i - 1].time);
+ s.Append(target.DOColor(c.color, colorDuration).SetEase(Ease.Linear));
+ }
+ s.SetTarget(target);
+ return s;
+ }
+
+ #endregion
+
+ #region Blendables
+
+ #region SpriteRenderer
+
+ /// Tweens a SpriteRenderer's color to the given value,
+ /// in a way that allows other DOBlendableColor tweens to work together on the same target,
+ /// instead than fight each other as multiple DOColor would do.
+ /// Also stores the SpriteRenderer as the tween's target so it can be used for filtered operations
+ /// The value to tween toThe duration of the tween
+ public static Tweener DOBlendableColor(this SpriteRenderer target, Color endValue, float duration)
+ {
+ endValue = endValue - target.color;
+ Color to = new Color(0, 0, 0, 0);
+ return DOTween.To(() => to, x => {
+ Color diff = x - to;
+ to = x;
+ target.color += diff;
+ }, endValue, duration)
+ .Blendable().SetTarget(target);
+ }
+
+ #endregion
+
+ #endregion
+
+ #endregion
+ }
+}
+#endif
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModuleSprite.cs.meta b/Assets/Plugins/DOTween/Modules/DOTweenModuleSprite.cs.meta
new file mode 100644
index 0000000..cb0b9f3
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModuleSprite.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: cc99c247524e74c46a2036e5bc0b8b42
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModuleUI.cs b/Assets/Plugins/DOTween/Modules/DOTweenModuleUI.cs
new file mode 100644
index 0000000..2381f4c
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModuleUI.cs
@@ -0,0 +1,662 @@
+// Author: Daniele Giardini - http://www.demigiant.com
+// Created: 2018/07/13
+
+#if true // MODULE_MARKER
+
+using System;
+using System.Globalization;
+using UnityEngine;
+using UnityEngine.UI;
+using DG.Tweening.Core;
+using DG.Tweening.Core.Enums;
+using DG.Tweening.Plugins;
+using DG.Tweening.Plugins.Options;
+using Outline = UnityEngine.UI.Outline;
+using Text = UnityEngine.UI.Text;
+
+#pragma warning disable 1591
+namespace DG.Tweening
+{
+ public static class DOTweenModuleUI
+ {
+ #region Shortcuts
+
+ #region CanvasGroup
+
+ /// Tweens a CanvasGroup's alpha color to the given value.
+ /// Also stores the canvasGroup as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOFade(this CanvasGroup target, float endValue, float duration)
+ {
+ TweenerCore t = DOTween.To(() => target.alpha, x => target.alpha = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ #endregion
+
+ #region Graphic
+
+ /// Tweens an Graphic's color to the given value.
+ /// Also stores the image as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOColor(this Graphic target, Color endValue, float duration)
+ {
+ TweenerCore t = DOTween.To(() => target.color, x => target.color = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ /// Tweens an Graphic's alpha color to the given value.
+ /// Also stores the image as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOFade(this Graphic target, float endValue, float duration)
+ {
+ TweenerCore t = DOTween.ToAlpha(() => target.color, x => target.color = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ #endregion
+
+ #region Image
+
+ /// Tweens an Image's color to the given value.
+ /// Also stores the image as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOColor(this Image target, Color endValue, float duration)
+ {
+ TweenerCore t = DOTween.To(() => target.color, x => target.color = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ /// Tweens an Image's alpha color to the given value.
+ /// Also stores the image as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOFade(this Image target, float endValue, float duration)
+ {
+ TweenerCore t = DOTween.ToAlpha(() => target.color, x => target.color = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ /// Tweens an Image's fillAmount to the given value.
+ /// Also stores the image as the tween's target so it can be used for filtered operations
+ /// The end value to reach (0 to 1)The duration of the tween
+ public static TweenerCore DOFillAmount(this Image target, float endValue, float duration)
+ {
+ if (endValue > 1) endValue = 1;
+ else if (endValue < 0) endValue = 0;
+ TweenerCore t = DOTween.To(() => target.fillAmount, x => target.fillAmount = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ /// Tweens an Image's colors using the given gradient
+ /// (NOTE 1: only uses the colors of the gradient, not the alphas - NOTE 2: creates a Sequence, not a Tweener).
+ /// Also stores the image as the tween's target so it can be used for filtered operations
+ /// The gradient to useThe duration of the tween
+ public static Sequence DOGradientColor(this Image target, Gradient gradient, float duration)
+ {
+ Sequence s = DOTween.Sequence();
+ GradientColorKey[] colors = gradient.colorKeys;
+ int len = colors.Length;
+ for (int i = 0; i < len; ++i) {
+ GradientColorKey c = colors[i];
+ if (i == 0 && c.time <= 0) {
+ target.color = c.color;
+ continue;
+ }
+ float colorDuration = i == len - 1
+ ? duration - s.Duration(false) // Verifies that total duration is correct
+ : duration * (i == 0 ? c.time : c.time - colors[i - 1].time);
+ s.Append(target.DOColor(c.color, colorDuration).SetEase(Ease.Linear));
+ }
+ s.SetTarget(target);
+ return s;
+ }
+
+ #endregion
+
+ #region LayoutElement
+
+ /// Tweens an LayoutElement's flexibleWidth/Height to the given value.
+ /// Also stores the LayoutElement as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOFlexibleSize(this LayoutElement target, Vector2 endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => new Vector2(target.flexibleWidth, target.flexibleHeight), x => {
+ target.flexibleWidth = x.x;
+ target.flexibleHeight = x.y;
+ }, endValue, duration);
+ t.SetOptions(snapping).SetTarget(target);
+ return t;
+ }
+
+ /// Tweens an LayoutElement's minWidth/Height to the given value.
+ /// Also stores the LayoutElement as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOMinSize(this LayoutElement target, Vector2 endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => new Vector2(target.minWidth, target.minHeight), x => {
+ target.minWidth = x.x;
+ target.minHeight = x.y;
+ }, endValue, duration);
+ t.SetOptions(snapping).SetTarget(target);
+ return t;
+ }
+
+ /// Tweens an LayoutElement's preferredWidth/Height to the given value.
+ /// Also stores the LayoutElement as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOPreferredSize(this LayoutElement target, Vector2 endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => new Vector2(target.preferredWidth, target.preferredHeight), x => {
+ target.preferredWidth = x.x;
+ target.preferredHeight = x.y;
+ }, endValue, duration);
+ t.SetOptions(snapping).SetTarget(target);
+ return t;
+ }
+
+ #endregion
+
+ #region Outline
+
+ /// Tweens a Outline's effectColor to the given value.
+ /// Also stores the Outline as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOColor(this Outline target, Color endValue, float duration)
+ {
+ TweenerCore t = DOTween.To(() => target.effectColor, x => target.effectColor = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a Outline's effectColor alpha to the given value.
+ /// Also stores the Outline as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOFade(this Outline target, float endValue, float duration)
+ {
+ TweenerCore t = DOTween.ToAlpha(() => target.effectColor, x => target.effectColor = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a Outline's effectDistance to the given value.
+ /// Also stores the Outline as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOScale(this Outline target, Vector2 endValue, float duration)
+ {
+ TweenerCore t = DOTween.To(() => target.effectDistance, x => target.effectDistance = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ #endregion
+
+ #region RectTransform
+
+ /// Tweens a RectTransform's anchoredPosition to the given value.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOAnchorPos(this RectTransform target, Vector2 endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, endValue, duration);
+ t.SetOptions(snapping).SetTarget(target);
+ return t;
+ }
+ /// Tweens a RectTransform's anchoredPosition X to the given value.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOAnchorPosX(this RectTransform target, float endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, new Vector2(endValue, 0), duration);
+ t.SetOptions(AxisConstraint.X, snapping).SetTarget(target);
+ return t;
+ }
+ /// Tweens a RectTransform's anchoredPosition Y to the given value.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOAnchorPosY(this RectTransform target, float endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, new Vector2(0, endValue), duration);
+ t.SetOptions(AxisConstraint.Y, snapping).SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a RectTransform's anchoredPosition3D to the given value.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOAnchorPos3D(this RectTransform target, Vector3 endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.anchoredPosition3D, x => target.anchoredPosition3D = x, endValue, duration);
+ t.SetOptions(snapping).SetTarget(target);
+ return t;
+ }
+ /// Tweens a RectTransform's anchoredPosition3D X to the given value.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOAnchorPos3DX(this RectTransform target, float endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.anchoredPosition3D, x => target.anchoredPosition3D = x, new Vector3(endValue, 0, 0), duration);
+ t.SetOptions(AxisConstraint.X, snapping).SetTarget(target);
+ return t;
+ }
+ /// Tweens a RectTransform's anchoredPosition3D Y to the given value.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOAnchorPos3DY(this RectTransform target, float endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.anchoredPosition3D, x => target.anchoredPosition3D = x, new Vector3(0, endValue, 0), duration);
+ t.SetOptions(AxisConstraint.Y, snapping).SetTarget(target);
+ return t;
+ }
+ /// Tweens a RectTransform's anchoredPosition3D Z to the given value.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOAnchorPos3DZ(this RectTransform target, float endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.anchoredPosition3D, x => target.anchoredPosition3D = x, new Vector3(0, 0, endValue), duration);
+ t.SetOptions(AxisConstraint.Z, snapping).SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a RectTransform's anchorMax to the given value.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOAnchorMax(this RectTransform target, Vector2 endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.anchorMax, x => target.anchorMax = x, endValue, duration);
+ t.SetOptions(snapping).SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a RectTransform's anchorMin to the given value.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOAnchorMin(this RectTransform target, Vector2 endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.anchorMin, x => target.anchorMin = x, endValue, duration);
+ t.SetOptions(snapping).SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a RectTransform's pivot to the given value.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOPivot(this RectTransform target, Vector2 endValue, float duration)
+ {
+ TweenerCore t = DOTween.To(() => target.pivot, x => target.pivot = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+ /// Tweens a RectTransform's pivot X to the given value.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOPivotX(this RectTransform target, float endValue, float duration)
+ {
+ TweenerCore t = DOTween.To(() => target.pivot, x => target.pivot = x, new Vector2(endValue, 0), duration);
+ t.SetOptions(AxisConstraint.X).SetTarget(target);
+ return t;
+ }
+ /// Tweens a RectTransform's pivot Y to the given value.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOPivotY(this RectTransform target, float endValue, float duration)
+ {
+ TweenerCore t = DOTween.To(() => target.pivot, x => target.pivot = x, new Vector2(0, endValue), duration);
+ t.SetOptions(AxisConstraint.Y).SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a RectTransform's sizeDelta to the given value.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOSizeDelta(this RectTransform target, Vector2 endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.sizeDelta, x => target.sizeDelta = x, endValue, duration);
+ t.SetOptions(snapping).SetTarget(target);
+ return t;
+ }
+
+ /// Punches a RectTransform's anchoredPosition towards the given direction and then back to the starting one
+ /// as if it was connected to the starting position via an elastic.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The direction and strength of the punch (added to the RectTransform's current position)
+ /// The duration of the tween
+ /// Indicates how much will the punch vibrate
+ /// Represents how much (0 to 1) the vector will go beyond the starting position when bouncing backwards.
+ /// 1 creates a full oscillation between the punch direction and the opposite direction,
+ /// while 0 oscillates only between the punch and the start position
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static Tweener DOPunchAnchorPos(this RectTransform target, Vector2 punch, float duration, int vibrato = 10, float elasticity = 1, bool snapping = false)
+ {
+ return DOTween.Punch(() => target.anchoredPosition, x => target.anchoredPosition = x, punch, duration, vibrato, elasticity)
+ .SetTarget(target).SetOptions(snapping);
+ }
+
+ /// Shakes a RectTransform's anchoredPosition with the given values.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The duration of the tween
+ /// The shake strength
+ /// Indicates how much will the shake vibrate
+ /// Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware).
+ /// Setting it to 0 will shake along a single direction.
+ /// If TRUE the tween will smoothly snap all values to integers
+ /// If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not
+ /// Randomness mode
+ public static Tweener DOShakeAnchorPos(this RectTransform target, float duration, float strength = 100, int vibrato = 10, float randomness = 90, bool snapping = false, bool fadeOut = true, ShakeRandomnessMode randomnessMode = ShakeRandomnessMode.Full)
+ {
+ return DOTween.Shake(() => target.anchoredPosition, x => target.anchoredPosition = x, duration, strength, vibrato, randomness, true, fadeOut, randomnessMode)
+ .SetTarget(target).SetSpecialStartupMode(SpecialStartupMode.SetShake).SetOptions(snapping);
+ }
+ /// Shakes a RectTransform's anchoredPosition with the given values.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The duration of the tween
+ /// The shake strength on each axis
+ /// Indicates how much will the shake vibrate
+ /// Indicates how much the shake will be random (0 to 180 - values higher than 90 kind of suck, so beware).
+ /// Setting it to 0 will shake along a single direction.
+ /// If TRUE the tween will smoothly snap all values to integers
+ /// If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not
+ /// Randomness mode
+ public static Tweener DOShakeAnchorPos(this RectTransform target, float duration, Vector2 strength, int vibrato = 10, float randomness = 90, bool snapping = false, bool fadeOut = true, ShakeRandomnessMode randomnessMode = ShakeRandomnessMode.Full)
+ {
+ return DOTween.Shake(() => target.anchoredPosition, x => target.anchoredPosition = x, duration, strength, vibrato, randomness, fadeOut, randomnessMode)
+ .SetTarget(target).SetSpecialStartupMode(SpecialStartupMode.SetShake).SetOptions(snapping);
+ }
+
+ #region Special
+
+ /// Tweens a RectTransform's anchoredPosition to the given value, while also applying a jump effect along the Y axis.
+ /// Returns a Sequence instead of a Tweener.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations
+ /// The end value to reach
+ /// Power of the jump (the max height of the jump is represented by this plus the final Y offset)
+ /// Total number of jumps
+ /// The duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static Sequence DOJumpAnchorPos(this RectTransform target, Vector2 endValue, float jumpPower, int numJumps, float duration, bool snapping = false)
+ {
+ if (numJumps < 1) numJumps = 1;
+ float startPosY = 0;
+ float offsetY = -1;
+ bool offsetYSet = false;
+
+ // Separate Y Tween so we can elaborate elapsedPercentage on that insted of on the Sequence
+ // (in case users add a delay or other elements to the Sequence)
+ Sequence s = DOTween.Sequence();
+ Tween yTween = DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, new Vector2(0, jumpPower), duration / (numJumps * 2))
+ .SetOptions(AxisConstraint.Y, snapping).SetEase(Ease.OutQuad).SetRelative()
+ .SetLoops(numJumps * 2, LoopType.Yoyo)
+ .OnStart(()=> startPosY = target.anchoredPosition.y);
+ s.Append(DOTween.To(() => target.anchoredPosition, x => target.anchoredPosition = x, new Vector2(endValue.x, 0), duration)
+ .SetOptions(AxisConstraint.X, snapping).SetEase(Ease.Linear)
+ ).Join(yTween)
+ .SetTarget(target).SetEase(DOTween.defaultEaseType);
+ s.OnUpdate(() => {
+ if (!offsetYSet) {
+ offsetYSet = true;
+ offsetY = s.isRelative ? endValue.y : endValue.y - startPosY;
+ }
+ Vector2 pos = target.anchoredPosition;
+ pos.y += DOVirtual.EasedValue(0, offsetY, s.ElapsedDirectionalPercentage(), Ease.OutQuad);
+ target.anchoredPosition = pos;
+ });
+ return s;
+ }
+
+ #endregion
+
+ #endregion
+
+ #region ScrollRect
+
+ /// Tweens a ScrollRect's horizontal/verticalNormalizedPosition to the given value.
+ /// Also stores the ScrollRect as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static Tweener DONormalizedPos(this ScrollRect target, Vector2 endValue, float duration, bool snapping = false)
+ {
+ return DOTween.To(() => new Vector2(target.horizontalNormalizedPosition, target.verticalNormalizedPosition),
+ x => {
+ target.horizontalNormalizedPosition = x.x;
+ target.verticalNormalizedPosition = x.y;
+ }, endValue, duration)
+ .SetOptions(snapping).SetTarget(target);
+ }
+ /// Tweens a ScrollRect's horizontalNormalizedPosition to the given value.
+ /// Also stores the ScrollRect as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static Tweener DOHorizontalNormalizedPos(this ScrollRect target, float endValue, float duration, bool snapping = false)
+ {
+ return DOTween.To(() => target.horizontalNormalizedPosition, x => target.horizontalNormalizedPosition = x, endValue, duration)
+ .SetOptions(snapping).SetTarget(target);
+ }
+ /// Tweens a ScrollRect's verticalNormalizedPosition to the given value.
+ /// Also stores the ScrollRect as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static Tweener DOVerticalNormalizedPos(this ScrollRect target, float endValue, float duration, bool snapping = false)
+ {
+ return DOTween.To(() => target.verticalNormalizedPosition, x => target.verticalNormalizedPosition = x, endValue, duration)
+ .SetOptions(snapping).SetTarget(target);
+ }
+
+ #endregion
+
+ #region Slider
+
+ /// Tweens a Slider's value to the given value.
+ /// Also stores the Slider as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOValue(this Slider target, float endValue, float duration, bool snapping = false)
+ {
+ TweenerCore t = DOTween.To(() => target.value, x => target.value = x, endValue, duration);
+ t.SetOptions(snapping).SetTarget(target);
+ return t;
+ }
+
+ #endregion
+
+ #region Text
+
+ /// Tweens a Text's color to the given value.
+ /// Also stores the Text as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOColor(this Text target, Color endValue, float duration)
+ {
+ TweenerCore t = DOTween.To(() => target.color, x => target.color = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ ///
+ /// Tweens a Text's text from one integer to another, with options for thousands separators
+ ///
+ /// The value to start from
+ /// The end value to reach
+ /// The duration of the tween
+ /// If TRUE (default) also adds thousands separators
+ /// The to use (InvariantCulture if NULL)
+ public static TweenerCore DOCounter(
+ this Text target, int fromValue, int endValue, float duration, bool addThousandsSeparator = true, CultureInfo culture = null
+ ){
+ int v = fromValue;
+ CultureInfo cInfo = !addThousandsSeparator ? null : culture ?? CultureInfo.InvariantCulture;
+ TweenerCore t = DOTween.To(() => v, x => {
+ v = x;
+ target.text = addThousandsSeparator
+ ? v.ToString("N0", cInfo)
+ : v.ToString();
+ }, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a Text's alpha color to the given value.
+ /// Also stores the Text as the tween's target so it can be used for filtered operations
+ /// The end value to reachThe duration of the tween
+ public static TweenerCore DOFade(this Text target, float endValue, float duration)
+ {
+ TweenerCore t = DOTween.ToAlpha(() => target.color, x => target.color = x, endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a Text's text to the given value.
+ /// Also stores the Text as the tween's target so it can be used for filtered operations
+ /// The end string to tween toThe duration of the tween
+ /// If TRUE (default), rich text will be interpreted correctly while animated,
+ /// otherwise all tags will be considered as normal text
+ /// The type of scramble mode to use, if any
+ /// A string containing the characters to use for scrambling.
+ /// Use as many characters as possible (minimum 10) because DOTween uses a fast scramble mode which gives better results with more characters.
+ /// Leave it to NULL (default) to use default ones
+ public static TweenerCore DOText(this Text target, string endValue, float duration, bool richTextEnabled = true, ScrambleMode scrambleMode = ScrambleMode.None, string scrambleChars = null)
+ {
+ if (endValue == null) {
+ if (Debugger.logPriority > 0) Debugger.LogWarning("You can't pass a NULL string to DOText: an empty string will be used instead to avoid errors");
+ endValue = "";
+ }
+ TweenerCore t = DOTween.To(() => target.text, x => target.text = x, endValue, duration);
+ t.SetOptions(richTextEnabled, scrambleMode, scrambleChars)
+ .SetTarget(target);
+ return t;
+ }
+
+ #endregion
+
+ #region Blendables
+
+ #region Graphic
+
+ /// Tweens a Graphic's color to the given value,
+ /// in a way that allows other DOBlendableColor tweens to work together on the same target,
+ /// instead than fight each other as multiple DOColor would do.
+ /// Also stores the Graphic as the tween's target so it can be used for filtered operations
+ /// The value to tween toThe duration of the tween
+ public static Tweener DOBlendableColor(this Graphic target, Color endValue, float duration)
+ {
+ endValue = endValue - target.color;
+ Color to = new Color(0, 0, 0, 0);
+ return DOTween.To(() => to, x => {
+ Color diff = x - to;
+ to = x;
+ target.color += diff;
+ }, endValue, duration)
+ .Blendable().SetTarget(target);
+ }
+
+ #endregion
+
+ #region Image
+
+ /// Tweens a Image's color to the given value,
+ /// in a way that allows other DOBlendableColor tweens to work together on the same target,
+ /// instead than fight each other as multiple DOColor would do.
+ /// Also stores the Image as the tween's target so it can be used for filtered operations
+ /// The value to tween toThe duration of the tween
+ public static Tweener DOBlendableColor(this Image target, Color endValue, float duration)
+ {
+ endValue = endValue - target.color;
+ Color to = new Color(0, 0, 0, 0);
+ return DOTween.To(() => to, x => {
+ Color diff = x - to;
+ to = x;
+ target.color += diff;
+ }, endValue, duration)
+ .Blendable().SetTarget(target);
+ }
+
+ #endregion
+
+ #region Text
+
+ /// Tweens a Text's color BY the given value,
+ /// in a way that allows other DOBlendableColor tweens to work together on the same target,
+ /// instead than fight each other as multiple DOColor would do.
+ /// Also stores the Text as the tween's target so it can be used for filtered operations
+ /// The value to tween toThe duration of the tween
+ public static Tweener DOBlendableColor(this Text target, Color endValue, float duration)
+ {
+ endValue = endValue - target.color;
+ Color to = new Color(0, 0, 0, 0);
+ return DOTween.To(() => to, x => {
+ Color diff = x - to;
+ to = x;
+ target.color += diff;
+ }, endValue, duration)
+ .Blendable().SetTarget(target);
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Shapes
+
+ /// Tweens a RectTransform's anchoredPosition so that it draws a circle around the given center.
+ /// Also stores the RectTransform as the tween's target so it can be used for filtered operations.
+ /// IMPORTANT: SetFrom(value) requires a instead of a float, where the X property represents the "from degrees value"
+ /// Circle-center/pivot around which to rotate (in UI anchoredPosition coordinates)
+ /// The end value degrees to reach (to rotate counter-clockwise pass a negative value)
+ /// The duration of the tween
+ /// If TRUE the coordinates will be considered as relative to the target's current anchoredPosition
+ /// If TRUE the tween will smoothly snap all values to integers
+ public static TweenerCore DOShapeCircle(
+ this RectTransform target, Vector2 center, float endValueDegrees, float duration, bool relativeCenter = false, bool snapping = false
+ )
+ {
+ TweenerCore t = DOTween.To(
+ CirclePlugin.Get(), () => target.anchoredPosition, x => target.anchoredPosition = x, center, duration
+ );
+ t.SetOptions(endValueDegrees, relativeCenter, snapping).SetTarget(target);
+ return t;
+ }
+
+ #endregion
+
+ #endregion
+
+ // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
+ // ███ INTERNAL CLASSES ████████████████████████████████████████████████████████████████████████████████████████████████
+ // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
+
+ public static class Utils
+ {
+ ///
+ /// Converts the anchoredPosition of the first RectTransform to the second RectTransform,
+ /// taking into consideration offset, anchors and pivot, and returns the new anchoredPosition
+ ///
+ public static Vector2 SwitchToRectTransform(RectTransform from, RectTransform to)
+ {
+ Vector2 localPoint;
+ Vector2 fromPivotDerivedOffset = new Vector2(from.rect.width * 0.5f + from.rect.xMin, from.rect.height * 0.5f + from.rect.yMin);
+ Vector2 screenP = RectTransformUtility.WorldToScreenPoint(null, from.position);
+ screenP += fromPivotDerivedOffset;
+ RectTransformUtility.ScreenPointToLocalPointInRectangle(to, screenP, null, out localPoint);
+ Vector2 pivotDerivedOffset = new Vector2(to.rect.width * 0.5f + to.rect.xMin, to.rect.height * 0.5f + to.rect.yMin);
+ return to.anchoredPosition + localPoint - pivotDerivedOffset;
+ }
+ }
+ }
+}
+#endif
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModuleUI.cs.meta b/Assets/Plugins/DOTween/Modules/DOTweenModuleUI.cs.meta
new file mode 100644
index 0000000..142bd25
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModuleUI.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: b3b53ff0082fc3e489adf16ee160d4f2
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModuleUnityVersion.cs b/Assets/Plugins/DOTween/Modules/DOTweenModuleUnityVersion.cs
new file mode 100644
index 0000000..8f818ba
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModuleUnityVersion.cs
@@ -0,0 +1,389 @@
+// Author: Daniele Giardini - http://www.demigiant.com
+// Created: 2018/07/13
+
+using System;
+using UnityEngine;
+using DG.Tweening.Core;
+using DG.Tweening.Plugins.Options;
+//#if UNITY_2018_1_OR_NEWER && (NET_4_6 || NET_STANDARD_2_0)
+//using Task = System.Threading.Tasks.Task;
+//#endif
+
+#pragma warning disable 1591
+namespace DG.Tweening
+{
+ ///
+ /// Shortcuts/functions that are not strictly related to specific Modules
+ /// but are available only on some Unity versions
+ ///
+ public static class DOTweenModuleUnityVersion
+ {
+ #region Material
+
+ /// Tweens a Material's color using the given gradient
+ /// (NOTE 1: only uses the colors of the gradient, not the alphas - NOTE 2: creates a Sequence, not a Tweener).
+ /// Also stores the image as the tween's target so it can be used for filtered operations
+ /// The gradient to useThe duration of the tween
+ public static Sequence DOGradientColor(this Material target, Gradient gradient, float duration)
+ {
+ Sequence s = DOTween.Sequence();
+ GradientColorKey[] colors = gradient.colorKeys;
+ int len = colors.Length;
+ for (int i = 0; i < len; ++i) {
+ GradientColorKey c = colors[i];
+ if (i == 0 && c.time <= 0) {
+ target.color = c.color;
+ continue;
+ }
+ float colorDuration = i == len - 1
+ ? duration - s.Duration(false) // Verifies that total duration is correct
+ : duration * (i == 0 ? c.time : c.time - colors[i - 1].time);
+ s.Append(target.DOColor(c.color, colorDuration).SetEase(Ease.Linear));
+ }
+ s.SetTarget(target);
+ return s;
+ }
+ /// Tweens a Material's named color property using the given gradient
+ /// (NOTE 1: only uses the colors of the gradient, not the alphas - NOTE 2: creates a Sequence, not a Tweener).
+ /// Also stores the image as the tween's target so it can be used for filtered operations
+ /// The gradient to use
+ /// The name of the material property to tween (like _Tint or _SpecColor)
+ /// The duration of the tween
+ public static Sequence DOGradientColor(this Material target, Gradient gradient, string property, float duration)
+ {
+ Sequence s = DOTween.Sequence();
+ GradientColorKey[] colors = gradient.colorKeys;
+ int len = colors.Length;
+ for (int i = 0; i < len; ++i) {
+ GradientColorKey c = colors[i];
+ if (i == 0 && c.time <= 0) {
+ target.SetColor(property, c.color);
+ continue;
+ }
+ float colorDuration = i == len - 1
+ ? duration - s.Duration(false) // Verifies that total duration is correct
+ : duration * (i == 0 ? c.time : c.time - colors[i - 1].time);
+ s.Append(target.DOColor(c.color, property, colorDuration).SetEase(Ease.Linear));
+ }
+ s.SetTarget(target);
+ return s;
+ }
+
+ #endregion
+
+ #region CustomYieldInstructions
+
+ ///
+ /// Returns a that waits until the tween is killed or complete.
+ /// It can be used inside a coroutine as a yield.
+ /// Example usage:yield return myTween.WaitForCompletion(true);
+ ///
+ public static CustomYieldInstruction WaitForCompletion(this Tween t, bool returnCustomYieldInstruction)
+ {
+ if (!t.active) {
+ if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
+ return null;
+ }
+ return new DOTweenCYInstruction.WaitForCompletion(t);
+ }
+
+ ///
+ /// Returns a that waits until the tween is killed or rewinded.
+ /// It can be used inside a coroutine as a yield.
+ /// Example usage:yield return myTween.WaitForRewind();
+ ///
+ public static CustomYieldInstruction WaitForRewind(this Tween t, bool returnCustomYieldInstruction)
+ {
+ if (!t.active) {
+ if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
+ return null;
+ }
+ return new DOTweenCYInstruction.WaitForRewind(t);
+ }
+
+ ///
+ /// Returns a that waits until the tween is killed.
+ /// It can be used inside a coroutine as a yield.
+ /// Example usage:yield return myTween.WaitForKill();
+ ///
+ public static CustomYieldInstruction WaitForKill(this Tween t, bool returnCustomYieldInstruction)
+ {
+ if (!t.active) {
+ if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
+ return null;
+ }
+ return new DOTweenCYInstruction.WaitForKill(t);
+ }
+
+ ///
+ /// Returns a that waits until the tween is killed or has gone through the given amount of loops.
+ /// It can be used inside a coroutine as a yield.
+ /// Example usage:yield return myTween.WaitForElapsedLoops(2);
+ ///
+ /// Elapsed loops to wait for
+ public static CustomYieldInstruction WaitForElapsedLoops(this Tween t, int elapsedLoops, bool returnCustomYieldInstruction)
+ {
+ if (!t.active) {
+ if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
+ return null;
+ }
+ return new DOTweenCYInstruction.WaitForElapsedLoops(t, elapsedLoops);
+ }
+
+ ///
+ /// Returns a that waits until the tween is killed
+ /// or has reached the given time position (loops included, delays excluded).
+ /// It can be used inside a coroutine as a yield.
+ /// Example usage:yield return myTween.WaitForPosition(2.5f);
+ ///
+ /// Position (loops included, delays excluded) to wait for
+ public static CustomYieldInstruction WaitForPosition(this Tween t, float position, bool returnCustomYieldInstruction)
+ {
+ if (!t.active) {
+ if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
+ return null;
+ }
+ return new DOTweenCYInstruction.WaitForPosition(t, position);
+ }
+
+ ///
+ /// Returns a that waits until the tween is killed or started
+ /// (meaning when the tween is set in a playing state the first time, after any eventual delay).
+ /// It can be used inside a coroutine as a yield.
+ /// Example usage:yield return myTween.WaitForStart();
+ ///
+ public static CustomYieldInstruction WaitForStart(this Tween t, bool returnCustomYieldInstruction)
+ {
+ if (!t.active) {
+ if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
+ return null;
+ }
+ return new DOTweenCYInstruction.WaitForStart(t);
+ }
+
+ #endregion
+
+#if UNITY_2018_1_OR_NEWER
+ #region Unity 2018.1 or Newer
+
+ #region Material
+
+ /// Tweens a Material's named texture offset property with the given ID to the given value.
+ /// Also stores the material as the tween's target so it can be used for filtered operations
+ /// The end value to reach
+ /// The ID of the material property to tween (also called nameID in Unity's manual)
+ /// The duration of the tween
+ public static TweenerCore DOOffset(this Material target, Vector2 endValue, int propertyID, float duration)
+ {
+ if (!target.HasProperty(propertyID)) {
+ if (Debugger.logPriority > 0) Debugger.LogMissingMaterialProperty(propertyID);
+ return null;
+ }
+ TweenerCore t = DOTween.To(() => target.GetTextureOffset(propertyID), x => target.SetTextureOffset(propertyID, x), endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ /// Tweens a Material's named texture scale property with the given ID to the given value.
+ /// Also stores the material as the tween's target so it can be used for filtered operations
+ /// The end value to reach
+ /// The ID of the material property to tween (also called nameID in Unity's manual)
+ /// The duration of the tween
+ public static TweenerCore DOTiling(this Material target, Vector2 endValue, int propertyID, float duration)
+ {
+ if (!target.HasProperty(propertyID)) {
+ if (Debugger.logPriority > 0) Debugger.LogMissingMaterialProperty(propertyID);
+ return null;
+ }
+ TweenerCore t = DOTween.To(() => target.GetTextureScale(propertyID), x => target.SetTextureScale(propertyID, x), endValue, duration);
+ t.SetTarget(target);
+ return t;
+ }
+
+ #endregion
+
+ #region .NET 4.6 or Newer
+
+#if UNITY_2018_1_OR_NEWER && (NET_4_6 || NET_STANDARD_2_0)
+
+ #region Async Instructions
+
+ ///
+ /// Returns an async that waits until the tween is killed or complete.
+ /// It can be used inside an async operation.
+ /// Example usage:await myTween.WaitForCompletion();
+ ///
+ public static async System.Threading.Tasks.Task AsyncWaitForCompletion(this Tween t)
+ {
+ if (!t.active) {
+ if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
+ return;
+ }
+ while (t.active && !t.IsComplete()) await System.Threading.Tasks.Task.Yield();
+ }
+
+ ///
+ /// Returns an async that waits until the tween is killed or rewinded.
+ /// It can be used inside an async operation.
+ /// Example usage:await myTween.AsyncWaitForRewind();
+ ///
+ public static async System.Threading.Tasks.Task AsyncWaitForRewind(this Tween t)
+ {
+ if (!t.active) {
+ if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
+ return;
+ }
+ while (t.active && (!t.playedOnce || t.position * (t.CompletedLoops() + 1) > 0)) await System.Threading.Tasks.Task.Yield();
+ }
+
+ ///
+ /// Returns an async that waits until the tween is killed.
+ /// It can be used inside an async operation.
+ /// Example usage:await myTween.AsyncWaitForKill();
+ ///
+ public static async System.Threading.Tasks.Task AsyncWaitForKill(this Tween t)
+ {
+ if (!t.active) {
+ if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
+ return;
+ }
+ while (t.active) await System.Threading.Tasks.Task.Yield();
+ }
+
+ ///
+ /// Returns an async that waits until the tween is killed or has gone through the given amount of loops.
+ /// It can be used inside an async operation.
+ /// Example usage:await myTween.AsyncWaitForElapsedLoops();
+ ///
+ /// Elapsed loops to wait for
+ public static async System.Threading.Tasks.Task AsyncWaitForElapsedLoops(this Tween t, int elapsedLoops)
+ {
+ if (!t.active) {
+ if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
+ return;
+ }
+ while (t.active && t.CompletedLoops() < elapsedLoops) await System.Threading.Tasks.Task.Yield();
+ }
+
+ ///
+ /// Returns an async that waits until the tween is killed or started
+ /// (meaning when the tween is set in a playing state the first time, after any eventual delay).
+ /// It can be used inside an async operation.
+ /// Example usage:await myTween.AsyncWaitForPosition();
+ ///
+ /// Position (loops included, delays excluded) to wait for
+ public static async System.Threading.Tasks.Task AsyncWaitForPosition(this Tween t, float position)
+ {
+ if (!t.active) {
+ if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
+ return;
+ }
+ while (t.active && t.position * (t.CompletedLoops() + 1) < position) await System.Threading.Tasks.Task.Yield();
+ }
+
+ ///
+ /// Returns an async that waits until the tween is killed.
+ /// It can be used inside an async operation.
+ /// Example usage:await myTween.AsyncWaitForKill();
+ ///
+ public static async System.Threading.Tasks.Task AsyncWaitForStart(this Tween t)
+ {
+ if (!t.active) {
+ if (Debugger.logPriority > 0) Debugger.LogInvalidTween(t);
+ return;
+ }
+ while (t.active && !t.playedOnce) await System.Threading.Tasks.Task.Yield();
+ }
+
+ #endregion
+#endif
+
+ #endregion
+
+ #endregion
+#endif
+ }
+
+ // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
+ // ███ CLASSES █████████████████████████████████████████████████████████████████████████████████████████████████████████
+ // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
+
+ public static class DOTweenCYInstruction
+ {
+ public class WaitForCompletion : CustomYieldInstruction
+ {
+ public override bool keepWaiting { get {
+ return t.active && !t.IsComplete();
+ }}
+ readonly Tween t;
+ public WaitForCompletion(Tween tween)
+ {
+ t = tween;
+ }
+ }
+
+ public class WaitForRewind : CustomYieldInstruction
+ {
+ public override bool keepWaiting { get {
+ return t.active && (!t.playedOnce || t.position * (t.CompletedLoops() + 1) > 0);
+ }}
+ readonly Tween t;
+ public WaitForRewind(Tween tween)
+ {
+ t = tween;
+ }
+ }
+
+ public class WaitForKill : CustomYieldInstruction
+ {
+ public override bool keepWaiting { get {
+ return t.active;
+ }}
+ readonly Tween t;
+ public WaitForKill(Tween tween)
+ {
+ t = tween;
+ }
+ }
+
+ public class WaitForElapsedLoops : CustomYieldInstruction
+ {
+ public override bool keepWaiting { get {
+ return t.active && t.CompletedLoops() < elapsedLoops;
+ }}
+ readonly Tween t;
+ readonly int elapsedLoops;
+ public WaitForElapsedLoops(Tween tween, int elapsedLoops)
+ {
+ t = tween;
+ this.elapsedLoops = elapsedLoops;
+ }
+ }
+
+ public class WaitForPosition : CustomYieldInstruction
+ {
+ public override bool keepWaiting { get {
+ return t.active && t.position * (t.CompletedLoops() + 1) < position;
+ }}
+ readonly Tween t;
+ readonly float position;
+ public WaitForPosition(Tween tween, float position)
+ {
+ t = tween;
+ this.position = position;
+ }
+ }
+
+ public class WaitForStart : CustomYieldInstruction
+ {
+ public override bool keepWaiting { get {
+ return t.active && !t.playedOnce;
+ }}
+ readonly Tween t;
+ public WaitForStart(Tween tween)
+ {
+ t = tween;
+ }
+ }
+ }
+}
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModuleUnityVersion.cs.meta b/Assets/Plugins/DOTween/Modules/DOTweenModuleUnityVersion.cs.meta
new file mode 100644
index 0000000..98b2eaf
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModuleUnityVersion.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 18d9445fb6655ae47ba1f4ea558de307
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModuleUtils.cs b/Assets/Plugins/DOTween/Modules/DOTweenModuleUtils.cs
new file mode 100644
index 0000000..12a365d
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModuleUtils.cs
@@ -0,0 +1,167 @@
+// Author: Daniele Giardini - http://www.demigiant.com
+// Created: 2018/07/13
+
+using System;
+using System.Reflection;
+using UnityEngine;
+using DG.Tweening.Core;
+using DG.Tweening.Plugins.Core.PathCore;
+using DG.Tweening.Plugins.Options;
+
+#pragma warning disable 1591
+namespace DG.Tweening
+{
+ ///
+ /// Utility functions that deal with available Modules.
+ /// Modules defines:
+ /// - DOTAUDIO
+ /// - DOTPHYSICS
+ /// - DOTPHYSICS2D
+ /// - DOTSPRITE
+ /// - DOTUI
+ /// Extra defines set and used for implementation of external assets:
+ /// - DOTWEEN_TMP ► TextMesh Pro
+ /// - DOTWEEN_TK2D ► 2D Toolkit
+ ///
+ public static class DOTweenModuleUtils
+ {
+ static bool _initialized;
+
+ #region Reflection
+
+ ///
+ /// Called via Reflection by DOTweenComponent on Awake
+ ///
+#if UNITY_2018_1_OR_NEWER
+ [UnityEngine.Scripting.Preserve]
+#endif
+ public static void Init()
+ {
+ if (_initialized) return;
+
+ _initialized = true;
+ DOTweenExternalCommand.SetOrientationOnPath += Physics.SetOrientationOnPath;
+
+#if UNITY_EDITOR
+#if UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_5 || UNITY_2017_1
+ UnityEditor.EditorApplication.playmodeStateChanged += PlaymodeStateChanged;
+#else
+ UnityEditor.EditorApplication.playModeStateChanged += PlaymodeStateChanged;
+#endif
+#endif
+ }
+
+#if UNITY_2018_1_OR_NEWER
+#pragma warning disable
+ [UnityEngine.Scripting.Preserve]
+ // Just used to preserve methods when building, never called
+ static void Preserver()
+ {
+ Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
+ MethodInfo mi = typeof(MonoBehaviour).GetMethod("Stub");
+ }
+#pragma warning restore
+#endif
+
+ #endregion
+
+#if UNITY_EDITOR
+ // Fires OnApplicationPause in DOTweenComponent even when Editor is paused (otherwise it's only fired at runtime)
+#if UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_5 || UNITY_2017_1
+ static void PlaymodeStateChanged()
+ #else
+ static void PlaymodeStateChanged(UnityEditor.PlayModeStateChange state)
+#endif
+ {
+ if (DOTween.instance == null) return;
+ DOTween.instance.OnApplicationPause(UnityEditor.EditorApplication.isPaused);
+ }
+#endif
+
+ // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
+ // ███ INTERNAL CLASSES ████████████████████████████████████████████████████████████████████████████████████████████████
+ // █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
+
+ public static class Physics
+ {
+ // Called via DOTweenExternalCommand callback
+ public static void SetOrientationOnPath(PathOptions options, Tween t, Quaternion newRot, Transform trans)
+ {
+#if true // PHYSICS_MARKER
+ if (options.isRigidbody) ((Rigidbody)t.target).rotation = newRot;
+ else trans.rotation = newRot;
+#else
+ trans.rotation = newRot;
+#endif
+ }
+
+ // Returns FALSE if the DOTween's Physics2D Module is disabled, or if there's no Rigidbody2D attached
+ public static bool HasRigidbody2D(Component target)
+ {
+#if true // PHYSICS2D_MARKER
+ return target.GetComponent() != null;
+#else
+ return false;
+#endif
+ }
+
+ #region Called via Reflection
+
+
+ // Called via Reflection by DOTweenPathInspector
+ // Returns FALSE if the DOTween's Physics Module is disabled, or if there's no rigidbody attached
+#if UNITY_2018_1_OR_NEWER
+ [UnityEngine.Scripting.Preserve]
+#endif
+ public static bool HasRigidbody(Component target)
+ {
+#if true // PHYSICS_MARKER
+ return target.GetComponent() != null;
+#else
+ return false;
+#endif
+ }
+
+ // Called via Reflection by DOTweenPath
+#if UNITY_2018_1_OR_NEWER
+ [UnityEngine.Scripting.Preserve]
+#endif
+ public static TweenerCore CreateDOTweenPathTween(
+ MonoBehaviour target, bool tweenRigidbody, bool isLocal, Path path, float duration, PathMode pathMode
+ ){
+ TweenerCore t = null;
+ bool rBodyFoundAndTweened = false;
+#if true // PHYSICS_MARKER
+ if (tweenRigidbody) {
+ Rigidbody rBody = target.GetComponent();
+ if (rBody != null) {
+ rBodyFoundAndTweened = true;
+ t = isLocal
+ ? rBody.DOLocalPath(path, duration, pathMode)
+ : rBody.DOPath(path, duration, pathMode);
+ }
+ }
+#endif
+#if true // PHYSICS2D_MARKER
+ if (!rBodyFoundAndTweened && tweenRigidbody) {
+ Rigidbody2D rBody2D = target.GetComponent();
+ if (rBody2D != null) {
+ rBodyFoundAndTweened = true;
+ t = isLocal
+ ? rBody2D.DOLocalPath(path, duration, pathMode)
+ : rBody2D.DOPath(path, duration, pathMode);
+ }
+ }
+#endif
+ if (!rBodyFoundAndTweened) {
+ t = isLocal
+ ? target.transform.DOLocalPath(path, duration, pathMode)
+ : target.transform.DOPath(path, duration, pathMode);
+ }
+ return t;
+ }
+
+ #endregion
+ }
+ }
+}
diff --git a/Assets/Plugins/DOTween/Modules/DOTweenModuleUtils.cs.meta b/Assets/Plugins/DOTween/Modules/DOTweenModuleUtils.cs.meta
new file mode 100644
index 0000000..f1215ab
--- /dev/null
+++ b/Assets/Plugins/DOTween/Modules/DOTweenModuleUtils.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 3bdc077a2bdb5324dafe472d24497d33
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/DOTween/readme.txt b/Assets/Plugins/DOTween/readme.txt
new file mode 100644
index 0000000..37ff7ef
--- /dev/null
+++ b/Assets/Plugins/DOTween/readme.txt
@@ -0,0 +1,29 @@
+DOTween and DOTween Pro are copyright (c) 2014-2018 Daniele Giardini - Demigiant
+
+// IMPORTANT!!! /////////////////////////////////////////////
+// Upgrading DOTween from versions older than 1.2.000 ///////
+// (or DOTween Pro older than 1.0.000) //////////////////////
+-------------------------------------------------------------
+If you're upgrading your project from a version of DOTween older than 1.2.000 (or DOTween Pro older than 1.0.000) please follow these instructions carefully.
+1) Import the new version in the same folder as the previous one, overwriting old files. A lot of errors will appear but don't worry
+2) Close and reopen Unity (and your project). This is fundamental: skipping this step will cause a bloodbath
+3) Open DOTween's Utility Panel (Tools > Demigiant > DOTween Utility Panel) if it doesn't open automatically, then press "Setup DOTween...": this will run the upgrade setup
+4) From the Add/Remove Modules panel that opens, activate/deactivate Modules for Unity systems and for external assets (Pro version only)
+
+// GET STARTED //////////////////////////////////////////////
+
+- After importing a new DOTween update, select DOTween's Utility Panel from the "Tools/Demigiant" menu (if it doesn't open automatically) and press the "Setup DOTween..." button to activate/deactivate Modules. You can also access a Preferences Tab from there to choose default settings for DOTween.
+- In your code, add "using DG.Tweening" to each class where you want to use DOTween.
+- You're ready to tween. Check out the links below for full documentation and license info.
+
+
+// LINKS ///////////////////////////////////////////////////////
+
+DOTween website (documentation, examples, etc): http://dotween.demigiant.com
+DOTween license: http://dotween.demigiant.com/license.php
+DOTween repository (Google Code): https://code.google.com/p/dotween/
+Demigiant website (documentation, examples, etc): http://www.demigiant.com
+
+// NOTES //////////////////////////////////////////////////////
+
+- DOTween's Utility Panel can be found under "Tools > Demigiant > DOTween Utility Panel" and also contains other useful options, plus a tab to set DOTween's preferences
\ No newline at end of file
diff --git a/Assets/Plugins/DOTween/readme.txt.meta b/Assets/Plugins/DOTween/readme.txt.meta
new file mode 100644
index 0000000..74ae866
--- /dev/null
+++ b/Assets/Plugins/DOTween/readme.txt.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 26cb44389b6669e479fed562495bc607
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus.meta b/Assets/Plugins/HighlightPlus.meta
new file mode 100644
index 0000000..2e0dc37
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 13d3639a276fe974c8db4da86dc6a69a
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Editor.meta b/Assets/Plugins/HighlightPlus/Editor.meta
new file mode 100644
index 0000000..e4f8846
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c4d9487b5d51a5340b44d2df89c0d411
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Editor/HighlightEffectEditor.cs b/Assets/Plugins/HighlightPlus/Editor/HighlightEffectEditor.cs
new file mode 100644
index 0000000..6d2f4d9
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor/HighlightEffectEditor.cs
@@ -0,0 +1,675 @@
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+
+namespace HighlightPlus {
+
+ [CustomEditor(typeof(HighlightEffect))]
+ [CanEditMultipleObjects]
+ public class HighlightEffectEditor : Editor {
+
+#pragma warning disable 0618
+
+ SerializedProperty profile, profileSync, camerasLayerMask, ignoreObjectVisibility, reflectionProbes, GPUInstancing;
+ SerializedProperty ignore, previewInEditor, effectGroup, effectGroupLayer, effectNameFilter, combineMeshes, alphaCutOff, cullBackFaces, depthClip, normalsOption, subMeshMask;
+ SerializedProperty highlighted, fadeInDuration, fadeOutDuration, flipY, constantWidth;
+ SerializedProperty overlay, overlayMode, overlayColor, overlayAnimationSpeed, overlayMinIntensity, overlayBlending, overlayTexture, overlayTextureUVSpace, overlayTextureScale;
+ SerializedProperty outline, outlineColor, outlineColorStyle, outlineGradient, outlineGradientInLocalSpace, outlineWidth, outlineQuality, outlineDownsampling, outlineVisibility, outlineOptimalBlit, outlineBlitDebug, outlineIndependent;
+ SerializedProperty glow, glowWidth, glowQuality, glowDownsampling, glowHQColor, glowDithering, glowMagicNumber1, glowMagicNumber2, glowAnimationSpeed, glowBlendPasses, glowPasses, glowVisibility, glowBlendMode, glowOptimalBlit, glowBlitDebug, glowIgnoreMask;
+ SerializedProperty innerGlow, innerGlowWidth, innerGlowColor, innerGlowVisibility;
+ SerializedProperty seeThrough, seeThroughOccluderMask, seeThroughOccluderMaskAccurate, seeThroughOccluderThreshold, seeThroughOccluderCheckInterval, seeThroughOccluderCheckIndividualObjects, seeThroughDepthOffset, seeThroughMaxDepth;
+ SerializedProperty seeThroughIntensity, seeThroughTintAlpha, seeThroughTintColor, seeThroughNoise, seeThroughBorder, seeThroughBorderWidth, seeThroughBorderColor, seeThroughOrdered, seeThroughBorderOnly, seeThroughTexture, seeThroughTextureUVSpace, seeThroughTextureScale;
+ SerializedProperty targetFX, targetFXTexture, targetFXColor, targetFXCenter, targetFXRotationSpeed, targetFXInitialScale, targetFXEndScale, targetFXScaleToRenderBounds;
+ SerializedProperty targetFXAlignToGround, targetFXFadePower, targetFXGroundMaxDistance, targetFXGroundLayerMask, targetFXTransitionDuration, targetFXStayDuration, targetFXVisibility;
+ SerializedProperty hitFxInitialIntensity, hitFxMode, hitFxFadeOutDuration, hitFxColor, hitFxRadius;
+ SerializedProperty cameraDistanceFade, cameraDistanceFadeNear, cameraDistanceFadeFar;
+
+ HighlightEffect thisEffect;
+ bool profileChanged, enableProfileApply;
+ bool expandGeneralSettings, expandHighlightOptions;
+ bool showCurrentOccluders;
+ const string HP_GENERAL_SETTINGS = "HPGeneralSettings";
+ const string HP_HIGHLIGHT_OPTIONS = "HPHighlightOptions";
+ GUIStyle foldoutBold;
+
+ void OnEnable() {
+ expandGeneralSettings = EditorPrefs.GetBool("HPGeneralSettings", true);
+ expandHighlightOptions = EditorPrefs.GetBool("HPHighlightOptions", true);
+
+ profile = serializedObject.FindProperty("profile");
+ profileSync = serializedObject.FindProperty("profileSync");
+ camerasLayerMask = serializedObject.FindProperty("camerasLayerMask");
+ reflectionProbes = serializedObject.FindProperty("reflectionProbes");
+ ignoreObjectVisibility = serializedObject.FindProperty("ignoreObjectVisibility");
+ GPUInstancing = serializedObject.FindProperty("GPUInstancing");
+ normalsOption = serializedObject.FindProperty("normalsOption");
+ subMeshMask = serializedObject.FindProperty("subMeshMask");
+ ignore = serializedObject.FindProperty("ignore");
+ previewInEditor = serializedObject.FindProperty("previewInEditor");
+ effectGroup = serializedObject.FindProperty("effectGroup");
+ effectGroupLayer = serializedObject.FindProperty("effectGroupLayer");
+ effectNameFilter = serializedObject.FindProperty("effectNameFilter");
+ combineMeshes = serializedObject.FindProperty("combineMeshes");
+ alphaCutOff = serializedObject.FindProperty("alphaCutOff");
+ cullBackFaces = serializedObject.FindProperty("cullBackFaces");
+ depthClip = serializedObject.FindProperty("depthClip");
+ highlighted = serializedObject.FindProperty("_highlighted");
+ fadeInDuration = serializedObject.FindProperty("fadeInDuration");
+ fadeOutDuration = serializedObject.FindProperty("fadeOutDuration");
+ flipY = serializedObject.FindProperty("flipY");
+ constantWidth = serializedObject.FindProperty("constantWidth");
+ overlay = serializedObject.FindProperty("overlay");
+ overlayMode = serializedObject.FindProperty("overlayMode");
+ overlayColor = serializedObject.FindProperty("overlayColor");
+ overlayAnimationSpeed = serializedObject.FindProperty("overlayAnimationSpeed");
+ overlayMinIntensity = serializedObject.FindProperty("overlayMinIntensity");
+ overlayBlending = serializedObject.FindProperty("overlayBlending");
+ overlayTexture = serializedObject.FindProperty("overlayTexture");
+ overlayTextureUVSpace = serializedObject.FindProperty("overlayTextureUVSpace");
+ overlayTextureScale = serializedObject.FindProperty("overlayTextureScale");
+ outline = serializedObject.FindProperty("outline");
+ outlineColor = serializedObject.FindProperty("outlineColor");
+ outlineColorStyle = serializedObject.FindProperty("outlineColorStyle");
+ outlineGradient = serializedObject.FindProperty("outlineGradient");
+ outlineGradientInLocalSpace = serializedObject.FindProperty("outlineGradientInLocalSpace");
+ outlineWidth = serializedObject.FindProperty("outlineWidth");
+ outlineQuality = serializedObject.FindProperty("outlineQuality");
+ outlineDownsampling = serializedObject.FindProperty("outlineDownsampling");
+ outlineVisibility = serializedObject.FindProperty("outlineVisibility");
+ outlineOptimalBlit = serializedObject.FindProperty("outlineOptimalBlit");
+ outlineBlitDebug = serializedObject.FindProperty("outlineBlitDebug");
+ outlineIndependent = serializedObject.FindProperty("outlineIndependent");
+ glow = serializedObject.FindProperty("glow");
+ glowWidth = serializedObject.FindProperty("glowWidth");
+ glowQuality = serializedObject.FindProperty("glowQuality");
+ glowDownsampling = serializedObject.FindProperty("glowDownsampling");
+ glowHQColor = serializedObject.FindProperty("glowHQColor");
+ glowAnimationSpeed = serializedObject.FindProperty("glowAnimationSpeed");
+ glowBlendPasses = serializedObject.FindProperty("glowBlendPasses");
+ glowDithering = serializedObject.FindProperty("glowDithering");
+ glowMagicNumber1 = serializedObject.FindProperty("glowMagicNumber1");
+ glowMagicNumber2 = serializedObject.FindProperty("glowMagicNumber2");
+ glowAnimationSpeed = serializedObject.FindProperty("glowAnimationSpeed");
+ glowPasses = serializedObject.FindProperty("glowPasses");
+ glowVisibility = serializedObject.FindProperty("glowVisibility");
+ glowBlendMode = serializedObject.FindProperty("glowBlendMode");
+ glowOptimalBlit = serializedObject.FindProperty("glowOptimalBlit");
+ glowBlitDebug = serializedObject.FindProperty("glowBlitDebug");
+ glowIgnoreMask = serializedObject.FindProperty("glowIgnoreMask");
+ innerGlow = serializedObject.FindProperty("innerGlow");
+ innerGlowColor = serializedObject.FindProperty("innerGlowColor");
+ innerGlowWidth = serializedObject.FindProperty("innerGlowWidth");
+ innerGlowVisibility = serializedObject.FindProperty("innerGlowVisibility");
+ seeThrough = serializedObject.FindProperty("seeThrough");
+ seeThroughOccluderMask = serializedObject.FindProperty("seeThroughOccluderMask");
+ seeThroughOccluderMaskAccurate = serializedObject.FindProperty("seeThroughOccluderMaskAccurate");
+ seeThroughOccluderThreshold = serializedObject.FindProperty("seeThroughOccluderThreshold");
+ seeThroughOccluderCheckInterval = serializedObject.FindProperty("seeThroughOccluderCheckInterval");
+ seeThroughOccluderCheckIndividualObjects = serializedObject.FindProperty("seeThroughOccluderCheckIndividualObjects");
+ seeThroughDepthOffset = serializedObject.FindProperty("seeThroughDepthOffset");
+ seeThroughMaxDepth = serializedObject.FindProperty("seeThroughMaxDepth");
+ seeThroughIntensity = serializedObject.FindProperty("seeThroughIntensity");
+ seeThroughTintAlpha = serializedObject.FindProperty("seeThroughTintAlpha");
+ seeThroughTintColor = serializedObject.FindProperty("seeThroughTintColor");
+ seeThroughNoise = serializedObject.FindProperty("seeThroughNoise");
+ seeThroughBorder = serializedObject.FindProperty("seeThroughBorder");
+ seeThroughBorderWidth = serializedObject.FindProperty("seeThroughBorderWidth");
+ seeThroughBorderColor = serializedObject.FindProperty("seeThroughBorderColor");
+ seeThroughOrdered = serializedObject.FindProperty("seeThroughOrdered");
+ seeThroughBorderOnly = serializedObject.FindProperty("seeThroughBorderOnly");
+ seeThroughTexture = serializedObject.FindProperty("seeThroughTexture");
+ seeThroughTextureScale = serializedObject.FindProperty("seeThroughTextureScale");
+ seeThroughTextureUVSpace = serializedObject.FindProperty("seeThroughTextureUVSpace");
+ targetFX = serializedObject.FindProperty("targetFX");
+ targetFXTexture = serializedObject.FindProperty("targetFXTexture");
+ targetFXRotationSpeed = serializedObject.FindProperty("targetFXRotationSpeed");
+ targetFXInitialScale = serializedObject.FindProperty("targetFXInitialScale");
+ targetFXEndScale = serializedObject.FindProperty("targetFXEndScale");
+ targetFXScaleToRenderBounds = serializedObject.FindProperty("targetFXScaleToRenderBounds");
+ targetFXAlignToGround = serializedObject.FindProperty("targetFXAlignToGround");
+ targetFXFadePower = serializedObject.FindProperty("targetFXFadePower");
+ targetFXGroundMaxDistance = serializedObject.FindProperty("targetFXGroundMaxDistance");
+ targetFXGroundLayerMask = serializedObject.FindProperty("targetFXGroundLayerMask");
+ targetFXColor = serializedObject.FindProperty("targetFXColor");
+ targetFXCenter = serializedObject.FindProperty("targetFXCenter");
+ targetFXTransitionDuration = serializedObject.FindProperty("targetFXTransitionDuration");
+ targetFXStayDuration = serializedObject.FindProperty("targetFXStayDuration");
+ targetFXVisibility = serializedObject.FindProperty("targetFXVisibility");
+ hitFxInitialIntensity = serializedObject.FindProperty("hitFxInitialIntensity");
+ hitFxMode = serializedObject.FindProperty("hitFxMode");
+ hitFxFadeOutDuration = serializedObject.FindProperty("hitFxFadeOutDuration");
+ hitFxColor = serializedObject.FindProperty("hitFxColor");
+ hitFxRadius = serializedObject.FindProperty("hitFxRadius");
+ cameraDistanceFade = serializedObject.FindProperty("cameraDistanceFade");
+ cameraDistanceFadeNear = serializedObject.FindProperty("cameraDistanceFadeNear");
+ cameraDistanceFadeFar = serializedObject.FindProperty("cameraDistanceFadeFar");
+
+ thisEffect = (HighlightEffect)target;
+ thisEffect.Refresh();
+ }
+
+ private void OnDisable() {
+ EditorPrefs.SetBool(HP_GENERAL_SETTINGS, expandGeneralSettings);
+ EditorPrefs.SetBool(HP_HIGHLIGHT_OPTIONS, expandHighlightOptions);
+ }
+
+ public override void OnInspectorGUI() {
+ bool isManager = IsDefaultEffectUsedByManager();
+ EditorGUILayout.Separator();
+ serializedObject.Update();
+
+ if (foldoutBold == null) {
+ foldoutBold = new GUIStyle(EditorStyles.foldout);
+ foldoutBold.fontStyle = FontStyle.Bold;
+ }
+
+ EditorGUILayout.BeginHorizontal();
+ HighlightProfile prevProfile = (HighlightProfile)profile.objectReferenceValue;
+ EditorGUILayout.PropertyField(profile, new GUIContent("Profile", "Create or load stored presets."));
+ if (profile.objectReferenceValue != null) {
+
+ if (prevProfile != profile.objectReferenceValue) {
+ profileChanged = true;
+ }
+
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.BeginHorizontal();
+ GUILayout.Label("", GUILayout.Width(EditorGUIUtility.labelWidth));
+ if (GUILayout.Button(new GUIContent("Create", "Creates a new profile which is a copy of the current settings."), GUILayout.Width(60))) {
+ CreateProfile();
+ profileChanged = false;
+ enableProfileApply = false;
+ GUIUtility.ExitGUI();
+ return;
+ }
+ if (GUILayout.Button(new GUIContent("Load", "Updates settings with the profile configuration."), GUILayout.Width(60))) {
+ profileChanged = true;
+ }
+ if (!enableProfileApply)
+ GUI.enabled = false;
+ if (GUILayout.Button(new GUIContent("Save", "Updates profile configuration with changes in this inspector."), GUILayout.Width(60))) {
+ enableProfileApply = false;
+ profileChanged = false;
+ thisEffect.profile.Save(thisEffect);
+ EditorUtility.SetDirty(thisEffect.profile);
+ GUIUtility.ExitGUI();
+ return;
+ }
+ GUI.enabled = true;
+ if (GUILayout.Button(new GUIContent("Locate", "Finds the profile in the project"), GUILayout.Width(60))) {
+ if (thisEffect.profile != null) {
+ Selection.activeObject = thisEffect.profile;
+ EditorGUIUtility.PingObject(thisEffect.profile);
+ }
+ }
+ EditorGUILayout.EndHorizontal();
+ EditorGUILayout.PropertyField(profileSync, new GUIContent("Sync With Profile", "If disabled, profile settings will only be loaded when clicking 'Load' which allows you to customize settings after loading a profile and keep those changes."));
+ EditorGUILayout.BeginHorizontal();
+ } else {
+ if (GUILayout.Button(new GUIContent("Create", "Creates a new profile which is a copy of the current settings."), GUILayout.Width(60))) {
+ CreateProfile();
+ GUIUtility.ExitGUI();
+ return;
+ }
+ }
+ EditorGUILayout.EndHorizontal();
+
+
+ if (isManager) {
+ EditorGUILayout.HelpBox("These are default settings for highlighted objects. If the highlighted object already has a Highlight Effect component, those properties will be used.", MessageType.Info);
+ }
+
+ expandGeneralSettings = EditorGUILayout.Foldout(expandGeneralSettings, "General Settings", true, foldoutBold);
+ if (expandGeneralSettings) {
+ if (!isManager) {
+ EditorGUILayout.PropertyField(previewInEditor);
+ }
+
+ EditorGUILayout.PropertyField(camerasLayerMask);
+ EditorGUILayout.PropertyField(ignoreObjectVisibility);
+ if (thisEffect.staticChildren) {
+ EditorGUILayout.HelpBox("This GameObject or one of its children is marked as static. If highlight is not visible, add a MeshCollider to them (the MeshCollider can be disabled).", MessageType.Warning);
+ }
+
+ EditorGUILayout.PropertyField(reflectionProbes);
+ EditorGUILayout.PropertyField(normalsOption);
+ EditorGUILayout.PropertyField(subMeshMask);
+ EditorGUILayout.PropertyField(GPUInstancing);
+ EditorGUILayout.Separator();
+ }
+
+ if (!isManager) {
+ EditorGUILayout.LabelField("State", EditorStyles.boldLabel);
+ if (isManager) {
+ EditorGUILayout.LabelField(new GUIContent("Highlighted", "Highlight state (controlled by Highlight Manager)."), new GUIContent(thisEffect.highlighted.ToString()));
+ } else {
+ EditorGUILayout.PropertyField(highlighted);
+ }
+ EditorGUILayout.LabelField(new GUIContent("Selected", "Selection state (used by Highlight Trigger or Manager) when using multi-selection option."), new GUIContent(thisEffect.isSelected.ToString()));
+ EditorGUILayout.Separator();
+ }
+
+ EditorGUILayout.BeginHorizontal();
+ expandHighlightOptions = EditorGUILayout.Foldout(expandHighlightOptions, "Highlight Options", true, foldoutBold);
+ if (GUILayout.Button("Help", GUILayout.Width(50))) {
+ EditorUtility.DisplayDialog("Quick Help", "Move the mouse over a setting for a short description.\n\nVisit kronnect.com's forum for support, questions and more cool assets.\n\nIf you like Highlight Plus please rate it or leave a review on the Asset Store! Thanks.", "Ok");
+ }
+ EditorGUILayout.EndHorizontal();
+ if (expandHighlightOptions) {
+ EditorGUI.BeginChangeCheck();
+ if (!isManager) {
+ EditorGUILayout.PropertyField(ignore, new GUIContent("Ignore", "This object won't be highlighted."));
+ }
+ if (!ignore.boolValue) {
+ EditorGUILayout.PropertyField(effectGroup, new GUIContent("Include", "Additional objects to highlight. Pro tip: when highlighting multiple objects at the same time include them in the same layer or under the same parent."));
+ if (effectGroup.intValue == (int)TargetOptions.LayerInScene || effectGroup.intValue == (int)TargetOptions.LayerInChildren) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(effectGroupLayer, new GUIContent("Layer"));
+ EditorGUI.indentLevel--;
+ }
+ bool usesHQEffects = (outlineQuality.intValue == (int)QualityLevel.Highest && outline.floatValue > 0) || (glowQuality.intValue == (int)QualityLevel.Highest && glow.floatValue > 0);
+ if (effectGroup.intValue != (int)TargetOptions.OnlyThisObject) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(effectNameFilter, new GUIContent("Object Name Filter"));
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.PropertyField(combineMeshes);
+ if (combineMeshes.boolValue) {
+ if (GUILayout.Button("Refresh", GUILayout.Width(70))) {
+ thisEffect.Refresh(true);
+ }
+ }
+ EditorGUILayout.EndHorizontal();
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.PropertyField(alphaCutOff, new GUIContent("Alpha Cut Off", "Only for semi-transparent objects. Leave this to zero for normal opaque objects."));
+ EditorGUILayout.PropertyField(cullBackFaces);
+ EditorGUILayout.PropertyField(fadeInDuration);
+ EditorGUILayout.PropertyField(fadeOutDuration);
+ EditorGUILayout.PropertyField(cameraDistanceFade);
+ if (cameraDistanceFade.boolValue) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(cameraDistanceFadeNear, new GUIContent("Near Distance"));
+ EditorGUILayout.PropertyField(cameraDistanceFadeFar, new GUIContent("Far Distance"));
+ EditorGUI.indentLevel--;
+ }
+ if (usesHQEffects) {
+ EditorGUILayout.PropertyField(depthClip);
+ if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.iOS || EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android) {
+ EditorGUILayout.HelpBox("On mobile, consider enabling 'Depth Clip' option for better results.", MessageType.Info);
+ }
+ if (VRCheck.IsActive()) {
+ EditorGUILayout.PropertyField(flipY, new GUIContent("Flip Y Fix", "Flips outline/glow effect to fix bug introduced in Unity 2019.1.0 when VR is enabled."));
+ }
+ }
+ if (glowQuality.intValue != (int)QualityLevel.Highest || outlineQuality.intValue != (int)QualityLevel.Highest) {
+ EditorGUILayout.PropertyField(constantWidth, new GUIContent("Constant Width", "Compensates outline/glow width with depth increase."));
+ }
+ EditorGUILayout.PropertyField(outlineIndependent, new GUIContent("Independent", "Do not combine outline or glow with other highlighted objects."));
+ }
+ }
+
+ if (!ignore.boolValue) {
+ EditorGUILayout.Separator();
+ EditorGUILayout.LabelField("Effects", EditorStyles.boldLabel);
+
+ EditorGUILayout.BeginVertical(GUI.skin.box);
+ DrawSectionField(outline, "Outline", outline.floatValue > 0);
+ if (outline.floatValue > 0) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(outlineWidth, new GUIContent("Width"));
+ EditorGUILayout.BeginHorizontal();
+ QualityPropertyField(outlineQuality);
+ if (outlineQuality.intValue == (int)QualityLevel.Highest) {
+ GUILayout.Label("(Screen-Space Effect)");
+ } else {
+ GUILayout.Label("(Mesh-based Effect)");
+ }
+ EditorGUILayout.EndHorizontal();
+ CheckVRSupport(outlineQuality.intValue);
+ if (outlineQuality.intValue == (int)QualityLevel.Highest) {
+ EditorGUILayout.PropertyField(outlineColor, new GUIContent("Color"));
+ } else {
+ EditorGUILayout.PropertyField(outlineColorStyle, new GUIContent("Color Style"));
+ switch ((ColorStyle)outlineColorStyle.intValue) {
+ case ColorStyle.SingleColor:
+ EditorGUILayout.PropertyField(outlineColor, new GUIContent("Color"));
+ break;
+ case ColorStyle.Gradient:
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(outlineGradient, new GUIContent("Gradient"));
+ EditorGUILayout.PropertyField(outlineGradientInLocalSpace, new GUIContent("In Local Space"));
+ EditorGUI.indentLevel--;
+ break;
+ }
+ }
+ if (outlineQuality.intValue == (int)QualityLevel.Highest) {
+ EditorGUILayout.PropertyField(outlineDownsampling, new GUIContent("Downsampling"));
+ EditorGUILayout.PropertyField(outlineOptimalBlit, new GUIContent("Optimal Blit", "Blits result over a section of the screen instead of rendering to the full screen buffer."));
+ if (outlineOptimalBlit.boolValue) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(outlineBlitDebug, new GUIContent("Debug View", "Shows the blitting rectangle on the screen."));
+ if (outlineBlitDebug.boolValue && (!previewInEditor.boolValue || !highlighted.boolValue)) {
+ EditorGUILayout.HelpBox("Enable \"Preview In Editor\" and \"Highlighted\" to display the outline Debug View.", MessageType.Warning);
+ }
+ EditorGUI.indentLevel--;
+ }
+ }
+
+ GUI.enabled = outlineQuality.intValue != (int)QualityLevel.Highest || CheckForwardMSAA();
+ if (outlineQuality.intValue == (int)QualityLevel.Highest && glowQuality.intValue == (int)QualityLevel.Highest && glow.floatValue > 0) {
+ EditorGUILayout.PropertyField(glowVisibility, new GUIContent("Visibility"));
+ } else {
+ EditorGUILayout.PropertyField(outlineVisibility, new GUIContent("Visibility"));
+ }
+ GUI.enabled = true;
+
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.EndVertical();
+
+ EditorGUILayout.BeginVertical(GUI.skin.box);
+ DrawSectionField(glow, "Outer Glow", glow.floatValue > 0);
+ if (glow.floatValue > 0) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(glowWidth, new GUIContent("Width"));
+ EditorGUILayout.BeginHorizontal();
+ QualityPropertyField(glowQuality);
+ if (glowQuality.intValue == (int)QualityLevel.Highest) {
+ GUILayout.Label("(Screen-Space Effect)");
+ } else {
+ GUILayout.Label("(Mesh-based Effect)");
+ }
+ EditorGUILayout.EndHorizontal();
+ CheckVRSupport(glowQuality.intValue);
+ if (glowQuality.intValue == (int)QualityLevel.Highest) {
+ EditorGUILayout.PropertyField(glowDownsampling, new GUIContent("Downsampling"));
+ EditorGUILayout.PropertyField(glowHQColor, new GUIContent("Color"));
+ EditorGUILayout.PropertyField(glowOptimalBlit, new GUIContent("Optimal Blit", "Blits result over a section of the screen instead of rendering to the full screen buffer."));
+ if (glowOptimalBlit.boolValue) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(glowBlitDebug, new GUIContent("Debug View", "Shows the blitting rectangle on the screen."));
+ if (glowBlitDebug.boolValue && (!previewInEditor.boolValue || !highlighted.boolValue)) {
+ EditorGUILayout.HelpBox("Enable \"Preview In Editor\" and \"Highlighted\" to display the glow Debug View.", MessageType.Warning);
+ }
+ EditorGUI.indentLevel--;
+ }
+ GUI.enabled = glowQuality.intValue != (int)QualityLevel.Highest || CheckForwardMSAA();
+ EditorGUILayout.PropertyField(glowVisibility, new GUIContent("Visibility"));
+ EditorGUILayout.PropertyField(glowBlendMode, new GUIContent("Blend Mode"));
+ GUI.enabled = true;
+ } else {
+ GUI.enabled = glowQuality.intValue != (int)QualityLevel.Highest || CheckForwardMSAA();
+ EditorGUILayout.PropertyField(glowVisibility, new GUIContent("Visibility"));
+ GUI.enabled = true;
+ EditorGUILayout.PropertyField(glowDithering, new GUIContent("Dithering"));
+ if (glowDithering.boolValue) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(glowMagicNumber1, new GUIContent("Magic Number 1"));
+ EditorGUILayout.PropertyField(glowMagicNumber2, new GUIContent("Magic Number 2"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.PropertyField(glowBlendPasses, new GUIContent("Blend Passes"));
+ if (!glowBlendPasses.boolValue) {
+ HighlightEffect ef = (HighlightEffect)target;
+ if (ef.glowPasses != null) {
+ for (int k = 0; k < ef.glowPasses.Length - 1; k++) {
+ if (ef.glowPasses[k].offset > ef.glowPasses[k + 1].offset) {
+ EditorGUILayout.HelpBox("Glow pass " + k + " has a greater offset than the next one. Reduce it to ensure the next glow pass is visible.", MessageType.Warning);
+ }
+ }
+ }
+ }
+ EditorGUILayout.PropertyField(glowPasses, true);
+ }
+ EditorGUILayout.PropertyField(glowAnimationSpeed, new GUIContent("Animation Speed"));
+ EditorGUILayout.PropertyField(glowIgnoreMask, new GUIContent("Ignore Mask"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.EndVertical();
+
+ EditorGUILayout.BeginVertical(GUI.skin.box);
+ DrawSectionField(innerGlow, "Inner Glow", innerGlow.floatValue > 0);
+ if (innerGlow.floatValue > 0) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(innerGlowColor, new GUIContent("Color"));
+ EditorGUILayout.PropertyField(innerGlowWidth, new GUIContent("Width"));
+ EditorGUILayout.PropertyField(innerGlowVisibility, new GUIContent("Visibility"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.EndVertical();
+
+ EditorGUILayout.BeginVertical(GUI.skin.box);
+ DrawSectionField(overlay, "Overlay", overlay.floatValue > 0);
+ if (overlay.floatValue > 0) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(overlayMode, new GUIContent("Mode"));
+ EditorGUILayout.PropertyField(overlayColor, new GUIContent("Color"));
+ EditorGUILayout.PropertyField(overlayTexture, new GUIContent("Texture"));
+ if (overlayTexture.objectReferenceValue != null) {
+ EditorGUILayout.PropertyField(overlayTextureUVSpace, new GUIContent("UV Space"));
+ EditorGUILayout.PropertyField(overlayTextureScale, new GUIContent("Texture Scale"));
+ }
+ EditorGUILayout.PropertyField(overlayBlending, new GUIContent("Blending"));
+ EditorGUILayout.PropertyField(overlayMinIntensity, new GUIContent("Min Intensity"));
+ EditorGUILayout.PropertyField(overlayAnimationSpeed, new GUIContent("Animation Speed"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.EndVertical();
+
+ EditorGUILayout.BeginVertical(GUI.skin.box);
+ DrawSectionField(targetFX, "Target", targetFX.boolValue);
+ if (targetFX.boolValue) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(targetFXTexture, new GUIContent("Texture", "The texture that contains the shape to be drawn over the highlighted object."));
+ EditorGUILayout.PropertyField(targetFXColor, new GUIContent("Color"));
+ EditorGUILayout.PropertyField(targetFXCenter, new GUIContent("Center", "Optionally assign a transform. Target will follow transform. If the object is skinned, you can also assign a bone to reflect currenct animation position."));
+ EditorGUILayout.PropertyField(targetFXRotationSpeed, new GUIContent("Rotation Speed"));
+ EditorGUILayout.PropertyField(targetFXInitialScale, new GUIContent("Initial Scale"));
+ EditorGUILayout.PropertyField(targetFXEndScale, new GUIContent("End Scale"));
+ EditorGUILayout.PropertyField(targetFXScaleToRenderBounds, new GUIContent("Scale To Object Bounds"));
+ EditorGUILayout.PropertyField(targetFXAlignToGround, new GUIContent("Align To Ground"));
+ if (targetFXAlignToGround.boolValue) {
+ EditorGUI.indentLevel++;
+ if (thisEffect.includedObjectsCount > 1 && targetFXCenter.objectReferenceValue == null && effectGroup.intValue != (int)TargetOptions.OnlyThisObject) {
+ EditorGUILayout.HelpBox("It's recommended to specify in the 'Center' property above, the specific object used to position the target fx image (will be rendered under that object on the ground).", MessageType.Info);
+ }
+ EditorGUILayout.PropertyField(targetFXGroundMaxDistance, new GUIContent("Ground Max Distance"));
+ EditorGUILayout.PropertyField(targetFXGroundLayerMask, new GUIContent("Ground Layer Mask"));
+ HighlightEffect he = (HighlightEffect)target;
+ if ((targetFXGroundLayerMask.intValue & (1 << he.gameObject.layer)) != 0) {
+ EditorGUILayout.HelpBox("Ground Layer Mask should not include this object layer.", MessageType.Warning);
+ }
+ EditorGUILayout.PropertyField(targetFXFadePower, new GUIContent("Fade Power"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.PropertyField(targetFXTransitionDuration, new GUIContent("Transition Duration"));
+ EditorGUILayout.PropertyField(targetFXStayDuration, new GUIContent("Stay Duration"));
+ EditorGUILayout.PropertyField(targetFXVisibility, new GUIContent("Visibility"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.EndVertical();
+ }
+
+ EditorGUILayout.BeginVertical(GUI.skin.box);
+ EditorGUILayout.PropertyField(seeThrough);
+ if (seeThrough.intValue != (int)SeeThroughMode.Never) {
+ if (isManager && seeThrough.intValue == (int)SeeThroughMode.AlwaysWhenOccluded) {
+ EditorGUILayout.HelpBox("This option is not valid in Manager.\nTo make an object always visible add a Highlight Effect component to the gameobject and enable this option on the component.", MessageType.Error);
+ }
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(seeThroughOccluderMask, new GUIContent("Occluder Layer"));
+ if (seeThroughOccluderMask.intValue > 0) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(seeThroughOccluderMaskAccurate, new GUIContent("Accurate"));
+ EditorGUILayout.PropertyField(seeThroughOccluderThreshold, new GUIContent("Radius Threshold", "Multiplier to the object bounds. Making the bounds smaller prevents false occlusion tests."));
+ EditorGUILayout.PropertyField(seeThroughOccluderCheckInterval, new GUIContent("Check Interval", "Interval in seconds between occlusion tests."));
+ EditorGUILayout.PropertyField(seeThroughOccluderCheckIndividualObjects, new GUIContent("Check Individual Objects"));
+ if (!showCurrentOccluders && Camera.main != null) {
+ GUI.enabled = Application.isPlaying;
+ EditorGUILayout.BeginHorizontal();
+ GUILayout.Label("", GUILayout.Width(30));
+ if (GUILayout.Button(" Show Current Occluders (only during Play Mode) ")) {
+ showCurrentOccluders = true;
+ }
+ GUILayout.FlexibleSpace();
+ EditorGUILayout.EndHorizontal();
+ GUI.enabled = true;
+ }
+ if (showCurrentOccluders) {
+ HighlightEffect h = (HighlightEffect)target;
+ List occluders = h.GetOccluders(Camera.main);
+ int count = occluders != null ? occluders.Count : 0;
+ if (count == 0) {
+ EditorGUILayout.LabelField("No occluders found (using main camera)");
+ } else {
+ EditorGUILayout.LabelField("Occluders found (using main camera):");
+ for (int k = 0; k < count; k++) {
+ if (occluders[k] == null) continue;
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.LabelField(occluders[k].name);
+ if (GUILayout.Button("Select")) {
+ Selection.activeGameObject = occluders[k].gameObject;
+ GUIUtility.ExitGUI();
+ }
+ EditorGUILayout.EndHorizontal();
+ }
+ }
+ }
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.PropertyField(seeThroughDepthOffset, new GUIContent("Depth Offset" + ((seeThroughDepthOffset.floatValue > 0) ? " •" : "")));
+ EditorGUILayout.PropertyField(seeThroughMaxDepth, new GUIContent("Max Depth" + ((seeThroughMaxDepth.floatValue > 0) ? " •" : "")));
+ EditorGUILayout.PropertyField(seeThroughIntensity, new GUIContent("Intensity"));
+ EditorGUILayout.PropertyField(seeThroughTintColor, new GUIContent("Color"));
+ EditorGUILayout.PropertyField(seeThroughTintAlpha, new GUIContent("Color Blend"));
+ EditorGUILayout.PropertyField(seeThroughNoise, new GUIContent("Noise"));
+ EditorGUILayout.PropertyField(seeThroughTexture, new GUIContent("Texture"));
+ if (seeThroughTexture.objectReferenceValue != null) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(seeThroughTextureUVSpace, new GUIContent("UV Space"));
+ EditorGUILayout.PropertyField(seeThroughTextureScale, new GUIContent("Texture Scale"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.PropertyField(seeThroughBorder, new GUIContent("Border When Hidden" + ((seeThroughBorder.floatValue > 0) ? " •" : "")));
+ if (seeThroughBorder.floatValue > 0) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(seeThroughBorderWidth, new GUIContent("Width"));
+ EditorGUILayout.PropertyField(seeThroughBorderColor, new GUIContent("Color"));
+ EditorGUILayout.PropertyField(seeThroughBorderOnly, new GUIContent("Border Only"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.PropertyField(seeThroughOrdered, new GUIContent("Ordered"));
+
+
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.EndVertical();
+
+ EditorGUILayout.BeginVertical(GUI.skin.box);
+ DrawSectionField(hitFxInitialIntensity, "Hit FX", hitFxInitialIntensity.floatValue > 0);
+ if (hitFxInitialIntensity.floatValue > 0) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(hitFxMode, new GUIContent("Mode"));
+ EditorGUILayout.PropertyField(hitFxFadeOutDuration, new GUIContent("Fade Out Duration"));
+ EditorGUILayout.PropertyField(hitFxColor, new GUIContent("Color"));
+ if ((HitFxMode)hitFxMode.intValue == HitFxMode.LocalHit) {
+ EditorGUILayout.PropertyField(hitFxRadius, new GUIContent("Radius"));
+ }
+ EditorGUI.indentLevel--;
+ }
+
+ if (!Application.isPlaying) {
+ EditorGUILayout.HelpBox("Enter Play Mode to test this feature. In your code, call effect.HitFX() method to execute this hit effect.", MessageType.Info);
+ } else {
+ EditorGUI.indentLevel++;
+ if (GUILayout.Button("Execute Hit")) {
+ thisEffect.HitFX();
+ }
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.EndVertical();
+
+
+ if (serializedObject.ApplyModifiedProperties() || profileChanged || Event.current.commandName == "UndoRedoPerformed") {
+ if (thisEffect.profile != null) {
+ if (profileChanged) {
+ thisEffect.profile.Load(thisEffect);
+ profileChanged = false;
+ enableProfileApply = false;
+ } else {
+ enableProfileApply = true;
+ }
+ }
+
+ foreach (HighlightEffect effect in targets) {
+ effect.Refresh();
+ }
+ }
+ }
+
+ void DrawSectionField(SerializedProperty property, string label, bool active) {
+ EditorGUILayout.PropertyField(property, new GUIContent(active ? label + " •" : label));
+ }
+
+ void CheckVRSupport(int qualityLevel) {
+ if (qualityLevel == (int)QualityLevel.Highest && VRCheck.IsActive()) {
+ if (PlayerSettings.stereoRenderingPath != StereoRenderingPath.MultiPass) {
+ EditorGUILayout.HelpBox("Highest Quality only supports VR Multi-Pass as CommandBuffers do not support this VR mode yet. Either switch to 'High Quality' or change VR Stereo mode to Multi-Pass.", MessageType.Error);
+ }
+ }
+ }
+
+ bool CheckForwardMSAA() {
+ if (QualitySettings.antiAliasing > 1) {
+ if (Camera.main != null && Camera.main.allowMSAA && !depthClip.boolValue) {
+ EditorGUILayout.HelpBox("Effect will be shown always on top due to MSAA. To enable depth clipping enable 'Depth Clip' option above OR disable MSAA in Quality Settings OR choose a different quality level.", MessageType.Info);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ static readonly int[] qualityValues = { 0, 3, 1, 2 };
+ static readonly GUIContent[] qualityTexts = { new GUIContent("Fastest"), new GUIContent("Medium"), new GUIContent("High"), new GUIContent("Highest") };
+
+ public static void QualityPropertyField(SerializedProperty prop) {
+ prop.intValue = EditorGUILayout.IntPopup(new GUIContent("Quality", "Default and High use a mesh displacement technique. Highest quality can provide best look and also performance depending on the complexity of mesh."), prop.intValue, qualityTexts, qualityValues);
+ }
+
+ bool IsDefaultEffectUsedByManager() {
+ MonoBehaviour[] components = thisEffect.GetComponents();
+ if (components != null) {
+ for (int k = 0; k < components.Length; k++) {
+ if (components[k] == null || !components[k].enabled)
+ continue;
+ string name = components[k].GetType().Name;
+ if ("HighlightManager".Equals(name)) return true;
+ }
+ }
+ return false;
+ }
+
+ #region Profile handling
+
+ void CreateProfile() {
+
+ HighlightProfile newProfile = CreateInstance();
+ newProfile.Save(thisEffect);
+
+ AssetDatabase.CreateAsset(newProfile, "Assets/Highlight Plus Profile.asset");
+ AssetDatabase.SaveAssets();
+
+ EditorUtility.FocusProjectWindow();
+ Selection.activeObject = newProfile;
+
+ thisEffect.profile = newProfile;
+ }
+
+
+ #endregion
+
+#pragma warning restore 0618
+
+ }
+
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Editor/HighlightEffectEditor.cs.meta b/Assets/Plugins/HighlightPlus/Editor/HighlightEffectEditor.cs.meta
new file mode 100644
index 0000000..7bceb10
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor/HighlightEffectEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: be287539f47634552a716f0705710448
+timeCreated: 1542886545
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Editor/HighlightManagerEditor.cs b/Assets/Plugins/HighlightPlus/Editor/HighlightManagerEditor.cs
new file mode 100644
index 0000000..4a5543c
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor/HighlightManagerEditor.cs
@@ -0,0 +1,71 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+
+namespace HighlightPlus {
+ [CustomEditor(typeof(HighlightManager))]
+ public class HighlightManagerEditor : Editor {
+
+ SerializedProperty highlightOnHover, layerMask, raycastCamera, raycastSource, minDistance, maxDistance, respectUI;
+ SerializedProperty selectOnClick, selectedProfile, selectedAndHighlightedProfile, singleSelection, toggleOnClick, keepSelection;
+
+ void OnEnable() {
+ highlightOnHover = serializedObject.FindProperty("highlightOnHover");
+ layerMask = serializedObject.FindProperty("layerMask");
+ raycastCamera = serializedObject.FindProperty("raycastCamera");
+ raycastSource = serializedObject.FindProperty("raycastSource");
+ minDistance = serializedObject.FindProperty("minDistance");
+ maxDistance = serializedObject.FindProperty("maxDistance");
+ respectUI = serializedObject.FindProperty("respectUI");
+ selectOnClick = serializedObject.FindProperty("selectOnClick");
+ selectedProfile = serializedObject.FindProperty("selectedProfile");
+ selectedAndHighlightedProfile = serializedObject.FindProperty("selectedAndHighlightedProfile");
+ singleSelection = serializedObject.FindProperty("singleSelection");
+ toggleOnClick = serializedObject.FindProperty("toggle");
+ keepSelection = serializedObject.FindProperty("keepSelection");
+ }
+
+ public override void OnInspectorGUI() {
+ EditorGUILayout.Separator();
+ EditorGUILayout.HelpBox("Only objects with a collider can be highlighted automatically.", MessageType.Info);
+
+ serializedObject.Update();
+
+ EditorGUILayout.PropertyField(layerMask);
+ EditorGUILayout.PropertyField(raycastCamera);
+ EditorGUILayout.PropertyField(raycastSource);
+ EditorGUILayout.PropertyField(minDistance);
+ EditorGUILayout.PropertyField(maxDistance);
+ EditorGUILayout.PropertyField(respectUI);
+ EditorGUILayout.PropertyField(highlightOnHover);
+ EditorGUILayout.PropertyField(selectOnClick);
+ if (selectOnClick.boolValue) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(selectedProfile);
+ EditorGUILayout.PropertyField(selectedAndHighlightedProfile);
+ EditorGUILayout.PropertyField(singleSelection);
+ EditorGUILayout.PropertyField(toggleOnClick);
+ EditorGUILayout.PropertyField(keepSelection);
+ EditorGUI.indentLevel--;
+ }
+
+ serializedObject.ApplyModifiedProperties();
+ }
+
+
+ [MenuItem("GameObject/Effects/Highlight Plus/Create Manager", false, 10)]
+ static void CreateManager(MenuCommand menuCommand) {
+ HighlightManager manager = FindObjectOfType();
+ if (manager == null) {
+ GameObject managerGO = new GameObject("HighlightPlusManager");
+ manager = managerGO.AddComponent();
+ // Register root object for undo.
+ Undo.RegisterCreatedObjectUndo(manager, "Create Highlight Plus Manager");
+ }
+ Selection.activeObject = manager;
+ }
+
+ }
+
+}
diff --git a/Assets/Plugins/HighlightPlus/Editor/HighlightManagerEditor.cs.meta b/Assets/Plugins/HighlightPlus/Editor/HighlightManagerEditor.cs.meta
new file mode 100644
index 0000000..54195ce
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor/HighlightManagerEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: ace58d1d278d649c98e5a2b5a066b3cd
+timeCreated: 1548711355
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Editor/HighlightProfileEditor.cs b/Assets/Plugins/HighlightPlus/Editor/HighlightProfileEditor.cs
new file mode 100644
index 0000000..b0f63f4
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor/HighlightProfileEditor.cs
@@ -0,0 +1,355 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+
+namespace HighlightPlus {
+
+ [CustomEditor(typeof(HighlightProfile))]
+ [CanEditMultipleObjects]
+ public class HighlightProfileEditor : Editor {
+
+ SerializedProperty effectGroup, effectGroupLayer, effectNameFilter, combineMeshes, alphaCutOff, cullBackFaces, depthClip, normalsOption;
+ SerializedProperty overlay, overlayMode, overlayColor, overlayAnimationSpeed, overlayMinIntensity, overlayTexture, overlayTextureScale, overlayTextureUVSpace, overlayBlending;
+ SerializedProperty fadeInDuration, fadeOutDuration, constantWidth;
+ SerializedProperty outline, outlineColor, outlineColorStyle, outlineGradient, outlineGradientInLocalSpace, outlineWidth, outlineQuality, outlineDownsampling, outlineOptimalBlit, outlineVisibility, outlineIndependent;
+ SerializedProperty glow, glowWidth, glowQuality, glowOptimalBlit, glowDownsampling, glowHQColor, glowDithering, glowMagicNumber1, glowMagicNumber2, glowAnimationSpeed, glowVisibility, glowBlendMode, glowBlendPasses, glowPasses, glowIgnoreMask;
+ SerializedProperty innerGlow, innerGlowWidth, innerGlowColor, innerGlowVisibility;
+ SerializedProperty targetFX, targetFXTexture, targetFXColor, targetFXRotationSpeed, targetFXInitialScale, targetFXEndScale, targetFXScaleToRenderBounds;
+ SerializedProperty targetFXAlignToGround, targetFXFadePower, targetFXGroundMaxDistance, targetFXGroundLayerMask, targetFXTransitionDuration, targetFXStayDuration, targetFXVisibility;
+ SerializedProperty seeThrough, seeThroughOccluderMask, seeThroughOccluderMaskAccurate, seeThroughOccluderThreshold, seeThroughOccluderCheckInterval, seeThroughOccluderCheckIndividualObjects, seeThroughDepthOffset, seeThroughMaxDepth;
+ SerializedProperty seeThroughIntensity, seeThroughTintAlpha, seeThroughTintColor, seeThroughNoise, seeThroughBorder, seeThroughBorderWidth, seeThroughBorderColor, seeThroughOrdered, seeThroughBorderOnly, seeThroughTexture, seeThroughTextureUVSpace, seeThroughTextureScale;
+ SerializedProperty hitFxInitialIntensity, hitFxMode, hitFxFadeOutDuration, hitFxColor, hitFxRadius;
+ SerializedProperty cameraDistanceFade, cameraDistanceFadeNear, cameraDistanceFadeFar;
+
+ void OnEnable() {
+ effectGroup = serializedObject.FindProperty("effectGroup");
+ effectGroupLayer = serializedObject.FindProperty("effectGroupLayer");
+ effectNameFilter = serializedObject.FindProperty("effectNameFilter");
+ combineMeshes = serializedObject.FindProperty("combineMeshes");
+ alphaCutOff = serializedObject.FindProperty("alphaCutOff");
+ cullBackFaces = serializedObject.FindProperty("cullBackFaces");
+ depthClip = serializedObject.FindProperty("depthClip");
+ normalsOption = serializedObject.FindProperty("normalsOption");
+ fadeInDuration = serializedObject.FindProperty("fadeInDuration");
+ fadeOutDuration = serializedObject.FindProperty("fadeOutDuration");
+ constantWidth = serializedObject.FindProperty("constantWidth");
+ overlay = serializedObject.FindProperty("overlay");
+ overlayMode = serializedObject.FindProperty("overlayMode");
+ overlayColor = serializedObject.FindProperty("overlayColor");
+ overlayAnimationSpeed = serializedObject.FindProperty("overlayAnimationSpeed");
+ overlayMinIntensity = serializedObject.FindProperty("overlayMinIntensity");
+ overlayBlending = serializedObject.FindProperty("overlayBlending");
+ overlayTexture = serializedObject.FindProperty("overlayTexture");
+ overlayTextureUVSpace = serializedObject.FindProperty("overlayTextureUVSpace");
+ overlayTextureScale = serializedObject.FindProperty("overlayTextureScale");
+ outline = serializedObject.FindProperty("outline");
+ outlineColor = serializedObject.FindProperty("outlineColor");
+ outlineColorStyle = serializedObject.FindProperty("outlineColorStyle");
+ outlineGradient = serializedObject.FindProperty("outlineGradient");
+ outlineGradientInLocalSpace = serializedObject.FindProperty("outlineGradientInLocalSpace");
+ outlineWidth = serializedObject.FindProperty("outlineWidth");
+ outlineQuality = serializedObject.FindProperty("outlineQuality");
+ outlineOptimalBlit = serializedObject.FindProperty("outlineOptimalBlit");
+ outlineDownsampling = serializedObject.FindProperty("outlineDownsampling");
+ outlineVisibility = serializedObject.FindProperty("outlineVisibility");
+ outlineIndependent = serializedObject.FindProperty("outlineIndependent");
+ glow = serializedObject.FindProperty("glow");
+ glowWidth = serializedObject.FindProperty("glowWidth");
+ glowQuality = serializedObject.FindProperty("glowQuality");
+ glowOptimalBlit = serializedObject.FindProperty("glowOptimalBlit");
+ glowDownsampling = serializedObject.FindProperty("glowDownsampling");
+ glowHQColor = serializedObject.FindProperty("glowHQColor");
+ glowAnimationSpeed = serializedObject.FindProperty("glowAnimationSpeed");
+ glowDithering = serializedObject.FindProperty("glowDithering");
+ glowMagicNumber1 = serializedObject.FindProperty("glowMagicNumber1");
+ glowMagicNumber2 = serializedObject.FindProperty("glowMagicNumber2");
+ glowAnimationSpeed = serializedObject.FindProperty("glowAnimationSpeed");
+ glowBlendPasses = serializedObject.FindProperty("glowBlendPasses");
+ glowVisibility = serializedObject.FindProperty("glowVisibility");
+ glowBlendMode = serializedObject.FindProperty("glowBlendMode");
+ glowPasses = serializedObject.FindProperty("glowPasses");
+ glowIgnoreMask = serializedObject.FindProperty("glowIgnoreMask");
+ innerGlow = serializedObject.FindProperty("innerGlow");
+ innerGlowColor = serializedObject.FindProperty("innerGlowColor");
+ innerGlowWidth = serializedObject.FindProperty("innerGlowWidth");
+ innerGlowVisibility = serializedObject.FindProperty("innerGlowVisibility");
+ targetFX = serializedObject.FindProperty("targetFX");
+ targetFXTexture = serializedObject.FindProperty("targetFXTexture");
+ targetFXRotationSpeed = serializedObject.FindProperty("targetFXRotationSpeed");
+ targetFXInitialScale = serializedObject.FindProperty("targetFXInitialScale");
+ targetFXEndScale = serializedObject.FindProperty("targetFXEndScale");
+ targetFXScaleToRenderBounds = serializedObject.FindProperty("targetFXScaleToRenderBounds");
+ targetFXAlignToGround = serializedObject.FindProperty("targetFXAlignToGround");
+ targetFXGroundMaxDistance = serializedObject.FindProperty("targetFXGroundMaxDistance");
+ targetFXGroundLayerMask = serializedObject.FindProperty("targetFXGroundLayerMask");
+ targetFXFadePower = serializedObject.FindProperty("targetFXFadePower");
+ targetFXColor = serializedObject.FindProperty("targetFXColor");
+ targetFXTransitionDuration = serializedObject.FindProperty("targetFXTransitionDuration");
+ targetFXStayDuration = serializedObject.FindProperty("targetFXStayDuration");
+ targetFXVisibility = serializedObject.FindProperty("targetFXVisibility");
+ seeThrough = serializedObject.FindProperty("seeThrough");
+ seeThroughOccluderMask = serializedObject.FindProperty("seeThroughOccluderMask");
+ seeThroughOccluderMaskAccurate = serializedObject.FindProperty("seeThroughOccluderMaskAccurate");
+ seeThroughOccluderThreshold = serializedObject.FindProperty("seeThroughOccluderThreshold");
+ seeThroughOccluderCheckInterval = serializedObject.FindProperty("seeThroughOccluderCheckInterval");
+ seeThroughOccluderCheckIndividualObjects = serializedObject.FindProperty("seeThroughOccluderCheckIndividualObjects");
+ seeThroughDepthOffset = serializedObject.FindProperty("seeThroughDepthOffset");
+ seeThroughMaxDepth = serializedObject.FindProperty("seeThroughMaxDepth");
+ seeThroughIntensity = serializedObject.FindProperty("seeThroughIntensity");
+ seeThroughTintAlpha = serializedObject.FindProperty("seeThroughTintAlpha");
+ seeThroughTintColor = serializedObject.FindProperty("seeThroughTintColor");
+ seeThroughNoise = serializedObject.FindProperty("seeThroughNoise");
+ seeThroughBorder = serializedObject.FindProperty("seeThroughBorder");
+ seeThroughBorderWidth = serializedObject.FindProperty("seeThroughBorderWidth");
+ seeThroughBorderColor = serializedObject.FindProperty("seeThroughBorderColor");
+ seeThroughBorderOnly = serializedObject.FindProperty("seeThroughBorderOnly");
+ seeThroughOrdered = serializedObject.FindProperty("seeThroughOrdered");
+ seeThroughTexture = serializedObject.FindProperty("seeThroughTexture");
+ seeThroughTextureScale = serializedObject.FindProperty("seeThroughTextureScale");
+ seeThroughTextureUVSpace = serializedObject.FindProperty("seeThroughTextureUVSpace");
+ hitFxInitialIntensity = serializedObject.FindProperty("hitFxInitialIntensity");
+ hitFxMode = serializedObject.FindProperty("hitFxMode");
+ hitFxFadeOutDuration = serializedObject.FindProperty("hitFxFadeOutDuration");
+ hitFxColor = serializedObject.FindProperty("hitFxColor");
+ hitFxRadius = serializedObject.FindProperty("hitFxRadius");
+ cameraDistanceFade = serializedObject.FindProperty("cameraDistanceFade");
+ cameraDistanceFadeNear = serializedObject.FindProperty("cameraDistanceFadeNear");
+ cameraDistanceFadeFar = serializedObject.FindProperty("cameraDistanceFadeFar");
+ }
+
+ public override void OnInspectorGUI() {
+
+ EditorGUILayout.Separator();
+ EditorGUILayout.LabelField("Highlight Options", EditorStyles.boldLabel);
+ EditorGUILayout.PropertyField(effectGroup, new GUIContent("Include"));
+ if (effectGroup.intValue == (int)TargetOptions.LayerInScene || effectGroup.intValue == (int)TargetOptions.LayerInChildren) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(effectGroupLayer, new GUIContent("Layer"));
+ EditorGUI.indentLevel--;
+ }
+ if (effectGroup.intValue != (int)TargetOptions.OnlyThisObject && effectGroup.intValue != (int)TargetOptions.Scripting) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(effectNameFilter, new GUIContent("Object Name Filter"));
+ EditorGUILayout.PropertyField(combineMeshes);
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.PropertyField(alphaCutOff);
+ EditorGUILayout.PropertyField(cullBackFaces);
+ EditorGUILayout.PropertyField(normalsOption);
+ EditorGUILayout.PropertyField(depthClip);
+ EditorGUILayout.PropertyField(fadeInDuration);
+ EditorGUILayout.PropertyField(fadeOutDuration);
+ EditorGUILayout.PropertyField(cameraDistanceFade);
+ if (cameraDistanceFade.boolValue) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(cameraDistanceFadeNear, new GUIContent("Near Distance"));
+ EditorGUILayout.PropertyField(cameraDistanceFadeFar, new GUIContent("Far Distance"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.PropertyField(constantWidth);
+ EditorGUILayout.PropertyField(outlineIndependent, new GUIContent("Independent", "Do not combine outline with other highlighted objects."));
+
+ EditorGUILayout.Separator();
+ EditorGUILayout.LabelField("Effects", EditorStyles.boldLabel);
+
+ EditorGUILayout.BeginVertical(GUI.skin.box);
+ DrawSectionField(outline, "Outline", outline.floatValue > 0);
+ if (outline.floatValue > 0) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(outlineWidth, new GUIContent("Width"));
+ HighlightEffectEditor.QualityPropertyField(outlineQuality);
+ if (outlineQuality.intValue == (int)QualityLevel.Highest) {
+ EditorGUILayout.PropertyField(outlineColor, new GUIContent("Color"));
+ } else {
+ EditorGUILayout.PropertyField(outlineColorStyle, new GUIContent("Color Style"));
+ switch ((ColorStyle)outlineColorStyle.intValue) {
+ case ColorStyle.SingleColor:
+ EditorGUILayout.PropertyField(outlineColor, new GUIContent("Color"));
+ break;
+ case ColorStyle.Gradient:
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(outlineGradient, new GUIContent("Gradient"));
+ EditorGUILayout.PropertyField(outlineGradientInLocalSpace, new GUIContent("In Local Space"));
+ EditorGUI.indentLevel--;
+ break;
+ }
+ }
+ if (outlineQuality.intValue == (int)QualityLevel.Highest) {
+ EditorGUILayout.PropertyField(outlineDownsampling, new GUIContent("Downsampling"));
+ EditorGUILayout.PropertyField(outlineOptimalBlit, new GUIContent("Optimal Blit", "Blits result over a section of the screen instead of rendering to the full screen buffer."));
+ }
+ if (outlineQuality.intValue == (int)QualityLevel.Highest && glowQuality.intValue == (int)QualityLevel.Highest) {
+ EditorGUILayout.PropertyField(glowVisibility, new GUIContent("Visibility"));
+ } else {
+ EditorGUILayout.PropertyField(outlineVisibility, new GUIContent("Visibility"));
+ }
+
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.EndVertical();
+
+ EditorGUILayout.BeginVertical(GUI.skin.box);
+ DrawSectionField(glow, "Outer Glow", glow.floatValue > 0);
+ if (glow.floatValue > 0) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(glowWidth, new GUIContent("Width"));
+ HighlightEffectEditor.QualityPropertyField(glowQuality);
+ if (glowQuality.intValue == (int)QualityLevel.Highest) {
+ EditorGUILayout.PropertyField(glowDownsampling, new GUIContent("Downsampling"));
+ EditorGUILayout.PropertyField(glowHQColor, new GUIContent("Color"));
+ EditorGUILayout.PropertyField(glowOptimalBlit, new GUIContent("Optimal Blit", "Blits result over a section of the screen instead of rendering to the full screen buffer."));
+ }
+ EditorGUILayout.PropertyField(glowAnimationSpeed, new GUIContent("Animation Speed"));
+ EditorGUILayout.PropertyField(glowVisibility, new GUIContent("Visibility"));
+ EditorGUILayout.PropertyField(glowBlendMode, new GUIContent("Blend Mode"));
+ if (glowQuality.intValue != (int)QualityLevel.Highest) {
+ EditorGUILayout.PropertyField(glowDithering, new GUIContent("Dithering"));
+ if (glowDithering.boolValue) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(glowMagicNumber1, new GUIContent("Magic Number 1"));
+ EditorGUILayout.PropertyField(glowMagicNumber2, new GUIContent("Magic Number 2"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.PropertyField(glowBlendPasses, new GUIContent("Blend Passes"));
+ EditorGUILayout.PropertyField(glowPasses, true);
+ EditorGUILayout.PropertyField(glowIgnoreMask, new GUIContent("Ignore Mask"));
+ }
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.EndVertical();
+
+ EditorGUILayout.BeginVertical(GUI.skin.box);
+ DrawSectionField(innerGlow, "Inner Glow", innerGlow.floatValue > 0);
+ if (innerGlow.floatValue > 0) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(innerGlowColor, new GUIContent("Color"));
+ EditorGUILayout.PropertyField(innerGlowWidth, new GUIContent("Width"));
+ EditorGUILayout.PropertyField(innerGlowVisibility, new GUIContent("Visibility"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.EndVertical();
+
+ EditorGUILayout.BeginVertical(GUI.skin.box);
+ DrawSectionField(overlay, "Overlay", overlay.floatValue > 0);
+ if (overlay.floatValue > 0) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(overlayMode, new GUIContent("Mode"));
+ EditorGUILayout.PropertyField(overlayColor, new GUIContent("Color"));
+ EditorGUILayout.PropertyField(overlayTexture, new GUIContent("Texture"));
+ if (overlayTexture.objectReferenceValue != null) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(overlayTextureUVSpace, new GUIContent("UV Space"));
+ EditorGUILayout.PropertyField(overlayTextureScale, new GUIContent("Texture Scale"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.PropertyField(overlayBlending, new GUIContent("Blending"));
+ EditorGUILayout.PropertyField(overlayMinIntensity, new GUIContent("Min Intensity"));
+ EditorGUILayout.PropertyField(overlayAnimationSpeed, new GUIContent("Animation Speed"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.EndVertical();
+
+ EditorGUILayout.BeginVertical(GUI.skin.box);
+ DrawSectionField(targetFX, "Target", targetFX.boolValue);
+ if (targetFX.boolValue) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(targetFXTexture, new GUIContent("Texture"));
+ EditorGUILayout.PropertyField(targetFXColor, new GUIContent("Color"));
+ EditorGUILayout.PropertyField(targetFXRotationSpeed, new GUIContent("Rotation Speed"));
+ EditorGUILayout.PropertyField(targetFXInitialScale, new GUIContent("Initial Scale"));
+ EditorGUILayout.PropertyField(targetFXEndScale, new GUIContent("End Scale"));
+ EditorGUILayout.PropertyField(targetFXScaleToRenderBounds, new GUIContent("Scale To Object Bounds"));
+ EditorGUILayout.PropertyField(targetFXAlignToGround, new GUIContent("Align To Ground"));
+ if (targetFXAlignToGround.boolValue) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(targetFXGroundMaxDistance, new GUIContent("Ground Max Distance"));
+ EditorGUILayout.PropertyField(targetFXGroundLayerMask, new GUIContent("Ground Layer Mask"));
+ EditorGUILayout.PropertyField(targetFXFadePower, new GUIContent("Fade Power"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.PropertyField(targetFXTransitionDuration, new GUIContent("Transition Duration"));
+ EditorGUILayout.PropertyField(targetFXStayDuration, new GUIContent("Stay Duration"));
+ EditorGUILayout.PropertyField(targetFXVisibility, new GUIContent("Visibility"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.EndVertical();
+
+ EditorGUILayout.BeginVertical(GUI.skin.box);
+ EditorGUILayout.PropertyField(seeThrough);
+ if (seeThrough.intValue != (int)SeeThroughMode.Never) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(seeThroughOccluderMask, new GUIContent("Occluder Layer"));
+ if (seeThroughOccluderMask.intValue > 0) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(seeThroughOccluderMaskAccurate, new GUIContent("Accurate"));
+ EditorGUILayout.PropertyField(seeThroughOccluderThreshold, new GUIContent("Radius Threshold", "Multiplier to the object bounds. Making the bounds smaller prevents false occlusion tests."));
+ EditorGUILayout.PropertyField(seeThroughOccluderCheckInterval, new GUIContent("Check Interval", "Interval in seconds between occlusion tests."));
+ EditorGUILayout.PropertyField(seeThroughOccluderCheckIndividualObjects, new GUIContent("Check Individual Objects", "Interval in seconds between occlusion tests."));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.PropertyField(seeThroughDepthOffset, new GUIContent("Depth Offset" + ((seeThroughDepthOffset.floatValue > 0) ? " •" : "")));
+ EditorGUILayout.PropertyField(seeThroughMaxDepth, new GUIContent("Max Depth" + ((seeThroughMaxDepth.floatValue > 0) ? " •" : "")));
+ EditorGUILayout.PropertyField(seeThroughIntensity, new GUIContent("Intensity"));
+ EditorGUILayout.PropertyField(seeThroughTintColor, new GUIContent("Color"));
+ EditorGUILayout.PropertyField(seeThroughTintAlpha, new GUIContent("Color Blend"));
+ EditorGUILayout.PropertyField(seeThroughNoise, new GUIContent("Noise"));
+ EditorGUILayout.PropertyField(seeThroughTexture, new GUIContent("Texture"));
+ if (seeThroughTexture.objectReferenceValue != null) {
+ EditorGUILayout.PropertyField(seeThroughTextureUVSpace, new GUIContent("UV Space"));
+ EditorGUILayout.PropertyField(seeThroughTextureScale, new GUIContent("Texture Scale"));
+ }
+ EditorGUILayout.PropertyField(seeThroughBorder, new GUIContent("Border When Hidden"));
+ if (seeThroughBorder.floatValue > 0) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(seeThroughBorderWidth, new GUIContent("Width"));
+ EditorGUILayout.PropertyField(seeThroughBorderColor, new GUIContent("Color"));
+ EditorGUILayout.PropertyField(seeThroughBorderOnly, new GUIContent("Border Only"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.PropertyField(seeThroughOrdered, new GUIContent("Ordered"));
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.EndVertical();
+
+ EditorGUILayout.BeginVertical(GUI.skin.box);
+ DrawSectionField(hitFxInitialIntensity, "Hit FX", hitFxInitialIntensity.floatValue > 0);
+ if (hitFxInitialIntensity.floatValue > 0) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(hitFxInitialIntensity, new GUIContent("Initial Intensity"));
+ EditorGUILayout.PropertyField(hitFxMode, new GUIContent("Mode"));
+ EditorGUILayout.PropertyField(hitFxFadeOutDuration, new GUIContent("Fade Out Duration"));
+ EditorGUILayout.PropertyField(hitFxColor, new GUIContent("Color"));
+ if ((HitFxMode)hitFxMode.intValue == HitFxMode.LocalHit) {
+ EditorGUILayout.PropertyField(hitFxRadius, new GUIContent("Radius"));
+ }
+ EditorGUI.indentLevel--;
+ }
+ EditorGUILayout.EndVertical();
+
+ if (serializedObject.ApplyModifiedProperties() || (Event.current.type == EventType.ValidateCommand &&
+ Event.current.commandName == "UndoRedoPerformed")) {
+
+ // Triggers profile reload on all Highlight Effect scripts
+ HighlightEffect[] effects = FindObjectsOfType();
+ for (int t = 0; t < targets.Length; t++) {
+ HighlightProfile profile = (HighlightProfile)targets[t];
+ for (int k = 0; k < effects.Length; k++) {
+ if (effects[k] != null && effects[k].profile == profile && effects[k].profileSync) {
+ profile.Load(effects[k]);
+ effects[k].Refresh();
+ }
+ }
+ }
+ EditorUtility.SetDirty(target);
+ }
+
+ }
+
+ void DrawSectionField(SerializedProperty property, string label, bool active) {
+ EditorGUILayout.PropertyField(property, new GUIContent(active ? label + " •" : label));
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Editor/HighlightProfileEditor.cs.meta b/Assets/Plugins/HighlightPlus/Editor/HighlightProfileEditor.cs.meta
new file mode 100644
index 0000000..ca1f349
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor/HighlightProfileEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: b3b0e551d6f4f4f3987e8e5be2e89285
+timeCreated: 1542886545
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Editor/HighlightSeeThroughOccluderEditor.cs b/Assets/Plugins/HighlightPlus/Editor/HighlightSeeThroughOccluderEditor.cs
new file mode 100644
index 0000000..02d90a4
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor/HighlightSeeThroughOccluderEditor.cs
@@ -0,0 +1,33 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace HighlightPlus {
+
+ [CustomEditor(typeof(HighlightSeeThroughOccluder))]
+ public class HighlightSeeThroughOccluderEditor : Editor {
+
+ SerializedProperty mode, detectionMethod;
+
+ void OnEnable() {
+ mode = serializedObject.FindProperty("mode");
+ detectionMethod = serializedObject.FindProperty("detectionMethod");
+ }
+
+ public override void OnInspectorGUI() {
+
+ serializedObject.Update();
+
+ EditorGUILayout.PropertyField(mode);
+ if (mode.intValue == (int)OccluderMode.BlocksSeeThrough) {
+ EditorGUILayout.HelpBox("This object will occlude any see-through effect.", MessageType.Info);
+ EditorGUILayout.PropertyField(detectionMethod);
+ } else {
+ EditorGUILayout.HelpBox("This object will trigger see-through effect. Use only on objects that do not write to depth buffer normally, like sprites or transparent objects.", MessageType.Info);
+ }
+
+ serializedObject.ApplyModifiedProperties();
+
+ }
+ }
+
+}
diff --git a/Assets/Plugins/HighlightPlus/Editor/HighlightSeeThroughOccluderEditor.cs.meta b/Assets/Plugins/HighlightPlus/Editor/HighlightSeeThroughOccluderEditor.cs.meta
new file mode 100644
index 0000000..c75b07a
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor/HighlightSeeThroughOccluderEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 11e725ecbe4d74569b232e1a0d57efba
+timeCreated: 1548711355
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Editor/HighlightTriggerEditor.cs b/Assets/Plugins/HighlightPlus/Editor/HighlightTriggerEditor.cs
new file mode 100644
index 0000000..3f18f57
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor/HighlightTriggerEditor.cs
@@ -0,0 +1,105 @@
+using UnityEditor;
+using UnityEngine;
+
+namespace HighlightPlus {
+ [CustomEditor(typeof(HighlightTrigger))]
+ public class HighlightTriggerEditor : Editor {
+
+ SerializedProperty highlightOnHover, triggerMode, raycastCamera, raycastSource, raycastLayerMask;
+ SerializedProperty minDistance, maxDistance, respectUI, volumeLayerMask;
+ SerializedProperty selectOnClick, selectedProfile, selectedAndHighlightedProfile, singleSelection, toggleOnClick, keepSelection;
+ HighlightTrigger trigger;
+
+ void OnEnable() {
+ highlightOnHover = serializedObject.FindProperty("highlightOnHover");
+ triggerMode = serializedObject.FindProperty("triggerMode");
+ raycastCamera = serializedObject.FindProperty("raycastCamera");
+ raycastSource = serializedObject.FindProperty("raycastSource");
+ raycastLayerMask = serializedObject.FindProperty("raycastLayerMask");
+ minDistance = serializedObject.FindProperty("minDistance");
+ maxDistance = serializedObject.FindProperty("maxDistance");
+ respectUI = serializedObject.FindProperty("respectUI");
+ volumeLayerMask = serializedObject.FindProperty("volumeLayerMask");
+ selectOnClick = serializedObject.FindProperty("selectOnClick");
+ selectedProfile = serializedObject.FindProperty("selectedProfile");
+ selectedAndHighlightedProfile = serializedObject.FindProperty("selectedAndHighlightedProfile");
+ singleSelection = serializedObject.FindProperty("singleSelection");
+ toggleOnClick = serializedObject.FindProperty("toggle");
+ keepSelection = serializedObject.FindProperty("keepSelection");
+ trigger = (HighlightTrigger)target;
+ trigger.Init();
+ }
+
+ public override void OnInspectorGUI() {
+
+ serializedObject.Update();
+
+ if (trigger.triggerMode == TriggerMode.RaycastOnThisObjectAndChildren) {
+ if (trigger.colliders == null || trigger.colliders.Length == 0) {
+ EditorGUILayout.HelpBox("No collider found on this object or any of its children. Add colliders to allow automatic highlighting.", MessageType.Warning);
+ }
+ } else {
+#if ENABLE_INPUT_SYSTEM
+ if (trigger.triggerMode == TriggerMode.ColliderEventsOnlyOnThisObject) {
+ EditorGUILayout.HelpBox("This trigger mode is not compatible with the new input system.", MessageType.Error);
+ }
+#endif
+ if (trigger.GetComponent() == null) {
+ EditorGUILayout.HelpBox("No collider found on this object. Add a collider to allow automatic highlighting.", MessageType.Error);
+ }
+ }
+
+ EditorGUILayout.PropertyField(triggerMode);
+ switch (trigger.triggerMode) {
+ case TriggerMode.RaycastOnThisObjectAndChildren:
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(raycastCamera);
+ EditorGUILayout.PropertyField(raycastSource);
+ EditorGUILayout.PropertyField(raycastLayerMask);
+ EditorGUILayout.PropertyField(minDistance);
+ EditorGUILayout.PropertyField(maxDistance);
+ EditorGUI.indentLevel--;
+ break;
+ case TriggerMode.Volume:
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(volumeLayerMask);
+ EditorGUI.indentLevel--;
+ break;
+ }
+
+ if (trigger.triggerMode != TriggerMode.Volume) {
+ EditorGUILayout.PropertyField(respectUI);
+ }
+ EditorGUILayout.PropertyField(highlightOnHover);
+ EditorGUILayout.PropertyField(selectOnClick);
+ if (selectOnClick.boolValue) {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.PropertyField(selectedProfile);
+ EditorGUILayout.PropertyField(selectedAndHighlightedProfile);
+ EditorGUILayout.PropertyField(singleSelection);
+ EditorGUILayout.PropertyField(toggleOnClick);
+ if (trigger.triggerMode == TriggerMode.RaycastOnThisObjectAndChildren) {
+ EditorGUI.BeginChangeCheck();
+ EditorGUILayout.PropertyField(keepSelection);
+ if (EditorGUI.EndChangeCheck()) {
+ // Update all triggers
+ HighlightTrigger[] triggers = FindObjectsOfType();
+ foreach(HighlightTrigger t in triggers) {
+ if (t.keepSelection != keepSelection.boolValue) {
+ t.keepSelection = keepSelection.boolValue;
+ EditorUtility.SetDirty(t);
+ }
+ }
+ }
+ }
+ EditorGUI.indentLevel--;
+ }
+
+ if (serializedObject.ApplyModifiedProperties()) {
+ trigger.Init();
+ }
+ }
+
+ }
+
+}
diff --git a/Assets/Plugins/HighlightPlus/Editor/HighlightTriggerEditor.cs.meta b/Assets/Plugins/HighlightPlus/Editor/HighlightTriggerEditor.cs.meta
new file mode 100644
index 0000000..8ed2128
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor/HighlightTriggerEditor.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: eaf7f56fbcfa343efb5081d4309cb76b
+timeCreated: 1548711355
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Editor/TransparentWithDepth.cs b/Assets/Plugins/HighlightPlus/Editor/TransparentWithDepth.cs
new file mode 100644
index 0000000..932f801
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor/TransparentWithDepth.cs
@@ -0,0 +1,132 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Rendering;
+using UnityEditor;
+
+namespace HighlightPlus {
+
+ public class TransparentWithDepth {
+
+ static Material bmDepthOnly;
+ static Material bmDepthClipping;
+
+
+ [MenuItem ("GameObject/Effects/Highlight Plus/Add Depth To Transparent Object", false, 100)]
+ static void AddDepthOption () {
+ Renderer renderer = GetRenderer ();
+ if (renderer == null)
+ return;
+
+ if (!EditorUtility.DisplayDialog("Add Depth to Transparent Object", "This option will force the transparent object to write to the depth buffer by adding a new special material to the renderer (existing materials are preserved) so it can occlude and allow See-Through effect.\nOnly use on transparent objects.\n\nProceed?", "Yes", "No")) {
+ return;
+ }
+
+ Material[] materials = renderer.sharedMaterials;
+ for (int k = 0; k < materials.Length; k++) {
+ if (materials [k] == bmDepthOnly) {
+ EditorUtility.DisplayDialog ("Depth Support", "Already set! Nothing to do.", "Ok");
+ return;
+ }
+ }
+ if (materials == null) {
+ renderer.sharedMaterial = bmDepthOnly;
+ } else {
+ List newMaterials = new List (materials);
+ newMaterials.Insert (0, bmDepthOnly);
+ renderer.sharedMaterials = newMaterials.ToArray ();
+ }
+ }
+
+
+ [MenuItem("GameObject/Effects/Highlight Plus/Make Transparent Object Compatible with Depth Clipping", false, 101)]
+ static void AddDepthClippingOption() {
+ Renderer renderer = GetRenderer();
+ if (renderer == null)
+ return;
+
+ if (!EditorUtility.DisplayDialog("Make Transparent Object Compatible with Depth Clipping", "This option will force the transparent object to write to _CameraDepthBuffer which is used by depth clip option (existing materials are preserved) so it can occlude outline and glow effects in High Quality mode.\nOnly use on transparent objects which need to occlude other outline / glow effects in high quality mode.\n\nProceed?", "Yes", "No")) {
+ return;
+ }
+
+ Material[] materials = renderer.sharedMaterials;
+ for (int k = 0; k < materials.Length; k++) {
+ if (materials[k] == bmDepthClipping) {
+ EditorUtility.DisplayDialog("Depth Clipping Support", "Already set! Nothing to do.", "Ok");
+ return;
+ }
+ }
+ if (materials == null) {
+ renderer.sharedMaterial = bmDepthClipping;
+ } else {
+ List newMaterials = new List(materials);
+ newMaterials.Insert(0, bmDepthClipping);
+ renderer.sharedMaterials = newMaterials.ToArray();
+ }
+ }
+
+
+ [MenuItem("GameObject/Effects/Highlight Plus/Remove Depth Compatibility", false, 102)]
+ static void RemoveDepthOption() {
+
+ Renderer renderer = GetRenderer();
+ if (renderer == null)
+ return;
+
+ bool found = false;
+ Material[] materials = renderer.sharedMaterials;
+ for (int k = 0; k < materials.Length; k++) {
+ if (materials[k] == bmDepthOnly || materials[k] == bmDepthClipping) {
+ materials[k] = null;
+ found = true;
+ }
+ }
+ if (found) {
+ List newMaterials = new List();
+ for (int k = 0; k < materials.Length; k++) {
+ if (materials[k] != null) {
+ newMaterials.Add(materials[k]);
+ }
+ }
+ renderer.sharedMaterials = newMaterials.ToArray();
+ return;
+ }
+
+ EditorUtility.DisplayDialog("Depth Support", "This object was not previously modified! Nothing to do.", "Ok");
+ }
+
+
+ static Renderer GetRenderer() {
+
+ if (Selection.activeGameObject == null) {
+ EditorUtility.DisplayDialog("Depth Support", "This option can only be used on GameObjects.", "Ok");
+ return null;
+ }
+ Renderer renderer = Selection.activeGameObject.GetComponent();
+ if (renderer == null) {
+ EditorUtility.DisplayDialog("Depth Support", "This option can only be used on GameObjects with a Renderer component attached.", "Ok");
+ return null;
+ }
+
+ if (bmDepthOnly == null) {
+ bmDepthOnly = Resources.Load("HighlightPlus/HighlightPlusDepthWrite");
+ if (bmDepthOnly == null) {
+ EditorUtility.DisplayDialog("Depth Support", "HighlightPlusDepthWrite material not found!", "Ok");
+ return null;
+ }
+ }
+
+ if (bmDepthClipping == null) {
+ bmDepthClipping = Resources.Load("HighlightPlus/HighlightPlusDepthClipComp");
+ if (bmDepthClipping == null) {
+ EditorUtility.DisplayDialog("Depth Clipping Support", "HighlightPlusDepthClipComp material not found!", "Ok");
+ return null;
+ }
+ }
+
+ return renderer;
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Editor/TransparentWithDepth.cs.meta b/Assets/Plugins/HighlightPlus/Editor/TransparentWithDepth.cs.meta
new file mode 100644
index 0000000..dcdeb20
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor/TransparentWithDepth.cs.meta
@@ -0,0 +1,13 @@
+fileFormatVersion: 2
+guid: be6e3be6d17ed49a3bd16d816815d6fd
+timeCreated: 1515683694
+licenseType: Pro
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Editor/VRCheck.cs b/Assets/Plugins/HighlightPlus/Editor/VRCheck.cs
new file mode 100644
index 0000000..cb900b5
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor/VRCheck.cs
@@ -0,0 +1,47 @@
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEditor;
+using UnityEngine.XR;
+
+namespace HighlightPlus {
+ public static class VRCheck {
+
+#if UNITY_2019_3_OR_NEWER
+
+ static List displaysDescs = new List();
+ static List displays = new List();
+
+ public static bool IsActive() {
+ displaysDescs.Clear();
+ SubsystemManager.GetSubsystemDescriptors(displaysDescs);
+
+ // If there are registered display descriptors that is a good indication that VR is most likely "enabled"
+ return displaysDescs.Count > 0;
+ }
+
+ public static bool IsVrRunning() {
+ bool vrIsRunning = false;
+ displays.Clear();
+ SubsystemManager.GetInstances(displays);
+ foreach (var displaySubsystem in displays) {
+ if (displaySubsystem.running) {
+ vrIsRunning = true;
+ break;
+ }
+ }
+
+ return vrIsRunning;
+ }
+#else
+ public static bool IsActive() {
+ return PlayerSettings.virtualRealitySupported;
+ }
+
+ public static bool IsVrRunning() {
+ return Application.isPlaying && PlayerSettings.virtualRealitySupported;
+ }
+#endif
+
+ }
+
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Editor/VRCheck.cs.meta b/Assets/Plugins/HighlightPlus/Editor/VRCheck.cs.meta
new file mode 100644
index 0000000..9ff75fa
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Editor/VRCheck.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e692cbce37dc14e29b436d0c876f45dc
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/README.txt b/Assets/Plugins/HighlightPlus/README.txt
new file mode 100644
index 0000000..4a5de77
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/README.txt
@@ -0,0 +1,484 @@
+**************************************
+* HIGHLIGHT PLUS *
+* Created by Ramiro Oliva (Kronnect) *
+* README FILE *
+**************************************
+
+
+Quick help: how to use this asset?
+----------------------------------
+
+1) Highlighting specific objects: add HighlightEffect.cs script to any GameObject. Customize the appearance options.
+ In the Highlight Effect inspector, you can specify which objects, in addition to this one, are also affected by the effect:
+ a) Only this object
+ b) This object and its children
+ c) All objects from the root to the children
+ d) All objects belonging to a layer
+
+2) Control highlight effect when mouse is over:
+ Add HighlightTrigger.cs script to the GameObject. It will activate highlight on the gameobject when mouse pass over it.
+
+3) Highlighting any object in the scene:
+ Select top menu GameObject -> Effects -> Highlight Plus -> Create Manager.
+ Customize appearance and behaviour of Highlight Manager. Those settings are default settings for all objects. If you want different settings for certain objects just add another HighlightEffect script to each different object. The manager will use those settings.
+
+4) Make transparent shaders compatible with See-Through effect:
+ If you want the See-Through effect be seen through other transparent objects, they need to be modified so they write to depth buffer (by default transparent objects do not write to z-buffer).
+ To do so, select top menu GameObject -> Effects -> Highlight Plus -> Add Depth To Transparent Object.
+
+5) Static batching:
+ Objects marked as "static" need a MeshCollider in order to be highlighted. This is because Unity combines the meshes of static objects so it's not possible to highlight individual objects if their meshes are combined.
+ To allow highlighting static objects make sure they have a MeshCollider attached (the MeshCollider can be disabled).
+
+
+
+Help & Support Forum
+--------------------
+
+Check the Documentation folder for detailed instructions:
+
+Have any question or issue?
+* Support-Web: https://kronnect.com/support
+* Support-Discord: https://discord.gg/EH2GMaM
+* Email: contact@kronnect.com
+* Twitter: @Kronnect
+
+If you like Highlight Plus, please rate it on the Asset Store. It encourages us to keep improving it! Thanks!
+
+
+
+Universal Rendering Pipeline
+----------------------------
+
+Customers can download a specific version of Highlight Plus designed for Universal Rendering Pipeline for free from our support forum on https://kronnect.com
+Please sign up on the forum and send a pm to "Kronnect" or email to contact@kronnect.com to get access to the private board.
+
+The Unity Asset Store currently does not allow you to select which package according to the pipeline to download so we have to offer this way so you can download it.
+
+
+Future updates
+--------------
+
+All our assets follow an incremental development process by which a few beta releases are published on our support forum (kronnect.com).
+We encourage you to signup and engage our forum. The forum is the primary support and feature discussions medium.
+
+Of course, all updates of Highlight Plus will be eventually available on the Asset Store.
+
+
+
+More Cool Assets!
+-----------------
+Check out our other assets here:
+https://assetstore.unity.com/publishers/15018
+
+
+
+Version history
+---------------
+
+Current version
+- Added new "UV Space" options to Overlay effect (now: triplanar, object space or screen space)
+- Added mask texture and "UV Space" options to See-Through effect
+- Camera Distance Fade now also affects the see-through effect
+
+Version 9.5
+- Outline: added Color Style property and new Gradient option
+- Internal buffer for highest quality outline/glow format changed to R8 format to reduce memory and improve performance on mobile
+- API: Refresh(discardCachedMeshes): added discardCachedMeshes optional parameter to force refresh of cached meshes (useful for combined meshes that have changed)
+
+Version 9.4
+- Highlight See Through Occluder: added mode for triggering the see-through offect on sprites and transparent objects
+- [Fix] Fixed a problem on Quest 2 standalone when using with other render features (ie. Liquid Volume Pro 2 irregular topology)
+
+Version 9.3
+- Overlay: added "Mode" option (only when highlighted or always)
+- Nested highlight effects are now included unless the 'Ignore' option is selected
+- Cached meshes are now reconstructed when calling the Refresh() method
+
+Version 9.2
+- Improved shared mesh cache handling
+- Improved see-through camera-layer based detection
+
+Version 9.1.2
+- [Fix] Fixed outline/glow distortion due to floating point math issues at distant positions from origin
+
+Version 9.1.1
+- Added support for Unity 2022
+- Added Layer Mask option to Highlight Trigger
+- Added "Keep Selection" option in Highlight Manager and Highlight Trigger
+- [Fix] Fixed a potential issue that could exceed the maximum 64k vertices when combining meshes
+
+Version 9.0
+- Added "Camera Distance Fade" option
+- Improved see-through accurate method which now takes into account multi-part meshes from compound parents
+- [Fix] Fixed glow/outline aspect ratio in Single Pass Instanced VR mode
+
+Version 8.5
+- Improved outline effect when combining "Independent" option with many elements in "Children" selection
+- Improved see-through border only effect
+
+Version 8.4
+- Added "Border Only" option to See-Through effect
+- Outline/glow shape now properly cuts when partially occluded (instead of following the shape of the occluder)
+- Adding a Highlight Effect component to a parent no longer deactivates highlighted children
+
+Version 8.3
+- Upgraded to Unity 2020.3.16
+- [Fix] Fixed outline/glow render issue when MSAA is enabled
+
+Version 8.2
+- Added "Ignore Mask" option to glow. Can be used to render the glow effect alone
+- [Fix] Fixed issue with new input system and highlight manager/trigger if no Event System is present in the scene
+- [Fix] Fixed glow passes UI overlap in Unity 2021.3.3 due to reorderable array bug
+
+Version 8.1
+- Selection state is now visible in inspector (used only by trigger and manager components)
+- [Fix] Fixed mobile input using the new input system
+- [Fix] Fixed outline settings mismatch when using a combination of Highlight Trigger and Manager
+
+Version 8.0
+- Added SelectObject / ToggleObject / UnselectObject methods to Highlight Manager
+- Added ability to control rendering order of effects (check documentation: Custom sorting section)
+
+Version 7.9.1
+- Default values for all effects are now 0 (disabled) except outline so desired effects must be enabled. This option allows you to ensure no extra/undesired effects are activated by mistake
+- Redesigned Highlight Plus Profile editor interface
+- Removed dependency of HighlightManager
+
+Version 7.8
+- Added outer glow blend mode option
+- API: added OnObjectHighlightStart/End events to HighlightTrigger (check documentation for differences with similar events on Highlight Effect main script)
+- [Fix] API: Fixed specific issues with SetTarget method when used on shader graph based materials that don't use standard texture names
+
+Version 7.7.2
+- [Fix] Fixed fade in/out issue when disabling/enabling objects
+
+Version 7.7
+- Added support for the new Input System
+- [Fix] Fixes to the align to ground option of target fx effect
+
+Version 7.6.2
+- [Fix] VR: fixed target effect "Align to Ground" issue with Single Pass Instanced
+
+Version 7.6.1
+- [Fix] Fixed overlay animation speed issue
+
+Version 7.6
+- Added "Target FX Align to Ground" option
+- Added isSeeThroughOccluded(camera). Is true when any see-through occluder using raycast mode is blocking the see-through effect
+- All shader keywords are now of local type reducing global keyword usage
+- Fixes and improvements to see-through when combined with outline/outer glow
+
+Version 7.5.2
+- [Fix] See-through is now visible when using glow/outline/inner glow with Always Visible option
+
+Version 7.5
+- Added new HitFX style: "Local Hit"
+- Added new demo scene showcasing the HitFx variations
+- Added "Overlay Texture" option
+- Added "Min Distance" option to Highlight Manager and Highlight Trigger
+- Added support for "Domain Reload" disabled option
+- API: added OnObjectHighlightStart, OnObjectHighlightEnd events to HighlightManager
+- [Fix] Fixed inner glow and overlay issue when MaterialPropertyBlock is used on the character material
+
+Version 7.1
+- Added "Respect UI" to Highlight Manager and Trigger which blocks interaction if pointer is over an UI element
+
+Version 7.0.2
+- Memory optimizations
+
+Version 7.0.1
+- [Fix] Highest quality outline/glow fixes on mobile
+
+Version 7.0
+- Added support for Single Pass Instanced
+- Internal improvements and fixes
+
+Version 6.9
+- Internal improvements to see-through
+
+Version 6.8
+- Changed see-through effect rendering order to improve support with other stencil effects
+- [Fix] Fixed properties not being reflected in scene immediately when invoking Undo
+
+Version 6.7
+- Added "SeeThrough Max Depth" option. Limits the visibility of the see-through effect to certain distance from the occluders
+- Added "SeeThrough Check Individual Objects" option. If enabled, occlusion test is performed for each individual child of the object, instead of using combined bounds
+
+Version 6.6
+- Added "SeeThrough Depth Offset" option. This option allows you to control the minimum distance from the occluder to the object before showing the see-through effect
+- Added "SeeThrough Non Overlap" option. Enable it only if the see-through effect produces flickering due to overlapping geometry in the hidden object
+- [Fix] Fixed properties not being reflected in scene immediately when invoking Undo
+
+Version 6.5.1
+- Calling ProfileLoad() method will now assign that profile to the highlight effect component in addition to loading its values
+- Prevents _Time overflow which can cause glitching on some Android devices
+
+Version 6.5
+- Name filter now is ignored when effect group is set to Only This Object
+- New shader "HighlightPlus/Geometry/UIMask" to cancel highlight effects when rendering through a UI Canvas (see documentation)
+
+Version 6.4
+- Added "Cameras Layer Mask" to specify which cameras can render the effects
+- Hit FX color in Highlight Profile now exposes HDR color options
+
+Version 6.3.1
+- Added "Single Selection" option to Highlight Manager/Trigger
+- Added "Toggle" option to Highlight Manager/Trigger
+- Selection is cleared now when clicking anywhere in the scene (requires Highlight Manager)
+- API: added SetGlowColor
+- Improved Highlight Manager inspector
+
+Version 6.2
+- Added TargetFX Scale To Object Bounds (defaults to false)
+- Added support for HDR color to Hit FX color field
+- Option to list occluders in the inspector when See Through Occluder Mask "Accurate" option is enabled
+
+Version 6.1
+- Added more accurate occluder layer system ("Accurate" option)
+- Added default hit fx settings to inspector & profile
+- Added hit fx modes (overlay or inner glow)
+
+Version 6.0
+- Added Selection feature
+- Inspector: sections can be now collapsed to reduce screen space
+- API: added OnObjectSelected / OnObjectUnSelected events
+
+Version 5.5
+- Added "Planar" mode to Normals option. Best choice for highlighting 2D meshes (quad/planes)
+
+Version 5.4 5/Feb/2021
+- Added Visibility option to targete effect
+- Stencil mask is no longer computed when only overlay or inner glow is used improving performance
+
+Version 5.3.5 22/Jan/2021
+- Added "CustomVertexTransform.cginc" file which can be used to include user-defined vertex transformations
+- Optimizations to material setters
+
+Version 5.3.4
+- Improvements to combine meshes option
+
+Version 5.3.3
+- Effects now reflect object transform changes when combines meshes option is enabled
+
+Version 5.3.2
+- Memory optimizations
+
+Version 5.3.1
+- Optimizations and fixes
+
+Version 5.3
+- Added "Combine Meshes" option to profile
+
+Version 5.2
+- Added "Object Name Filter" option to profile
+
+Version 5.0
+- API: added "TargetFX" method to programmatically start the target effect
+- [Fix] Depth Clip option can now be used on mobile even with visibility set to Always On Top
+
+Version 4.9
+- Added "Medium" quality level
+
+Version 4.8.1
+- [Fix] Fixed outline/glow issue on iOS when using Highest Quality mode in Unity 2010.1
+
+Version 4.8
+- Added "Outer Glow Blend Passes" option
+- Added support for HDR colors
+
+Version 4.7
+- Added "Normals Option" with Smooth, Preserve and Reorient variants to improve results
+- Target effect now only renders once per gameobject if a specific target transform is specified
+- API: added OnTargetAnimates. Allows you to override center, rotation and scale of target effect on a per-frame basis.
+
+Version 4.6
+- Added "SubMesh Mask" which allows to exclude certain submeshes
+- [Fix] Fixed shader compilation issue with Single Pass Instanced mode enabled
+
+Version 4.5
+- Added "Preserve Original Mesh" option to inspector and profile
+
+Version 4.4
+- Added HitFX effect
+- Improved quality of outer glow when using Highest Quality mode
+- Improvements to SeeThrough Occluder when Detection Mode is set to RayCast
+- API: added SetTargets(transform, renderers)
+- API: added static method HighlightEffect.DrawEffectsNow() to force render all effects on demand
+
+Version 4.2
+- Added GPU Instancing support for outline / glow effects
+- Highlight Trigger: added volume collision detection
+
+Version 4.1.1
+- [Fix] Fixed issue with grouped objects when independent option is enabled and Highest Quality outer glow or outline is used
+
+Version 4.1
+- Improved "Outline Independent" option for Highest Quality Mode
+- Consistency: enabling "Outline Independent" in Highest Quality Mode now also affects Outer Glow is used
+
+Version 4.0
+- Start up peformance & memory allocation optimizations
+- Added "Independent" support to outline in Highest Quality mode
+- Added "Make Transparent Object Compatible With Depth Clip" option
+
+Version 3.9
+- Added "Depth Clip" option (only applies to HQ outline/glow effects)
+
+Version 3.8
+- Glow/Outline downsampling and glow blend mode option added to profiles
+- [Fix] Fixed an issue which marked the scene as dirty
+- [Fix] Removed VR API usage console warning
+
+Version 3.7
+- See Through: added "Occluder Mask" option. When set to a custom layer, it performs a BoxCast check to ensure only objects in the specific layers are occluding the target. Customize this behaviour using the Radius Threshold and Check Interval settings.
+- Added "Max Distance" to Highlight Trigger
+- Reduced allocations when averaging normals
+- [Fix] Fixed flickering of outer glow when used in Highest quality with thin objects
+
+Version 3.6
+- Added "Outline Independent" option. Shows full outline regardless of any other highlighted object behind.
+
+Version 3.5
+- Improved quality of Outline effect when quality level is set to Highest
+- Added "SeeThrough Border" feature
+- Added "Blend Mode" option to Outer Glow for highest quality level
+- [Fix] Fixed issue during Prefab editor mode
+
+Version 3.4.4
+- Added option in occluder script to use raycast instead of stencil buffer to cancel see-through (useful for avoiding terrain triggering see-through effect)
+- [Fix] Fixed see-through in deferred rendering path
+
+Version 3.4.2
+- [Fix] Fixed an issue when adding the effect at runtime with outline/glow in higuest quality
+
+Version 3.4.1
+- [Fix] Fixed occluder objects removing glow effect when placed in the background
+- [Fix] Added missing SeeThrough noise option to Highlight Profile asset
+
+Version 3.4
+- Added LayerInChildren option to "Include" filter
+- Improved occluder system
+- [Fix] Prevent an error when the mesh normals count does not match the vertex count
+
+Version 3.3
+- Outline, Glow and Inner Glow "Always On Top" option expanded to "Normal", "Always On Top" or "Only When Occluded"
+- Added Noise slider to See-Through effect
+
+Version 3.2.4
+- [Fix] Fixed flickering issue when combining mesh & skinned mesh renderers
+
+Version 3.2.3
+- General improvements and fixes
+
+Version 3.2.2
+- [Fix] Fixed issue when trying to read normals from a non-readable mesh
+
+Version 3.2.1
+- [Fix] Fixed glow disappearing when object crosses camera near clip
+
+Version 3.2
+- Added "Reflection Probes" option
+- Internal improvements and fixes
+
+Version 3.1
+- Added "Constant Width" option to Glow/Outline in Fastest/High quality level
+- Added "Optimal Blit" option to Glow/Outline with Debug View
+
+Version 3.0.2
+- API: added proxy methods ProfileLoad, ProfileReload, ProfileSaveChanges to load/store profile settings at runtime. You can also load/save changes between effect and profile using the Load/Save methods on the profile object itself.
+
+Version 3.0.1
+- [Fix] Fixed an exception when glow was enabled, outline disabled in highest quality level
+
+Version 3.0
+- Added HQ Highest quality glow and outline options
+- Added "Include" option to choose which objects are affected by the effects (same gameobject, children, root to children, or many objects in layer)
+- Added "Alpha CutOff"
+
+Version 2.6.1
+- Minor internal improvements
+
+Version 2.6
+- Added Target effect
+- Improved performance on Skinned Mesh Renderers. Slightly improved performance on normal renderers.
+
+Version 2.5.2
+- [Fix] Fixed issue with HQ Outer Glow not showing when there's multiple selected objects parented to the same object
+
+Version 2.5.1
+- Added support for orthographic camera
+
+Version 2.5
+- Added support for VR Single Pass Instanced
+- Minor improvements and fixes
+
+Version 2.4
+- New HighlightSeeThroughOccluder script. Add it to any object to cancel any see-through effect
+- Added "Fade In Duration" / "Fade Out Duration" to create smooth transition states
+- Added "Glow HQ" to produce better outer glow on certain shapes
+- Added "OnRendererHighlightStart" event
+- API: added "OverlayOnShot" method for impact effects
+
+Version 2.3
+- Added "Raycast Source" to Highlight Trigger and Manager components
+- Added "Skinned Mesh Bake Mode" to optimize highlight on many models
+
+Version 2.2
+- Added "Always On Top" option to Outline, Outer and Inner Glow
+- Added "Trigger Mode" to Highlight Trigger to support complex objects
+
+Version 2.1
+- Added "Outline HQ" to inspector. Creates a better outline on certain shapes
+- Added "Ignore Object Visibility" to enable effects on disabled renderers or hidden objects
+
+Version 2.0
+- Profiles. Store/load/share settings across different objects.
+- [Fix] Fixed issue when copying component values between two objects
+- [Fix] Fixed effects ignoring culling mask on additional cameras
+
+Version 1.5
+- Added "Inner Glow" effect
+
+Version 1.4
+- Added "Overlay Min Intensity" and "Overlay Blending" options
+- Added "Ignore" option
+- Minor improvements & fixes
+
+Version 1.3
+- Added option to add depth compatibility for transparent shaders
+
+Version 1.2.4
+- [Fix] Fix for multiple skinned models
+- [Fix] Fix for scaled skinned models
+
+Version 1.2.3
+- [Fix] Fixes for Steam VR
+
+Version 1.2.1
+- Internal improvements and fixes
+
+Version 1.2.1
+- [Fix] Fixed script execution order issue with scripts changing transform in LateUpdate()
+
+Version 1.2
+- Support for LOD groups
+
+Version 1.1
+- Redesigned editor inspector
+- Minor improvements
+
+Version 1.0.4
+- Supports meshes with negative scales
+
+Version 1.0.3
+- Support for multiple submeshes
+
+Version 1.0.2
+- [Fix] Fixed scale issue with grouped objects
+
+Version 1.0.1
+- Supports combined meshes
+
+Version 1.0 - Nov/2018
+- Initial release
diff --git a/Assets/Plugins/HighlightPlus/README.txt.meta b/Assets/Plugins/HighlightPlus/README.txt.meta
new file mode 100644
index 0000000..66f5cba
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/README.txt.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 53265a9967ed548efaf71f5807638781
+timeCreated: 1542901568
+licenseType: Pro
+TextScriptImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources.meta b/Assets/Plugins/HighlightPlus/Resources.meta
new file mode 100644
index 0000000..7c6c2dc
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 3a476022645d74299b862c36d0daa1df
+folderAsset: yes
+timeCreated: 1542876301
+licenseType: Pro
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus.meta
new file mode 100644
index 0000000..e3104c5
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 6bd97436761b94109a0785ed6823647c
+folderAsset: yes
+timeCreated: 1542893576
+licenseType: Pro
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/CustomVertexTransform.cginc b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/CustomVertexTransform.cginc
new file mode 100644
index 0000000..60241d2
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/CustomVertexTransform.cginc
@@ -0,0 +1,10 @@
+#ifndef CUSTOM_VERTEX_TRANSFORM_INCLUDED
+#define CUSTOM_VERTEX_TRANSFORM_INCLUDED
+
+float4 ComputeVertexPosition(float4 vertex) {
+ // Add here any custom vertex transform
+ float4 pos = UnityObjectToClipPos(vertex);
+ return pos;
+}
+
+#endif
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/CustomVertexTransform.cginc.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/CustomVertexTransform.cginc.meta
new file mode 100644
index 0000000..62d91ea
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/CustomVertexTransform.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: e25b1281ec6724b028e33a5df5a3f266
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightAddDepth.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightAddDepth.shader
new file mode 100644
index 0000000..835a34c
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightAddDepth.shader
@@ -0,0 +1,49 @@
+Shader "HighlightPlus/Geometry/JustDepth"
+{
+ Properties
+ {
+ }
+ SubShader
+ {
+ Tags { "RenderType"="Opaque" }
+ ColorMask 0
+ Pass
+ {
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+
+ #include "UnityCG.cginc"
+ #include "CustomVertexTransform.cginc"
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos : SV_POSITION;
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = ComputeVertexPosition(v.vertex);
+ return o;
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ return 0;
+ }
+ ENDCG
+ }
+ }
+}
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightAddDepth.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightAddDepth.shader.meta
new file mode 100644
index 0000000..123e669
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightAddDepth.shader.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 058a572e30b2d446bade2dda32bcef0f
+timeCreated: 1515682635
+licenseType: Pro
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightAddDepthClip.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightAddDepthClip.shader
new file mode 100644
index 0000000..a7961f2
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightAddDepthClip.shader
@@ -0,0 +1,43 @@
+Shader "HighlightPlus/Geometry/DepthClipComp"
+{
+ Properties
+ {
+ }
+ SubShader
+ {
+ Pass {
+ Name "ShadowCaster"
+ Tags { "LightMode" = "ShadowCaster" }
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+ #pragma target 2.0
+ #pragma multi_compile_shadowcaster
+ #pragma multi_compile_instancing
+ #include "UnityCG.cginc"
+
+ struct v2f {
+ V2F_SHADOW_CASTER;
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ v2f vert( appdata_base v ) {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
+ return o;
+ }
+
+ float4 frag( v2f i ) : SV_Target {
+ SHADOW_CASTER_FRAGMENT(i)
+ }
+ ENDCG
+
+ }
+
+ }
+
+}
+
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightAddDepthClip.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightAddDepthClip.shader.meta
new file mode 100644
index 0000000..ad6f592
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightAddDepthClip.shader.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 0917f634da79a4983ad78bac83d5a715
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightBlurGlow.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightBlurGlow.shader
new file mode 100644
index 0000000..aba3ecf
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightBlurGlow.shader
@@ -0,0 +1,158 @@
+Shader "HighlightPlus/Geometry/BlurGlow" {
+Properties {
+ _MainTex ("Texture", Any) = "white" {}
+ _Color ("Color", Color) = (1,1,0) // not used; dummy property to avoid inspector warning "material has no _Color property"
+ _BlurScale("Blur Scale", Float) = 2.0
+ _Speed("Speed", Float) = 1
+}
+ SubShader
+ {
+ ZTest Always
+ ZWrite Off
+ Cull Off
+ CGINCLUDE
+
+ #include "UnityCG.cginc"
+
+ UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex);
+ float4 _MainTex_TexelSize;
+ float4 _MainTex_ST;
+ float _BlurScale, _Speed;
+
+ struct appdata {
+ float4 vertex : POSITION;
+ float2 texcoord : TEXCOORD0;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2fCross {
+ float4 pos : SV_POSITION;
+ float2 uv: TEXCOORD0;
+ float2 uv1: TEXCOORD1;
+ float2 uv2: TEXCOORD2;
+ float2 uv3: TEXCOORD3;
+ float2 uv4: TEXCOORD4;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ v2fCross vertCross(appdata v) {
+ v2fCross o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = UnityObjectToClipPos(v.vertex);
+ #if UNITY_UV_STARTS_AT_TOP
+ if (_MainTex_TexelSize.y < 0) {
+ // Texture is inverted WRT the main texture
+ v.texcoord.y = 1.0 - v.texcoord.y;
+ }
+ #endif
+ o.uv = v.texcoord;
+ float3 offsets = _MainTex_TexelSize.xyx * float3(1,1,-1);
+ o.uv1 = v.texcoord - offsets.xy;
+ o.uv2 = v.texcoord - offsets.zy;
+ o.uv3 = v.texcoord + offsets.zy;
+ o.uv4 = v.texcoord + offsets.xy;
+ return o;
+ }
+
+
+ v2fCross vertBlurH(appdata v) {
+ v2fCross o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = UnityObjectToClipPos(v.vertex);
+ #if UNITY_UV_STARTS_AT_TOP
+ if (_MainTex_TexelSize.y < 0) {
+ // Texture is inverted WRT the main texture
+ v.texcoord.y = 1.0 - v.texcoord.y;
+ }
+ #endif
+ float animatedWidth = _BlurScale * (1.0 + 0.25 * sin(_Time.w * _Speed));
+ o.uv = v.texcoord;
+ float2 inc = float2(_MainTex_TexelSize.x * 1.3846153846 * animatedWidth, 0);
+ o.uv1 = v.texcoord - inc;
+ o.uv2 = v.texcoord + inc;
+ float2 inc2 = float2(_MainTex_TexelSize.x * 3.2307692308 * animatedWidth, 0);
+ o.uv3 = v.texcoord - inc2;
+ o.uv4 = v.texcoord + inc2;
+ return o;
+ }
+
+ v2fCross vertBlurV(appdata v) {
+ v2fCross o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = UnityObjectToClipPos(v.vertex);
+ #if UNITY_UV_STARTS_AT_TOP
+ if (_MainTex_TexelSize.y < 0) {
+ // Texture is inverted WRT the main texture
+ v.texcoord.y = 1.0 - v.texcoord.y;
+ }
+ #endif
+ float animatedWidth = _BlurScale * (1.0 + 0.25 * sin(_Time.w * _Speed));
+ o.uv = v.texcoord;
+ float2 inc = float2(0, _MainTex_TexelSize.y * 1.3846153846 * animatedWidth);
+ o.uv1 = v.texcoord - inc;
+ o.uv2 = v.texcoord + inc;
+ float2 inc2 = float2(0, _MainTex_TexelSize.y * 3.2307692308 * animatedWidth);
+ o.uv3 = v.texcoord - inc2;
+ o.uv4 = v.texcoord + inc2;
+ return o;
+ }
+
+ float4 fragBlur (v2fCross i): SV_Target {
+ UNITY_SETUP_INSTANCE_ID(i);
+ UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
+ float4 pixel = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv) * 0.2270270270
+ + (UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv1) + UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv2)) * 0.3162162162
+ + (UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv3) + UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv4)) * 0.0702702703;
+ return pixel;
+ }
+
+ float4 fragResample(v2fCross i) : SV_Target {
+ UNITY_SETUP_INSTANCE_ID(i);
+ UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
+ float4 c1 = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv1);
+ float4 c2 = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv2);
+ float4 c3 = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv3);
+ float4 c4 = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv4);
+ return (c1+c2+c3+c4) * 0.25;
+ }
+
+
+ ENDCG
+
+ Pass {
+ CGPROGRAM
+ #pragma vertex vertBlurH
+ #pragma fragment fragBlur
+ #pragma fragmentoption ARB_precision_hint_fastest
+ #pragma target 3.0
+ ENDCG
+ }
+
+ Pass {
+ CGPROGRAM
+ #pragma vertex vertBlurV
+ #pragma fragment fragBlur
+ #pragma fragmentoption ARB_precision_hint_fastest
+ #pragma target 3.0
+ ENDCG
+ }
+
+ Pass {
+ CGPROGRAM
+ #pragma vertex vertCross
+ #pragma fragment fragResample
+ #pragma fragmentoption ARB_precision_hint_fastest
+ #pragma target 3.0
+ ENDCG
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightBlurGlow.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightBlurGlow.shader.meta
new file mode 100644
index 0000000..365d4fc
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightBlurGlow.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 84c84ee93ec484bdda371ffbdebfcc7c
+timeCreated: 1556874239
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightBlurOutline.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightBlurOutline.shader
new file mode 100644
index 0000000..4e07846
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightBlurOutline.shader
@@ -0,0 +1,156 @@
+Shader "HighlightPlus/Geometry/BlurOutline" {
+Properties {
+ _MainTex ("Texture", Any) = "white" {}
+ _Color ("Color", Color) = (1,1,0) // not used; dummy property to avoid inspector warning "material has no _Color property"
+ _BlurScale("Blur Scale", Float) = 2.0
+}
+ SubShader
+ {
+ Tags { "Queue"="Transparent+100" "RenderType"="Transparent" }
+ ZTest Always
+ ZWrite Off
+ Cull Off
+ CGINCLUDE
+
+ #include "UnityCG.cginc"
+
+ UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex);
+ float4 _MainTex_TexelSize;
+ float4 _MainTex_ST;
+ float _BlurScale;
+
+ struct appdata {
+ float4 vertex : POSITION;
+ float2 texcoord : TEXCOORD0;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+
+ struct v2fCross {
+ float4 pos : SV_POSITION;
+ float2 uv: TEXCOORD0;
+ float2 uv1: TEXCOORD1;
+ float2 uv2: TEXCOORD2;
+ float2 uv3: TEXCOORD3;
+ float2 uv4: TEXCOORD4;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ v2fCross vertCross(appdata v) {
+ v2fCross o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = UnityObjectToClipPos(v.vertex);
+ #if UNITY_UV_STARTS_AT_TOP
+ if (_MainTex_TexelSize.y < 0) {
+ // Texture is inverted WRT the main texture
+ v.texcoord.y = 1.0 - v.texcoord.y;
+ }
+ #endif
+ o.uv = v.texcoord;
+ float3 offsets = _MainTex_TexelSize.xyx * float3(1,1,-1);
+ o.uv1 = v.texcoord - offsets.xy;
+ o.uv2 = v.texcoord - offsets.zy;
+ o.uv3 = v.texcoord + offsets.zy;
+ o.uv4 = v.texcoord + offsets.xy;
+ return o;
+ }
+
+
+ v2fCross vertBlurH(appdata v) {
+ v2fCross o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = UnityObjectToClipPos(v.vertex);
+ #if UNITY_UV_STARTS_AT_TOP
+ if (_MainTex_TexelSize.y < 0) {
+ // Texture is inverted WRT the main texture
+ v.texcoord.y = 1.0 - v.texcoord.y;
+ }
+ #endif
+ o.uv = v.texcoord;
+ float2 inc = float2(_MainTex_TexelSize.x * 1.3846153846 * _BlurScale, 0);
+ o.uv1 = v.texcoord - inc;
+ o.uv2 = v.texcoord + inc;
+ float2 inc2 = float2(_MainTex_TexelSize.x * 3.2307692308 * _BlurScale, 0);
+ o.uv3 = v.texcoord - inc2;
+ o.uv4 = v.texcoord + inc2;
+ return o;
+ }
+
+ v2fCross vertBlurV(appdata v) {
+ v2fCross o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = UnityObjectToClipPos(v.vertex);
+ #if UNITY_UV_STARTS_AT_TOP
+ if (_MainTex_TexelSize.y < 0) {
+ // Texture is inverted WRT the main texture
+ v.texcoord.y = 1.0 - v.texcoord.y;
+ }
+ #endif
+ o.uv = v.texcoord;
+ float2 inc = float2(0, _MainTex_TexelSize.y * 1.3846153846 * _BlurScale);
+ o.uv1 = v.texcoord - inc;
+ o.uv2 = v.texcoord + inc;
+ float2 inc2 = float2(0, _MainTex_TexelSize.y * 3.2307692308 * _BlurScale);
+ o.uv3 = v.texcoord - inc2;
+ o.uv4 = v.texcoord + inc2;
+ return o;
+ }
+
+ float4 fragBlur (v2fCross i): SV_Target {
+ UNITY_SETUP_INSTANCE_ID(i);
+ UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
+ float4 pixel = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv) * 0.2270270270
+ + (UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv1) + UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv2)) * 0.3162162162
+ + (UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv3) + UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv4)) * 0.0702702703;
+ return pixel;
+ }
+
+ float4 fragResample(v2fCross i) : SV_Target {
+ UNITY_SETUP_INSTANCE_ID(i);
+ UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
+ float4 c1 = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv1);
+ float4 c2 = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv2);
+ float4 c3 = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv3);
+ float4 c4 = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv4);
+ return (c1+c2+c3+c4) * 0.25;
+ }
+
+
+ ENDCG
+
+ Pass {
+ CGPROGRAM
+ #pragma vertex vertBlurH
+ #pragma fragment fragBlur
+ #pragma fragmentoption ARB_precision_hint_fastest
+ #pragma target 3.0
+ ENDCG
+ }
+
+ Pass {
+ CGPROGRAM
+ #pragma vertex vertBlurV
+ #pragma fragment fragBlur
+ #pragma fragmentoption ARB_precision_hint_fastest
+ #pragma target 3.0
+ ENDCG
+ }
+
+ Pass {
+ CGPROGRAM
+ #pragma vertex vertCross
+ #pragma fragment fragResample
+ #pragma fragmentoption ARB_precision_hint_fastest
+ #pragma target 3.0
+ ENDCG
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightBlurOutline.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightBlurOutline.shader.meta
new file mode 100644
index 0000000..93ce1e8
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightBlurOutline.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 74f3491dcf1224f0c91238381c035439
+timeCreated: 1556874239
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightClearStencil.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightClearStencil.shader
new file mode 100644
index 0000000..99cc59e
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightClearStencil.shader
@@ -0,0 +1,97 @@
+Shader "HighlightPlus/ClearStencil"
+{
+ Properties
+ {
+ }
+ SubShader
+ {
+ Stencil {
+ Ref 8 // bit 8 is used by HighlightUIMask shader to prevent Clear Stencil passes
+ Comp NotEqual
+ Pass zero
+ ReadMask 8
+ WriteMask 6
+ }
+ ZTest Always
+ ZWrite Off
+ Cull Off
+ ColorMask 0
+
+ Pass // Ordered full screen
+ {
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+
+ #include "UnityCG.cginc"
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos : SV_POSITION;
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = float4(v.vertex.xy, 0, 0.5);
+ return o;
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ return 0;
+ }
+ ENDCG
+ }
+
+ Pass // Ordered object-space
+ {
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+
+ #include "UnityCG.cginc"
+ #include "CustomVertexTransform.cginc"
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos : SV_POSITION;
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = ComputeVertexPosition(v.vertex);
+ return o;
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ return 0;
+ }
+ ENDCG
+ }
+ }
+}
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightClearStencil.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightClearStencil.shader.meta
new file mode 100644
index 0000000..d7237e9
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightClearStencil.shader.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 632d26701d1f14d9ab2950021e6fed87
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightComposeGlow.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightComposeGlow.shader
new file mode 100644
index 0000000..3bb5e69
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightComposeGlow.shader
@@ -0,0 +1,147 @@
+Shader "HighlightPlus/Geometry/ComposeGlow" {
+Properties {
+ _MainTex ("Texture", Any) = "black" {}
+ _Color ("Color", Color) = (1,1,1) // not used; dummy property to avoid inspector warning "material has no _Color property"
+ [HideInInspector] _Cull ("Cull Mode", Int) = 2
+ [HideInInspector] _ZTest ("ZTest Mode", Int) = 0
+ [HideInInspector] _Flip("Flip", Vector) = (0, 1, 0)
+ [HideInInspector] _BlendSrc("Blend Src", Int) = 1
+ [HideInInspector] _BlendDst("Blend Dst", Int) = 1
+ _Debug("Debug Color", Color) = (0,0,0,0)
+ [HideInInspector] _GlowStencilComp ("Stencil Comp", Int) = 6
+}
+ SubShader
+ {
+ Tags { "Queue"="Transparent+102" "RenderType"="Transparent" }
+ Blend [_BlendSrc] [_BlendDst]
+
+ // Compose effect on camera target
+ Pass
+ {
+ ZWrite Off
+ ZTest [_ZTest]
+ Cull Off //[_Cull]
+ Stencil {
+ Ref 2
+ Comp [_GlowStencilComp]
+ Pass keep
+ ReadMask 2
+ WriteMask 2
+ }
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+
+ #include "UnityCG.cginc"
+
+ UNITY_DECLARE_SCREENSPACE_TEXTURE(_HPComposeGlowFinal);
+ fixed4 _Color;
+ float3 _Flip;
+ fixed4 _Debug;
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos: SV_POSITION;
+ float4 scrPos: TEXCOORD0;
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = UnityObjectToClipPos(v.vertex);
+ o.scrPos = ComputeScreenPos(o.pos);
+ o.scrPos.y = o.scrPos.w * _Flip.x + o.scrPos.y * _Flip.y;
+ return o;
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
+ fixed4 glow = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_HPComposeGlowFinal, i.scrPos.xy/i.scrPos.w);
+ fixed4 color = _Color;
+ color *= glow.r;
+ color += _Debug;
+ color.a = saturate(color.a);
+ return color;
+ }
+ ENDCG
+ }
+
+ // Compose effect on camera target (full-screen blit)
+ Pass
+ {
+ ZWrite Off
+ ZTest Always //[_ZTest]
+ Cull Off //[_Cull]
+
+ Stencil {
+ Ref 2
+ Comp NotEqual
+ Pass keep
+ ReadMask 2
+ WriteMask 2
+ }
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+
+ #include "UnityCG.cginc"
+
+ UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex);
+ float4 _MainTex_ST;
+ fixed4 _Color;
+ float3 _Flip;
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ float2 uv : TEXCOORD0;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos: SV_POSITION;
+ float2 uv : TEXCOORD0;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ v2f vert(appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = UnityObjectToClipPos(v.vertex);
+ o.uv = UnityStereoScreenSpaceUVAdjust(v.uv, _MainTex_ST);
+ o.uv.y = _Flip.x + o.uv.y * _Flip.y;
+ return o;
+ }
+
+ fixed4 frag(v2f i) : SV_Target
+ {
+ UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
+ fixed4 glow = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv);
+ fixed4 color = _Color;
+ color *= glow.r;
+ color.a = saturate(color.a);
+ return color;
+ }
+ ENDCG
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightComposeGlow.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightComposeGlow.shader.meta
new file mode 100644
index 0000000..685907e
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightComposeGlow.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 975a91ee935da4d9c8a3e807fecd8047
+timeCreated: 1544699251
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightComposeOutline.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightComposeOutline.shader
new file mode 100644
index 0000000..b80cf1e
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightComposeOutline.shader
@@ -0,0 +1,144 @@
+Shader "HighlightPlus/Geometry/ComposeOutline" {
+Properties {
+ _MainTex ("Texture", Any) = "black" {}
+ _Color("Color", Color) = (1,1,1) // not used; dummy property to avoid inspector warning "material has no _Color property"
+ _Cull("Cull Mode", Int) = 2
+ _ZTest("ZTest Mode", Int) = 0
+ _Flip("Flip", Vector) = (0, 1, 0)
+ _Debug("Debug Color", Color) = (0,0,0,0)
+}
+SubShader
+ {
+ Tags { "Queue" = "Transparent+120" "RenderType" = "Transparent" }
+ Blend SrcAlpha OneMinusSrcAlpha
+
+ // Compose effect on camera target (optimal quad blit)
+ Pass
+ {
+ ZWrite Off
+ ZTest [_ZTest]
+ Cull Off // [_Cull]
+ Stencil {
+ Ref 2
+ Comp NotEqual
+ Pass keep
+ ReadMask 2
+ WriteMask 2
+ }
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+
+ #include "UnityCG.cginc"
+
+ UNITY_DECLARE_SCREENSPACE_TEXTURE(_HPComposeOutlineFinal);
+
+ fixed4 _Color;
+ float3 _Flip;
+ fixed4 _Debug;
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos: SV_POSITION;
+ float4 scrPos: TEXCOORD0;
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = UnityObjectToClipPos(v.vertex);
+ o.scrPos = ComputeScreenPos(o.pos);
+ o.scrPos.y = o.scrPos.w * _Flip.x + o.scrPos.y * _Flip.y;
+ return o;
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
+ fixed4 outline = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_HPComposeOutlineFinal, i.scrPos.xy/i.scrPos.w);
+ fixed4 color = _Color;
+ color.a *= outline.r;
+ color += _Debug;
+ color.a = saturate(color.a);
+ return color;
+ }
+ ENDCG
+ }
+
+ // Compose effect on camera target (full-screen blit)
+ Pass
+ {
+ ZWrite Off
+ ZTest Always // [_ZTest]
+ Cull Off // [_Cull]
+ Stencil {
+ Ref 2
+ Comp NotEqual
+ Pass keep
+ ReadMask 2
+ WriteMask 2
+ }
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+
+ #include "UnityCG.cginc"
+
+ UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex);
+ float4 _MainTex_ST;
+ fixed4 _Color;
+ float3 _Flip;
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ float2 uv : TEXCOORD0;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos: SV_POSITION;
+ float2 uv : TEXCOORD0;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ v2f vert(appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = UnityObjectToClipPos(v.vertex);
+ o.uv = UnityStereoScreenSpaceUVAdjust(v.uv, _MainTex_ST);
+ o.uv.y = _Flip.x + o.uv.y * _Flip.y;
+ return o;
+ }
+
+ fixed4 frag(v2f i) : SV_Target
+ {
+ UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
+ fixed4 outline = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv);
+ fixed4 color = _Color;
+ color.a *= outline.r;
+ color = saturate(color);
+ return color;
+ }
+ ENDCG
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightComposeOutline.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightComposeOutline.shader.meta
new file mode 100644
index 0000000..8d27750
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightComposeOutline.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 0a6de74b6cfa9440182f8f56e4a0e4f1
+timeCreated: 1544699251
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightGlow.mat b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightGlow.mat
new file mode 100644
index 0000000..202a9ca
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightGlow.mat
@@ -0,0 +1,84 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+ serializedVersion: 6
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_Name: HighlightGlow
+ m_Shader: {fileID: 4800000, guid: 049d9e75e07674a78a703cf1203c07dd, type: 3}
+ m_ShaderKeywords:
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 1
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _BumpMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailAlbedoMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailMask:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailNormalMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _EmissionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MainTex:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MetallicGlossMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _OcclusionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _ParallaxMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Floats:
+ - _BumpScale: 1
+ - _ConstantWidth: 1
+ - _Cull: 2
+ - _Cutoff: 0.5
+ - _DetailNormalMapScale: 1
+ - _DstBlend: 0
+ - _GlossMapScale: 1
+ - _Glossiness: 0.5
+ - _GlossyReflections: 1
+ - _GlowZTest: 4
+ - _Metallic: 0
+ - _Mode: 0
+ - _OcclusionStrength: 1
+ - _Parallax: 0.02
+ - _SmoothnessTextureChannel: 0
+ - _SpecularHighlights: 1
+ - _SrcBlend: 1
+ - _UVSec: 0
+ - _ZWrite: 1
+ m_Colors:
+ - _Color: {r: 1, g: 1, b: 1, a: 1}
+ - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+ - _Glow: {r: 1, g: 0.025, b: 0.75, a: 0.5}
+ - _Glow2: {r: 0.01, g: 1, b: 0.5, a: 0}
+ - _GlowColor: {r: 1, g: 1, b: 1, a: 1}
+ - _GlowDirection: {r: 1, g: 1, b: 0, a: 1}
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightGlow.mat.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightGlow.mat.meta
new file mode 100644
index 0000000..4565bca
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightGlow.mat.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 60e964940a24547a585c3ffff7e52e9b
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightGlow.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightGlow.shader
new file mode 100644
index 0000000..3fe23cc
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightGlow.shader
@@ -0,0 +1,114 @@
+Shader "HighlightPlus/Geometry/Glow" {
+Properties {
+ _MainTex ("Texture", Any) = "white" {}
+ _Glow ("Glow", Vector) = (1, 0.025, 0.75, 0.5)
+ _Glow2 ("Glow2", Vector) = (0.01, 1, 0.5, 0)
+ _GlowColor ("Glow Color", Color) = (1,1,1)
+ _Color ("Color", Color) = (1,1,1) // not used; dummy property to avoid inspector warning "material has no _Color property"
+ _GlowDirection("GlowDir", Vector) = (1,1,0)
+ _Cull ("Cull Mode", Int) = 2
+ _ConstantWidth ("Constant Width", Float) = 1
+ _GlowZTest ("ZTest", Int) = 4
+ _GlowStencilOp ("Stencil Operation", Int) = 0
+ _GlowStencilComp ("Stencil Comp", Int) = 6
+}
+ SubShader
+ {
+ Tags { "Queue"="Transparent+102" "RenderType"="Transparent" "DisableBatching"="True" }
+
+ // Glow passes
+ Pass
+ {
+ Stencil {
+ Ref 2
+ Comp [_GlowStencilComp]
+ Pass [_GlowStencilOp]
+ ReadMask 2
+ WriteMask 2
+ }
+ Blend SrcAlpha OneMinusSrcAlpha
+ ZWrite Off
+ Cull [_Cull]
+ ZTest [_GlowZTest]
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+ #pragma multi_compile_instancing
+ #include "UnityCG.cginc"
+ #include "CustomVertexTransform.cginc"
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ float3 normal : NORMAL;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos : SV_POSITION;
+ fixed4 color : COLOR;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ //float4 _Glow; // x = intensity, y = width, z = magic number 1, w = magic number 2
+ float3 _Glow2; // x = outline width, y = glow speed, z = dither on/off
+ float _ConstantWidth;
+
+ UNITY_INSTANCING_BUFFER_START(Props)
+ UNITY_DEFINE_INSTANCED_PROP(float4, _GlowColor)
+ UNITY_DEFINE_INSTANCED_PROP(float4, _Glow)
+ UNITY_DEFINE_INSTANCED_PROP(float4, _GlowDirection)
+ UNITY_INSTANCING_BUFFER_END(Props)
+
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+
+ float4 glowDirection = UNITY_ACCESS_INSTANCED_PROP(Props, _GlowDirection);
+ #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED) || defined(SINGLE_PASS_STEREO)
+ glowDirection.x *= 2.0;
+ #endif
+
+ v.vertex.xyz += v.normal * glowDirection.z;
+ float4 pos = ComputeVertexPosition(v.vertex);
+ float3 norm = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
+ float2 offset = TransformViewToProjection(normalize(norm.xy));
+
+ offset += glowDirection.xy;
+ float z = lerp(UNITY_Z_0_FAR_FROM_CLIPSPACE(pos.z), 2.0, UNITY_MATRIX_P[3][3]);
+ z = _ConstantWidth * (z - 2.0) + 2.0;
+ float outlineWidth = _Glow2.x;
+
+ float4 glow = UNITY_ACCESS_INSTANCED_PROP(Props, _Glow);
+
+ float animatedWidth = glow.y * (1.0 + 0.25 * sin(_Time.w * _Glow2.y));
+ offset *= z * (outlineWidth + animatedWidth);
+ pos.xy += offset;
+ o.pos = pos;
+ o.color = UNITY_ACCESS_INSTANCED_PROP(Props, _GlowColor);
+ o.color.a = glow.x;
+ return o;
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ UNITY_SETUP_INSTANCE_ID(i);
+ fixed4 color = i.color;
+ float4 glow = UNITY_ACCESS_INSTANCED_PROP(Props, _Glow);
+ float2 screenPos = floor( i.pos.xy * glow.z ) * glow.w;
+ color.a *= saturate(_Glow2.z + frac(screenPos.x + screenPos.y));
+ return color;
+ }
+ ENDCG
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightGlow.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightGlow.shader.meta
new file mode 100644
index 0000000..fe91538
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightGlow.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 049d9e75e07674a78a703cf1203c07dd
+timeCreated: 1544699250
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightInnerGlow.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightInnerGlow.shader
new file mode 100644
index 0000000..b0bf6c4
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightInnerGlow.shader
@@ -0,0 +1,95 @@
+Shader "HighlightPlus/Geometry/InnerGlow" {
+Properties {
+ _MainTex ("Texture", Any) = "white" {}
+ _Color ("Color", Color) = (1,1,1) // not used; dummy property to avoid inspector warning "material has no _Color property"
+ _InnerGlowColor ("Inner Glow Color", Color) = (1,1,1,1)
+ _InnerGlowWidth ("Width", Float) = 1.0
+ _CutOff("CutOff", Float ) = 0.5
+ _Cull ("Cull Mode", Int) = 2
+ _InnerGlowZTest ("ZTest", Int) = 4
+}
+ SubShader
+ {
+ Tags { "Queue"="Transparent+122" "RenderType"="Transparent" "DisableBatching"="True" }
+
+ // Inner Glow
+ Pass
+ {
+ Stencil {
+ Ref 4
+ ReadMask 4
+ Comp NotEqual
+ Pass keep
+ }
+ Blend SrcAlpha One
+ ZWrite Off
+ ZTest [_InnerGlowZTest]
+ Cull [_Cull]
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+ #pragma multi_compile_local _ HP_ALPHACLIP
+
+ #include "UnityCG.cginc"
+ #include "CustomVertexTransform.cginc"
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ float2 uv : TEXCOORD0;
+ float3 normal : NORMAL;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos : SV_POSITION;
+ float2 uv : TEXCOORD0;
+ float3 wpos : TEXCOORD1;
+ float3 normal : NORMAL;
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ sampler2D _MainTex;
+ float4 _MainTex_ST;
+ fixed _CutOff;
+ fixed4 _InnerGlowColor;
+ fixed _InnerGlowWidth;
+
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = ComputeVertexPosition(v.vertex);
+ #if UNITY_REVERSED_Z
+ o.pos.z += 0.0001;
+ #else
+ o.pos.z -= 0.0001;
+ #endif
+ o.wpos = mul(unity_ObjectToWorld, v.vertex).xyz;
+ o.normal = UnityObjectToWorldNormal(v.normal);
+ o.uv = TRANSFORM_TEX (v.uv, _MainTex);
+ return o;
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ #if HP_ALPHACLIP
+ fixed4 color = tex2D(_MainTex, i.uv);
+ clip(color.a - _CutOff);
+ #endif
+
+ float3 viewDir = normalize(i.wpos - _WorldSpaceCameraPos.xyz);
+ fixed dx = saturate(_InnerGlowWidth - abs(dot(viewDir, normalize(i.normal)))) / _InnerGlowWidth;
+ fixed4 col = _InnerGlowColor * dx;
+ return col;
+ }
+ ENDCG
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightInnerGlow.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightInnerGlow.shader.meta
new file mode 100644
index 0000000..5f67e27
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightInnerGlow.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: e5a069457bd344391acd5af227c0ce11
+timeCreated: 1544699250
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightMask.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightMask.shader
new file mode 100644
index 0000000..8e0e7df
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightMask.shader
@@ -0,0 +1,140 @@
+Shader "HighlightPlus/Geometry/Mask" {
+Properties {
+ _MainTex ("Texture", Any) = "white" {}
+ _Color ("Color", Color) = (1,1,1) // not used; dummy property to avoid inspector warning "material has no _Color property"
+ _CutOff("CutOff", Float ) = 0.5
+ _Cull ("Cull Mode", Int) = 2
+ _ZTest ("ZTest", Int) = 4
+}
+ SubShader
+ {
+ Tags { "Queue"="Transparent+100" "RenderType"="Transparent" "DisableBatching"="True" }
+
+ CGINCLUDE
+
+ #include "UnityCG.cginc"
+ #include "CustomVertexTransform.cginc"
+
+ sampler2D _MainTex;
+ float4 _MainTex_ST;
+ float4 _MainTex_TexelSize;
+ fixed _CutOff;
+ UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ float2 uv : TEXCOORD0;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos: SV_POSITION;
+ float2 uv : TEXCOORD0;
+ #if HP_DEPTHCLIP
+ float4 scrPos : TEXCOORD1;
+ float depth : TEXCOORD2;
+ #endif
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = ComputeVertexPosition(v.vertex);
+ o.uv = TRANSFORM_TEX (v.uv, _MainTex);
+ #if HP_DEPTHCLIP
+ o.scrPos = ComputeScreenPos(o.pos);
+ COMPUTE_EYEDEPTH(o.depth);
+ #endif
+ #if UNITY_REVERSED_Z
+ o.pos.z += 0.0001;
+ #else
+ o.pos.z -= 0.0001;
+ #endif
+ return o;
+ }
+
+ float GetEyeDepth(float rawDepth) {
+ float persp = LinearEyeDepth(rawDepth);
+ float ortho = (_ProjectionParams.z-_ProjectionParams.y)*(1-rawDepth)+_ProjectionParams.y;
+ return lerp(persp,ortho,unity_OrthoParams.w);
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ UNITY_SETUP_INSTANCE_ID(i);
+ UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
+ #if HP_ALPHACLIP
+ fixed4 col = tex2D(_MainTex, i.uv);
+ clip(col.a - _CutOff);
+ #endif
+ #if HP_DEPTHCLIP
+ float sceneZ = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoTransformScreenSpaceTex(i.scrPos.xy / i.scrPos.w));
+ float sceneDepth = GetEyeDepth(sceneZ);
+ clip(sceneDepth - i.depth * 0.999);
+ #endif
+ return 0;
+ }
+
+ ENDCG
+
+ // Create mask
+ Pass
+ {
+ Name "Mask"
+ Stencil {
+ Ref 2
+ Comp always
+ Pass replace
+ WriteMask 2
+ ReadMask 2
+ }
+ ColorMask 0
+ ZWrite Off
+ Cull [_Cull] // default Cull Back improves glow in high quality)
+ ZTest [_ZTest]
+ Offset -1, -1 // avoid issues on Quest 2 standalone when using with other render features (ie. Liquid Volume Pro 2 irregular topology)
+
+ CGPROGRAM
+ #pragma multi_compile_local _ HP_ALPHACLIP
+ #pragma multi_compile_local _ HP_DEPTHCLIP
+ #pragma vertex vert
+ #pragma fragment frag
+ ENDCG
+ }
+
+ // Create mask for see-through (the only difference is the ZTest)
+ Pass
+ {
+ Name "See-through Mask"
+ Stencil {
+ Ref 2
+ Comp always
+ Pass replace
+ WriteMask 2
+ ReadMask 2
+ }
+ ColorMask 0
+ ZWrite Off
+ Cull [_Cull] // default Cull Back improves glow in high quality)
+ ZTest LEqual
+ Offset -1, -1 // avoid issues on Quest 2 standalone when using with other render features (ie. Liquid Volume Pro 2 irregular topology)
+
+ CGPROGRAM
+ #pragma multi_compile_local _ HP_ALPHACLIP
+ #pragma multi_compile_local _ HP_DEPTHCLIP
+ #pragma vertex vert
+ #pragma fragment frag
+ ENDCG
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightMask.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightMask.shader.meta
new file mode 100644
index 0000000..b550df4
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightMask.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: e694fa934b6db4a00b8d4b9887115332
+timeCreated: 1544699251
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOccluder.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOccluder.shader
new file mode 100644
index 0000000..3cff099
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOccluder.shader
@@ -0,0 +1,62 @@
+Shader "HighlightPlus/Geometry/SeeThroughOccluder" {
+Properties {
+ _MainTex ("Texture", Any) = "white" {}
+ _Color ("Color", Color) = (1,1,1) // not used; dummy property to avoid inspector warning "material has no _Color property"
+}
+ SubShader
+ {
+ Tags { "Queue"="Transparent+100" "RenderType"="Transparent" "DisableBatching"="True" }
+
+ // Create mask
+ Pass
+ {
+ Stencil {
+ Ref 2
+ Comp always
+ Pass DecrWrap
+ }
+ ColorMask 0
+ ZWrite Off
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+
+ #include "UnityCG.cginc"
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos : SV_POSITION;
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = UnityObjectToClipPos(v.vertex);
+ #if UNITY_REVERSED_Z
+ o.pos.z += 0.0001;
+ #else
+ o.pos.z -= 0.0001;
+ #endif
+ return o;
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ return 0;
+ }
+ ENDCG
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOccluder.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOccluder.shader.meta
new file mode 100644
index 0000000..47ef424
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOccluder.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 229baf997355a43cda580dd4cf86b71e
+timeCreated: 1544699251
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOutline.mat b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOutline.mat
new file mode 100644
index 0000000..0bdabcf
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOutline.mat
@@ -0,0 +1,83 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+ serializedVersion: 6
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_Name: HighlightOutline
+ m_Shader: {fileID: 4800000, guid: cbbf740e9c8644e8492d08b1a3fd0203, type: 3}
+ m_ShaderKeywords:
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 1
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _BumpMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailAlbedoMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailMask:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailNormalMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _EmissionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MainTex:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MetallicGlossMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _OcclusionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _ParallaxMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Floats:
+ - _BumpScale: 1
+ - _ConstantWidth: 1
+ - _Cull: 2
+ - _Cutoff: 0.5
+ - _DetailNormalMapScale: 1
+ - _DstBlend: 0
+ - _GlossMapScale: 1
+ - _Glossiness: 0.5
+ - _GlossyReflections: 1
+ - _Metallic: 0
+ - _Mode: 0
+ - _OcclusionStrength: 1
+ - _OutlineWidth: 0.01
+ - _OutlineZTest: 4
+ - _Parallax: 0.02
+ - _SmoothnessTextureChannel: 0
+ - _SpecularHighlights: 1
+ - _SrcBlend: 1
+ - _UVSec: 0
+ - _ZWrite: 1
+ m_Colors:
+ - _Color: {r: 1, g: 1, b: 1, a: 1}
+ - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+ - _OutlineColor: {r: 0, g: 0, b: 0, a: 1}
+ - _OutlineDirection: {r: 0, g: 0, b: 0, a: 1}
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOutline.mat.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOutline.mat.meta
new file mode 100644
index 0000000..499962b
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOutline.mat.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 57729312cdd6d4eb685a81a3b0bf8a5b
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOutline.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOutline.shader
new file mode 100644
index 0000000..f07f100
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOutline.shader
@@ -0,0 +1,174 @@
+Shader "HighlightPlus/Geometry/Outline" {
+Properties {
+ _MainTex ("Texture", Any) = "white" {}
+ _OutlineColor ("Outline Color", Color) = (0,0,0,1)
+ _OutlineWidth ("Outline Offset", Float) = 0.01
+ _OutlineDirection("Outline Direction", Vector) = (0,0,0)
+ _OutlineGradientTex("Outline Gradient Tex", 2D) = "white" {}
+ _Color ("Color", Color) = (1,1,1) // not used; dummy property to avoid inspector warning "material has no _Color property"
+ _Cull ("Cull Mode", Int) = 2
+ _ConstantWidth ("Constant Width", Float) = 1
+ _OutlineZTest("ZTest", Int) = 4
+}
+ SubShader
+ {
+ Tags { "Queue"="Transparent+120" "RenderType"="Transparent" "DisableBatching"="True" }
+
+ Pass
+ {
+ Name "Outline"
+ Stencil {
+ Ref 2
+ Comp NotEqual
+ Pass replace
+ ReadMask 2
+ WriteMask 2
+ }
+
+ Blend SrcAlpha OneMinusSrcAlpha
+ ZWrite On
+ Cull [_Cull]
+ ZTest [_OutlineZTest]
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+ #pragma multi_compile_instancing
+ #pragma multi_compile_local _ HP_ALPHACLIP
+ #pragma multi_compile_local _ HP_OUTLINE_GRADIENT_WS HP_OUTLINE_GRADIENT_LS
+ #include "UnityCG.cginc"
+ #include "CustomVertexTransform.cginc"
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ float3 normal : NORMAL;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos : SV_POSITION;
+ fixed yt : TEXCOORD0;
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ fixed4 _OutlineColor;
+ sampler2D _OutlineGradientTex;
+
+ float _OutlineWidth;
+ float _ConstantWidth;
+ float _OutlineVertexWidth;
+ fixed2 _OutlineVertexData;
+
+ UNITY_INSTANCING_BUFFER_START(Props)
+ UNITY_DEFINE_INSTANCED_PROP(float4, _OutlineDirection)
+ UNITY_INSTANCING_BUFFER_END(Props)
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+
+ #if HP_OUTLINE_GRADIENT_WS
+ float posy = mul(unity_ObjectToWorld, v.vertex).y;
+ o.yt = saturate( (posy - _OutlineVertexData.x) / _OutlineVertexData.y);
+ #else
+ o.yt = saturate( (v.vertex.y - _OutlineVertexData.x) / _OutlineVertexData.y);
+ #endif
+
+ v.vertex.xyz += v.normal * _OutlineVertexWidth;
+ o.pos = ComputeVertexPosition(v.vertex);
+ float3 norm = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
+ float2 offset = TransformViewToProjection(normalize(norm.xy));
+ float z = lerp(UNITY_Z_0_FAR_FROM_CLIPSPACE(o.pos.z), 2.0, UNITY_MATRIX_P[3][3]);
+ z = _ConstantWidth * (z - 2.0) + 2.0;
+
+ float4 outlineDirection = UNITY_ACCESS_INSTANCED_PROP(Props, _OutlineDirection);
+ #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED) || defined(SINGLE_PASS_STEREO)
+ outlineDirection.x *= 2.0;
+ #endif
+ o.pos.xy += offset * z * _OutlineWidth + outlineDirection.xy * z;
+ return o;
+ }
+
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ #if HP_OUTLINE_GRADIENT_WS || HP_OUTLINE_GRADIENT_LS
+ half4 color = tex2D(_OutlineGradientTex, float2(i.yt, 0));
+ color.a *= _OutlineColor.a;
+ #else
+ half4 color = _OutlineColor;
+ #endif
+ return color;
+ }
+ ENDCG
+ }
+
+ Pass
+ {
+ Name "Outline Clear Stencil"
+ Stencil {
+ Ref 8 // bit 8 is used by HighlightUIMask shader to prevent Clear Stencil passes
+ Comp NotEqual
+ Pass zero
+ ReadMask 8
+ WriteMask 6
+ }
+
+ ColorMask 0
+ ZWrite Off
+ Cull [_Cull]
+ ZTest Always
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+ #include "UnityCG.cginc"
+ #include "CustomVertexTransform.cginc"
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ float3 normal : NORMAL;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos : SV_POSITION;
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ fixed4 _OutlineColor;
+ float _OutlineWidth;
+ float2 _OutlineDirection;
+ float _ConstantWidth;
+ float _OutlineVertexWidth;
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ v.vertex.xyz += v.normal * _OutlineVertexWidth;
+ o.pos = ComputeVertexPosition(v.vertex);
+ float3 norm = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
+ float2 offset = TransformViewToProjection(normalize(norm.xy));
+ float z = lerp(UNITY_Z_0_FAR_FROM_CLIPSPACE(o.pos.z), 2.0, UNITY_MATRIX_P[3][3]);
+ z = _ConstantWidth * (z - 2.0) + 2.0;
+ o.pos.xy += offset * z * _OutlineWidth + _OutlineDirection * z;
+ return o;
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ return 0;
+ }
+ ENDCG
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOutline.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOutline.shader.meta
new file mode 100644
index 0000000..c1e26d2
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOutline.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: cbbf740e9c8644e8492d08b1a3fd0203
+timeCreated: 1544699250
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOverlay.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOverlay.shader
new file mode 100644
index 0000000..7b02a6a
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOverlay.shader
@@ -0,0 +1,143 @@
+Shader "HighlightPlus/Geometry/Overlay" {
+Properties {
+ _MainTex ("Texture", Any) = "white" {}
+ _Color ("Color", Color) = (1,1,1) // not used; dummy property to avoid inspector warning "material has no _Color property"
+ _OverlayColor ("Overlay Color", Color) = (1,1,1,1)
+ _OverlayBackColor ("Overlay Back Color", Color) = (1,1,1,1)
+ _OverlayData("Overlay Data", Vector) = (1,0.5,1,1)
+ _OverlayHitPosData("Overlay Hit Pos Data", Vector) = (0,0,0,0)
+ _OverlayHitStartTime("Overlay Hit Start Time", Float) = 0
+ _OverlayTexture("Overlay Texture", 2D) = "white" {}
+ _CutOff("CutOff", Float ) = 0.5
+ _Cull ("Cull Mode", Int) = 2
+}
+ SubShader
+ {
+ Tags { "Queue"="Transparent+121" "RenderType"="Transparent" "DisableBatching"="True" }
+
+ // Overlay
+ Pass
+ {
+ Stencil {
+ Ref 4
+ ReadMask 4
+ Comp NotEqual
+ Pass keep
+ }
+ Blend SrcAlpha OneMinusSrcAlpha
+ ZWrite Off
+ Cull [_Cull]
+ Offset -1, -1 // avoid issues on Quest 2 standalone when using with other render features (ie. Liquid Volume Pro 2 irregular topology)
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+ #pragma multi_compile_local _ HP_ALPHACLIP
+ #pragma multi_compile_local _ HP_TEXTURE_TRIPLANAR HP_TEXTURE_SCREENSPACE HP_TEXTURE_OBJECTSPACE
+
+ #include "UnityCG.cginc"
+ #include "CustomVertexTransform.cginc"
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ float2 uv : TEXCOORD0;
+ float3 norm : NORMAL;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos : SV_POSITION;
+ float2 uv : TEXCOORD0;
+ float3 wpos : TEXCOORD1;
+ #if HP_TEXTURE_TRIPLANAR
+ float3 wnorm : TEXCOORD2;
+ #endif
+ #if HP_TEXTURE_SCREENSPACE
+ float4 scrPos : TEXCOORD3;
+ #endif
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ fixed4 _OverlayColor;
+ sampler2D _MainTex;
+ float4 _MainTex_ST;
+ fixed4 _OverlayBackColor;
+ fixed4 _OverlayData; // x = speed, y = MinIntensity, z = blend, w = texture scale
+ float4 _OverlayHitPosData;
+ float _OverlayHitStartTime;
+ fixed _CutOff;
+ sampler2D _OverlayTexture;
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = ComputeVertexPosition(v.vertex);
+ #if HP_TEXTURE_SCREENSPACE
+ o.scrPos = ComputeScreenPos(o.pos);
+ o.scrPos.x *= _ScreenParams.x / _ScreenParams.y;
+ #endif
+ #if UNITY_REVERSED_Z
+ o.pos.z += 0.0001;
+ #else
+ o.pos.z -= 0.0001;
+ #endif
+ o.wpos = mul(unity_ObjectToWorld, v.vertex).xyz;
+ #if HP_TEXTURE_TRIPLANAR
+ o.wnorm = UnityObjectToWorldNormal(v.norm);
+ #endif
+ o.uv = TRANSFORM_TEX (v.uv, _MainTex);
+ return o;
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ fixed4 color = tex2D(_MainTex, i.uv);
+ #if HP_ALPHACLIP
+ clip(color.a - _CutOff);
+ #endif
+ float time = _Time.y % 1000;
+ fixed t = _OverlayData.y + (1.0 - _OverlayData.y) * 2.0 * abs(0.5 - frac(time * _OverlayData.x));
+ fixed4 col = lerp(_OverlayColor, color * _OverlayBackColor * _OverlayColor, _OverlayData.z);
+ col.a *= t;
+
+ if (_OverlayHitPosData.w>0) {
+ float elapsed = _Time.y - _OverlayHitStartTime;
+ float hitDist = distance(i.wpos, _OverlayHitPosData.xyz);
+ float atten = saturate( min(elapsed, _OverlayHitPosData.w) / hitDist );
+ col.a *= atten;
+ }
+
+ #if HP_TEXTURE_TRIPLANAR
+ half3 triblend = saturate(pow(i.wnorm, 4));
+ triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);
+
+ // triplanar uvs
+ float3 tpos = i.wpos * _OverlayData.w;
+ float2 uvX = tpos.zy;
+ float2 uvY = tpos.xz;
+ float2 uvZ = tpos.xy;
+
+ // albedo textures
+ fixed4 colX = tex2D(_OverlayTexture, uvX);
+ fixed4 colY = tex2D(_OverlayTexture, uvY);
+ fixed4 colZ = tex2D(_OverlayTexture, uvZ);
+ fixed4 tex = colX * triblend.x + colY * triblend.y + colZ * triblend.z;
+ col *= tex;
+ #elif HP_TEXTURE_SCREENSPACE
+ col *= tex2D(_OverlayTexture, (i.scrPos.xy / i.scrPos.w) * _OverlayData.w);
+ #elif HP_TEXTURE_OBJECTSPACE
+ col *= tex2D(_OverlayTexture, i.uv * _OverlayData.w);
+ #endif
+
+ return col;
+ }
+ ENDCG
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOverlay.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOverlay.shader.meta
new file mode 100644
index 0000000..5560e90
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightOverlay.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: d17a98d19ada34bb7b4f86130e590159
+timeCreated: 1544699250
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightPlusDepthClipComp.mat b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightPlusDepthClipComp.mat
new file mode 100644
index 0000000..2822c39
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightPlusDepthClipComp.mat
@@ -0,0 +1,76 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+ serializedVersion: 6
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 0}
+ m_Name: HighlightPlusDepthClipComp
+ m_Shader: {fileID: 4800000, guid: 0917f634da79a4983ad78bac83d5a715, type: 3}
+ m_ShaderKeywords:
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _BumpMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailAlbedoMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailMask:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailNormalMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _EmissionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MainTex:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MetallicGlossMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _OcclusionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _ParallaxMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Floats:
+ - _BumpScale: 1
+ - _Cutoff: 0.5
+ - _DetailNormalMapScale: 1
+ - _DstBlend: 0
+ - _GlossMapScale: 1
+ - _Glossiness: 0.5
+ - _GlossyReflections: 1
+ - _Metallic: 0
+ - _Mode: 0
+ - _OcclusionStrength: 1
+ - _Parallax: 0.02
+ - _SmoothnessTextureChannel: 0
+ - _SpecularHighlights: 1
+ - _SrcBlend: 1
+ - _UVSec: 0
+ - _ZWrite: 1
+ m_Colors:
+ - _Color: {r: 1, g: 1, b: 1, a: 1}
+ - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightPlusDepthClipComp.mat.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightPlusDepthClipComp.mat.meta
new file mode 100644
index 0000000..9399349
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightPlusDepthClipComp.mat.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 94aad838a87c54e1b89e9ef47ecad5bf
+timeCreated: 1546857910
+licenseType: Pro
+NativeFormatImporter:
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightPlusDepthWrite.mat b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightPlusDepthWrite.mat
new file mode 100644
index 0000000..a13e488
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightPlusDepthWrite.mat
@@ -0,0 +1,76 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+ serializedVersion: 6
+ m_ObjectHideFlags: 0
+ m_PrefabParentObject: {fileID: 0}
+ m_PrefabInternal: {fileID: 0}
+ m_Name: HighlightPlusDepthWrite
+ m_Shader: {fileID: 4800000, guid: 058a572e30b2d446bade2dda32bcef0f, type: 3}
+ m_ShaderKeywords:
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _BumpMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailAlbedoMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailMask:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailNormalMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _EmissionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MainTex:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MetallicGlossMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _OcclusionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _ParallaxMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Floats:
+ - _BumpScale: 1
+ - _Cutoff: 0.5
+ - _DetailNormalMapScale: 1
+ - _DstBlend: 0
+ - _GlossMapScale: 1
+ - _Glossiness: 0.5
+ - _GlossyReflections: 1
+ - _Metallic: 0
+ - _Mode: 0
+ - _OcclusionStrength: 1
+ - _Parallax: 0.02
+ - _SmoothnessTextureChannel: 0
+ - _SpecularHighlights: 1
+ - _SrcBlend: 1
+ - _UVSec: 0
+ - _ZWrite: 1
+ m_Colors:
+ - _Color: {r: 1, g: 1, b: 1, a: 1}
+ - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightPlusDepthWrite.mat.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightPlusDepthWrite.mat.meta
new file mode 100644
index 0000000..c02afaf
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightPlusDepthWrite.mat.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 825cb444e111842cf97788cbb7583edd
+timeCreated: 1546857910
+licenseType: Pro
+NativeFormatImporter:
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughBorder.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughBorder.shader
new file mode 100644
index 0000000..bfd34bd
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughBorder.shader
@@ -0,0 +1,132 @@
+Shader "HighlightPlus/Geometry/SeeThroughBorder" {
+Properties {
+ _MainTex ("Texture", Any) = "white" {}
+ _SeeThroughBorderColor ("Outline Color", Color) = (0,0,0,1)
+ _Color ("Color", Color) = (1,1,1) // not used; dummy property to avoid inspector warning "material has no _Color property"
+ _CutOff("CutOff", Float ) = 0.5
+ _SeeThroughBorderWidth ("Outline Offset", Float) = 0.01
+ _SeeThroughBorderConstantWidth ("Constant Width", Float) = 1
+ _SeeThroughStencilRef ("Stencil Ref", Int) = 2
+ _SeeThroughStencilComp ("Stencil Comp", Int) = 5
+ _SeeThroughDepthOffset ("Depth Offset", Float) = 0
+ _SeeThroughMaxDepth("Max Depth", Float) = 0
+ _SeeThroughStencilPassOp ("Stencil Pass Operation", Int) = 0
+ _SeeThroughOrdered("Ordered", Int) = 1
+ _ZTest("ZTest", Int) = 4
+}
+ SubShader
+ {
+ Tags { "Queue"="Transparent+201" "RenderType"="Transparent" "DisableBatching"="True" }
+
+ Pass
+ {
+ Name "See-through border"
+ Stencil {
+ ReadMask 3
+ WriteMask 3
+ Ref [_SeeThroughStencilRef]
+ Comp [_SeeThroughStencilComp]
+ Pass [_SeeThroughStencilPassOp]
+ Fail [_SeeThroughStencilPassOp]
+ }
+
+ ZTest [_ZTest]
+ ZWrite On
+ Blend SrcAlpha OneMinusSrcAlpha
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+ #pragma multi_compile_local _ HP_ALPHACLIP
+ #pragma multi_compile_local _ HP_DEPTH_OFFSET
+
+ #include "UnityCG.cginc"
+ #include "CustomVertexTransform.cginc"
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ float2 uv : TEXCOORD0;
+ float3 normal : NORMAL;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos: SV_POSITION;
+ float2 uv : TEXCOORD0;
+ #if HP_DEPTH_OFFSET
+ float4 scrPos : TEXCOORD1;
+ float depth : TEXCOORD2;
+ #endif
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ sampler2D _MainTex;
+ float4 _MainTex_ST;
+ fixed4 _SeeThroughBorderColor;
+ fixed _CutOff;
+ float _SeeThroughDepthOffset;
+ float _SeeThroughMaxDepth;
+ int _SeeThroughOrdered;
+ float _SeeThroughBorderWidth;
+ float _SeeThroughBorderConstantWidth;
+ fixed _HP_Fade;
+
+ UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = ComputeVertexPosition(v.vertex);
+ #if HP_DEPTH_OFFSET
+ o.scrPos = ComputeScreenPos(o.pos);
+ COMPUTE_EYEDEPTH(o.depth);
+ #endif
+
+ float3 norm = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
+ float2 offset = any(norm.xy)!=0 ? TransformViewToProjection(normalize(norm.xy)) : 0.0.xx;
+ float z = lerp(UNITY_Z_0_FAR_FROM_CLIPSPACE(o.pos.z), 2.0, UNITY_MATRIX_P[3][3]);
+ z = _SeeThroughBorderConstantWidth * (z - 2.0) + 2.0;
+ o.pos.xy += offset * z * _SeeThroughBorderWidth;
+
+ #if UNITY_REVERSED_Z
+ o.pos.z -= 0.0001;
+ o.pos.z = _SeeThroughOrdered ? o.pos.w - (o.pos.w - o.pos.z) * 0.001 : o.pos.z;
+ #else
+ o.pos.z += 0.0001;
+ o.pos.z = _SeeThroughOrdered ? -o.pos.w + ( o.pos.z + o.pos.w ) * 0.001 : o.pos.z;
+ #endif
+ o.uv = TRANSFORM_TEX(v.uv, _MainTex);
+ return o;
+ }
+
+ float GetEyeDepth(float rawDepth) {
+ float persp = LinearEyeDepth(rawDepth);
+ float ortho = (_ProjectionParams.z-_ProjectionParams.y)*(1-rawDepth)+_ProjectionParams.y;
+ return lerp(persp,ortho,unity_OrthoParams.w);
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ #if HP_DEPTH_OFFSET
+ float sceneZ = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.scrPos.xy / i.scrPos.w);
+ float sceneDepth = GetEyeDepth(sceneZ);
+ if (i.depth - sceneDepth - _SeeThroughDepthOffset < 0 || i.depth - sceneDepth > _SeeThroughMaxDepth) discard;
+ #endif
+ #if HP_ALPHACLIP
+ fixed4 col = tex2D(_MainTex, i.uv);
+ clip(col.a - _CutOff);
+ #endif
+ fixed4 res = _SeeThroughBorderColor;
+ res.a *= _HP_Fade;
+ return res;
+ }
+ ENDCG
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughBorder.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughBorder.shader.meta
new file mode 100644
index 0000000..3009623
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughBorder.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 47198bbf0b2a44882aceef6af17a467d
+timeCreated: 1544699250
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughInner.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughInner.shader
new file mode 100644
index 0000000..2158c55
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughInner.shader
@@ -0,0 +1,173 @@
+Shader "HighlightPlus/Geometry/SeeThroughInner" {
+Properties {
+ _MainTex ("Texture", Any) = "white" {}
+ _SeeThrough ("See Through", Range(0,1)) = 0.8
+ _SeeThroughTintColor ("See Through Tint Color", Color) = (1,0,0,0.8)
+ _SeeThroughNoise("Noise", Float) = 1
+ _Color ("Color", Color) = (1,1,1) // not used; dummy property to avoid inspector warning "material has no _Color property"
+ _CutOff("CutOff", Float ) = 0.5
+ _SeeThroughStencilRef ("Stencil Ref", Int) = 2
+ _SeeThroughStencilComp ("Stencil Comp", Int) = 5
+ _SeeThroughStencilPassOp ("Stencil Pass Operation", Int) = 0
+ _SeeThroughDepthOffset ("Depth Offset", Float) = 0
+ _SeeThroughMaxDepth("Max Depth", Float) = 0
+ _SeeThroughOrdered("Ordered", Int) = 1
+ _SeeThroughTexture("Mask Texture", 2D) = "white" {}
+ _SeeThroughTextureScale("Mask Texture Scale", Float) = 1.0
+ _ZTest("ZTest", Int) = 4
+}
+ SubShader
+ {
+ Tags { "Queue"="Transparent+201" "RenderType"="Transparent" "DisableBatching"="True" }
+
+ // See through effect
+ Pass
+ {
+ Name "See-through"
+ Stencil {
+ ReadMask 3
+ WriteMask 3
+ Ref [_SeeThroughStencilRef]
+ Comp [_SeeThroughStencilComp]
+ Pass [_SeeThroughStencilPassOp]
+ Fail [_SeeThroughStencilPassOp]
+ }
+
+ ZTest [_ZTest]
+ ZWrite On // Needs to be on so see-through border do not overlap
+// Cull Off
+ Blend SrcAlpha OneMinusSrcAlpha
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+ #pragma multi_compile_local _ HP_ALPHACLIP
+ #pragma multi_compile_local _ HP_DEPTH_OFFSET
+ #pragma multi_compile_local _ HP_SEETHROUGH_ONLY_BORDER
+ #pragma multi_compile_local _ HP_TEXTURE_TRIPLANAR HP_TEXTURE_SCREENSPACE HP_TEXTURE_OBJECTSPACE
+
+ #include "UnityCG.cginc"
+ #include "CustomVertexTransform.cginc"
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ float3 norm : NORMAL;
+ float2 uv : TEXCOORD0;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos: SV_POSITION;
+ float2 uv : TEXCOORD0;
+ #if HP_DEPTH_OFFSET || HP_TEXTURE_SCREENSPACE
+ float4 scrPos : TEXCOORD1;
+ #endif
+ #if HP_DEPTH_OFFSET
+ float depth : TEXCOORD2;
+ #endif
+ float3 wpos : TEXCOORD3;
+ #if HP_TEXTURE_TRIPLANAR
+ float3 wnorm : TEXCOORD4;
+ #endif
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ sampler2D _MainTex;
+ float4 _MainTex_ST;
+ fixed _SeeThrough;
+ fixed4 _SeeThroughTintColor;
+ fixed _CutOff;
+ fixed _SeeThroughNoise;
+ float _SeeThroughDepthOffset;
+ float _SeeThroughMaxDepth;
+ int _SeeThroughOrdered;
+ fixed _HP_Fade;
+ sampler2D _SeeThroughTexture;
+ fixed _SeeThroughTextureScale;
+ UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = ComputeVertexPosition(v.vertex);
+ #if HP_DEPTH_OFFSET || HP_TEXTURE_SCREENSPACE
+ o.scrPos = ComputeScreenPos(o.pos);
+ #endif
+ #if HP_DEPTH_OFFSET
+ COMPUTE_EYEDEPTH(o.depth);
+ #endif
+ o.wpos = mul(unity_ObjectToWorld, v.vertex).xyz;
+ #if HP_TEXTURE_TRIPLANAR
+ o.wnorm = UnityObjectToWorldNormal(v.norm);
+ #endif
+ o.uv = TRANSFORM_TEX(v.uv, _MainTex);
+ return o;
+ }
+
+ float GetEyeDepth(float rawDepth) {
+ float persp = LinearEyeDepth(rawDepth);
+ float ortho = (_ProjectionParams.z-_ProjectionParams.y)*(1-rawDepth)+_ProjectionParams.y;
+ return lerp(persp,ortho,unity_OrthoParams.w);
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ #if HP_SEETHROUGH_ONLY_BORDER
+ return 0;
+ #else
+
+ #if HP_DEPTH_OFFSET
+ float sceneZ = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.scrPos.xy / i.scrPos.w);
+ float sceneDepth = GetEyeDepth(sceneZ);
+ if (i.depth - sceneDepth - _SeeThroughDepthOffset < 0 || i.depth - sceneDepth > _SeeThroughMaxDepth) discard;
+ #endif
+ fixed4 col = tex2D(_MainTex, i.uv);
+ #if HP_ALPHACLIP
+ clip(col.a - _CutOff);
+ #endif
+ col.rgb = lerp(col.rgb, _SeeThroughTintColor.rgb, _SeeThroughTintColor.a);
+ float scry = i.pos.y;
+ float time = _Time.w % 1.0;
+ col.rgb += _SeeThroughNoise *(frac( scry * time ) * 0.1);
+ col.a = _SeeThrough;
+ col.a = lerp(col.a, col.a * ( (scry % 2) - 1.0 ), _SeeThroughNoise);
+ col.a *= _HP_Fade;
+
+ #if HP_TEXTURE_TRIPLANAR
+ half3 triblend = saturate(pow(i.wnorm, 4));
+ triblend /= max(dot(triblend, half3(1,1,1)), 0.0001);
+
+ // triplanar uvs
+ float3 tpos = i.wpos * _SeeThroughTextureScale;
+ float2 uvX = tpos.zy;
+ float2 uvY = tpos.xz;
+ float2 uvZ = tpos.xy;
+
+ // albedo textures
+ fixed4 colX = tex2D(_SeeThroughTexture, uvX);
+ fixed4 colY = tex2D(_SeeThroughTexture, uvY);
+ fixed4 colZ = tex2D(_SeeThroughTexture, uvZ);
+ fixed4 tex = colX * triblend.x + colY * triblend.y + colZ * triblend.z;
+ col *= tex;
+ #elif HP_TEXTURE_SCREENSPACE
+ float2 uv = (i.scrPos.xy / i.scrPos.w);
+ uv.x *= _ScreenParams.x / _ScreenParams.y;
+ col *= tex2D(_SeeThroughTexture, uv * _SeeThroughTextureScale);
+ #elif HP_TEXTURE_OBJECTSPACE
+ col *= tex2D(_SeeThroughTexture, i.uv * _SeeThroughTextureScale);
+ #endif
+
+ return col;
+
+ #endif // HP_ONLY_BORDER
+ }
+ ENDCG
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughInner.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughInner.shader.meta
new file mode 100644
index 0000000..01f6f33
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughInner.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: f5e95a6a4248649f7ac2ac6127ca0dd1
+timeCreated: 1544699250
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughMask.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughMask.shader
new file mode 100644
index 0000000..ea0166b
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughMask.shader
@@ -0,0 +1,61 @@
+Shader "HighlightPlus/Geometry/SeeThroughMask" {
+Properties {
+ _MainTex ("Texture", Any) = "white" {}
+ _Color ("Color", Color) = (1,1,1) // not used; dummy property to avoid inspector warning "material has no _Color property"
+}
+ SubShader
+ {
+ Tags { "Queue"="Transparent+201" "RenderType"="Transparent" "DisableBatching"="True" }
+
+ // See through effect
+ Pass
+ {
+ Stencil {
+ WriteMask 3
+ Ref 1
+ Comp always
+ Pass replace
+ }
+
+ ZTest Always
+ ZWrite Off
+ ColorMask 0
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+
+ #include "UnityCG.cginc"
+ #include "CustomVertexTransform.cginc"
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos: SV_POSITION;
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = ComputeVertexPosition(v.vertex);
+ return o;
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ return 0;
+ }
+ ENDCG
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughMask.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughMask.shader.meta
new file mode 100644
index 0000000..b9b1fec
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSeeThroughMask.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 05afe1e2da9484c1f9317f48d5edb58c
+timeCreated: 1544699251
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSolidColor.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSolidColor.shader
new file mode 100644
index 0000000..b50cb44
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSolidColor.shader
@@ -0,0 +1,101 @@
+Shader "HighlightPlus/Geometry/SolidColor" {
+Properties {
+ _MainTex ("Texture", Any) = "white" {}
+ _Color ("Color", Color) = (1,1,1) // not used; dummy property to avoid inspector warning "material has no _Color property"
+ _CutOff("CutOff", Float ) = 0.5
+ _Cull ("Cull Mode", Int) = 2
+ _ZTest("ZTest", Int) = 4
+}
+ SubShader
+ {
+ Tags { "Queue"="Transparent+100" "RenderType"="Transparent" }
+
+ // Compose effect on camera target
+ Pass
+ {
+ ZWrite Off
+ Cull [_Cull]
+ ZTest [_ZTest]
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+ #pragma multi_compile_local _ HP_ALPHACLIP
+ #pragma multi_compile_local _ HP_DEPTHCLIP
+
+ #include "UnityCG.cginc"
+ #include "CustomVertexTransform.cginc"
+
+ sampler2D _MainTex;
+ float4 _MainTex_ST;
+ fixed _CutOff;
+ fixed4 _Color;
+ UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ float2 uv : TEXCOORD0;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos: SV_POSITION;
+ float2 uv : TEXCOORD0;
+ #if HP_DEPTHCLIP
+ float4 scrPos : TEXCOORD1;
+ float depth : TEXCOORD2;
+ #endif
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = ComputeVertexPosition(v.vertex);
+ o.uv = TRANSFORM_TEX (v.uv, _MainTex);
+ #if HP_DEPTHCLIP
+ o.scrPos = ComputeScreenPos(o.pos);
+ COMPUTE_EYEDEPTH(o.depth);
+ #endif
+ #if UNITY_REVERSED_Z
+ o.pos.z += 0.0001;
+ #else
+ o.pos.z -= 0.0001;
+ #endif
+ return o;
+ }
+
+ float GetEyeDepth(float rawDepth) {
+ float persp = LinearEyeDepth(rawDepth);
+ float ortho = (_ProjectionParams.z-_ProjectionParams.y)*(1-rawDepth)+_ProjectionParams.y;
+ return lerp(persp,ortho,unity_OrthoParams.w);
+ }
+
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ UNITY_SETUP_INSTANCE_ID(i);
+ UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
+ #if HP_ALPHACLIP
+ fixed4 col = tex2D(_MainTex, i.uv);
+ clip(col.a - _CutOff);
+ #endif
+ #if HP_DEPTHCLIP
+ float sceneZ = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoTransformScreenSpaceTex(i.scrPos.xy / i.scrPos.w));
+ float sceneDepth = GetEyeDepth(sceneZ);
+ clip(sceneDepth - i.depth * 0.999);
+ #endif
+ return fixed4(1.0, 1.0, 1.0, 1.0);
+ }
+ ENDCG
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSolidColor.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSolidColor.shader.meta
new file mode 100644
index 0000000..9afd1bb
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightSolidColor.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 77643996218224478a471439e0ea5fb4
+timeCreated: 1544699251
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightTarget.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightTarget.shader
new file mode 100644
index 0000000..50a5f39
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightTarget.shader
@@ -0,0 +1,165 @@
+Shader "HighlightPlus/Geometry/Target" {
+Properties {
+ _MainTex ("Texture", 2D) = "white" {}
+ _Color ("Color", Color) = (1,1,1,1)
+ _ZTest ("ZTest", Int) = 0
+}
+
+ SubShader
+ {
+ Tags { "RenderType" = "Transparent" "Queue" = "Transparent-1" "DisableBatching" = "True" }
+
+ Pass
+ {
+ Name "Target FX Decal"
+ Stencil {
+ Ref 2
+ Comp NotEqual
+ ReadMask 2
+ }
+ Blend SrcAlpha OneMinusSrcAlpha
+ ZWrite Off
+ ZTest [_ZTest]
+ Cull Off
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+ #pragma target 3.0
+ #include "UnityCG.cginc"
+
+ struct appdata
+ {
+ float4 positionOS : POSITION;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 positionCS : SV_POSITION;
+ float4 screenPos : TEXCOORD0;
+ float4 rayVS : TEXCOORD1;
+ float3 camPosVS : TEXCOORD2;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ sampler2D _MainTex;
+ float4 _MainTex_ST;
+ half4 _Color;
+ float4 _TargetFXRenderData;
+ UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
+
+ #define GROUND_NORMAL _TargetFXRenderData.xyz
+ #define FADE_POWER _TargetFXRenderData.w
+
+ #define UNITY_MATRIX_I_M unity_WorldToObject
+
+ v2f vert(appdata input)
+ {
+ v2f o;
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_SETUP_INSTANCE_ID(input);
+ UNITY_TRANSFER_INSTANCE_ID(input, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.positionCS = UnityObjectToClipPos(input.positionOS);
+ o.screenPos = ComputeScreenPos(o.positionCS);
+
+ float3 viewRay = UnityObjectToViewPos(input.positionOS);
+ o.rayVS.w = viewRay.z;
+ float4x4 viewToObject = mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V);
+ o.rayVS.xyz = mul((float3x3)viewToObject, -viewRay);
+ o.camPosVS = mul(viewToObject, float4(0,0,0,1)).xyz;
+ return o;
+ }
+
+
+
+ half4 frag(v2f i) : SV_Target
+ {
+ UNITY_SETUP_INSTANCE_ID(i);
+ UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
+ float depth = UNITY_SAMPLE_DEPTH(UNITY_SAMPLE_SCREENSPACE_TEXTURE(_CameraDepthTexture, i.screenPos.xy / i.screenPos.w));
+ float3 decalPos;
+ if(unity_OrthoParams.w) {
+ #if defined(UNITY_REVERSED_Z)
+ depth = 1.0 - depth;
+ #endif
+ float sceneDepthVS = lerp(_ProjectionParams.y, _ProjectionParams.z, depth);
+ float2 rayVSEnd = float2(unity_OrthoParams.xy * (i.screenPos.xy - 0.5) * 2.0);
+ float4 posVS = float4(rayVSEnd, -sceneDepthVS, 1);
+ float3 wpos = mul(UNITY_MATRIX_I_V, posVS).xyz;
+ decalPos = mul(UNITY_MATRIX_I_M, float4(wpos, 1)).xyz;
+ } else {
+ float depthEye = LinearEyeDepth(depth);
+ decalPos = i.camPosVS + (i.rayVS.xyz / i.rayVS.w) * depthEye;
+ }
+ clip(0.5 - abs(decalPos));
+
+ // check normal
+ float3 normal = normalize(cross(ddx(decalPos), -ddy(decalPos)));
+ float slope = dot(normal, GROUND_NORMAL);
+ clip(slope - 0.01);
+
+ float2 uv = decalPos.xz + 0.5;
+ half4 col = tex2D(_MainTex, uv);
+ col *= _Color;
+
+ // atten with elevation
+ col.a /= 1.0 + pow(1.0 + max(0, decalPos.y - 0.1), FADE_POWER);
+
+ return col;
+ }
+ ENDCG
+ }
+
+ Pass
+ {
+ Name "Target FX Regular"
+ Blend SrcAlpha OneMinusSrcAlpha
+ ZWrite Off
+ ZTest [_ZTest]
+ Cull Off
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+
+ #include "UnityCG.cginc"
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ float2 uv : TEXCOORD0;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos : SV_POSITION;
+ float2 uv : TEXCOORD0;
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ sampler2D _MainTex;
+ fixed4 _Color;
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = UnityObjectToClipPos(v.vertex);
+ o.uv = v.uv;
+ return o;
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ return tex2D(_MainTex, i.uv) * _Color;
+ }
+ ENDCG
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightTarget.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightTarget.shader.meta
new file mode 100644
index 0000000..2d63221
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightTarget.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 54328cae8f89d442da972097ce4f23d9
+timeCreated: 1544699250
+licenseType: Pro
+ShaderImporter:
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightUIMask.mat b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightUIMask.mat
new file mode 100644
index 0000000..22c9c22
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightUIMask.mat
@@ -0,0 +1,84 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!21 &2100000
+Material:
+ serializedVersion: 6
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_Name: HighlightUIMask
+ m_Shader: {fileID: 4800000, guid: f65ebd3db9df34222b24b0b7b2b752b2, type: 3}
+ m_ShaderKeywords:
+ m_LightmapFlags: 4
+ m_EnableInstancingVariants: 0
+ m_DoubleSidedGI: 0
+ m_CustomRenderQueue: -1
+ stringTagMap: {}
+ disabledShaderPasses: []
+ m_SavedProperties:
+ serializedVersion: 3
+ m_TexEnvs:
+ - _BumpMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailAlbedoMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailMask:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _DetailNormalMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _EmissionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MainTex:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _MetallicGlossMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _OcclusionMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ - _ParallaxMap:
+ m_Texture: {fileID: 0}
+ m_Scale: {x: 1, y: 1}
+ m_Offset: {x: 0, y: 0}
+ m_Floats:
+ - _BumpScale: 1
+ - _ColorMask: 15
+ - _CutOff: 0.5
+ - _Cutoff: 0.5
+ - _DetailNormalMapScale: 1
+ - _DstBlend: 0
+ - _GlossMapScale: 1
+ - _Glossiness: 0.5
+ - _GlossyReflections: 1
+ - _Metallic: 0
+ - _Mode: 0
+ - _OcclusionStrength: 1
+ - _Parallax: 0.02
+ - _SmoothnessTextureChannel: 0
+ - _SpecularHighlights: 1
+ - _SrcBlend: 1
+ - _Stencil: 0
+ - _StencilComp: 8
+ - _StencilOp: 0
+ - _StencilReadMask: 255
+ - _StencilWriteMask: 255
+ - _UVSec: 0
+ - _ZWrite: 1
+ m_Colors:
+ - _Color: {r: 1, g: 1, b: 1, a: 1}
+ - _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightUIMask.mat.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightUIMask.mat.meta
new file mode 100644
index 0000000..443f0fa
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightUIMask.mat.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 7e86e0b9dab6441b2a8c2787c90d22aa
+NativeFormatImporter:
+ externalObjects: {}
+ mainObjectFileID: 2100000
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightUIMask.shader b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightUIMask.shader
new file mode 100644
index 0000000..2164a2a
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightUIMask.shader
@@ -0,0 +1,78 @@
+Shader "HighlightPlus/UI/Mask" {
+Properties {
+ _MainTex ("Texture", Any) = "white" {}
+ _Color ("Color", Color) = (1,1,1) // not used; dummy property to avoid inspector warning "material has no _Color property"
+ _CutOff("CutOff", Float ) = 0.5
+ _StencilComp("Stencil Comparison", Float) = 8
+ _Stencil("Stencil ID", Float) = 0
+ _StencilOp("Stencil Operation", Float) = 0
+ _StencilWriteMask("Stencil Write Mask", Float) = 255
+ _StencilReadMask("Stencil Read Mask", Float) = 255
+ _ColorMask("Color Mask", Float) = 15
+}
+ SubShader
+ {
+ Tags { "Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector" = "True" }
+
+ // Create mask
+ Pass
+ {
+ Stencil {
+ Ref 14 // bit 8 is used by HighlightUIMask shader to prevent Clear Stencil passes
+ Comp always
+ Pass replace
+ ReadMask 14
+ WriteMask 14
+ ZFail replace
+ }
+ ColorMask 0
+ ZWrite Off
+ Cull Off
+
+ CGPROGRAM
+ #pragma vertex vert
+ #pragma fragment frag
+ #include "UnityCG.cginc"
+ #include "CustomVertexTransform.cginc"
+
+ sampler2D _MainTex;
+ float4 _MainTex_ST;
+ float4 _MainTex_TexelSize;
+ fixed _CutOff;
+
+ struct appdata
+ {
+ float4 vertex : POSITION;
+ float2 uv : TEXCOORD0;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ struct v2f
+ {
+ float4 pos: SV_POSITION;
+ float2 uv : TEXCOORD0;
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+ v2f vert (appdata v)
+ {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ o.pos = ComputeVertexPosition(v.vertex);
+ o.uv = TRANSFORM_TEX (v.uv, _MainTex);
+ return o;
+ }
+
+ fixed4 frag (v2f i) : SV_Target
+ {
+ fixed4 col = tex2D(_MainTex, i.uv);
+ clip(col.a - _CutOff);
+ return 0;
+ }
+ ENDCG
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightUIMask.shader.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightUIMask.shader.meta
new file mode 100644
index 0000000..b546bf7
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/HighlightUIMask.shader.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: f65ebd3db9df34222b24b0b7b2b752b2
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/target.png b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/target.png
new file mode 100644
index 0000000..f9fadf8
Binary files /dev/null and b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/target.png differ
diff --git a/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/target.png.meta b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/target.png.meta
new file mode 100644
index 0000000..43c03a4
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Resources/HighlightPlus/target.png.meta
@@ -0,0 +1,100 @@
+fileFormatVersion: 2
+guid: 1de3c566a6c8c405b9f6f453137273ec
+timeCreated: 1555360741
+licenseType: Pro
+TextureImporter:
+ fileIDToRecycleName: {}
+ serializedVersion: 4
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ isReadable: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ filterMode: -1
+ aniso: -1
+ mipBias: -1
+ wrapMode: -1
+ nPOTScale: 1
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 0
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spritePixelsToUnits: 100
+ alphaUsage: 1
+ alphaIsTransparency: 1
+ spriteTessellationDetail: -1
+ textureType: 0
+ textureShape: 1
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ platformSettings:
+ - buildTarget: DefaultTexturePlatform
+ maxTextureSize: 2048
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ - buildTarget: Standalone
+ maxTextureSize: 2048
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ - buildTarget: iPhone
+ maxTextureSize: 2048
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ - buildTarget: Android
+ maxTextureSize: 2048
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ - buildTarget: WebGL
+ maxTextureSize: 2048
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ spritePackingTag:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Scripts.meta b/Assets/Plugins/HighlightPlus/Scripts.meta
new file mode 100644
index 0000000..3294e59
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 89ce39cd6bb34454bbaf48f1d111f236
+folderAsset: yes
+timeCreated: 1542876305
+licenseType: Pro
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Scripts/HighlightEffect.cs b/Assets/Plugins/HighlightPlus/Scripts/HighlightEffect.cs
new file mode 100644
index 0000000..9c4a4fa
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/HighlightEffect.cs
@@ -0,0 +1,2866 @@
+///
+/// Highlight Plus - (c) 2018-2021 Kronnect Technologies SL
+///
+
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Rendering;
+
+namespace HighlightPlus {
+
+ public delegate bool OnObjectHighlightEvent(GameObject obj);
+ public delegate bool OnRendererHighlightEvent(Renderer renderer);
+
+ ///
+ /// Triggers when target effect animation occurs
+ ///
+ /// A value from 0 to 1 that represent the animation time from start to end, based on target duration and start time
+ public delegate void OnTargetAnimatesEvent(ref Vector3 center, ref Quaternion rotation, ref Vector3 scale, float t);
+
+ public enum NormalsOption {
+ Smooth = 0,
+ PreserveOriginal = 1,
+ Reorient = 2,
+ Planar = 3
+ }
+
+ public enum SeeThroughMode {
+ WhenHighlighted = 0,
+ AlwaysWhenOccluded = 1,
+ Never = 2
+ }
+
+ public enum OverlayMode {
+ WhenHighlighted = 0,
+ Always = 10
+ }
+
+ public enum TextureUVSpace {
+ Triplanar = 0,
+ ObjectSpace = 1,
+ ScreenSpace = 2
+ }
+
+ public enum QualityLevel {
+ Fastest = 0,
+ High = 1,
+ Highest = 2,
+ Medium = 3
+ }
+
+ public static class QualityLevelExtensions {
+ public static bool UsesMultipleOffsets(this QualityLevel qualityLevel) {
+ return qualityLevel == QualityLevel.Medium || qualityLevel == QualityLevel.High;
+ }
+ }
+
+ public enum TargetOptions {
+ Children,
+ OnlyThisObject,
+ RootToChildren,
+ LayerInScene,
+ LayerInChildren,
+ Scripting
+ }
+
+ public enum Visibility {
+ Normal,
+ AlwaysOnTop,
+ OnlyWhenOccluded
+ }
+
+ public enum ColorStyle {
+ SingleColor,
+ Gradient
+ }
+
+ public enum GlowBlendMode {
+ Additive,
+ AlphaBlending
+ }
+
+ [Serializable]
+ public struct GlowPassData {
+ public float offset;
+ public float alpha;
+ public Color color;
+ }
+
+ [ExecuteInEditMode]
+ [HelpURL("https://kronnect.com/guides/highlight-plus-introduction/")]
+ public partial class HighlightEffect : MonoBehaviour {
+
+ ///
+ /// Gets or sets the current profile. To load a profile and apply its settings at runtime, please use ProfileLoad() method.
+ ///
+ [Tooltip("The current profile (optional). A profile let you store Highlight Plus settings and apply those settings easily to many objects. You can also load a profile and apply its settings at runtime, using the ProfileLoad() method of the Highlight Effect component.")]
+ public HighlightProfile profile;
+
+ ///
+ /// Sets if changes to the original profile should propagate to this effect.
+ ///
+ [Tooltip("If enabled, settings from the profile will be applied to this component automatically when game starts or when any profile setting is updated.")]
+ public bool profileSync;
+
+ ///
+ /// Makes the effects visible in the SceneView.
+ ///
+ [Tooltip("If enabled, effects will be visible also when not in Play mode.")]
+ public bool previewInEditor = true;
+
+ ///
+ /// Which cameras can render the effects
+ ///
+ [Tooltip("Which cameras can render the effect.")]
+ public LayerMask camerasLayerMask = -1;
+
+ ///
+ /// Specifies which objects are affected by this effect.
+ ///
+ [Tooltip("Different options to specify which objects are affected by this Highlight Effect component.")]
+ public TargetOptions effectGroup = TargetOptions.Children;
+
+ ///
+ /// The layer that contains the affected objects by this effect when effectGroup is set to LayerMask.
+ ///
+ [Tooltip("The layer that contains the affected objects by this effect when effectGroup is set to LayerMask.")]
+ public LayerMask effectGroupLayer = -1;
+
+ ///
+ /// Optional object name filter
+ ///
+ [Tooltip("Only include objects whose names contains this text.")]
+ public string effectNameFilter;
+
+ ///
+ /// Combine objects into a single mesh
+ ///
+ [Tooltip("Combine meshes of all objects in this group affected by Highlight Effect reducing draw calls.")]
+ public bool combineMeshes;
+
+ ///
+ /// The alpha threshold for transparent cutout objects. Pixels with alpha below this value will be discarded.
+ ///
+ [Tooltip("The alpha threshold for transparent cutout objects. Pixels with alpha below this value will be discarded.")]
+ [Range(0, 1)]
+ public float alphaCutOff;
+
+ ///
+ /// If back facing triangles are ignored. Backfaces triangles are not visible but you may set this property to false to force highlight effects to act on those triangles as well.
+ ///
+ [Tooltip("If back facing triangles are ignored.Backfaces triangles are not visible but you may set this property to false to force highlight effects to act on those triangles as well.")]
+ public bool cullBackFaces = true;
+
+ ///
+ /// Show highlight effects even if the object is currently not visible. This option is useful if the affected objects are rendered using GPU instancing tools which render directly to the GPU without creating real game object geometry in CPU.
+ ///
+ [Tooltip("Show highlight effects even if the object is not visible. If this object or its children use GPU Instancing tools, the MeshRenderer can be disabled although the object is visible. In this case, this option is useful to enable highlighting.")]
+ public bool ignoreObjectVisibility;
+
+ ///
+ /// Enable to support reflection probes
+ ///
+ [Tooltip("Support reflection probes. Enable only if you want the effects to be visible in reflections.")]
+ public bool reflectionProbes;
+
+ ///
+ /// Enable to support reflection probes
+ ///
+ [Tooltip("Enables GPU instancing. Reduces draw calls in outline and outer glow effects on platforms that support GPU instancing. Should be enabled by default.")]
+ public bool GPUInstancing = true;
+
+ ///
+ /// Enabled depth buffer flip in HQ
+ ///
+ [Tooltip("Enables depth buffer clipping. Only applies to outline or outer glow in High Quality mode.")]
+ public bool depthClip;
+
+ [Tooltip("Fades out effects based on distance to camera")]
+ public bool cameraDistanceFade;
+
+ [Tooltip("The closest distance particles can get to the camera before they fade from the camera’s view.")]
+ public float cameraDistanceFadeNear;
+
+ [Tooltip("The farthest distance particles can get away from the camera before they fade from the camera’s view.")]
+ public float cameraDistanceFadeFar = 1000;
+
+ [Tooltip("Normals handling option:\nPreserve original: use original mesh normals.\nSmooth: average normals to produce a smoother outline/glow mesh based effect.\nReorient: recomputes normals based on vertex direction to centroid.\nPlanar: same than reorient but renders outline and glow in an optimized way for 2D or planar meshes like quads or planes.")]
+ public NormalsOption normalsOption;
+
+ ///
+ /// Ignores highlight effects on this object.
+ ///
+ [Tooltip("Ignore highlighting on this object.")]
+ public bool ignore;
+
+ [SerializeField]
+ bool _highlighted;
+
+ public bool highlighted { get { return _highlighted; } set { SetHighlighted(value); } }
+
+ public float fadeInDuration;
+ public float fadeOutDuration;
+ public bool flipY;
+
+ [Tooltip("Keeps the outline/glow size unaffected by object distance.")]
+ public bool constantWidth = true;
+
+ [Tooltip("Mask to include or exclude certain submeshes. By default, all submeshes are included.")]
+ public int subMeshMask = -1;
+
+ [Range(0, 1)]
+ [Tooltip("Intensity of the overlay effect. A value of 0 disables the overlay completely.")]
+ public float overlay;
+ public OverlayMode overlayMode = OverlayMode.WhenHighlighted;
+ [ColorUsage(true, true)] public Color overlayColor = Color.yellow;
+ public float overlayAnimationSpeed = 1f;
+ [Range(0, 1)]
+ public float overlayMinIntensity = 0.5f;
+ [Range(0, 1)]
+ [Tooltip("Controls the blending or mix of the overlay color with the natural colors of the object.")]
+ public float overlayBlending = 1.0f;
+ [Tooltip("Optional overlay texture.")]
+ public Texture2D overlayTexture;
+ public TextureUVSpace overlayTextureUVSpace;
+ public float overlayTextureScale = 1f;
+
+ [Range(0, 1)]
+ [Tooltip("Intensity of the outline. A value of 0 disables the outline completely.")]
+ public float outline = 1f;
+ [ColorUsage(true, true)] public Color outlineColor = Color.black;
+ public ColorStyle outlineColorStyle = ColorStyle.SingleColor;
+ [GradientUsage(hdr: true, ColorSpace.Linear)] public Gradient outlineGradient;
+ public bool outlineGradientInLocalSpace;
+ public float outlineWidth = 0.45f;
+ public QualityLevel outlineQuality = QualityLevel.Medium;
+ [Range(1, 8)]
+ [Tooltip("Reduces the quality of the outline but improves performance a bit.")]
+ public int outlineDownsampling = 2;
+ public Visibility outlineVisibility = Visibility.Normal;
+ public GlowBlendMode glowBlendMode = GlowBlendMode.Additive;
+ public bool outlineOptimalBlit = true;
+ public bool outlineBlitDebug;
+ [Tooltip("If enabled, this object won't combine the outline with other objects.")]
+ public bool outlineIndependent;
+
+ [Range(0, 5)]
+ [Tooltip("The intensity of the outer glow effect. A value of 0 disables the glow completely.")]
+ public float glow;
+ public float glowWidth = 0.4f;
+ public QualityLevel glowQuality = QualityLevel.Medium;
+ [Range(1, 8)]
+ [Tooltip("Reduces the quality of the glow but improves performance a bit.")]
+ public int glowDownsampling = 2;
+ [ColorUsage(true, true)] public Color glowHQColor = new Color(0.64f, 1f, 0f, 1f);
+ [Tooltip("When enabled, outer glow renders with dithering. When disabled, glow appears as a solid color.")]
+ public bool glowDithering = true;
+ [Tooltip("Seed for the dithering effect")]
+ public float glowMagicNumber1 = 0.75f;
+ [Tooltip("Another seed for the dithering effect that combines with first seed to create different patterns")]
+ public float glowMagicNumber2 = 0.5f;
+ public float glowAnimationSpeed = 1f;
+ public Visibility glowVisibility = Visibility.Normal;
+ [Tooltip("Performs a blit to screen only over the affected area, instead of a full-screen pass")]
+ public bool glowOptimalBlit = true;
+ public bool glowBlitDebug;
+ [Tooltip("Blends glow passes one after another. If this option is disabled, glow passes won't overlap (in this case, make sure the glow pass 1 has a smaller offset than pass 2, etc.)")]
+ public bool glowBlendPasses = true;
+#if UNITY_2020_2_OR_NEWER
+ [NonReorderable]
+#endif
+ public GlowPassData[] glowPasses;
+ [Tooltip("If enabled, glow effect will not use a stencil mask. This can be used to render the glow effect alone.")]
+ public bool glowIgnoreMask;
+
+ [Range(0, 5f)]
+ [Tooltip("The intensity of the inner glow effect. A value of 0 disables the glow completely.")]
+ public float innerGlow;
+ [Range(0, 2)]
+ public float innerGlowWidth = 1f;
+ [ColorUsage(true, true)] public Color innerGlowColor = Color.white;
+ public Visibility innerGlowVisibility = Visibility.Normal;
+
+ [Tooltip("Enables the targetFX effect. This effect draws an animated sprite over the object.")]
+ public bool targetFX;
+ public Texture2D targetFXTexture;
+ [ColorUsage(true, true)] public Color targetFXColor = Color.white;
+ public Transform targetFXCenter;
+ public float targetFXRotationSpeed = 50f;
+ public float targetFXInitialScale = 4f;
+ public float targetFXEndScale = 1.5f;
+ [Tooltip("Makes target scale relative to object renderer bounds")]
+ public bool targetFXScaleToRenderBounds = true;
+ [Tooltip("Places target FX sprite at the bottom of the highlighted object.")]
+ public bool targetFXAlignToGround;
+ [Tooltip("Fade out effect with altitude")]
+ public float targetFXFadePower = 32;
+ public float targetFXGroundMaxDistance = 10f;
+ public LayerMask targetFXGroundLayerMask = -1;
+ public float targetFXTransitionDuration = 0.5f;
+ [Tooltip("The duration of the effect. A value of 0 will keep the target sprite on screen while object is highlighted.")]
+ public float targetFXStayDuration = 1.5f;
+ public Visibility targetFXVisibility = Visibility.AlwaysOnTop;
+
+ public event OnObjectHighlightEvent OnObjectHighlightStart;
+ public event OnObjectHighlightEvent OnObjectHighlightEnd;
+ public event OnRendererHighlightEvent OnRendererHighlightStart;
+ public event OnTargetAnimatesEvent OnTargetAnimates;
+
+ [Tooltip("See-through mode for this Highlight Effect component.")]
+ public SeeThroughMode seeThrough = SeeThroughMode.Never;
+ [Tooltip("This mask setting let you specify which objects will be considered as occluders and cause the see-through effect for this Highlight Effect component. For example, you assign your walls to a different layer and specify that layer here, so only walls and not other objects, like ground or ceiling, will trigger the see-through effect.")]
+ public LayerMask seeThroughOccluderMask = -1;
+ [Tooltip("A multiplier for the occluder volume size which can be used to reduce the actual size of occluders when Highlight Effect checks if they're occluding this object.")]
+ [Range(0.01f, 0.6f)] public float seeThroughOccluderThreshold = 0.3f;
+ [Tooltip("Uses stencil buffers to ensure pixel-accurate occlusion test. If this option is disabled, only physics raycasting is used to test for occlusion.")]
+ public bool seeThroughOccluderMaskAccurate;
+ [Tooltip("The interval of time between occlusion tests.")]
+ public float seeThroughOccluderCheckInterval = 1f;
+ [Tooltip("If enabled, occlusion test is performed for each children element. If disabled, the bounds of all children is combined and a single occlusion test is performed for the combined bounds.")]
+ public bool seeThroughOccluderCheckIndividualObjects;
+ [Tooltip("Shows the see-through effect only if the occluder if at this 'offset' distance from the object.")]
+ public float seeThroughDepthOffset;
+ [Tooltip("Hides the see-through effect if the occluder is further than this distance from the object (0 = infinite)")]
+ public float seeThroughMaxDepth;
+ [Range(0, 5f)] public float seeThroughIntensity = 0.8f;
+ [Range(0, 1)] public float seeThroughTintAlpha = 0.5f;
+ [ColorUsage(true, true)] public Color seeThroughTintColor = Color.red;
+ [Range(0, 1)] public float seeThroughNoise = 1f;
+ [Range(0, 1)] public float seeThroughBorder;
+ public Color seeThroughBorderColor = Color.black;
+ [Tooltip("Only display the border instead of the full see-through effect.")]
+ public bool seeThroughBorderOnly;
+ public float seeThroughBorderWidth = 0.45f;
+ [Tooltip("Renders see-through effect on overlapping objects in a sequence that's relative to the distance to the camera")]
+ public bool seeThroughOrdered;
+ [Tooltip("Optional see-through mask effect texture.")]
+ public Texture2D seeThroughTexture;
+ public TextureUVSpace seeThroughTextureUVSpace;
+ public float seeThroughTextureScale = 1f;
+
+ struct ModelMaterials {
+ public bool render; // if this object can render this frame
+ public Transform transform;
+ public bool bakedTransform;
+ public Vector3 currentPosition, currentRotation, currentScale;
+ public bool renderWasVisibleDuringSetup;
+ public Mesh mesh, originalMesh;
+ public Renderer renderer;
+ public bool isSkinnedMesh;
+ public NormalsOption normalsOption;
+ public Material[] fxMatMask, fxMatSolidColor, fxMatSeeThroughInner, fxMatSeeThroughBorder, fxMatOverlay, fxMatInnerGlow;
+ public Matrix4x4 renderingMatrix;
+ public bool isCombined;
+ public bool preserveOriginalMesh { get { return !isCombined && normalsOption == NormalsOption.PreserveOriginal; } }
+
+ public void Init() {
+ render = false;
+ transform = null;
+ bakedTransform = false;
+ currentPosition = currentRotation = currentScale = Vector3.zero;
+ mesh = originalMesh = null;
+ renderer = null;
+ isSkinnedMesh = false;
+ normalsOption = NormalsOption.Smooth;
+ isCombined = false;
+ }
+ }
+
+ enum FadingState {
+ FadingOut = -1,
+ NoFading = 0,
+ FadingIn = 1
+ }
+
+ [SerializeField, HideInInspector]
+ ModelMaterials[] rms;
+ [SerializeField, HideInInspector]
+ int rmsCount;
+
+ ///
+ /// Number of objects affected by this highlight effect script
+ ///
+ public int includedObjectsCount => rmsCount;
+
+#if UNITY_EDITOR
+ ///
+ /// True if there's some static children
+ ///
+ [NonSerialized]
+ public bool staticChildren;
+
+#endif
+
+ [NonSerialized]
+ public Transform target;
+
+ ///
+ /// Time in which the highlight started
+ ///
+ [NonSerialized]
+ public float highlightStartTime;
+
+ ///
+ /// Time in which the target fx started
+ ///
+ [NonSerialized]
+ public float targetFxStartTime;
+
+ ///
+ /// True if this object is selected (if selectOnClick is used)
+ ///
+ [NonSerialized]
+ public bool isSelected;
+
+
+ [NonSerialized]
+ public HighlightProfile previousSettings;
+
+ public void RestorePreviousHighlightEffectSettings() {
+ previousSettings.Load(this);
+ }
+
+ const float TAU = 0.70711f;
+
+ // Reference materials. These are instanced per object (rms).
+ static Material fxMatMask, fxMatSolidColor, fxMatSeeThroughInner, fxMatSeeThroughBorder, fxMatOverlay, fxMatClearStencil;
+ static Material fxMatGlowRef, fxMatInnerGlow, fxMatOutlineRef, fxMatTargetRef;
+ static Material fxMatComposeGlowRef, fxMatComposeOutlineRef, fxMatBlurGlowRef, fxMatBlurOutlineRef;
+ static Material fxMatSeeThroughMask;
+
+ // Per-object materials
+ Material _fxMatOutline, _fxMatGlow, _fxMatTarget;
+ Material _fxMatComposeGlow, _fxMatComposeOutline, _fxMatBlurGlow, _fxMatBlurOutline;
+
+ Material fxMatOutline {
+ get {
+ if (_fxMatOutline == null && fxMatOutlineRef != null) {
+ _fxMatOutline = Instantiate(fxMatOutlineRef);
+ if (useGPUInstancing) _fxMatOutline.enableInstancing = true; else _fxMatOutline.enableInstancing = false;
+ }
+ return _fxMatOutline;
+ }
+ }
+
+ Material fxMatGlow {
+ get {
+ if (_fxMatGlow == null && fxMatGlowRef != null) {
+ _fxMatGlow = Instantiate(fxMatGlowRef);
+ if (useGPUInstancing) _fxMatGlow.enableInstancing = true; else _fxMatGlow.enableInstancing = false;
+ }
+ return _fxMatGlow;
+ }
+ }
+
+ Material fxMatTarget {
+ get {
+ if (_fxMatTarget == null && fxMatTargetRef != null) _fxMatTarget = Instantiate(fxMatTargetRef);
+ return _fxMatTarget;
+ }
+ }
+
+ Material fxMatComposeGlow {
+ get {
+ if (_fxMatComposeGlow == null && fxMatComposeGlowRef != null) _fxMatComposeGlow = Instantiate(fxMatComposeGlowRef);
+ return _fxMatComposeGlow;
+ }
+ }
+
+ Material fxMatComposeOutline {
+ get {
+ if (_fxMatComposeOutline == null && fxMatComposeOutlineRef != null) _fxMatComposeOutline = Instantiate(fxMatComposeOutlineRef);
+ return _fxMatComposeOutline;
+ }
+ }
+
+ Material fxMatBlurGlow {
+ get {
+ if (_fxMatBlurGlow == null && fxMatBlurGlowRef != null) _fxMatBlurGlow = Instantiate(fxMatBlurGlowRef);
+ return _fxMatBlurGlow;
+ }
+ }
+
+ Material fxMatBlurOutline {
+ get {
+ if (_fxMatBlurOutline == null && fxMatBlurOutlineRef != null) _fxMatBlurOutline = Instantiate(fxMatBlurOutlineRef);
+ return _fxMatBlurOutline;
+ }
+ }
+
+ static Vector4[] offsets;
+
+ float fadeStartTime;
+ FadingState fading = FadingState.NoFading;
+ CommandBuffer cbMask, cbSeeThrough, cbGlow, cbOutline, cbOverlay, cbInnerGlow;
+ CommandBuffer cbSmoothBlend;
+ int[] mipGlowBuffers, mipOutlineBuffers;
+ int glowRT, outlineRT;
+ static Mesh quadMesh, cubeMesh;
+ int sourceRT;
+ Matrix4x4 quadGlowMatrix, quadOutlineMatrix;
+ Vector4[] corners;
+ RenderTextureDescriptor sourceDesc;
+ Color debugColor, blackColor;
+ Visibility lastOutlineVisibility;
+ bool requireUpdateMaterial;
+ bool useGPUInstancing;
+
+ class PerCameraOcclusionData {
+ public float checkLastTime = -10000;
+ public int occlusionRenderFrame;
+ public bool lastOcclusionTestResult;
+ public readonly List cachedOccluders = new List();
+ }
+ readonly Dictionary perCameraOcclusionData = new Dictionary();
+
+
+ MaterialPropertyBlock glowPropertyBlock, outlinePropertyBlock;
+ static readonly List matDataDirection = new List();
+ static readonly List matDataGlow = new List();
+ static readonly List matDataColor = new List();
+ static Matrix4x4[] matrices;
+ public static readonly List effects = new List();
+ public static bool customSorting;
+ static int customSortingFrame;
+ static Camera customSortingCamera;
+
+ int skipThisFrame = -1;
+ int outlineOffsetsMin, outlineOffsetsMax;
+ int glowOffsetsMin, glowOffsetsMax;
+ static CombineInstance[] combineInstances;
+ bool maskRequired;
+
+ Texture2D outlineGradientTex;
+ Color[] outlineGradientColors;
+
+ void OnEnable() {
+ lastOutlineVisibility = outlineVisibility;
+ debugColor = new Color(1f, 0f, 0f, 0.5f);
+ blackColor = new Color(0, 0, 0, 0);
+ if (offsets == null || offsets.Length != 8) {
+ offsets = new Vector4[] {
+ new Vector4(0,1),
+ new Vector4(1,0),
+ new Vector4(0,-1),
+ new Vector4(-1,0),
+ new Vector4 (-TAU, TAU),
+ new Vector4 (TAU, TAU),
+ new Vector4 (TAU, -TAU),
+ new Vector4 (-TAU, -TAU)
+ };
+ }
+ if (corners == null || corners.Length != 8) {
+ corners = new Vector4[8];
+ }
+ if (quadMesh == null) {
+ BuildQuad();
+ }
+ if (cubeMesh == null) {
+ BuildCube();
+ }
+ if (target == null) {
+ target = transform;
+ }
+ if (profileSync && profile != null) {
+ profile.Load(this);
+ }
+ if (glowPasses == null || glowPasses.Length == 0) {
+ glowPasses = new GlowPassData[4];
+ glowPasses[0] = new GlowPassData() { offset = 4, alpha = 0.1f, color = new Color(0.64f, 1f, 0f, 1f) };
+ glowPasses[1] = new GlowPassData() { offset = 3, alpha = 0.2f, color = new Color(0.64f, 1f, 0f, 1f) };
+ glowPasses[2] = new GlowPassData() { offset = 2, alpha = 0.3f, color = new Color(0.64f, 1f, 0f, 1f) };
+ glowPasses[3] = new GlowPassData() { offset = 1, alpha = 0.4f, color = new Color(0.64f, 1f, 0f, 1f) };
+ }
+ sourceRT = Shader.PropertyToID("_HPSourceRT");
+ useGPUInstancing = GPUInstancing && SystemInfo.supportsInstancing;
+ if (useGPUInstancing) {
+ if (glowPropertyBlock == null) {
+ glowPropertyBlock = new MaterialPropertyBlock();
+ }
+ if (outlinePropertyBlock == null) {
+ outlinePropertyBlock = new MaterialPropertyBlock();
+ }
+ }
+
+ CheckGeometrySupportDependencies();
+
+ if (!effects.Contains(this)) {
+ effects.Add(this);
+ }
+ }
+
+ private void Start() {
+ SetupMaterial();
+ }
+
+ void OnDisable() {
+ UpdateMaterialPropertiesNow();
+ }
+
+
+ void Reset() {
+ SetupMaterial();
+ }
+
+ void DestroyMaterial(Material mat) {
+ if (mat != null) DestroyImmediate(mat);
+ }
+
+ void DestroyMaterialArray(Material[] mm) {
+ if (mm == null) return;
+ for (int k = 0; k < mm.Length; k++) {
+ DestroyMaterial(mm[k]);
+ }
+ }
+
+ void OnDestroy() {
+ if (rms != null) {
+ for (int k = 0; k < rms.Length; k++) {
+ DestroyMaterialArray(rms[k].fxMatMask);
+ DestroyMaterialArray(rms[k].fxMatSolidColor);
+ DestroyMaterialArray(rms[k].fxMatSeeThroughInner);
+ DestroyMaterialArray(rms[k].fxMatSeeThroughBorder);
+ DestroyMaterialArray(rms[k].fxMatOverlay);
+ DestroyMaterialArray(rms[k].fxMatInnerGlow);
+ }
+ }
+
+ DestroyMaterial(fxMatGlow);
+ DestroyMaterial(fxMatOutline);
+ DestroyMaterial(fxMatTarget);
+ DestroyMaterial(fxMatComposeGlow);
+ DestroyMaterial(fxMatComposeOutline);
+ DestroyMaterial(fxMatBlurGlow);
+ DestroyMaterial(fxMatBlurOutline);
+
+ if (effects.Contains(this)) {
+ effects.Remove(this);
+ }
+
+ if (combinedMeshes.TryGetValue(combinedMeshesHashId, out _)) {
+ combinedMeshes.Remove(combinedMeshesHashId);
+ }
+
+ foreach (Mesh instancedMesh in instancedMeshes) {
+ if (instancedMesh == null) continue;
+ int usageCount;
+ if (sharedMeshUsage.TryGetValue(instancedMesh, out usageCount)) {
+ if (usageCount <= 1) {
+ sharedMeshUsage.Remove(instancedMesh);
+ DestroyImmediate(instancedMesh);
+ } else {
+ sharedMeshUsage[instancedMesh] = usageCount - 1;
+ }
+ }
+ }
+ }
+
+
+ public static void DrawEffectsNow(Camera cam = null) {
+ if (cam == null) {
+ cam = Camera.current;
+ if (cam == null) return;
+ }
+ int effectsCount = effects.Count;
+ int thisFrame = Time.frameCount;
+ for (int k = 0; k < effectsCount; k++) {
+ HighlightEffect effect = effects[k];
+ if (effect != null) {
+ effect.DoOnRenderObject(cam);
+ effect.skipThisFrame = thisFrame;
+ }
+ }
+ }
+
+ void OnRenderObject() {
+ DoOnRenderObject(Camera.current);
+ }
+
+ ///
+ /// Loads a profile into this effect
+ ///
+ public void ProfileLoad(HighlightProfile profile) {
+ if (profile != null) {
+ this.profile = profile;
+ profile.Load(this);
+ }
+ }
+
+ ///
+ /// Reloads currently assigned profile
+ ///
+ public void ProfileReload() {
+ if (profile != null) {
+ profile.Load(this);
+ }
+ }
+
+
+ ///
+ /// Save current settings into given profile
+ ///
+ public void ProfileSaveChanges(HighlightProfile profile) {
+ if (profile != null) {
+ profile.Save(this);
+ }
+ }
+
+ ///
+ /// Save current settings into current profile
+ ///
+ public void ProfileSaveChanges() {
+ if (profile != null) {
+ profile.Save(this);
+ }
+ }
+
+
+ public void Refresh(bool discardCachedMeshes = false) {
+ if (discardCachedMeshes) {
+ RefreshCachedMeshes();
+ }
+ if (enabled) {
+ SetupMaterial();
+ }
+ }
+
+
+ void DoOnRenderObject(Camera cam) {
+
+ if (customSorting) {
+ int frameCount = Time.frameCount;
+ if (customSortingFrame != frameCount || customSortingCamera != cam) {
+ customSortingFrame = frameCount;
+ customSortingCamera = cam;
+ int effectsCount = effects.Count;
+ for (int k = 0; k < effectsCount; k++) {
+ HighlightEffect effect = effects[k];
+ effect.skipThisFrame = -1;
+ effect.RenderEffect(cam);
+ effect.skipThisFrame = frameCount;
+ }
+ }
+ } else {
+ RenderEffect(cam);
+ }
+ }
+
+ void RenderEffect(Camera cam) {
+
+ if (cam == null || ((1 << cam.gameObject.layer) & camerasLayerMask) == 0) return;
+
+ if (!reflectionProbes && cam.cameraType == CameraType.Reflection)
+ return;
+
+#if UNITY_EDITOR
+ if (!previewInEditor && !Application.isPlaying)
+ return;
+#endif
+
+ if (requireUpdateMaterial) {
+ requireUpdateMaterial = false;
+ UpdateMaterialPropertiesNow();
+ }
+
+ bool seeThroughReal = seeThroughIntensity > 0 && (seeThrough == SeeThroughMode.AlwaysWhenOccluded || (seeThrough == SeeThroughMode.WhenHighlighted && _highlighted));
+ if (seeThroughReal) {
+ seeThroughReal = RenderSeeThroughOccluders(cam);
+ if (seeThroughReal && seeThroughOccluderMask != -1) {
+ if (seeThroughOccluderMaskAccurate) {
+ CheckOcclusionAccurate(cam);
+ } else {
+ seeThroughReal = CheckOcclusion(cam);
+ }
+ }
+ }
+
+ bool showOverlay = hitActive || overlayMode == OverlayMode.Always;
+ if (!_highlighted && !seeThroughReal && !showOverlay) {
+ return;
+ }
+
+ if (skipThisFrame == Time.frameCount) {
+ return;
+ }
+
+ if (rms == null) {
+ SetupMaterial();
+ if (rms == null) return;
+ }
+
+ // Check camera culling mask
+ int cullingMask = cam.cullingMask;
+
+ // Ensure renderers are valid and visible (in case LODgroup has changed active renderer)
+ if (!ignoreObjectVisibility) {
+ for (int k = 0; k < rmsCount; k++) {
+ if (rms[k].renderer != null && rms[k].renderer.isVisible != rms[k].renderWasVisibleDuringSetup) {
+ SetupMaterial();
+ break;
+ }
+ }
+ }
+
+ if (fxMatMask == null)
+ return;
+
+ // Apply effect
+ float glowReal = _highlighted ? this.glow : 0;
+
+ // Check smooth blend ztesting capability
+ bool useSmoothGlow = glow > 0 && glowQuality == QualityLevel.Highest;
+ bool useSmoothOutline = outline > 0 && outlineQuality == QualityLevel.Highest;
+ bool useSmoothBlend = useSmoothGlow || useSmoothOutline;
+ if (useSmoothBlend) {
+ if (useSmoothGlow && useSmoothOutline) {
+ outlineVisibility = glowVisibility;
+ }
+ }
+ Visibility smoothGlowVisibility = glowVisibility;
+ Visibility smoothOutlineVisibility = outlineVisibility;
+#if UNITY_EDITOR
+ if (useSmoothBlend && cam.cameraType == CameraType.SceneView) {
+ smoothGlowVisibility = smoothOutlineVisibility = Visibility.AlwaysOnTop;
+ }
+#endif
+ if (useSmoothBlend) {
+ if (depthClip) {
+ cam.depthTextureMode |= DepthTextureMode.Depth;
+ }
+ if (Application.isMobilePlatform || (cam.allowMSAA && QualitySettings.antiAliasing > 1)) {
+ smoothGlowVisibility = smoothOutlineVisibility = Visibility.AlwaysOnTop;
+ } else if (UnityEngine.XR.XRSettings.enabled && Application.isPlaying) {
+ smoothGlowVisibility = smoothOutlineVisibility = Visibility.AlwaysOnTop;
+ }
+ }
+
+ // First create masks
+ float camAspect = cam.aspect;
+ bool independentFullScreenNotExecuted = true;
+ bool somePartVisible = false;
+
+ for (int k = 0; k < rmsCount; k++) {
+ rms[k].render = false;
+
+ Transform t = rms[k].transform;
+ if (t == null)
+ continue;
+
+ Mesh mesh = rms[k].mesh;
+ if (mesh == null)
+ continue;
+
+ int layer = t.gameObject.layer;
+ if (!ignoreObjectVisibility) {
+ if (((1 << layer) & cullingMask) == 0)
+ continue;
+ if (!rms[k].renderer.isVisible)
+ continue;
+ }
+
+ rms[k].render = true;
+ somePartVisible = true;
+
+ if (rms[k].isCombined) {
+ rms[k].renderingMatrix = t.localToWorldMatrix;
+ } else if (!rms[k].preserveOriginalMesh) {
+ Vector3 lossyScale = t.lossyScale;
+ Vector3 position = t.position;
+ if (rms[k].bakedTransform) {
+ if (rms[k].currentPosition != t.position || rms[k].currentRotation != t.eulerAngles || rms[k].currentScale != t.lossyScale) {
+ BakeTransform(k, true);
+ }
+ rms[k].renderingMatrix = Matrix4x4.identity;
+ } else {
+ rms[k].renderingMatrix = Matrix4x4.TRS(position, t.rotation, lossyScale);
+ }
+ }
+
+ // Outline
+ if (outlineIndependent) {
+ if (useSmoothBlend) {
+ if (independentFullScreenNotExecuted) {
+ independentFullScreenNotExecuted = false;
+ fxMatClearStencil.SetPass(0);
+ if (subMeshMask > 0) {
+ for (int l = 0; l < mesh.subMeshCount; l++) {
+ if (((1 << l) & subMeshMask) != 0) {
+ Graphics.DrawMeshNow(quadMesh, Matrix4x4.identity, l);
+ }
+ }
+ } else {
+ Graphics.DrawMeshNow(quadMesh, Matrix4x4.identity);
+ }
+ }
+ } else if (outline > 0 || glow > 0) {
+ float width = outlineWidth;
+ if (glow > 0) {
+ width = Mathf.Max(width, glowWidth);
+ }
+ Material mat = fxMatOutline;
+ bool usesMultipleOffsets = normalsOption != NormalsOption.Planar && outlineQuality.UsesMultipleOffsets();
+ for (int l = 0; l < mesh.subMeshCount; l++) {
+ if (((1 << l) & subMeshMask) == 0) continue;
+ if (usesMultipleOffsets) {
+ for (int o = outlineOffsetsMin; o <= outlineOffsetsMax; o++) {
+ Vector3 direction = offsets[o] * (width / 100f);
+ direction.y *= camAspect;
+ mat.SetVector(ShaderParams.OutlineDirection, direction);
+ if (rms[k].preserveOriginalMesh) {
+ cbOutline.Clear();
+ cbOutline.DrawRenderer(rms[k].renderer, mat, l, 1);
+ Graphics.ExecuteCommandBuffer(cbOutline);
+ } else {
+ mat.SetPass(1);
+ Graphics.DrawMeshNow(mesh, rms[k].renderingMatrix, l);
+ }
+ }
+ } else {
+ if (rms[k].preserveOriginalMesh) {
+ cbOutline.Clear();
+ cbOutline.DrawRenderer(rms[k].renderer, mat, l, 1);
+ Graphics.ExecuteCommandBuffer(cbOutline);
+ } else {
+ mat.SetPass(1);
+ Graphics.DrawMeshNow(mesh, rms[k].renderingMatrix, l);
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ if (!somePartVisible) return;
+
+ bool renderMaskOnTop = _highlighted && ((outline > 0 && smoothOutlineVisibility != Visibility.Normal) || (glow > 0 && smoothGlowVisibility != Visibility.Normal) || (innerGlow > 0 && innerGlowVisibility != Visibility.Normal));
+ if (maskRequired) {
+ for (int k = 0; k < rmsCount; k++) {
+ if (rms[k].render) {
+ RenderMask(k, rms[k].mesh, renderMaskOnTop);
+ }
+ }
+ }
+
+ // Compute tweening
+ float fadeGroup = 1f;
+ float fade = 1f;
+ if (fading != FadingState.NoFading) {
+ if (fading == FadingState.FadingIn) {
+ if (fadeInDuration > 0) {
+ fadeGroup = (Time.time - fadeStartTime) / fadeInDuration;
+ if (fadeGroup > 1f) {
+ fadeGroup = 1f;
+ fading = FadingState.NoFading;
+ }
+ }
+ } else if (fadeOutDuration > 0) {
+ fadeGroup = 1f - (Time.time - fadeStartTime) / fadeOutDuration;
+ if (fadeGroup < 0f) {
+ fadeGroup = 0f;
+ fading = FadingState.NoFading;
+ _highlighted = false;
+ if (OnObjectHighlightEnd != null) {
+ OnObjectHighlightEnd(gameObject);
+ }
+ SendMessage("HighlightEnd", null, SendMessageOptions.DontRequireReceiver);
+ }
+ }
+ }
+
+ if (glowQuality == QualityLevel.High) {
+ glowReal *= 0.25f;
+ } else if (glowQuality == QualityLevel.Medium) {
+ glowReal *= 0.5f;
+ }
+
+ int smoothRTWidth = 0;
+ int smoothRTHeight = 0;
+ Bounds smoothBounds = new Bounds();
+
+ if (useSmoothBlend) {
+ // Prepare smooth outer glow / outline target
+ if (cbSmoothBlend == null) {
+ CheckBlurCommandBuffer();
+ }
+ cbSmoothBlend.Clear();
+ smoothRTWidth = cam.pixelWidth;
+ smoothRTHeight = cam.pixelHeight;
+ if (smoothRTHeight <= 0) {
+ smoothRTHeight = 1;
+ }
+ if (UnityEngine.XR.XRSettings.enabled && Application.isPlaying) {
+ sourceDesc = UnityEngine.XR.XRSettings.eyeTextureDesc;
+ } else {
+ sourceDesc = new RenderTextureDescriptor(smoothRTWidth, smoothRTHeight, RenderTextureFormat.R8); // Application.isMobilePlatform ? RenderTextureFormat.Default : RenderTextureFormat.DefaultHDR);
+ sourceDesc.volumeDepth = 1;
+ }
+ sourceDesc.msaaSamples = 1;
+ sourceDesc.useMipMap = false;
+ sourceDesc.depthBufferBits = 0;
+
+ cbSmoothBlend.GetTemporaryRT(sourceRT, sourceDesc, FilterMode.Bilinear);
+ RenderTargetIdentifier sourceDestination = new RenderTargetIdentifier(sourceRT, 0, CubemapFace.Unknown, -1);
+ if ((glow > 0 && smoothGlowVisibility == Visibility.AlwaysOnTop) || (outline > 0 && smoothOutlineVisibility == Visibility.AlwaysOnTop)) {
+ cbSmoothBlend.SetRenderTarget(sourceDestination);
+ } else {
+ RenderTargetIdentifier targetDestination = new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget, 0, CubemapFace.Unknown, -1);
+ if (Application.isMobilePlatform) {
+ cbSmoothBlend.SetRenderTarget(sourceDestination, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare, targetDestination, RenderBufferLoadAction.Load, RenderBufferStoreAction.DontCare);
+ } else {
+ cbSmoothBlend.SetRenderTarget(sourceDestination, targetDestination);
+ }
+ }
+ cbSmoothBlend.ClearRenderTarget(false, true, new Color(0, 0, 0, 0));
+ }
+
+ bool targetEffectRendered = false;
+ cbSeeThrough.Clear();
+
+ // Add effects
+ if (seeThroughReal && renderMaskOnTop) {
+ for (int k = 0; k < rmsCount; k++) {
+ if (!rms[k].render)
+ continue;
+ Mesh mesh = rms[k].mesh;
+ RenderSeeThroughClearStencil(k, mesh);
+ }
+ for (int k = 0; k < rmsCount; k++) {
+ if (!rms[k].render)
+ continue;
+ Mesh mesh = rms[k].mesh;
+ RenderSeeThroughMask(k, mesh);
+ }
+ }
+
+ for (int k = 0; k < rmsCount; k++) {
+ if (!rms[k].render)
+ continue;
+ Mesh mesh = rms[k].mesh;
+
+ fade = fadeGroup;
+ // Distance fade
+ if (cameraDistanceFade) {
+ fade *= ComputeCameraDistanceFade(rms[k].transform.position, cam.transform);
+ cbSeeThrough.SetGlobalFloat(ShaderParams.FadeFactor, fade);
+ } else {
+ cbSeeThrough.SetGlobalFloat(ShaderParams.FadeFactor, 1f);
+ }
+
+ // See-Through
+ if (seeThroughReal) {
+ if (seeThroughDepthOffset > 0) {
+ cam.depthTextureMode |= DepthTextureMode.Depth;
+ }
+ bool usesSeeThroughBorder = (seeThroughBorder * seeThroughBorderWidth) > 0;
+ if (rms[k].preserveOriginalMesh) {
+ for (int l = 0; l < mesh.subMeshCount; l++) {
+ if (((1 << l) & subMeshMask) == 0) continue;
+ if (l < rms[k].fxMatSeeThroughInner.Length && rms[k].fxMatSeeThroughInner[l] != null) {
+ cbSeeThrough.DrawRenderer(rms[k].renderer, rms[k].fxMatSeeThroughInner[l], l);
+ if (usesSeeThroughBorder) {
+ cbSeeThrough.DrawRenderer(rms[k].renderer, rms[k].fxMatSeeThroughBorder[l], l);
+ }
+ }
+ }
+ } else {
+ for (int l = 0; l < mesh.subMeshCount; l++) {
+ if (((1 << l) & subMeshMask) == 0) continue;
+ if (l < rms[k].fxMatSeeThroughInner.Length && rms[k].fxMatSeeThroughInner[l] != null) {
+ cbSeeThrough.DrawMesh(mesh, rms[k].renderingMatrix, rms[k].fxMatSeeThroughInner[l], l);
+ if (usesSeeThroughBorder) {
+ cbSeeThrough.DrawMesh(mesh, rms[k].renderingMatrix, rms[k].fxMatSeeThroughBorder[l], l);
+ }
+ }
+ }
+ }
+ }
+
+ if (_highlighted || showOverlay) {
+ // Hit FX
+ Color overlayColor = this.overlayColor;
+ float overlayMinIntensity = this.overlayMinIntensity;
+ float overlayBlending = this.overlayBlending;
+
+ Color innerGlowColorA = this.innerGlowColor;
+ float innerGlow = this.innerGlow;
+
+ if (hitActive) {
+ overlayColor.a = _highlighted ? overlay : 0;
+ innerGlowColorA.a = _highlighted ? innerGlow : 0;
+ float t = hitFadeOutDuration > 0 ? (Time.time - hitStartTime) / hitFadeOutDuration : 1f;
+ if (t >= 1f) {
+ hitActive = false;
+ } else {
+ if (hitFxMode == HitFxMode.InnerGlow) {
+ bool lerpToCurrentInnerGlow = _highlighted && innerGlow > 0;
+ innerGlowColorA = lerpToCurrentInnerGlow ? Color.Lerp(hitColor, innerGlowColor, t) : hitColor;
+ innerGlowColorA.a = lerpToCurrentInnerGlow ? Mathf.Lerp(1f - t, innerGlow, t) : 1f - t;
+ innerGlowColorA.a *= hitInitialIntensity;
+ } else {
+ bool lerpToCurrentOverlay = _highlighted && overlay > 0;
+ overlayColor = lerpToCurrentOverlay ? Color.Lerp(hitColor, overlayColor, t) : hitColor;
+ overlayColor.a = lerpToCurrentOverlay ? Mathf.Lerp(1f - t, overlay, t) : 1f - t;
+ overlayColor.a *= hitInitialIntensity;
+ overlayMinIntensity = 1f;
+ overlayBlending = 0;
+ }
+ }
+ } else {
+ overlayColor.a = overlay * fade;
+ innerGlowColorA.a = innerGlow * fade;
+ }
+
+ for (int l = 0; l < mesh.subMeshCount; l++) {
+ if (((1 << l) & subMeshMask) == 0) continue;
+
+ // Overlay
+ if (overlayColor.a > 0) {
+ Material fxMat = rms[k].fxMatOverlay[l];
+ fxMat.SetColor(ShaderParams.OverlayColor, overlayColor);
+ fxMat.SetVector(ShaderParams.OverlayData, new Vector4(overlayAnimationSpeed, overlayMinIntensity, overlayBlending, overlayTextureScale));
+ if (hitActive && hitFxMode == HitFxMode.LocalHit) {
+ fxMat.SetVector(ShaderParams.OverlayHitPosData, new Vector4(hitPosition.x, hitPosition.y, hitPosition.z, hitRadius));
+ fxMat.SetFloat(ShaderParams.OverlayHitStartTime, hitStartTime);
+ } else {
+ fxMat.SetVector(ShaderParams.OverlayHitPosData, Vector4.zero);
+ }
+ if (rms[k].preserveOriginalMesh) {
+ cbOverlay.Clear();
+ cbOverlay.DrawRenderer(rms[k].renderer, fxMat, l);
+ Graphics.ExecuteCommandBuffer(cbOverlay);
+ } else {
+ fxMat.SetPass(0);
+ Graphics.DrawMeshNow(mesh, rms[k].renderingMatrix, l);
+ }
+ }
+
+ // Inner Glow
+ if (innerGlowColorA.a > 0) {
+ rms[k].fxMatInnerGlow[l].SetColor(ShaderParams.InnerGlowColor, innerGlowColorA);
+
+ if (rms[k].preserveOriginalMesh) {
+ cbInnerGlow.Clear();
+ cbInnerGlow.DrawRenderer(rms[k].renderer, rms[k].fxMatInnerGlow[l], l);
+ Graphics.ExecuteCommandBuffer(cbInnerGlow);
+ } else {
+ rms[k].fxMatInnerGlow[l].SetPass(0);
+ Graphics.DrawMeshNow(mesh, rms[k].renderingMatrix, l);
+ }
+ }
+ }
+ }
+
+ if (!_highlighted)
+ continue;
+
+ if (useSmoothBlend) {
+ if (k == 0) {
+ smoothBounds = rms[k].renderer.bounds;
+ } else {
+ smoothBounds.Encapsulate(rms[k].renderer.bounds);
+ }
+ }
+
+ for (int l = 0; l < mesh.subMeshCount; l++) {
+ if (((1 << l) & subMeshMask) == 0) continue;
+
+ // Render object body for glow/outline highest quality
+ if (useSmoothBlend) {
+ if (l < rms[k].fxMatSolidColor.Length) {
+ if (rms[k].preserveOriginalMesh) {
+ cbSmoothBlend.DrawRenderer(rms[k].renderer, rms[k].fxMatSolidColor[l], l);
+ } else {
+ cbSmoothBlend.DrawMesh(mesh, rms[k].renderingMatrix, rms[k].fxMatSolidColor[l], l);
+ }
+ }
+ }
+
+ // Glow
+ if (glow > 0 && glowQuality != QualityLevel.Highest) {
+ matDataGlow.Clear();
+ matDataColor.Clear();
+ matDataDirection.Clear();
+ Material mat = fxMatGlow;
+ Vector4 directionZero = normalsOption == NormalsOption.Planar ? new Vector4(0, 0, glowWidth / 100f, 0) : Vector4.zero;
+ mat.SetVector(ShaderParams.GlowDirection, directionZero);
+ for (int j = 0; j < glowPasses.Length; j++) {
+ Color dataColor = glowPasses[j].color;
+ mat.SetColor(ShaderParams.GlowColor, dataColor);
+ Vector4 dataGlow = new Vector4(fade * glowReal * glowPasses[j].alpha, normalsOption == NormalsOption.Planar ? 0 : glowPasses[j].offset * glowWidth / 100f, glowMagicNumber1, glowMagicNumber2);
+ mat.SetVector(ShaderParams.Glow, dataGlow);
+ if (normalsOption != NormalsOption.Planar && glowQuality.UsesMultipleOffsets()) {
+ for (int o = glowOffsetsMin; o <= glowOffsetsMax; o++) {
+ Vector4 direction = offsets[o];
+ direction.y *= camAspect;
+ mat.SetVector(ShaderParams.GlowDirection, direction);
+ if (rms[k].preserveOriginalMesh) {
+ cbGlow.Clear();
+ cbGlow.DrawRenderer(rms[k].renderer, mat, l);
+ Graphics.ExecuteCommandBuffer(cbGlow);
+ } else {
+ if (useGPUInstancing) {
+ matDataDirection.Add(direction);
+ matDataGlow.Add(dataGlow);
+ matDataColor.Add(new Vector4(dataColor.r, dataColor.g, dataColor.b, dataColor.a));
+ } else {
+ mat.SetPass(0);
+ Graphics.DrawMeshNow(mesh, rms[k].renderingMatrix, l);
+ }
+ }
+ }
+ } else {
+ if (rms[k].preserveOriginalMesh) {
+ cbGlow.Clear();
+ cbGlow.DrawRenderer(rms[k].renderer, mat, l);
+ Graphics.ExecuteCommandBuffer(cbGlow);
+ } else {
+ if (useGPUInstancing) {
+ matDataDirection.Add(directionZero);
+ matDataGlow.Add(dataGlow);
+ matDataColor.Add(new Vector4(dataColor.r, dataColor.g, dataColor.b, dataColor.a));
+ } else {
+ mat.SetPass(0);
+ Graphics.DrawMeshNow(mesh, rms[k].renderingMatrix, l);
+ }
+ }
+ }
+ }
+ if (useGPUInstancing) {
+ int instanceCount = matDataDirection.Count;
+ if (instanceCount > 0) {
+ glowPropertyBlock.Clear();
+ glowPropertyBlock.SetVectorArray(ShaderParams.GlowDirection, matDataDirection);
+ glowPropertyBlock.SetVectorArray(ShaderParams.GlowColor, matDataColor);
+ glowPropertyBlock.SetVectorArray(ShaderParams.Glow, matDataGlow);
+ if (matrices == null || matrices.Length < instanceCount) {
+ matrices = new Matrix4x4[instanceCount];
+ }
+ for (int m = 0; m < instanceCount; m++) {
+ matrices[m] = rms[k].renderingMatrix;
+ }
+ cbGlow.Clear();
+ cbGlow.DrawMeshInstanced(mesh, l, mat, 0, matrices, instanceCount, glowPropertyBlock);
+ Graphics.ExecuteCommandBuffer(cbGlow);
+ }
+ }
+ }
+
+ // Outline
+ if (outline > 0 && outlineQuality != QualityLevel.Highest) {
+ Material mat = fxMatOutline;
+ Color outlineColor = this.outlineColor;
+ if (outlineColorStyle == ColorStyle.Gradient) {
+ outlineColor.a *= outline * fade;
+ Bounds bounds = outlineGradientInLocalSpace ? mesh.bounds : rms[k].renderer.bounds;
+ mat.SetVector(ShaderParams.OutlineVertexData, new Vector4(bounds.min.y, bounds.size.y + 0.0001f, 0));
+ } else {
+ outlineColor.a = outline * fade;
+ mat.SetVector(ShaderParams.OutlineVertexData, new Vector4(-1e6f, 1f, 1f, 0));
+ }
+ mat.SetColor(ShaderParams.OutlineColor, outlineColor);
+ if (normalsOption != NormalsOption.Planar && outlineQuality.UsesMultipleOffsets()) {
+ matDataDirection.Clear();
+ for (int o = outlineOffsetsMin; o <= outlineOffsetsMax; o++) {
+ Vector4 direction = offsets[o] * (outlineWidth / 100f);
+ direction.y *= camAspect;
+ mat.SetVector(ShaderParams.OutlineDirection, direction);
+ if (rms[k].preserveOriginalMesh) {
+ cbOutline.Clear();
+ cbOutline.DrawRenderer(rms[k].renderer, mat, l, 0);
+ Graphics.ExecuteCommandBuffer(cbOutline);
+ } else {
+ if (useGPUInstancing) {
+ matDataDirection.Add(direction);
+ } else {
+ mat.SetPass(0);
+ Graphics.DrawMeshNow(mesh, rms[k].renderingMatrix, l);
+ }
+ }
+ }
+ if (useGPUInstancing) {
+ int instanceCount = matDataDirection.Count;
+ if (instanceCount > 0) {
+ outlinePropertyBlock.Clear();
+ outlinePropertyBlock.SetVectorArray(ShaderParams.OutlineDirection, matDataDirection);
+ if (matrices == null || matrices.Length < instanceCount) {
+ matrices = new Matrix4x4[instanceCount];
+ }
+ for (int m = 0; m < instanceCount; m++) {
+ matrices[m] = rms[k].renderingMatrix;
+ }
+ cbGlow.Clear(); // we reuse the same commandbuffer for glow
+ cbGlow.DrawMeshInstanced(mesh, l, mat, 0, matrices, instanceCount, outlinePropertyBlock);
+ Graphics.ExecuteCommandBuffer(cbGlow);
+ }
+ }
+ } else {
+ if (rms[k].preserveOriginalMesh) {
+ cbOutline.Clear();
+ cbOutline.DrawRenderer(rms[k].renderer, mat, l, 0);
+ Graphics.ExecuteCommandBuffer(cbOutline);
+ } else {
+ mat.SetPass(0);
+ Graphics.DrawMeshNow(mesh, rms[k].renderingMatrix, l);
+ }
+ }
+ }
+ }
+
+ // Target
+ if (targetFX) {
+ float fadeOut = 1f;
+ if (targetFXStayDuration > 0 && Application.isPlaying) {
+ fadeOut = (Time.time - targetFxStartTime);
+ if (fadeOut >= targetFXStayDuration) {
+ fadeOut -= targetFXStayDuration;
+ fadeOut = 1f - fadeOut;
+ }
+ if (fadeOut > 1f) {
+ fadeOut = 1f;
+ }
+ }
+ bool usesTarget = targetFXCenter != null;
+ if (fadeOut > 0 && !(targetEffectRendered && usesTarget)) {
+ targetEffectRendered = true;
+ float scaleT = 1f;
+ float time;
+ float normalizedTime = 0;
+ if (Application.isPlaying) {
+ normalizedTime = (Time.time - targetFxStartTime) / targetFXTransitionDuration;
+ if (normalizedTime > 1f) {
+ normalizedTime = 1f;
+ }
+ scaleT = Mathf.Sin(normalizedTime * Mathf.PI * 0.5f);
+ time = Time.time;
+ } else {
+ time = (float)DateTime.Now.Subtract(DateTime.Today).TotalSeconds;
+ }
+
+ Bounds bounds = rms[k].renderer.bounds;
+ if (!targetFXScaleToRenderBounds) {
+ bounds.size = Vector3.one;
+ }
+ Vector3 scale = bounds.size;
+ float minSize = scale.x;
+ if (scale.y < minSize) {
+ minSize = scale.y;
+ }
+ if (scale.z < minSize) {
+ minSize = scale.z;
+ }
+ scale.x = scale.y = scale.z = minSize;
+ scale = Vector3.Lerp(scale * targetFXInitialScale, scale * targetFXEndScale, scaleT);
+ Vector3 center = usesTarget ? targetFXCenter.transform.position : bounds.center;
+ Quaternion rotation;
+ if (targetFXAlignToGround) {
+ rotation = Quaternion.Euler(90, 0, 0);
+ center.y += 0.5f; // a bit of offset in case it's in contact with ground
+ if (Physics.Raycast(center, Vector3.down, out RaycastHit groundHitInfo, targetFXGroundMaxDistance, targetFXGroundLayerMask)) {
+ cam.depthTextureMode |= DepthTextureMode.Depth;
+ center = groundHitInfo.point;
+ center.y += 0.01f;
+ Vector4 renderData = groundHitInfo.normal;
+ renderData.w = targetFXFadePower;
+ fxMatTarget.SetVector(ShaderParams.TargetFXRenderData, renderData);
+ rotation = Quaternion.Euler(0, time * targetFXRotationSpeed, 0);
+ if (OnTargetAnimates != null) {
+ OnTargetAnimates(ref center, ref rotation, ref scale, normalizedTime);
+ }
+ Matrix4x4 m = Matrix4x4.TRS(center, rotation, scale);
+ Color color = targetFXColor;
+ color.a *= fade * fadeOut;
+ Material mat = fxMatTarget;
+ mat.color = color;
+ mat.SetPass(0);
+ Graphics.DrawMeshNow(cubeMesh, m);
+ }
+ } else {
+ rotation = Quaternion.LookRotation(cam.transform.position - rms[k].transform.position);
+ Quaternion animationRot = Quaternion.Euler(0, 0, time * targetFXRotationSpeed);
+ rotation *= animationRot;
+ if (OnTargetAnimates != null) {
+ OnTargetAnimates(ref center, ref rotation, ref scale, normalizedTime);
+ }
+ Matrix4x4 m = Matrix4x4.TRS(center, rotation, scale);
+ Color color = targetFXColor;
+ color.a *= fade * fadeOut;
+ Material mat = fxMatTarget;
+ mat.color = color;
+ mat.SetPass(1);
+ Graphics.DrawMeshNow(quadMesh, m);
+ }
+ }
+ }
+ }
+
+ if (useSmoothBlend) {
+ if (ComputeSmoothQuadMatrix(cam, smoothBounds)) {
+ // Smooth Glow
+ if (useSmoothGlow) {
+ float intensity = glow * fade;
+ fxMatComposeGlow.color = new Color(glowHQColor.r * intensity, glowHQColor.g * intensity, glowHQColor.b * intensity, glowHQColor.a * intensity);
+ SmoothGlow(smoothRTWidth / glowDownsampling, smoothRTHeight / glowDownsampling);
+ }
+
+ // Smooth Outline
+ if (useSmoothOutline) {
+ fxMatComposeOutline.color = new Color(outlineColor.r, outlineColor.g, outlineColor.b, 5f * outlineColor.a * outline * fade);
+ SmoothOutline(smoothRTWidth / outlineDownsampling, smoothRTHeight / outlineDownsampling);
+ }
+
+ // Bit result
+ ComposeSmoothBlend(smoothGlowVisibility, smoothOutlineVisibility);
+ }
+ }
+
+ if (seeThroughReal && seeThroughOrdered) { // Ordered for see-through
+ for (int k = 0; k < rmsCount; k++) {
+ if (!rms[k].render)
+ continue;
+ Mesh mesh = rms[k].mesh;
+ for (int l = 0; l < mesh.subMeshCount; l++) {
+ if (((1 << l) & subMeshMask) == 0) continue;
+ if (rms[k].isCombined) {
+ cbSeeThrough.DrawMesh(mesh, rms[k].renderingMatrix, fxMatClearStencil, l, 1);
+ } else {
+ cbSeeThrough.DrawRenderer(rms[k].renderer, fxMatClearStencil, l, 1);
+ }
+ }
+ }
+ }
+
+ Graphics.ExecuteCommandBuffer(cbSeeThrough);
+ }
+
+
+ void RenderMask(int k, Mesh mesh, bool alwaysOnTop) {
+ if (rms[k].preserveOriginalMesh) {
+ cbMask.Clear();
+ for (int l = 0; l < mesh.subMeshCount; l++) {
+ if (((1 << l) & subMeshMask) == 0) continue;
+ if (alwaysOnTop) {
+ rms[k].fxMatMask[l].SetInt(ShaderParams.ZTest, (int)CompareFunction.Always);
+ } else {
+ rms[k].fxMatMask[l].SetInt(ShaderParams.ZTest, (int)CompareFunction.LessEqual);
+ }
+ cbMask.DrawRenderer(rms[k].renderer, rms[k].fxMatMask[l], l, 0);
+ }
+ Graphics.ExecuteCommandBuffer(cbMask);
+ } else {
+ for (int l = 0; l < mesh.subMeshCount; l++) {
+ if (((1 << l) & subMeshMask) == 0) continue;
+ if (alwaysOnTop) {
+ rms[k].fxMatMask[l].SetInt(ShaderParams.ZTest, (int)CompareFunction.Always);
+ } else {
+ rms[k].fxMatMask[l].SetInt(ShaderParams.ZTest, (int)CompareFunction.LessEqual);
+ }
+ rms[k].fxMatMask[l].SetPass(0);
+ Graphics.DrawMeshNow(mesh, rms[k].renderingMatrix, l);
+ }
+ }
+
+
+ }
+
+ void RenderSeeThroughClearStencil(int k, Mesh mesh) {
+ if (rms[k].preserveOriginalMesh) {
+ for (int l = 0; l < mesh.subMeshCount; l++) {
+ if (((1 << l) & subMeshMask) == 0) continue;
+ cbSeeThrough.DrawRenderer(rms[k].renderer, fxMatClearStencil, l, 1);
+ }
+ } else {
+ for (int l = 0; l < mesh.subMeshCount; l++) {
+ if (((1 << l) & subMeshMask) == 0) continue;
+ cbSeeThrough.DrawMesh(mesh, rms[k].renderingMatrix, fxMatClearStencil, l, 1);
+ }
+ }
+ }
+
+ void RenderSeeThroughMask(int k, Mesh mesh) {
+ if (rms[k].preserveOriginalMesh) {
+ for (int l = 0; l < mesh.subMeshCount; l++) {
+ if (((1 << l) & subMeshMask) == 0) continue;
+ cbSeeThrough.DrawRenderer(rms[k].renderer, rms[k].fxMatMask[l], l, 1);
+ }
+ } else {
+ for (int l = 0; l < mesh.subMeshCount; l++) {
+ if (((1 << l) & subMeshMask) == 0) continue;
+ cbSeeThrough.DrawMesh(mesh, rms[k].renderingMatrix, rms[k].fxMatMask[l], l, 1);
+ }
+ }
+ }
+
+
+ void WorldToViewportPoint(ref Matrix4x4 m, ref Vector4 p) {
+ p = m * p;
+ p.x = (p.x / p.w + 1f) * 0.5f;
+ p.y = (p.y / p.w + 1f) * 0.5f;
+ }
+
+ bool ComputeSmoothQuadMatrix(Camera cam, Bounds bounds) {
+ // Compute bounds in screen space and enlarge for glow space
+
+ Vector3 shift = cam.transform.position;
+ cam.transform.position -= shift;
+ bounds.center -= shift;
+ bool res = ComputeSmoothQuadMatrixOriginShifted(cam, ref bounds, ref shift);
+ cam.transform.position += shift;
+ return res;
+ }
+
+ bool ComputeSmoothQuadMatrixOriginShifted(Camera cam, ref Bounds bounds, ref Vector3 shift) {
+ // Compute bounds in screen space and enlarge for glow space
+
+ Matrix4x4 mat = cam.projectionMatrix * cam.worldToCameraMatrix;
+ Vector3 min = bounds.min;
+ Vector3 max = bounds.max;
+ corners[0] = new Vector4(min.x, min.y, min.z, 1f);
+ corners[1] = new Vector4(min.x, min.y, max.z, 1f);
+ corners[2] = new Vector4(max.x, min.y, min.z, 1f);
+ corners[3] = new Vector4(max.x, min.y, max.z, 1f);
+ corners[4] = new Vector4(min.x, max.y, min.z, 1f);
+ corners[5] = new Vector4(min.x, max.y, max.z, 1f);
+ corners[6] = new Vector4(max.x, max.y, min.z, 1f);
+ corners[7] = new Vector4(max.x, max.y, max.z, 1f);
+ Vector3 scrMin = new Vector3(float.MaxValue, float.MaxValue, 0);
+ Vector3 scrMax = new Vector3(float.MinValue, float.MinValue, 0);
+ float distance = float.MaxValue;
+ float nearClipPlane = cam.nearClipPlane;
+
+ for (int k = 0; k < 8; k++) {
+ WorldToViewportPoint(ref mat, ref corners[k]);
+ if (corners[k].x < scrMin.x) {
+ scrMin.x = corners[k].x;
+ }
+ if (corners[k].y < scrMin.y) {
+ scrMin.y = corners[k].y;
+ }
+ if (corners[k].x > scrMax.x) {
+ scrMax.x = corners[k].x;
+ }
+ if (corners[k].y > scrMax.y) {
+ scrMax.y = corners[k].y;
+ }
+ if (corners[k].z < distance) {
+ distance = corners[k].z;
+ if (distance < nearClipPlane) {
+ scrMin.x = scrMin.y = 0;
+ scrMax.x = 1f;
+ scrMax.y = 1f;
+ break;
+ }
+ }
+ }
+ if (scrMax.y == scrMin.y)
+ return false;
+
+ int pixelWidth = cam.pixelWidth;
+ int pixelHeight = cam.pixelHeight;
+ scrMin.x *= pixelWidth;
+ scrMax.x *= pixelWidth;
+ scrMin.y *= pixelHeight;
+ scrMax.y *= pixelHeight;
+
+ if (distance < nearClipPlane) {
+ distance = nearClipPlane + 0.01f;
+ }
+ scrMin.z = scrMax.z = distance;
+ if (outline > 0) {
+ BuildMatrix(cam, scrMin, scrMax, (int)(10 + 20 * outlineWidth + 5 * outlineDownsampling), ref quadOutlineMatrix, ref shift);
+ }
+ if (glow > 0) {
+ BuildMatrix(cam, scrMin, scrMax, (int)(20 + 30 * glowWidth + 10 * glowDownsampling), ref quadGlowMatrix, ref shift);
+ }
+ return true;
+ }
+
+ void BuildMatrix(Camera cam, Vector3 scrMin, Vector3 scrMax, int border, ref Matrix4x4 quadMatrix, ref Vector3 shift) {
+
+ // Insert padding to make room for effects
+ scrMin.x -= border;
+ scrMin.y -= border;
+ scrMax.x += border;
+ scrMax.y += border;
+
+ // Back to world space
+ Vector3 third = new Vector3(scrMax.x, scrMin.y, scrMin.z);
+ scrMin = cam.ScreenToWorldPoint(scrMin);
+ scrMax = cam.ScreenToWorldPoint(scrMax);
+ third = cam.ScreenToWorldPoint(third);
+
+ float width = Vector3.Distance(scrMin, third);
+ float height = Vector3.Distance(scrMax, third);
+
+ quadMatrix = Matrix4x4.TRS((scrMin + scrMax) * 0.5f + shift, cam.transform.rotation, new Vector3(width, height, 1f));
+ }
+
+ void SmoothGlow(int rtWidth, int rtHeight) {
+ const int blurPasses = 4;
+
+ // Blur buffers
+ int bufferCount = blurPasses * 2;
+ if (mipGlowBuffers == null || mipGlowBuffers.Length != bufferCount) {
+ mipGlowBuffers = new int[bufferCount];
+ for (int k = 0; k < bufferCount; k++) {
+ mipGlowBuffers[k] = Shader.PropertyToID("_HPSmoothGlowTemp" + k);
+ }
+ glowRT = Shader.PropertyToID("_HPComposeGlowFinal");
+ mipGlowBuffers[bufferCount - 2] = glowRT;
+ }
+ RenderTextureDescriptor glowDesc = sourceDesc;
+ glowDesc.depthBufferBits = 0;
+
+ for (int k = 0; k < bufferCount; k++) {
+ float reduction = k / 2 + 2;
+ int reducedWidth = (int)(rtWidth / reduction);
+ int reducedHeight = (int)(rtHeight / reduction);
+ if (reducedWidth <= 0) {
+ reducedWidth = 1;
+ }
+ if (reducedHeight <= 0) {
+ reducedHeight = 1;
+ }
+ glowDesc.width = reducedWidth;
+ glowDesc.height = reducedHeight;
+ cbSmoothBlend.GetTemporaryRT(mipGlowBuffers[k], glowDesc, FilterMode.Bilinear);
+ }
+
+ Material matBlur = fxMatBlurGlow;
+
+ for (int k = 0; k < bufferCount - 1; k += 2) {
+ if (k == 0) {
+ cbSmoothBlend.Blit(sourceRT, mipGlowBuffers[k + 1], matBlur, 0);
+ } else {
+ cbSmoothBlend.Blit(mipGlowBuffers[k], mipGlowBuffers[k + 1], matBlur, 0);
+ }
+ cbSmoothBlend.Blit(mipGlowBuffers[k + 1], mipGlowBuffers[k], matBlur, 1);
+
+ if (k < bufferCount - 2) {
+ cbSmoothBlend.Blit(mipGlowBuffers[k], mipGlowBuffers[k + 2], matBlur, 2);
+ }
+ }
+ }
+
+ void SmoothOutline(int rtWidth, int rtHeight) {
+ const int blurPasses = 2;
+
+ // Blur buffers
+ int bufferCount = blurPasses * 2;
+ if (mipOutlineBuffers == null || mipOutlineBuffers.Length != bufferCount) {
+ mipOutlineBuffers = new int[bufferCount];
+ for (int k = 0; k < bufferCount; k++) {
+ mipOutlineBuffers[k] = Shader.PropertyToID("_HPSmoothOutlineTemp" + k);
+ }
+ outlineRT = Shader.PropertyToID("_HPComposeOutlineFinal");
+ mipOutlineBuffers[bufferCount - 2] = outlineRT;
+ }
+ RenderTextureDescriptor outlineDesc = sourceDesc;
+ outlineDesc.depthBufferBits = 0;
+
+ for (int k = 0; k < bufferCount; k++) {
+ float reduction = k / 2 + 2;
+ int reducedWidth = (int)(rtWidth / reduction);
+ int reducedHeight = (int)(rtHeight / reduction);
+ if (reducedWidth <= 0) {
+ reducedWidth = 1;
+ }
+ if (reducedHeight <= 0) {
+ reducedHeight = 1;
+ }
+ outlineDesc.width = reducedWidth;
+ outlineDesc.height = reducedHeight;
+ cbSmoothBlend.GetTemporaryRT(mipOutlineBuffers[k], outlineDesc, FilterMode.Bilinear);
+ }
+
+ Material matBlur = fxMatBlurOutline;
+ for (int k = 0; k < bufferCount - 1; k += 2) {
+ if (k == 0) {
+ cbSmoothBlend.Blit(sourceRT, mipOutlineBuffers[k + 1], matBlur, 0);
+ } else {
+ cbSmoothBlend.Blit(mipOutlineBuffers[k], mipOutlineBuffers[k + 1], matBlur, 0);
+ }
+ cbSmoothBlend.Blit(mipOutlineBuffers[k + 1], mipOutlineBuffers[k], matBlur, 1);
+
+ if (k < bufferCount - 2) {
+ cbSmoothBlend.Blit(mipOutlineBuffers[k], mipOutlineBuffers[k + 2], matBlur, 2);
+ }
+ }
+ }
+
+ void ComposeSmoothBlend(Visibility smoothGlowVisibility, Visibility smoothOutlineVisibility) {
+ bool renderSmoothGlow = glow > 0 && glowQuality == QualityLevel.Highest;
+ RenderTargetIdentifier cameraTargetDestination = new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget, 0, CubemapFace.Unknown, -1);
+ if (renderSmoothGlow) {
+ Material matComposeGlow = fxMatComposeGlow;
+ matComposeGlow.SetVector(ShaderParams.Flip, (UnityEngine.XR.XRSettings.enabled && flipY) ? new Vector3(1, -1, 0) : new Vector3(0, 1, 0));
+ if (glowOptimalBlit) {
+ if (Application.isMobilePlatform && smoothGlowVisibility != Visibility.AlwaysOnTop) {
+ cbSmoothBlend.SetRenderTarget(cameraTargetDestination, RenderBufferLoadAction.Load, RenderBufferStoreAction.DontCare);
+ } else {
+ cbSmoothBlend.SetRenderTarget(cameraTargetDestination);
+ }
+ matComposeGlow.SetInt(ShaderParams.ZTest, GetZTestValue(smoothGlowVisibility));
+ matComposeGlow.SetColor(ShaderParams.Debug, glowBlitDebug ? debugColor : blackColor);
+ cbSmoothBlend.DrawMesh(quadMesh, quadGlowMatrix, matComposeGlow, 0, 0);
+ } else {
+ cbSmoothBlend.Blit(glowRT, cameraTargetDestination, matComposeGlow, 1);
+ }
+ }
+ bool renderSmoothOutline = outline > 0 && outlineQuality == QualityLevel.Highest;
+ if (renderSmoothOutline) {
+ Material matComposeOutline = fxMatComposeOutline;
+ matComposeOutline.SetVector(ShaderParams.Flip, (UnityEngine.XR.XRSettings.enabled && flipY) ? new Vector3(1, -1, 0) : new Vector3(0, 1, 0));
+ if (outlineOptimalBlit) {
+ if (Application.isMobilePlatform && smoothOutlineVisibility != Visibility.AlwaysOnTop) {
+ cbSmoothBlend.SetRenderTarget(cameraTargetDestination, RenderBufferLoadAction.Load, RenderBufferStoreAction.DontCare);
+ } else {
+ cbSmoothBlend.SetRenderTarget(cameraTargetDestination);
+ }
+ matComposeOutline.SetInt(ShaderParams.ZTest, GetZTestValue(smoothOutlineVisibility));
+ matComposeOutline.SetColor(ShaderParams.Debug, outlineBlitDebug ? debugColor : blackColor);
+ cbSmoothBlend.DrawMesh(quadMesh, quadOutlineMatrix, matComposeOutline, 0, 0);
+ } else {
+ cbSmoothBlend.Blit(outlineRT, cameraTargetDestination, matComposeOutline, 1);
+ }
+ }
+ // Release render textures
+ if (renderSmoothGlow) {
+ for (int k = 0; k < mipGlowBuffers.Length; k++) {
+ cbSmoothBlend.ReleaseTemporaryRT(mipGlowBuffers[k]);
+ }
+ }
+ if (renderSmoothOutline) {
+ for (int k = 0; k < mipOutlineBuffers.Length; k++) {
+ cbSmoothBlend.ReleaseTemporaryRT(mipOutlineBuffers[k]);
+ }
+ }
+
+ cbSmoothBlend.ReleaseTemporaryRT(sourceRT);
+
+ Graphics.ExecuteCommandBuffer(cbSmoothBlend);
+ }
+
+ void InitMaterial(ref Material material, string shaderName) {
+ if (material == null) {
+ Shader shaderFX = Shader.Find(shaderName);
+ if (shaderFX == null) {
+ Debug.LogError("Shader " + shaderName + " not found.");
+ return;
+ }
+ material = new Material(shaderFX);
+ }
+ }
+
+ ///
+ /// Sets target for highlight effects
+ ///
+ public void SetTarget(Transform transform) {
+ if (transform == target || transform == null)
+ return;
+
+ if (_highlighted) {
+ ImmediateFadeOut();
+ }
+
+ target = transform;
+ SetupMaterial();
+ }
+
+
+ ///
+ /// Sets target for highlight effects and also specify a list of renderers to be included as well
+ ///
+ public void SetTargets(Transform transform, Renderer[] renderers) {
+ if (transform == null)
+ return;
+
+ if (_highlighted) {
+ ImmediateFadeOut();
+ }
+
+ effectGroup = TargetOptions.Scripting;
+ target = transform;
+ SetupMaterial(renderers);
+ }
+
+
+ ///
+ /// Start or finish highlight on the object
+ ///
+ public void SetHighlighted(bool state) {
+
+ if (!Application.isPlaying) {
+ _highlighted = state;
+ return;
+ }
+
+ float now = Time.time;
+
+ if (fading == FadingState.NoFading) {
+ fadeStartTime = now;
+ }
+
+ if (state && !ignore) {
+ if (_highlighted && fading == FadingState.NoFading) {
+ return;
+ }
+ if (OnObjectHighlightStart != null) {
+ if (!OnObjectHighlightStart(gameObject)) {
+ return;
+ }
+ }
+ SendMessage("HighlightStart", null, SendMessageOptions.DontRequireReceiver);
+ highlightStartTime = targetFxStartTime = now;
+ if (fadeInDuration > 0) {
+ if (fading == FadingState.FadingOut) {
+ float remaining = fadeOutDuration - (now - fadeStartTime);
+ fadeStartTime = now - remaining;
+ fadeStartTime = Mathf.Min(fadeStartTime, now);
+ }
+ fading = FadingState.FadingIn;
+ } else {
+ fading = FadingState.NoFading;
+ }
+ _highlighted = true;
+ requireUpdateMaterial = true;
+ } else if (_highlighted) {
+ if (fadeOutDuration > 0) {
+ if (fading == FadingState.FadingIn) {
+ float elapsed = now - fadeStartTime;
+ fadeStartTime = now + elapsed - fadeInDuration;
+ fadeStartTime = Mathf.Min(fadeStartTime, now);
+ }
+ fading = FadingState.FadingOut; // when fade out ends, highlighted will be set to false in OnRenderObject
+ } else {
+ fading = FadingState.NoFading;
+ ImmediateFadeOut();
+ requireUpdateMaterial = true;
+ }
+ }
+ }
+
+ void ImmediateFadeOut() {
+ fading = FadingState.NoFading;
+ _highlighted = false;
+ if (OnObjectHighlightEnd != null) {
+ OnObjectHighlightEnd(gameObject);
+ }
+ SendMessage("HighlightEnd", null, SendMessageOptions.DontRequireReceiver);
+ }
+
+ void SetupMaterial() {
+
+#if UNITY_EDITOR
+ staticChildren = false;
+#endif
+
+ if (target == null || fxMatMask == null)
+ return;
+
+ Renderer[] rr = null;
+ switch (effectGroup) {
+ case TargetOptions.OnlyThisObject:
+ Renderer renderer = target.GetComponent();
+ if (renderer != null) {
+ rr = new Renderer[1];
+ rr[0] = renderer;
+ }
+ break;
+ case TargetOptions.RootToChildren:
+ Transform root = target;
+ while (root.parent != null) {
+ root = root.parent;
+ }
+ rr = root.GetComponentsInChildren();
+ break;
+ case TargetOptions.LayerInScene: {
+ HighlightEffect eg = this;
+ if (target != transform) {
+ HighlightEffect targetEffect = target.GetComponent();
+ if (targetEffect != null) {
+ eg = targetEffect;
+ }
+ }
+ rr = FindRenderersWithLayerInScene(eg.effectGroupLayer);
+ }
+ break;
+ case TargetOptions.LayerInChildren: {
+ HighlightEffect eg = this;
+ if (target != transform) {
+ HighlightEffect targetEffect = target.GetComponent();
+ if (targetEffect != null) {
+ eg = targetEffect;
+ }
+ }
+ rr = FindRenderersWithLayerInChildren(eg.effectGroupLayer);
+ }
+ break;
+ case TargetOptions.Children:
+ rr = target.GetComponentsInChildren();
+ break;
+ case TargetOptions.Scripting:
+ if (rmsCount > 0) return;
+ return;
+ }
+
+ SetupMaterial(rr);
+ }
+
+ void SetupMaterial(Renderer[] rr) {
+
+ if (rr == null) {
+ rr = new Renderer[0];
+ }
+ if (rms == null || rms.Length < rr.Length) {
+ rms = new ModelMaterials[rr.Length];
+ }
+
+ rmsCount = 0;
+ for (int k = 0; k < rr.Length; k++) {
+ rms[rmsCount].Init();
+ Renderer renderer = rr[k];
+ if (renderer == null) continue;
+ if (effectGroup != TargetOptions.OnlyThisObject && !string.IsNullOrEmpty(effectNameFilter)) {
+ if (!renderer.name.Contains(effectNameFilter)) continue;
+ }
+ rms[rmsCount].renderer = renderer;
+ rms[rmsCount].renderWasVisibleDuringSetup = renderer.isVisible;
+
+ if (renderer.transform != target) {
+ HighlightEffect otherEffect = renderer.GetComponent();
+ if (otherEffect != null && otherEffect.enabled && otherEffect.ignore) {
+ continue; // ignore this object
+ }
+ }
+
+ if (OnRendererHighlightStart != null) {
+ if (!OnRendererHighlightStart(renderer)) {
+ rmsCount++;
+ continue;
+ }
+ }
+
+ rms[rmsCount].isCombined = false;
+ bool isSkinnedMesh = renderer is SkinnedMeshRenderer;
+ rms[rmsCount].isSkinnedMesh = isSkinnedMesh;
+ rms[rmsCount].normalsOption = isSkinnedMesh ? NormalsOption.PreserveOriginal : normalsOption;
+ if (rms[rmsCount].preserveOriginalMesh || combineMeshes) {
+ CheckCommandBuffers();
+ }
+ if (isSkinnedMesh) {
+ // ignore cloth skinned renderers
+ rms[rmsCount].mesh = ((SkinnedMeshRenderer)renderer).sharedMesh;
+ } else if (Application.isPlaying && renderer.isPartOfStaticBatch) {
+ // static batched objects need to have a mesh collider in order to use its original mesh
+ MeshCollider mc = renderer.GetComponent();
+ if (mc != null) {
+ rms[rmsCount].mesh = mc.sharedMesh;
+ }
+ } else {
+ MeshFilter mf = renderer.GetComponent();
+ if (mf != null) {
+ rms[rmsCount].mesh = mf.sharedMesh;
+
+#if UNITY_EDITOR
+ if (renderer.gameObject.isStatic && renderer.GetComponent() == null) {
+ staticChildren = true;
+ }
+#endif
+
+ }
+ }
+
+ if (rms[rmsCount].mesh == null) {
+ continue;
+ }
+
+ rms[rmsCount].transform = renderer.transform;
+ Fork(fxMatMask, ref rms[rmsCount].fxMatMask, rms[rmsCount].mesh);
+ Fork(fxMatSeeThroughInner, ref rms[rmsCount].fxMatSeeThroughInner, rms[rmsCount].mesh);
+ Fork(fxMatSeeThroughBorder, ref rms[rmsCount].fxMatSeeThroughBorder, rms[rmsCount].mesh);
+ Fork(fxMatOverlay, ref rms[rmsCount].fxMatOverlay, rms[rmsCount].mesh);
+ Fork(fxMatInnerGlow, ref rms[rmsCount].fxMatInnerGlow, rms[rmsCount].mesh);
+ Fork(fxMatSolidColor, ref rms[rmsCount].fxMatSolidColor, rms[rmsCount].mesh);
+ rms[rmsCount].originalMesh = rms[rmsCount].mesh;
+ if (!rms[rmsCount].preserveOriginalMesh) {
+ if (innerGlow > 0 || (glow > 0 && glowQuality != QualityLevel.Highest) || (outline > 0 && outlineQuality != QualityLevel.Highest)) {
+ if (normalsOption == NormalsOption.Reorient || normalsOption == NormalsOption.Planar) {
+ ReorientNormals(rmsCount);
+ } else {
+ AverageNormals(rmsCount);
+ }
+ }
+ // check if scale is negative
+ BakeTransform(rmsCount, true);
+ }
+ rmsCount++;
+ }
+
+#if UNITY_EDITOR
+ // Avoids command buffer issue when refreshing asset inside the Editor
+ if (!Application.isPlaying) {
+ mipGlowBuffers = null;
+ mipOutlineBuffers = null;
+ }
+#endif
+
+ if (combineMeshes) {
+ CombineMeshes();
+ }
+
+ UpdateMaterialPropertiesNow();
+ }
+
+ readonly List tempRR = new List();
+
+ Renderer[] FindRenderersWithLayerInScene(LayerMask layer) {
+ Renderer[] rr = FindObjectsOfType();
+ tempRR.Clear();
+ for (var i = 0; i < rr.Length; i++) {
+ Renderer r = rr[i];
+ if (((1 << r.gameObject.layer) & layer) != 0) {
+ tempRR.Add(r);
+ }
+ }
+ return tempRR.ToArray();
+ }
+
+ Renderer[] FindRenderersWithLayerInChildren(LayerMask layer) {
+ Renderer[] rr = target.GetComponentsInChildren();
+ tempRR.Clear();
+ for (var i = 0; i < rr.Length; i++) {
+ Renderer r = rr[i];
+ if (((1 << r.gameObject.layer) & layer) != 0) {
+ tempRR.Add(r);
+ }
+ }
+ return tempRR.ToArray();
+ }
+
+ void CheckGeometrySupportDependencies() {
+ InitMaterial(ref fxMatMask, "HighlightPlus/Geometry/Mask");
+ InitMaterial(ref fxMatOverlay, "HighlightPlus/Geometry/Overlay");
+ InitMaterial(ref fxMatSeeThroughInner, "HighlightPlus/Geometry/SeeThroughInner");
+ InitMaterial(ref fxMatSeeThroughBorder, "HighlightPlus/Geometry/SeeThroughBorder");
+ InitMaterial(ref fxMatSeeThroughMask, "HighlightPlus/Geometry/SeeThroughMask");
+ InitMaterial(ref fxMatSolidColor, "HighlightPlus/Geometry/SolidColor");
+ InitMaterial(ref fxMatClearStencil, "HighlightPlus/ClearStencil");
+ InitMaterial(ref fxMatOutlineRef, "HighlightPlus/Geometry/Outline");
+ InitMaterial(ref fxMatGlowRef, "HighlightPlus/Geometry/Glow");
+ InitMaterial(ref fxMatInnerGlow, "HighlightPlus/Geometry/InnerGlow");
+ InitMaterial(ref fxMatTargetRef, "HighlightPlus/Geometry/Target");
+ InitMaterial(ref fxMatComposeOutlineRef, "HighlightPlus/Geometry/ComposeOutline");
+ InitMaterial(ref fxMatComposeGlowRef, "HighlightPlus/Geometry/ComposeGlow");
+ InitMaterial(ref fxMatBlurOutlineRef, "HighlightPlus/Geometry/BlurOutline");
+ InitMaterial(ref fxMatBlurGlowRef, "HighlightPlus/Geometry/BlurGlow");
+ CheckRequiredCommandBuffers();
+ }
+
+ void CheckRequiredCommandBuffers() {
+ if (cbGlow == null) {
+ cbGlow = new CommandBuffer();
+ cbGlow.name = "Outer Glow for " + name;
+ }
+ if (cbSeeThrough == null) {
+ cbSeeThrough = new CommandBuffer();
+ cbSeeThrough.name = "See Through for " + name;
+ }
+ }
+
+ void CheckCommandBuffers() {
+ if (cbMask == null) {
+ cbMask = new CommandBuffer();
+ cbMask.name = "Mask for " + name;
+ }
+ if (cbOutline == null) {
+ cbOutline = new CommandBuffer();
+ cbOutline.name = "Outline for " + name;
+ }
+ if (cbOverlay == null) {
+ cbOverlay = new CommandBuffer();
+ cbOverlay.name = "Overlay for " + name;
+ }
+ if (cbInnerGlow == null) {
+ cbInnerGlow = new CommandBuffer();
+ cbInnerGlow.name = "Inner Glow for " + name;
+ }
+ }
+
+ void CheckBlurCommandBuffer() {
+ if (cbSmoothBlend == null) {
+ cbSmoothBlend = new CommandBuffer();
+ cbSmoothBlend.name = "Smooth Blend for " + name;
+ }
+ }
+
+ void Fork(Material mat, ref Material[] mats, Mesh mesh) {
+ if (mesh == null)
+ return;
+ int count = mesh.subMeshCount;
+ if (mats == null || mats.Length < count) {
+ DestroyMaterialArray(mats);
+ mats = new Material[count];
+ }
+ for (int k = 0; k < count; k++) {
+ if (mats[k] == null) {
+ mats[k] = Instantiate(mat);
+ }
+ }
+ }
+
+ void BakeTransform(int objIndex, bool duplicateMesh) {
+ if (rms[objIndex].mesh == null)
+ return;
+ Transform t = rms[objIndex].transform;
+ Vector3 scale = t.localScale;
+ if (scale.x >= 0 && scale.y >= 0 && scale.z >= 0) {
+ rms[objIndex].bakedTransform = false;
+ return;
+ }
+ // Duplicates mesh and bake rotation
+ Mesh fixedMesh = duplicateMesh ? Instantiate(rms[objIndex].originalMesh) : rms[objIndex].mesh;
+ Vector3[] vertices = fixedMesh.vertices;
+ for (int k = 0; k < vertices.Length; k++) {
+ vertices[k] = t.TransformPoint(vertices[k]);
+ }
+ fixedMesh.vertices = vertices;
+ Vector3[] normals = fixedMesh.normals;
+ if (normals != null) {
+ for (int k = 0; k < normals.Length; k++) {
+ normals[k] = t.TransformVector(normals[k]).normalized;
+ }
+ fixedMesh.normals = normals;
+ }
+ fixedMesh.RecalculateBounds();
+ rms[objIndex].mesh = fixedMesh;
+ rms[objIndex].bakedTransform = true;
+ rms[objIndex].currentPosition = t.position;
+ rms[objIndex].currentRotation = t.eulerAngles;
+ rms[objIndex].currentScale = t.lossyScale;
+ }
+
+ public void UpdateMaterialProperties(bool forceNow = false) {
+ if (forceNow || !Application.isPlaying) {
+ requireUpdateMaterial = false;
+ UpdateMaterialPropertiesNow();
+ } else {
+ requireUpdateMaterial = true;
+ }
+ }
+
+
+ void UpdateMaterialPropertiesNow() {
+
+ if (rms == null)
+ return;
+
+ if (ignore) {
+ _highlighted = false;
+ }
+
+ maskRequired = (_highlighted && (outline > 0 || (glow > 0 && !glowIgnoreMask))) || seeThrough != SeeThroughMode.Never || (targetFX && targetFXAlignToGround);
+
+ Color seeThroughTintColor = this.seeThroughTintColor;
+ seeThroughTintColor.a = this.seeThroughTintAlpha;
+
+ if (lastOutlineVisibility != outlineVisibility) {
+ // change by scripting?
+ if (glowQuality == QualityLevel.Highest && outlineQuality == QualityLevel.Highest) {
+ glowVisibility = outlineVisibility;
+ }
+ lastOutlineVisibility = outlineVisibility;
+ }
+ if (outlineWidth < 0) {
+ outlineWidth = 0;
+ }
+ if (outlineQuality == QualityLevel.Medium) {
+ outlineOffsetsMin = 4; outlineOffsetsMax = 7;
+ } else if (outlineQuality == QualityLevel.High) {
+ outlineOffsetsMin = 0; outlineOffsetsMax = 7;
+ } else {
+ outlineOffsetsMin = outlineOffsetsMax = 0;
+ }
+ if (glowWidth < 0) {
+ glowWidth = 0;
+ }
+ if (glowQuality == QualityLevel.Medium) {
+ glowOffsetsMin = 4; glowOffsetsMax = 7;
+ } else if (glowQuality == QualityLevel.High) {
+ glowOffsetsMin = 0; glowOffsetsMax = 7;
+ } else {
+ glowOffsetsMin = glowOffsetsMax = 0;
+ }
+ if (targetFXTransitionDuration <= 0) {
+ targetFXTransitionDuration = 0.0001f;
+ }
+ if (targetFXStayDuration <= 0) {
+ targetFXStayDuration = 0;
+ }
+ if (seeThroughDepthOffset < 0) {
+ seeThroughDepthOffset = 0;
+ }
+ if (seeThroughMaxDepth < 0) {
+ seeThroughMaxDepth = 0;
+ }
+ if (seeThroughBorderWidth < 0) {
+ seeThroughBorderWidth = 0;
+ }
+ if (targetFXFadePower < 0) {
+ targetFXFadePower = 0;
+ }
+
+ // Setup materials
+
+ // Outline
+ float scaledOutlineWidth = (outlineQuality == QualityLevel.High || normalsOption == NormalsOption.Planar) ? 0f : outlineWidth / 100f;
+ Material matOutline = fxMatOutline;
+ matOutline.SetFloat(ShaderParams.OutlineWidth, scaledOutlineWidth);
+ matOutline.SetFloat(ShaderParams.OutlineVertexWidth, normalsOption == NormalsOption.Planar ? outlineWidth / 100f : 0);
+ matOutline.SetVector(ShaderParams.OutlineDirection, Vector3.zero);
+ matOutline.SetInt(ShaderParams.OutlineZTest, GetZTestValue(outlineVisibility));
+ matOutline.SetInt(ShaderParams.Cull, cullBackFaces ? (int)CullMode.Back : (int)CullMode.Off);
+ matOutline.SetFloat(ShaderParams.ConstantWidth, constantWidth ? 1.0f : 0);
+ bool useSmoothOutline = outline > 0 && outlineQuality == QualityLevel.Highest;
+ if (useSmoothOutline) {
+ CheckBlurCommandBuffer();
+ fxMatComposeOutline.SetInt(ShaderParams.Cull, cullBackFaces ? (int)CullMode.Back : (int)CullMode.Off);
+ fxMatBlurOutline.SetFloat(ShaderParams.BlurScale, outlineWidth / outlineDownsampling);
+ }
+ matOutline.DisableKeyword(ShaderParams.SKW_OUTLINE_GRADIENT_WS);
+ matOutline.DisableKeyword(ShaderParams.SKW_OUTLINE_GRADIENT_LS);
+ if (outlineColorStyle == ColorStyle.Gradient) {
+ const int OUTLINE_GRADIENT_TEX_SIZE = 32;
+ bool requiresUpdate = false;
+ if (outlineGradientTex == null) {
+ outlineGradientTex = new Texture2D(OUTLINE_GRADIENT_TEX_SIZE, 1, TextureFormat.RGBA32, mipChain: false, linear: true);
+ outlineGradientTex.wrapMode = TextureWrapMode.Clamp;
+ requiresUpdate = true;
+ }
+ if (outlineGradientColors == null || outlineGradientColors.Length != OUTLINE_GRADIENT_TEX_SIZE) {
+ outlineGradientColors = new Color[OUTLINE_GRADIENT_TEX_SIZE];
+ requiresUpdate = true;
+ }
+ for (int k = 0; k < OUTLINE_GRADIENT_TEX_SIZE; k++) {
+ float t = (float)k / OUTLINE_GRADIENT_TEX_SIZE;
+ Color color = outlineGradient.Evaluate(t);
+ if (color != outlineGradientColors[k]) {
+ outlineGradientColors[k] = color;
+ requiresUpdate = true;
+ }
+ }
+ if (requiresUpdate) {
+ outlineGradientTex.SetPixels(outlineGradientColors);
+ outlineGradientTex.Apply();
+ }
+ matOutline.SetTexture(ShaderParams.OutlineGradientTex, outlineGradientTex);
+ matOutline.EnableKeyword(outlineGradientInLocalSpace ? ShaderParams.SKW_OUTLINE_GRADIENT_LS : ShaderParams.SKW_OUTLINE_GRADIENT_WS);
+ }
+
+ // Outer Glow
+ Material matGlow = fxMatGlow;
+ matGlow.SetVector(ShaderParams.Glow2, new Vector4(normalsOption == NormalsOption.Planar ? 0 : outlineWidth / 100f, glowAnimationSpeed, glowDithering ? 0 : 1, 0));
+ matGlow.SetInt(ShaderParams.GlowZTest, GetZTestValue(glowVisibility));
+ matGlow.SetInt(ShaderParams.Cull, cullBackFaces ? (int)CullMode.Back : (int)CullMode.Off);
+ matGlow.SetFloat(ShaderParams.ConstantWidth, constantWidth ? 1.0f : 0);
+ matGlow.SetInt(ShaderParams.GlowStencilOp, glowBlendPasses ? (int)StencilOp.Keep : (int)StencilOp.Replace);
+ matGlow.SetInt(ShaderParams.GlowStencilComp, glowIgnoreMask ? (int)CompareFunction.Always : (int)CompareFunction.NotEqual);
+
+ bool useSmoothGlow = glow > 0 && glowQuality == QualityLevel.Highest;
+ if (useSmoothGlow) {
+ CheckBlurCommandBuffer();
+ fxMatComposeGlow.SetInt(ShaderParams.Cull, cullBackFaces ? (int)CullMode.Back : (int)CullMode.Off);
+ fxMatComposeGlow.SetInt(ShaderParams.GlowStencilComp, glowIgnoreMask ? (int)CompareFunction.Always : (int)CompareFunction.NotEqual);
+ if (glowBlendMode == GlowBlendMode.Additive) {
+ fxMatComposeGlow.SetInt(ShaderParams.BlendSrc, (int)BlendMode.One);
+ fxMatComposeGlow.SetInt(ShaderParams.BlendDst, (int)BlendMode.One);
+ } else {
+ fxMatComposeGlow.SetInt(ShaderParams.BlendSrc, (int)BlendMode.SrcAlpha);
+ fxMatComposeGlow.SetInt(ShaderParams.BlendDst, (int)BlendMode.OneMinusSrcAlpha);
+ }
+ fxMatBlurGlow.SetFloat(ShaderParams.BlurScale, glowWidth / glowDownsampling);
+ fxMatBlurGlow.SetFloat(ShaderParams.Speed, glowAnimationSpeed);
+ }
+ // Target
+ if (targetFX) {
+ if (targetFXTexture == null) {
+ targetFXTexture = Resources.Load("HighlightPlus/target");
+ }
+ fxMatTarget.mainTexture = targetFXTexture;
+ fxMatTarget.SetInt(ShaderParams.ZTest, GetZTestValue(targetFXVisibility));
+ }
+
+ // Per object materials
+ bool renderMaskOnTop = _highlighted && ((outline > 0 && outlineVisibility != Visibility.Normal) || (glow > 0 && glowVisibility != Visibility.Normal) || (innerGlow > 0 && innerGlowVisibility != Visibility.Normal));
+ for (int k = 0; k < rmsCount; k++) {
+
+ if (rms[k].mesh != null) {
+
+ Renderer renderer = rms[k].renderer;
+ if (renderer == null)
+ continue;
+
+ // Mask, See-through & Overlay per submesh
+ for (int l = 0; l < rms[k].mesh.subMeshCount; l++) {
+ if (((1 << l) & subMeshMask) == 0) continue;
+
+ Material mat = null;
+ renderer.GetSharedMaterials(rendererSharedMaterials);
+ if (l < rendererSharedMaterials.Count) {
+ mat = rendererSharedMaterials[l];
+ }
+ if (mat == null)
+ continue;
+
+ bool hasTexture = mat.HasProperty(ShaderParams.MainTex);
+ bool useAlphaTest = alphaCutOff > 0 && hasTexture;
+
+ // Mask
+ if (rms[k].fxMatMask != null && rms[k].fxMatMask.Length > l) {
+ Material fxMat = rms[k].fxMatMask[l];
+ if (fxMat != null) {
+ if (hasTexture) {
+ Texture texture = mat.mainTexture;
+ fxMat.mainTexture = texture;
+ fxMat.mainTextureOffset = mat.mainTextureOffset;
+ fxMat.mainTextureScale = mat.mainTextureScale;
+ }
+ if (useAlphaTest) {
+ fxMat.SetFloat(ShaderParams.CutOff, alphaCutOff);
+ fxMat.EnableKeyword(ShaderParams.SKW_ALPHACLIP);
+ } else {
+ fxMat.DisableKeyword(ShaderParams.SKW_ALPHACLIP);
+ }
+ if (depthClip && !renderMaskOnTop) {
+ fxMat.EnableKeyword(ShaderParams.SKW_DEPTHCLIP);
+ } else {
+ fxMat.DisableKeyword(ShaderParams.SKW_DEPTHCLIP);
+ }
+ fxMat.SetInt(ShaderParams.Cull, cullBackFaces ? (int)CullMode.Back : (int)CullMode.Off);
+ }
+ }
+
+ // See-through inner
+ bool usesSeeThroughBorder = rms[k].fxMatSeeThroughBorder != null && rms[k].fxMatSeeThroughBorder.Length > l && (seeThroughBorder * seeThroughBorderWidth > 0);
+ if (rms[k].fxMatSeeThroughInner != null && rms[k].fxMatSeeThroughInner.Length > l) {
+ Material fxMat = rms[k].fxMatSeeThroughInner[l];
+ if (fxMat != null) {
+ fxMat.SetFloat(ShaderParams.SeeThrough, seeThroughIntensity);
+ fxMat.SetFloat(ShaderParams.SeeThroughNoise, seeThroughNoise);
+ fxMat.SetColor(ShaderParams.SeeThroughTintColor, seeThroughTintColor);
+ if (seeThroughOccluderMaskAccurate && seeThroughOccluderMask != -1) {
+ fxMat.SetInt(ShaderParams.SeeThroughStencilRef, 1);
+ fxMat.SetInt(ShaderParams.SeeThroughStencilComp, (int)CompareFunction.Equal);
+ fxMat.SetInt(ShaderParams.SeeThroughStencilPassOp, (int)StencilOp.Zero);
+ } else {
+ fxMat.SetInt(ShaderParams.SeeThroughStencilRef, 2);
+ fxMat.SetInt(ShaderParams.SeeThroughStencilComp, (int)CompareFunction.Greater);
+ fxMat.SetInt(ShaderParams.SeeThroughStencilPassOp, (int)StencilOp.Replace);
+ }
+ if (seeThroughOrdered) {
+ fxMat.SetInt(ShaderParams.ZTest, (int)CompareFunction.LessEqual);
+ fxMat.SetInt(ShaderParams.SeeThroughOrdered, 1);
+ } else {
+ fxMat.SetInt(ShaderParams.ZTest, (int)CompareFunction.Greater);
+ fxMat.SetInt(ShaderParams.SeeThroughOrdered, 0);
+ }
+ if (hasTexture) {
+ Texture texture = mat.mainTexture;
+ fxMat.mainTexture = texture;
+ fxMat.mainTextureOffset = mat.mainTextureOffset;
+ fxMat.mainTextureScale = mat.mainTextureScale;
+ }
+ if (useAlphaTest) {
+ fxMat.SetFloat(ShaderParams.CutOff, alphaCutOff);
+ fxMat.EnableKeyword(ShaderParams.SKW_ALPHACLIP);
+ } else {
+ fxMat.DisableKeyword(ShaderParams.SKW_ALPHACLIP);
+ }
+ if (seeThroughDepthOffset > 0 || seeThroughMaxDepth > 0) {
+ fxMat.SetFloat(ShaderParams.SeeThroughDepthOffset, seeThroughDepthOffset > 0 ? seeThroughDepthOffset : -1);
+ fxMat.SetFloat(ShaderParams.SeeThroughMaxDepth, seeThroughMaxDepth > 0 ? seeThroughMaxDepth : 999999);
+ fxMat.EnableKeyword(ShaderParams.SKW_DEPTH_OFFSET);
+ } else {
+ fxMat.DisableKeyword(ShaderParams.SKW_DEPTH_OFFSET);
+ }
+ if (seeThroughBorderOnly) {
+ fxMat.EnableKeyword(ShaderParams.SKW_SEETHROUGH_ONLY_BORDER);
+ } else {
+ fxMat.DisableKeyword(ShaderParams.SKW_SEETHROUGH_ONLY_BORDER);
+ }
+
+ fxMat.DisableKeyword(ShaderParams.SKW_TEXTURE_TRIPLANAR);
+ fxMat.DisableKeyword(ShaderParams.SKW_TEXTURE_OBJECTSPACE);
+ fxMat.DisableKeyword(ShaderParams.SKW_TEXTURE_SCREENSPACE);
+ if (seeThroughTexture != null) {
+ fxMat.SetTexture(ShaderParams.SeeThroughTexture, seeThroughTexture);
+ fxMat.SetFloat(ShaderParams.SeeThroughTextureScale, seeThroughTextureScale);
+ switch (seeThroughTextureUVSpace) {
+ case TextureUVSpace.ScreenSpace:
+ fxMat.EnableKeyword(ShaderParams.SKW_TEXTURE_SCREENSPACE);
+ break;
+ case TextureUVSpace.ObjectSpace:
+ fxMat.EnableKeyword(ShaderParams.SKW_TEXTURE_OBJECTSPACE);
+ break;
+ default:
+ fxMat.EnableKeyword(ShaderParams.SKW_TEXTURE_TRIPLANAR);
+ break;
+ }
+ }
+
+ }
+ }
+
+ // See-through border
+ if (usesSeeThroughBorder) {
+ Material fxMat = rms[k].fxMatSeeThroughBorder[l];
+ if (fxMat != null) {
+ fxMat.SetColor(ShaderParams.SeeThroughBorderColor, new Color(seeThroughBorderColor.r, seeThroughBorderColor.g, seeThroughBorderColor.b, seeThroughBorder));
+ fxMat.SetFloat(ShaderParams.SeeThroughBorderWidth, (seeThroughBorder * seeThroughBorderWidth) > 0 ? seeThroughBorderWidth / 100f : 0);
+ fxMat.SetFloat(ShaderParams.SeeThroughBorderConstantWidth, constantWidth ? 1.0f : 0);
+ if (seeThroughOccluderMaskAccurate && seeThroughOccluderMask != -1) {
+ fxMat.SetInt(ShaderParams.SeeThroughStencilRef, 1);
+ fxMat.SetInt(ShaderParams.SeeThroughStencilComp, (int)CompareFunction.Equal);
+ fxMat.SetInt(ShaderParams.SeeThroughStencilPassOp, (int)StencilOp.Zero);
+ } else {
+ fxMat.SetInt(ShaderParams.SeeThroughStencilRef, 2);
+ fxMat.SetInt(ShaderParams.SeeThroughStencilComp, (int)CompareFunction.Greater);
+ fxMat.SetInt(ShaderParams.SeeThroughStencilPassOp, (int)StencilOp.Replace);
+ }
+ if (seeThroughOrdered) {
+ fxMat.SetInt(ShaderParams.ZTest, (int)CompareFunction.LessEqual);
+ fxMat.SetInt(ShaderParams.SeeThroughOrdered, 1);
+ } else {
+ fxMat.SetInt(ShaderParams.ZTest, (int)CompareFunction.Greater);
+ fxMat.SetInt(ShaderParams.SeeThroughOrdered, 0);
+ }
+ if (hasTexture) {
+ Texture texture = mat.mainTexture;
+ fxMat.mainTexture = texture;
+ fxMat.mainTextureOffset = mat.mainTextureOffset;
+ fxMat.mainTextureScale = mat.mainTextureScale;
+ }
+ if (useAlphaTest) {
+ fxMat.SetFloat(ShaderParams.CutOff, alphaCutOff);
+ fxMat.EnableKeyword(ShaderParams.SKW_ALPHACLIP);
+ } else {
+ fxMat.DisableKeyword(ShaderParams.SKW_ALPHACLIP);
+ }
+ if (seeThroughDepthOffset > 0 || seeThroughMaxDepth > 0) {
+ fxMat.SetFloat(ShaderParams.SeeThroughDepthOffset, seeThroughDepthOffset > 0 ? seeThroughDepthOffset : -1);
+ fxMat.SetFloat(ShaderParams.SeeThroughMaxDepth, seeThroughMaxDepth > 0 ? seeThroughMaxDepth : 999999);
+ fxMat.EnableKeyword(ShaderParams.SKW_DEPTH_OFFSET);
+ } else {
+ fxMat.DisableKeyword(ShaderParams.SKW_DEPTH_OFFSET);
+ }
+ }
+ }
+
+ // Overlay
+ if (rms[k].fxMatOverlay != null && rms[k].fxMatOverlay.Length > l) {
+ Material fxMat = rms[k].fxMatOverlay[l];
+ if (fxMat != null) {
+ if (hasTexture) {
+ Texture texture = mat.mainTexture;
+ fxMat.mainTexture = texture;
+ fxMat.mainTextureOffset = mat.mainTextureOffset;
+ fxMat.mainTextureScale = mat.mainTextureScale;
+ }
+ if (mat.HasProperty(ShaderParams.Color)) {
+ fxMat.SetColor(ShaderParams.OverlayBackColor, mat.GetColor(ShaderParams.Color));
+ }
+ fxMat.SetInt(ShaderParams.Cull, cullBackFaces ? (int)CullMode.Back : (int)CullMode.Off);
+
+ fxMat.DisableKeyword(ShaderParams.SKW_TEXTURE_TRIPLANAR);
+ fxMat.DisableKeyword(ShaderParams.SKW_TEXTURE_OBJECTSPACE);
+ fxMat.DisableKeyword(ShaderParams.SKW_TEXTURE_SCREENSPACE);
+ if (overlayTexture != null) {
+ fxMat.SetTexture(ShaderParams.OverlayTexture, overlayTexture);
+ switch (overlayTextureUVSpace) {
+ case TextureUVSpace.ScreenSpace:
+ fxMat.EnableKeyword(ShaderParams.SKW_TEXTURE_SCREENSPACE);
+ break;
+ case TextureUVSpace.ObjectSpace:
+ fxMat.EnableKeyword(ShaderParams.SKW_TEXTURE_OBJECTSPACE);
+ break;
+ default:
+ fxMat.EnableKeyword(ShaderParams.SKW_TEXTURE_TRIPLANAR);
+ break;
+ }
+ }
+
+ if (useAlphaTest) {
+ fxMat.SetFloat(ShaderParams.CutOff, alphaCutOff);
+ fxMat.EnableKeyword(ShaderParams.SKW_ALPHACLIP);
+ } else {
+ fxMat.DisableKeyword(ShaderParams.SKW_ALPHACLIP);
+ }
+ }
+ }
+
+ // Inner Glow
+ if (rms[k].fxMatInnerGlow != null && rms[k].fxMatInnerGlow.Length > l) {
+ Material fxMat = rms[k].fxMatInnerGlow[l];
+ if (fxMat != null) {
+ if (hasTexture) {
+ Texture texture = mat.mainTexture;
+ fxMat.mainTexture = texture;
+ fxMat.mainTextureOffset = mat.mainTextureOffset;
+ fxMat.mainTextureScale = mat.mainTextureScale;
+ }
+ fxMat.SetFloat(ShaderParams.InnerGlowWidth, innerGlowWidth);
+ fxMat.SetInt(ShaderParams.InnerGlowZTest, GetZTestValue(innerGlowVisibility));
+ fxMat.SetInt(ShaderParams.Cull, cullBackFaces ? (int)CullMode.Back : (int)CullMode.Off);
+ if (useAlphaTest) {
+ fxMat.SetFloat(ShaderParams.CutOff, alphaCutOff);
+ fxMat.EnableKeyword(ShaderParams.SKW_ALPHACLIP);
+ } else {
+ fxMat.DisableKeyword(ShaderParams.SKW_ALPHACLIP);
+ }
+ }
+ }
+
+ // Solid Color for smooth glow
+ if (rms[k].fxMatSolidColor != null && rms[k].fxMatSolidColor.Length > l) {
+ Material fxMat = rms[k].fxMatSolidColor[l];
+ if (fxMat != null) {
+ fxMat.color = glowHQColor;
+ fxMat.SetInt(ShaderParams.Cull, cullBackFaces ? (int)CullMode.Back : (int)CullMode.Off);
+ fxMat.SetInt(ShaderParams.ZTest, GetZTestValue(useSmoothGlow ? glowVisibility : outlineVisibility));
+ if (hasTexture) {
+ Texture texture = mat.mainTexture;
+ fxMat.mainTexture = texture;
+ fxMat.mainTextureOffset = mat.mainTextureOffset;
+ fxMat.mainTextureScale = mat.mainTextureScale;
+ }
+ if (useAlphaTest) {
+ fxMat.SetFloat(ShaderParams.CutOff, alphaCutOff);
+ fxMat.EnableKeyword(ShaderParams.SKW_ALPHACLIP);
+ } else {
+ fxMat.DisableKeyword(ShaderParams.SKW_ALPHACLIP);
+ }
+ if (depthClip && !renderMaskOnTop) {
+ fxMat.EnableKeyword(ShaderParams.SKW_DEPTHCLIP);
+ } else {
+ fxMat.DisableKeyword(ShaderParams.SKW_DEPTHCLIP);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ float ComputeCameraDistanceFade(Vector3 position, Transform cameraTransform) {
+ Vector3 heading = position - cameraTransform.position;
+ float distance = Vector3.Dot(heading, cameraTransform.forward);
+ if (distance < cameraDistanceFadeNear) {
+ return 1f - Mathf.Min(1f, cameraDistanceFadeNear - distance);
+ }
+ if (distance > cameraDistanceFadeFar) {
+ return 1f - Mathf.Min(1f, distance - cameraDistanceFadeFar);
+ }
+ return 1f;
+ }
+
+ int GetZTestValue(Visibility param) {
+ switch (param) {
+ case Visibility.AlwaysOnTop:
+ return (int)CompareFunction.Always;
+ case Visibility.OnlyWhenOccluded:
+ return (int)CompareFunction.Greater;
+ default:
+ return (int)CompareFunction.LessEqual;
+ }
+ }
+
+ void BuildQuad() {
+ quadMesh = new Mesh();
+
+ // Setup vertices
+ Vector3[] newVertices = new Vector3[4];
+ float halfHeight = 0.5f;
+ float halfWidth = 0.5f;
+ newVertices[0] = new Vector3(-halfWidth, -halfHeight, 0);
+ newVertices[1] = new Vector3(-halfWidth, halfHeight, 0);
+ newVertices[2] = new Vector3(halfWidth, -halfHeight, 0);
+ newVertices[3] = new Vector3(halfWidth, halfHeight, 0);
+
+ // Setup UVs
+ Vector2[] newUVs = new Vector2[newVertices.Length];
+ newUVs[0] = new Vector2(0, 0);
+ newUVs[1] = new Vector2(0, 1);
+ newUVs[2] = new Vector2(1, 0);
+ newUVs[3] = new Vector2(1, 1);
+
+ // Setup triangles
+ int[] newTriangles = { 0, 1, 2, 3, 2, 1 };
+
+ // Setup normals
+ Vector3[] newNormals = new Vector3[newVertices.Length];
+ for (int i = 0; i < newNormals.Length; i++) {
+ newNormals[i] = Vector3.forward;
+ }
+
+ // Create quad
+ quadMesh.vertices = newVertices;
+ quadMesh.uv = newUVs;
+ quadMesh.triangles = newTriangles;
+ quadMesh.normals = newNormals;
+
+ quadMesh.RecalculateBounds();
+ }
+
+ void BuildCube() {
+ cubeMesh = Resources.GetBuiltinResource("Cube.fbx");
+ }
+
+
+ ///
+ /// Returns true if a given transform is included in this effect
+ ///
+ public bool Includes(Transform transform) {
+ for (int k = 0; k < rmsCount; k++) {
+ if (rms[k].transform == transform) return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Updates profile glow color
+ ///
+ public void SetGlowColor(Color color) {
+ if (glowPasses != null) {
+ for (int k = 0; k < glowPasses.Length; k++) {
+ glowPasses[k].color = color;
+ }
+ }
+ glowHQColor = color;
+ UpdateMaterialProperties();
+ }
+
+
+ #region Normals handling
+
+ static List vertices;
+ static List normals;
+ static Vector3[] newNormals;
+ static int[] matches;
+ static readonly Dictionary vv = new Dictionary();
+ static readonly List rendererSharedMaterials = new List();
+
+ // cached meshes
+ static readonly Dictionary smoothMeshes = new Dictionary();
+ static readonly Dictionary reorientedMeshes = new Dictionary();
+ static readonly Dictionary combinedMeshes = new Dictionary();
+ int combinedMeshesHashId;
+
+ // annotate usage count of the instanced meshes due to normals or combine mesh option
+ // when highlighte effect is destroyed and the usage count is zero, we destroy the cached mesh
+ static readonly Dictionary sharedMeshUsage = new Dictionary();
+ readonly List instancedMeshes = new List();
+
+ void AverageNormals(int objIndex) {
+ if (rms == null || objIndex >= rms.Length) return;
+ Mesh mesh = rms[objIndex].mesh;
+
+ Mesh newMesh;
+ int hashCode = mesh.GetHashCode();
+ if (!smoothMeshes.TryGetValue(hashCode, out newMesh) || newMesh == null) {
+ if (!mesh.isReadable) return;
+ if (normals == null) {
+ normals = new List();
+ } else {
+ normals.Clear();
+ }
+ mesh.GetNormals(normals);
+ int normalsCount = normals.Count;
+ if (normalsCount == 0)
+ return;
+ if (vertices == null) {
+ vertices = new List();
+ } else {
+ vertices.Clear();
+ }
+ mesh.GetVertices(vertices);
+ int vertexCount = vertices.Count;
+ if (normalsCount < vertexCount) {
+ vertexCount = normalsCount;
+ }
+ if (newNormals == null || newNormals.Length < vertexCount) {
+ newNormals = new Vector3[vertexCount];
+ } else {
+ Vector3 zero = Vector3.zero;
+ for (int k = 0; k < vertexCount; k++) {
+ newNormals[k] = zero;
+ }
+ }
+ if (matches == null || matches.Length < vertexCount) {
+ matches = new int[vertexCount];
+ }
+ // Locate overlapping vertices
+ vv.Clear();
+ for (int k = 0; k < vertexCount; k++) {
+ int i;
+ Vector3 v = vertices[k];
+ if (!vv.TryGetValue(v, out i)) {
+ vv[v] = i = k;
+ }
+ matches[k] = i;
+ }
+ // Average normals
+ for (int k = 0; k < vertexCount; k++) {
+ int match = matches[k];
+ newNormals[match] += normals[k];
+ }
+ for (int k = 0; k < vertexCount; k++) {
+ int match = matches[k];
+ normals[k] = newNormals[match].normalized;
+ }
+ // Reassign normals
+ newMesh = Instantiate(mesh);
+ newMesh.SetNormals(normals);
+ smoothMeshes[hashCode] = newMesh;
+ IncrementeMeshUsage(newMesh);
+ }
+ rms[objIndex].mesh = newMesh;
+ }
+
+
+ void ReorientNormals(int objIndex) {
+ if (rms == null || objIndex >= rms.Length) return;
+ Mesh mesh = rms[objIndex].mesh;
+
+ Mesh newMesh;
+ int hashCode = mesh.GetHashCode();
+ if (!reorientedMeshes.TryGetValue(hashCode, out newMesh) || newMesh == null) {
+ if (!mesh.isReadable) return;
+ if (normals == null) {
+ normals = new List();
+ } else {
+ normals.Clear();
+ }
+ if (vertices == null) {
+ vertices = new List();
+ } else {
+ vertices.Clear();
+ }
+ mesh.GetVertices(vertices);
+ int vertexCount = vertices.Count;
+ if (vertexCount == 0) return;
+
+ Vector3 mid = Vector3.zero;
+ for (int k = 0; k < vertexCount; k++) {
+ mid += vertices[k];
+ }
+ mid /= vertexCount;
+ // Average normals
+ for (int k = 0; k < vertexCount; k++) {
+ normals.Add((vertices[k] - mid).normalized);
+ }
+ // Reassign normals
+ newMesh = Instantiate(mesh);
+ newMesh.SetNormals(normals);
+ reorientedMeshes[hashCode] = newMesh;
+ IncrementeMeshUsage(newMesh);
+ }
+ rms[objIndex].mesh = newMesh;
+ }
+
+ const int MAX_VERTEX_COUNT = 65535;
+ void CombineMeshes() {
+
+ if (rmsCount <= 1) return;
+
+ // Combine meshes of group into the first mesh in rms
+ if (combineInstances == null || combineInstances.Length != rmsCount) {
+ combineInstances = new CombineInstance[rmsCount];
+ }
+ int first = -1;
+ int count = 0;
+ combinedMeshesHashId = 0;
+ int vertexCount = 0;
+ Matrix4x4 im = Matrix4x4.identity;
+ for (int k = 0; k < rmsCount; k++) {
+ combineInstances[k].mesh = null;
+ if (!rms[k].isSkinnedMesh) {
+ Mesh mesh = rms[k].mesh;
+ if (mesh != null && mesh.isReadable) {
+ if (vertexCount + mesh.vertexCount > MAX_VERTEX_COUNT) continue;
+ vertexCount += mesh.vertexCount;
+ combineInstances[k].mesh = mesh;
+ int instanceId = rms[k].renderer.gameObject.GetInstanceID();
+ if (first < 0) {
+ first = k;
+ combinedMeshesHashId = instanceId;
+ im = rms[k].transform.worldToLocalMatrix;
+ } else {
+ combinedMeshesHashId ^= instanceId;
+ rms[k].mesh = null;
+ }
+ combineInstances[k].transform = im * rms[k].transform.localToWorldMatrix;
+ count++;
+ }
+ }
+ }
+ if (count < 2) return;
+
+ Mesh combinedMesh;
+ if (!combinedMeshes.TryGetValue(combinedMeshesHashId, out combinedMesh) || combinedMesh == null) {
+ combinedMesh = new Mesh();
+ combinedMesh.CombineMeshes(combineInstances, true, true);
+ combinedMeshes[combinedMeshesHashId] = combinedMesh;
+ IncrementeMeshUsage(combinedMesh);
+ }
+ rms[first].mesh = combinedMesh;
+ rms[first].isCombined = true;
+ }
+
+
+ void IncrementeMeshUsage(Mesh mesh) {
+ int usageCount;
+ sharedMeshUsage.TryGetValue(mesh, out usageCount);
+ usageCount++;
+ sharedMeshUsage[mesh] = usageCount;
+ instancedMeshes.Add(mesh);
+ }
+
+ ///
+ /// Destroys any cached mesh
+ ///
+ public static void ClearMeshCache() {
+ foreach (Mesh mesh in combinedMeshes.Values) {
+ if (mesh != null) DestroyImmediate(mesh);
+ }
+ foreach (Mesh mesh in smoothMeshes.Values) {
+ if (mesh != null) DestroyImmediate(mesh);
+ }
+ foreach (Mesh mesh in reorientedMeshes.Values) {
+ if (mesh != null) DestroyImmediate(mesh);
+ }
+ }
+
+ ///
+ /// Clears cached mesh only for the highlighted object
+ ///
+ void RefreshCachedMeshes() {
+ if (combinedMeshes.TryGetValue(combinedMeshesHashId, out Mesh combinedMesh)) {
+ DestroyImmediate(combinedMesh);
+ combinedMeshes.Remove(combinedMeshesHashId);
+ }
+ if (rms == null) return;
+ for (int k = 0; k < rms.Length; k++) {
+ Mesh mesh = rms[k].mesh;
+ if (mesh != null) {
+ if (smoothMeshes.ContainsValue(mesh) || reorientedMeshes.ContainsValue(mesh)) {
+ DestroyImmediate(mesh);
+ }
+ }
+
+ }
+ }
+ #endregion
+
+ }
+}
diff --git a/Assets/Plugins/HighlightPlus/Scripts/HighlightEffect.cs.meta b/Assets/Plugins/HighlightPlus/Scripts/HighlightEffect.cs.meta
new file mode 100644
index 0000000..0ad03a7
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/HighlightEffect.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 888380afc233049ce9e618f9f36c8ba8
+timeCreated: 1545593776
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 900
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Scripts/HighlightEffectActions.cs b/Assets/Plugins/HighlightPlus/Scripts/HighlightEffectActions.cs
new file mode 100644
index 0000000..ffacad6
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/HighlightEffectActions.cs
@@ -0,0 +1,86 @@
+using UnityEngine;
+
+namespace HighlightPlus {
+
+ public enum HitFxMode {
+ Overlay = 0,
+ InnerGlow = 1,
+ LocalHit = 2
+ }
+
+ public partial class HighlightEffect : MonoBehaviour {
+
+ [Range(0,1)] public float hitFxInitialIntensity;
+ public HitFxMode hitFxMode = HitFxMode.Overlay;
+ public float hitFxFadeOutDuration = 0.25f;
+ [ColorUsage(true, true)] public Color hitFxColor = Color.white;
+ public float hitFxRadius = 0.5f;
+
+ float hitInitialIntensity;
+ float hitStartTime;
+ float hitFadeOutDuration;
+ Color hitColor;
+ bool hitActive;
+ Vector3 hitPosition;
+ float hitRadius;
+
+ ///
+ /// Performs a hit effect using default values
+ ///
+ public void HitFX() {
+ HitFX(hitFxColor, hitFxFadeOutDuration, hitFxInitialIntensity);
+ }
+
+ ///
+ /// Performs a hit effect localized at hit position and radius with default values
+ ///
+ public void HitFX(Vector3 position) {
+ HitFX(hitFxColor, hitFxFadeOutDuration, hitFxInitialIntensity, position, hitFxRadius);
+
+ }
+
+ ///
+ /// Performs a hit effect using desired color, fade out duration and optionally initial intensity (0-1)
+ ///
+ public void HitFX(Color color, float fadeOutDuration, float initialIntensity = 1f) {
+ hitInitialIntensity = initialIntensity;
+ hitFadeOutDuration = fadeOutDuration;
+ hitColor = color;
+ hitStartTime = Time.time;
+ hitActive = true;
+ if (overlay == 0) {
+ UpdateMaterialProperties();
+ }
+ }
+
+
+ ///
+ /// Performs a hit effect using desired color, fade out duration, initial intensity (0-1), hit position and radius of effect
+ ///
+ public void HitFX(Color color, float fadeOutDuration, float initialIntensity, Vector3 position, float radius) {
+ hitInitialIntensity = initialIntensity;
+ hitFadeOutDuration = fadeOutDuration;
+ hitColor = color;
+ hitStartTime = Time.time;
+ hitActive = true;
+ hitPosition = position;
+ hitRadius = radius;
+ if (overlay == 0) {
+ UpdateMaterialProperties();
+ }
+ }
+
+ ///
+ /// Initiates the target FX on demand using predefined configuration (see targetFX... properties)
+ ///
+ public void TargetFX() {
+ targetFxStartTime = Time.time;
+ if (!targetFX) {
+ targetFX = true;
+ UpdateMaterialProperties();
+ }
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Scripts/HighlightEffectActions.cs.meta b/Assets/Plugins/HighlightPlus/Scripts/HighlightEffectActions.cs.meta
new file mode 100644
index 0000000..1461989
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/HighlightEffectActions.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: e749f80d0d29a49d49d6e0f4752065cd
+timeCreated: 1542876337
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Scripts/HighlightEffectOccluderManager.cs b/Assets/Plugins/HighlightPlus/Scripts/HighlightEffectOccluderManager.cs
new file mode 100644
index 0000000..d80b4eb
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/HighlightEffectOccluderManager.cs
@@ -0,0 +1,271 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Rendering;
+
+namespace HighlightPlus {
+
+
+ public partial class HighlightEffect : MonoBehaviour {
+
+ static readonly List occluders = new List();
+ static readonly Dictionary occludersFrameCount = new Dictionary();
+ static CommandBuffer cbOccluder;
+ static Material fxMatSeeThroughOccluder, fxMatDepthWrite;
+ static RaycastHit[] hits;
+
+ ///
+ /// True if the see-through is cancelled by an occluder using raycast method
+ ///
+ public bool IsSeeThroughOccluded(Camera cam) {
+ // Compute bounds
+ Bounds bounds = new Bounds();
+ for (int r = 0; r < rms.Length; r++) {
+ if (rms[r].renderer != null) {
+ if (bounds.size.x == 0) {
+ bounds = rms[r].renderer.bounds;
+ } else {
+ bounds.Encapsulate(rms[r].renderer.bounds);
+ }
+ }
+ }
+ Vector3 pos = bounds.center;
+ Vector3 camPos = cam.transform.position;
+ Vector3 offset = pos - camPos;
+ float maxDistance = Vector3.Distance(pos, camPos);
+ if (hits == null || hits.Length == 0) {
+ hits = new RaycastHit[64];
+ }
+ int occludersCount = occluders.Count;
+ int hitCount = Physics.BoxCastNonAlloc(pos - offset, bounds.extents * 0.9f, offset.normalized, hits, Quaternion.identity, maxDistance);
+ for (int k = 0; k < hitCount; k++) {
+ for (int j = 0; j < occludersCount; j++) {
+ if (hits[k].collider.transform == occluders[j].transform) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public static void RegisterOccluder(HighlightSeeThroughOccluder occluder) {
+ if (!occluders.Contains(occluder)) {
+ occluders.Add(occluder);
+ }
+ }
+
+ public static void UnregisterOccluder(HighlightSeeThroughOccluder occluder) {
+ if (occluders.Contains(occluder)) {
+ occluders.Remove(occluder);
+ }
+ }
+
+ ///
+ /// Test see-through occluders.
+ ///
+ /// The camera to be tested
+ /// Returns true if there's no raycast-based occluder cancelling the see-through effect
+ public bool RenderSeeThroughOccluders(Camera cam) {
+
+ int occludersCount = occluders.Count;
+ if (occludersCount == 0 || rmsCount == 0) return true;
+
+ bool useRayCastCheck = false;
+ // Check if raycast method is needed
+ for (int k = 0; k < occludersCount; k++) {
+ HighlightSeeThroughOccluder occluder = occluders[k];
+ if (occluder == null || !occluder.isActiveAndEnabled) continue;
+ if (occluder.detectionMethod == DetectionMethod.RayCast) {
+ useRayCastCheck = true;
+ break;
+ }
+ }
+ if (useRayCastCheck) {
+ if (IsSeeThroughOccluded(cam)) return false;
+ }
+
+ // do not render see-through occluders more than once this frame per camera (there can be many highlight effect scripts in the scene, we only need writing to stencil once)
+ int lastFrameCount;
+ occludersFrameCount.TryGetValue(cam, out lastFrameCount);
+ int currentFrameCount = Time.frameCount;
+ if (currentFrameCount == lastFrameCount) return true;
+ occludersFrameCount[cam] = currentFrameCount;
+
+ if (cbOccluder == null) {
+ cbOccluder = new CommandBuffer();
+ cbOccluder.name = "Occluder";
+ }
+
+ if (fxMatSeeThroughOccluder == null) {
+ InitMaterial(ref fxMatSeeThroughOccluder, "HighlightPlus/Geometry/SeeThroughOccluder");
+ if (fxMatSeeThroughOccluder == null) return true;
+ }
+ if (fxMatDepthWrite == null) {
+ InitMaterial(ref fxMatDepthWrite, "HighlightPlus/Geometry/JustDepth");
+ if (fxMatDepthWrite == null) return true;
+ }
+
+
+ cbOccluder.Clear();
+ for (int k = 0; k < occludersCount; k++) {
+ HighlightSeeThroughOccluder occluder = occluders[k];
+ if (occluder == null || !occluder.isActiveAndEnabled) continue;
+ if (occluder.detectionMethod == DetectionMethod.Stencil) {
+ if (occluder.meshData == null) continue;
+ int meshDataLength = occluder.meshData.Length;
+ // Per renderer
+ for (int m = 0; m < meshDataLength; m++) {
+ // Per submesh
+ Renderer renderer = occluder.meshData[m].renderer;
+ if (renderer.isVisible) {
+ for (int s = 0; s < occluder.meshData[m].subMeshCount; s++) {
+ cbOccluder.DrawRenderer(renderer, occluder.mode == OccluderMode.BlocksSeeThrough ? fxMatSeeThroughOccluder : fxMatDepthWrite, s);
+ }
+ }
+ }
+ }
+ }
+ Graphics.ExecuteCommandBuffer(cbOccluder);
+
+ return true;
+ }
+
+ bool CheckOcclusion(Camera cam) {
+
+ if (!perCameraOcclusionData.TryGetValue(cam, out PerCameraOcclusionData occlusionData)) {
+ occlusionData = new PerCameraOcclusionData();
+ perCameraOcclusionData[cam] = occlusionData;
+ }
+
+ float now = Time.time;
+ int frameCount = Time.frameCount; // ensure all cameras are checked this frame
+
+ if (now - occlusionData.checkLastTime < seeThroughOccluderCheckInterval && Application.isPlaying && occlusionData.occlusionRenderFrame != frameCount) return occlusionData.lastOcclusionTestResult;
+ occlusionData.checkLastTime = now;
+ occlusionData.occlusionRenderFrame = frameCount;
+
+ if (rms == null || rms.Length == 0 || rms[0].renderer == null) return false;
+
+ Vector3 camPos = cam.transform.position;
+
+ if (seeThroughOccluderCheckIndividualObjects) {
+ for (int r = 0; r < rms.Length; r++) {
+ if (rms[r].renderer != null) {
+ Bounds bounds = rms[r].renderer.bounds;
+ Vector3 pos = bounds.center;
+ float maxDistance = Vector3.Distance(pos, camPos);
+ if (Physics.BoxCast(pos, bounds.extents * seeThroughOccluderThreshold, (camPos - pos).normalized, Quaternion.identity, maxDistance, seeThroughOccluderMask)) {
+ occlusionData.lastOcclusionTestResult = true;
+ return true;
+ }
+ }
+ }
+ occlusionData.lastOcclusionTestResult = false;
+ return false;
+ } else {
+ // Compute combined bounds
+ Bounds bounds = rms[0].renderer.bounds;
+ for (int r = 1; r < rms.Length; r++) {
+ if (rms[r].renderer != null) {
+ bounds.Encapsulate(rms[r].renderer.bounds);
+ }
+ }
+ Vector3 pos = bounds.center;
+ float maxDistance = Vector3.Distance(pos, camPos);
+ occlusionData.lastOcclusionTestResult = Physics.BoxCast(pos, bounds.extents * seeThroughOccluderThreshold, (camPos - pos).normalized, Quaternion.identity, maxDistance, seeThroughOccluderMask);
+ return occlusionData.lastOcclusionTestResult;
+ }
+ }
+
+
+ const int MAX_OCCLUDER_HITS = 50;
+ static RaycastHit[] occluderHits;
+
+ void AddWithoutRepetition(List target, List source) {
+ int sourceCount = source.Count;
+ for (int k = 0; k < sourceCount; k++) {
+ T entry = source[k];
+ if (entry != null && !target.Contains(entry)) {
+ target.Add(entry);
+ }
+ }
+ }
+
+ void CheckOcclusionAccurate(Camera cam) {
+
+ if (!perCameraOcclusionData.TryGetValue(cam, out PerCameraOcclusionData occlusionData)) {
+ occlusionData = new PerCameraOcclusionData();
+ perCameraOcclusionData[cam] = occlusionData;
+ }
+
+ float now = Time.time;
+ int frameCount = Time.frameCount; // ensure all cameras are checked this frame
+ bool reuse = now - occlusionData.checkLastTime < seeThroughOccluderCheckInterval && Application.isPlaying && occlusionData.occlusionRenderFrame != frameCount;
+
+ if (!reuse) {
+ if (rms == null || rms.Length == 0 || rms[0].renderer == null) return;
+
+ occlusionData.checkLastTime = now;
+ occlusionData.occlusionRenderFrame = frameCount;
+ Quaternion quaternionIdentity = Quaternion.identity;
+ Vector3 camPos = cam.transform.position;
+
+ occlusionData.cachedOccluders.Clear();
+
+ if (occluderHits == null || occluderHits.Length < MAX_OCCLUDER_HITS) {
+ occluderHits = new RaycastHit[MAX_OCCLUDER_HITS];
+ }
+
+ if (seeThroughOccluderCheckIndividualObjects) {
+ for (int r = 0; r < rms.Length; r++) {
+ if (rms[r].renderer != null) {
+ Bounds bounds = rms[r].renderer.bounds;
+ Vector3 pos = bounds.center;
+ float maxDistance = Vector3.Distance(pos, camPos);
+ int numOccluderHits = Physics.BoxCastNonAlloc(pos, bounds.extents * seeThroughOccluderThreshold, (camPos - pos).normalized, occluderHits, quaternionIdentity, maxDistance, seeThroughOccluderMask);
+ for (int k = 0; k < numOccluderHits; k++) {
+ occluderHits[k].collider.transform.root.GetComponentsInChildren(tempRR);
+ AddWithoutRepetition(occlusionData.cachedOccluders, tempRR);
+ }
+ }
+ }
+ } else {
+ // Compute combined bounds
+ Bounds bounds = rms[0].renderer.bounds;
+ for (int r = 1; r < rms.Length; r++) {
+ if (rms[r].renderer != null) {
+ bounds.Encapsulate(rms[r].renderer.bounds);
+ }
+ }
+ Vector3 pos = bounds.center;
+ float maxDistance = Vector3.Distance(pos, camPos);
+ int numOccluderHits = Physics.BoxCastNonAlloc(pos, bounds.extents * seeThroughOccluderThreshold, (camPos - pos).normalized, occluderHits, quaternionIdentity, maxDistance, seeThroughOccluderMask);
+ for (int k = 0; k < numOccluderHits; k++) {
+ occluderHits[k].collider.transform.root.GetComponentsInChildren(tempRR);
+ AddWithoutRepetition(occlusionData.cachedOccluders, tempRR);
+ }
+ }
+ }
+
+ // render occluders
+ int occluderRenderersCount = occlusionData.cachedOccluders.Count;
+ if (occluderRenderersCount > 0) {
+ cbSeeThrough.Clear();
+ for (int k = 0; k < occluderRenderersCount; k++) {
+ Renderer r = occlusionData.cachedOccluders[k];
+ if (r != null) {
+ cbSeeThrough.DrawRenderer(r, fxMatSeeThroughMask);
+ }
+ }
+ Graphics.ExecuteCommandBuffer(cbSeeThrough);
+ }
+ }
+
+ public List GetOccluders(Camera camera) {
+ if (perCameraOcclusionData.TryGetValue(camera, out PerCameraOcclusionData occlusionData)) {
+ return occlusionData.cachedOccluders;
+ }
+ return null;
+ }
+ }
+}
diff --git a/Assets/Plugins/HighlightPlus/Scripts/HighlightEffectOccluderManager.cs.meta b/Assets/Plugins/HighlightPlus/Scripts/HighlightEffectOccluderManager.cs.meta
new file mode 100644
index 0000000..c459f5e
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/HighlightEffectOccluderManager.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: d0bc1f04199a64e66ae9630062b3a6ad
+timeCreated: 1542876337
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Scripts/HighlightManager.cs b/Assets/Plugins/HighlightPlus/Scripts/HighlightManager.cs
new file mode 100644
index 0000000..292e61f
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/HighlightManager.cs
@@ -0,0 +1,420 @@
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.EventSystems;
+
+namespace HighlightPlus {
+
+ public delegate bool OnObjectSelectionEvent(GameObject obj);
+
+
+ [RequireComponent(typeof(HighlightEffect))]
+ [DefaultExecutionOrder(100)]
+ [HelpURL("https://kronnect.com/guides/highlight-plus-introduction/")]
+ public class HighlightManager : MonoBehaviour {
+
+ [Tooltip("Enables highlight when pointer is over this object.")]
+ public bool highlightOnHover = true;
+
+ public LayerMask layerMask = -1;
+ public Camera raycastCamera;
+ public RayCastSource raycastSource = RayCastSource.MousePosition;
+ [Tooltip("Minimum distance for target.")]
+ public float minDistance;
+ [Tooltip("Maximum distance for target. 0 = infinity")]
+ public float maxDistance;
+ [Tooltip("Blocks interaction if pointer is over an UI element")]
+ public bool respectUI = true;
+
+ [Tooltip("If the object will be selected by clicking with mouse or tapping on it.")]
+ public bool selectOnClick;
+ [Tooltip("Optional profile for objects selected by clicking on them")]
+ public HighlightProfile selectedProfile;
+ [Tooltip("Profile to use whtn object is selected and highlighted.")]
+ public HighlightProfile selectedAndHighlightedProfile;
+ [Tooltip("Automatically deselects other previously selected objects")]
+ public bool singleSelection;
+ [Tooltip("Toggles selection on/off when clicking object")]
+ public bool toggle;
+ [Tooltip("Keeps current selection when clicking outside of any selectable object")]
+ public bool keepSelection = true;
+
+ HighlightEffect baseEffect, currentEffect;
+ Transform currentObject;
+
+ public readonly static List selectedObjects = new List();
+ public event OnObjectSelectionEvent OnObjectSelected;
+ public event OnObjectSelectionEvent OnObjectUnSelected;
+ public event OnObjectHighlightEvent OnObjectHighlightStart;
+ public event OnObjectHighlightEvent OnObjectHighlightEnd;
+ public static int lastTriggerFrame;
+
+ static HighlightManager _instance;
+ public static HighlightManager instance {
+ get {
+ if (_instance == null) {
+ _instance = FindObjectOfType();
+ }
+ return _instance;
+ }
+ }
+
+ [RuntimeInitializeOnLoadMethod]
+ void DomainReloadDisabledSupport() {
+ selectedObjects.Clear();
+ lastTriggerFrame = 0;
+ _instance = null;
+ }
+
+ void OnEnable() {
+ currentObject = null;
+ currentEffect = null;
+ if (baseEffect == null) {
+ baseEffect = GetComponent();
+ if (baseEffect == null) {
+ baseEffect = gameObject.AddComponent();
+ }
+ }
+ raycastCamera = GetComponent();
+ if (raycastCamera == null) {
+ raycastCamera = GetCamera();
+ if (raycastCamera == null) {
+ Debug.LogError("Highlight Manager: no camera found!");
+ }
+ }
+ InputProxy.Init();
+ }
+
+
+ void OnDisable() {
+ SwitchesCollider(null);
+ internal_DeselectAll();
+ }
+
+ void Update() {
+ if (raycastCamera == null)
+ return;
+
+#if ENABLE_INPUT_SYSTEM
+ if (respectUI) {
+ EventSystem es = EventSystem.current;
+ if (es == null) {
+ es = CreateEventSystem();
+ }
+ List raycastResults = new List();
+ PointerEventData eventData = new PointerEventData(es);
+ Vector3 cameraPos = raycastCamera.transform.position;
+ if (raycastSource == RayCastSource.MousePosition) {
+ eventData.position = InputProxy.mousePosition;
+ } else {
+ eventData.position = new Vector2(raycastCamera.pixelWidth * 0.5f, raycastCamera.pixelHeight * 0.5f);
+ }
+ es.RaycastAll(eventData, raycastResults);
+ int hitCount = raycastResults.Count;
+ // check UI blocker
+ bool blocked = false;
+ for (int k = 0; k < hitCount; k++) {
+ RaycastResult rr = raycastResults[k];
+ if (rr.module is UnityEngine.UI.GraphicRaycaster) {
+ blocked = true;
+ break;
+ }
+ }
+ if (blocked) return;
+
+ // look for our gameobject
+ for (int k = 0; k < hitCount; k++) {
+ RaycastResult rr = raycastResults[k];
+ float distance = Vector3.Distance(rr.worldPosition, cameraPos);
+ if (distance < minDistance || (maxDistance > 0 && distance > maxDistance)) continue;
+
+ GameObject theGameObject = rr.gameObject;
+ if ((layerMask & (1 << rr.gameObject.layer)) == 0) continue;
+
+ // is this object state controller by Highlight Trigger?
+ HighlightTrigger trigger = theGameObject.GetComponent();
+ if (trigger != null) return;
+
+ // Toggles selection
+ Transform t = theGameObject.transform;
+ if (InputProxy.GetMouseButtonDown(0)) {
+ if (selectOnClick) {
+ ToggleSelection(t, !toggle);
+ }
+ } else {
+ // Check if the object has a Highlight Effect
+ if (t != currentObject) {
+ SwitchesCollider(t);
+ }
+ }
+ return;
+ }
+ }
+ // if not blocked by UI and no hit found, fallback to raycast (required if no PhysicsRaycaster is present on the camera)
+#endif
+
+ Ray ray;
+ if (raycastSource == RayCastSource.MousePosition) {
+#if !ENABLE_INPUT_SYSTEM
+ if (!CanInteract()) {
+ return;
+ }
+#endif
+ ray = raycastCamera.ScreenPointToRay(InputProxy.mousePosition);
+ } else {
+ ray = new Ray(raycastCamera.transform.position, raycastCamera.transform.forward);
+ }
+ RaycastHit hitInfo;
+ if (Physics.Raycast(ray, out hitInfo, maxDistance > 0 ? maxDistance : raycastCamera.farClipPlane, layerMask) && Vector3.Distance(hitInfo.point, ray.origin) >= minDistance) {
+ Transform t = hitInfo.collider.transform;
+ // is this object state controller by Highlight Trigger?
+ HighlightTrigger trigger = t.GetComponent();
+ if (trigger != null) return;
+
+ // Toggles selection
+ if (InputProxy.GetMouseButtonDown(0)) {
+ if (selectOnClick) {
+ ToggleSelection(t, !toggle);
+ }
+ } else {
+ // Check if the object has a Highlight Effect
+ if (t != currentObject) {
+ SwitchesCollider(t);
+ }
+ }
+ return;
+ }
+
+ // no hit
+ if (selectOnClick && !keepSelection && InputProxy.GetMouseButtonDown(0) && lastTriggerFrame < Time.frameCount) {
+ internal_DeselectAll();
+ }
+ SwitchesCollider(null);
+ }
+
+
+#if ENABLE_INPUT_SYSTEM
+ EventSystem CreateEventSystem() {
+ GameObject eo = new GameObject("Event System created by Highlight Plus", typeof(EventSystem), typeof(UnityEngine.InputSystem.UI.InputSystemUIInputModule));
+ return eo.GetComponent();
+ }
+#endif
+
+
+ void SwitchesCollider(Transform newObject) {
+ if (currentEffect != null) {
+ if (highlightOnHover) {
+ Highlight(false);
+ }
+ currentEffect = null;
+ }
+ currentObject = newObject;
+ if (newObject == null) return;
+ HighlightTrigger ht = newObject.GetComponent();
+ if (ht != null && ht.enabled)
+ return;
+
+ HighlightEffect otherEffect = newObject.GetComponent();
+ if (otherEffect == null) {
+ // Check if there's a parent highlight effect that includes this object
+ HighlightEffect parentEffect = newObject.GetComponentInParent();
+ if (parentEffect != null && parentEffect.Includes(newObject)) {
+ currentEffect = parentEffect;
+ if (highlightOnHover) {
+ Highlight(true);
+ }
+ return;
+ }
+ }
+ currentEffect = otherEffect != null ? otherEffect : baseEffect;
+ baseEffect.enabled = currentEffect == baseEffect;
+ currentEffect.SetTarget(currentObject);
+
+ if (highlightOnHover) {
+ Highlight(true);
+ }
+ }
+
+
+ bool CanInteract() {
+ if (!respectUI) return true;
+ EventSystem es = EventSystem.current;
+ if (es == null) return true;
+ if (Application.isMobilePlatform && InputProxy.touchCount > 0 && es.IsPointerOverGameObject(InputProxy.GetFingerIdFromTouch(0))) {
+ return false;
+ } else if (es.IsPointerOverGameObject(-1))
+ return false;
+ return true;
+ }
+
+
+ void ToggleSelection(Transform t, bool forceSelection) {
+
+ // We need a highlight effect on each selected object
+ HighlightEffect hb = t.GetComponent();
+ if (hb == null) {
+ HighlightEffect parentEffect = t.GetComponentInParent();
+ if (parentEffect != null && parentEffect.Includes(t)) {
+ hb = parentEffect;
+ if (hb.previousSettings == null) {
+ hb.previousSettings = ScriptableObject.CreateInstance();
+ }
+ hb.previousSettings.Save(hb);
+ } else {
+ hb = t.gameObject.AddComponent();
+ hb.previousSettings = ScriptableObject.CreateInstance();
+ // copy default highlight effect settings from this manager into this highlight plus component
+ hb.previousSettings.Save(baseEffect);
+ hb.previousSettings.Load(hb);
+ }
+ }
+
+ bool currentState = hb.isSelected;
+ bool newState = forceSelection ? true : !currentState;
+ if (newState == currentState) return;
+
+ if (newState) {
+ if (OnObjectSelected != null && !OnObjectSelected(t.gameObject)) return;
+ } else {
+ if (OnObjectUnSelected != null && !OnObjectUnSelected(t.gameObject)) return;
+ }
+
+ if (singleSelection) {
+ internal_DeselectAll();
+ }
+
+ currentEffect = hb;
+ currentEffect.isSelected = newState;
+ baseEffect.enabled = false;
+
+ if (currentEffect.isSelected) {
+ if (currentEffect.previousSettings == null) {
+ currentEffect.previousSettings = ScriptableObject.CreateInstance();
+ }
+ hb.previousSettings.Save(hb);
+
+ if (!selectedObjects.Contains(currentEffect)) {
+ selectedObjects.Add(currentEffect);
+ }
+ } else {
+ if (currentEffect.previousSettings != null) {
+ currentEffect.previousSettings.Load(hb);
+ }
+ if (selectedObjects.Contains(currentEffect)) {
+ selectedObjects.Remove(currentEffect);
+ }
+ }
+
+ Highlight(true);
+ }
+
+ void Highlight(bool state) {
+ if (state) {
+ if (!currentEffect.highlighted) {
+ if (OnObjectHighlightStart != null && currentEffect.target != null) {
+ if (!OnObjectHighlightStart(currentEffect.target.gameObject)) return;
+ }
+ }
+ } else {
+ if (currentEffect.highlighted) {
+ if (OnObjectHighlightEnd != null && currentEffect.target != null) {
+ OnObjectHighlightEnd(currentEffect.target.gameObject);
+ }
+ }
+ }
+ if (selectOnClick || currentEffect.isSelected) {
+ if (currentEffect.isSelected) {
+ if (state && selectedAndHighlightedProfile != null) {
+ selectedAndHighlightedProfile.Load(currentEffect);
+ } else if (selectedProfile != null) {
+ selectedProfile.Load(currentEffect);
+ } else {
+ currentEffect.previousSettings.Load(currentEffect);
+ }
+ if (currentEffect.highlighted) {
+ currentEffect.UpdateMaterialProperties();
+ } else {
+ currentEffect.SetHighlighted(true);
+ }
+ return;
+ } else if (!highlightOnHover) {
+ currentEffect.SetHighlighted(false);
+ return;
+ }
+ }
+ currentEffect.SetHighlighted(state);
+ }
+
+ public static Camera GetCamera() {
+ Camera raycastCamera = Camera.main;
+ if (raycastCamera == null) {
+ raycastCamera = FindObjectOfType();
+ }
+ return raycastCamera;
+ }
+
+ void internal_DeselectAll() {
+ foreach (HighlightEffect hb in selectedObjects) {
+ if (hb != null && hb.gameObject != null) {
+ if (OnObjectUnSelected != null) {
+ if (!OnObjectUnSelected(hb.gameObject)) continue;
+ }
+ hb.RestorePreviousHighlightEffectSettings();
+ hb.isSelected = false;
+ hb.SetHighlighted(false);
+ }
+ }
+ selectedObjects.Clear();
+ }
+
+
+ public static void DeselectAll() {
+ foreach (HighlightEffect hb in selectedObjects) {
+ if (hb != null && hb.gameObject != null) {
+ hb.isSelected = false;
+ if (hb.highlighted && _instance != null) {
+ _instance.Highlight(false);
+ } else {
+ hb.SetHighlighted(false);
+ }
+ }
+ }
+ selectedObjects.Clear();
+ }
+
+ ///
+ /// Manually causes highlight manager to select an object
+ ///
+ public void SelectObject(Transform t) {
+ ToggleSelection(t, true);
+ }
+
+ ///
+ /// Manually causes highlight manager to toggle selection on an object
+ ///
+ public void ToggleObject(Transform t) {
+ ToggleSelection(t, false);
+ }
+
+ ///
+ /// Manually causes highlight manager to unselect an object
+ ///
+ public void UnselectObject(Transform t) {
+ if (t == null) return;
+ HighlightEffect hb = t.GetComponent();
+ if (hb == null) return;
+
+ if (selectedObjects.Contains(hb)) {
+ if (OnObjectUnSelected != null) {
+ if (!OnObjectUnSelected(hb.gameObject)) return;
+ }
+ hb.isSelected = false;
+ hb.SetHighlighted(false);
+ selectedObjects.Remove(hb);
+ }
+ }
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Scripts/HighlightManager.cs.meta b/Assets/Plugins/HighlightPlus/Scripts/HighlightManager.cs.meta
new file mode 100644
index 0000000..5f9c58e
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/HighlightManager.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: af4d46fd89b9543e5be2358ac0c9ced0
+timeCreated: 1542876337
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Scripts/HighlightProfile.cs b/Assets/Plugins/HighlightPlus/Scripts/HighlightProfile.cs
new file mode 100644
index 0000000..fb2f5d0
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/HighlightProfile.cs
@@ -0,0 +1,387 @@
+using UnityEngine;
+
+namespace HighlightPlus {
+
+ [CreateAssetMenu(menuName = "Highlight Plus Profile", fileName = "Highlight Plus Profile", order = 100)]
+ [HelpURL("https://www.dropbox.com/s/v9qgn68ydblqz8x/Documentation.pdf?dl=0")]
+ public class HighlightProfile : ScriptableObject {
+
+ [Tooltip("Different options to specify which objects are affected by this Highlight Effect component.")]
+ public TargetOptions effectGroup = TargetOptions.Children;
+ [Tooltip("The layer that contains the affected objects by this effect when effectGroup is set to LayerMask.")]
+ public LayerMask effectGroupLayer = -1;
+ [Tooltip("Only include objects whose names contains this text.")]
+ public string effectNameFilter;
+ [Tooltip("Combine meshes of all objects in this group affected by Highlight Effect reducing draw calls.")]
+ public bool combineMeshes;
+ [Tooltip("The alpha threshold for transparent cutout objects. Pixels with alpha below this value will be discarded.")]
+ [Range(0, 1)]
+ public float alphaCutOff;
+ [Tooltip("If back facing triangles are ignored.Backfaces triangles are not visible but you may set this property to false to force highlight effects to act on those triangles as well.")]
+ public bool cullBackFaces = true;
+ public bool depthClip;
+ [Tooltip("Normals handling option:\nPreserve original: use original mesh normals.\nSmooth: average normals to produce a smoother outline/glow mesh based effect.\nReorient: recomputes normals based on vertex direction to centroid.")]
+ public NormalsOption normalsOption;
+
+ public float fadeInDuration;
+ public float fadeOutDuration;
+
+ [Tooltip("Fades out effects based on distance to camera")]
+ public bool cameraDistanceFade;
+
+ [Tooltip("The closest distance particles can get to the camera before they fade from the camera’s view.")]
+ public float cameraDistanceFadeNear;
+
+ [Tooltip("The farthest distance particles can get away from the camera before they fade from the camera’s view.")]
+ public float cameraDistanceFadeFar = 1000;
+
+ [Tooltip("Keeps the outline/glow size unaffected by object distance.")]
+ public bool constantWidth = true;
+
+ [Range(0, 1)]
+ [Tooltip("Intensity of the overlay effect. A value of 0 disables the overlay completely.")]
+ public float overlay;
+ public OverlayMode overlayMode = OverlayMode.WhenHighlighted;
+ [ColorUsage(true, true)] public Color overlayColor = Color.yellow;
+ public float overlayAnimationSpeed = 1f;
+ [Range(0, 1)]
+ public float overlayMinIntensity = 0.5f;
+ [Range(0, 1)]
+ [Tooltip("Controls the blending or mix of the overlay color with the natural colors of the object.")]
+ public float overlayBlending = 1.0f;
+ [Tooltip("Optional overlay texture.")]
+ public Texture2D overlayTexture;
+ public TextureUVSpace overlayTextureUVSpace;
+ public float overlayTextureScale = 1f;
+
+ [Range(0, 1)]
+ [Tooltip("Intensity of the outline. A value of 0 disables the outline completely.")]
+ public float outline = 1f;
+ [ColorUsage(true, true)] public Color outlineColor = Color.black;
+ public ColorStyle outlineColorStyle = ColorStyle.SingleColor;
+ [GradientUsage(hdr: true, ColorSpace.Linear)] public Gradient outlineGradient;
+ public bool outlineGradientInLocalSpace;
+ public float outlineWidth = 0.45f;
+ public QualityLevel outlineQuality = QualityLevel.High;
+ [Range(1, 8)]
+ [Tooltip("Reduces the quality of the outline but improves performance a bit.")]
+ public int outlineDownsampling = 2;
+ public bool outlineOptimalBlit = true;
+ public Visibility outlineVisibility = Visibility.Normal;
+ [Tooltip("If enabled, this object won't combine the outline with other objects.")]
+ public bool outlineIndependent;
+
+ [Range(0, 5)]
+ [Tooltip("The intensity of the outer glow effect. A value of 0 disables the glow completely.")]
+ public float glow;
+ public float glowWidth = 0.4f;
+ public QualityLevel glowQuality = QualityLevel.High;
+ [Range(1, 8)]
+ [Tooltip("Reduces the quality of the glow but improves performance a bit.")]
+ public int glowDownsampling = 2;
+ [ColorUsage(true, true)] public Color glowHQColor = new Color (0.64f, 1f, 0f, 1f);
+ [Tooltip("When enabled, outer glow renders with dithering. When disabled, glow appears as a solid color.")]
+ public bool glowDithering = true;
+ public bool glowOptimalBlit = true;
+ [Tooltip("Seed for the dithering effect")]
+ public float glowMagicNumber1 = 0.75f;
+ [Tooltip("Another seed for the dithering effect that combines with first seed to create different patterns")]
+ public float glowMagicNumber2 = 0.5f;
+ public float glowAnimationSpeed = 1f;
+ public Visibility glowVisibility = Visibility.Normal;
+ public GlowBlendMode glowBlendMode = GlowBlendMode.Additive;
+ [Tooltip("Blends glow passes one after another. If this option is disabled, glow passes won't overlap (in this case, make sure the glow pass 1 has a smaller offset than pass 2, etc.)")]
+ public bool glowBlendPasses = true;
+ public GlowPassData[] glowPasses;
+ [Tooltip("If enabled, glow effect will not use a stencil mask. This can be used to render the glow effect alone.")]
+ public bool glowIgnoreMask;
+
+ [Range(0, 5f)]
+ [Tooltip("The intensity of the inner glow effect. A value of 0 disables the glow completely.")]
+ public float innerGlow;
+ [Range(0, 2)]
+ public float innerGlowWidth = 1f;
+ [ColorUsage(true, true)] public Color innerGlowColor = Color.white;
+ public Visibility innerGlowVisibility = Visibility.Normal;
+
+ [Tooltip("Enables the targetFX effect. This effect draws an animated sprite over the object.")]
+ public bool targetFX;
+ public Texture2D targetFXTexture;
+ [ColorUsage(true, true)] public Color targetFXColor = Color.white;
+ public float targetFXRotationSpeed = 50f;
+ public float targetFXInitialScale = 4f;
+ public float targetFXEndScale = 1.5f;
+ [Tooltip("Makes target scale relative to object renderer bounds.")]
+ public bool targetFXScaleToRenderBounds;
+ [Tooltip("Places target FX sprite at the bottom of the highlighted object.")]
+ public bool targetFXAlignToGround;
+ [Tooltip("Max distance from the center of the highlighted object to the ground.")]
+ public float targetFXGroundMaxDistance = 15f;
+ public LayerMask targetFXGroundLayerMask = -1;
+ [Tooltip("Fade out effect with altitude")]
+ public float targetFXFadePower = 32;
+ public float targetFXTransitionDuration = 0.5f;
+ public float targetFXStayDuration = 1.5f;
+ public Visibility targetFXVisibility = Visibility.AlwaysOnTop;
+
+ [Tooltip("See-through mode for this Highlight Effect component.")]
+ public SeeThroughMode seeThrough = SeeThroughMode.Never;
+ [Tooltip("This mask setting let you specify which objects will be considered as occluders and cause the see-through effect for this Highlight Effect component. For example, you assign your walls to a different layer and specify that layer here, so only walls and not other objects, like ground or ceiling, will trigger the see-through effect.")]
+ public LayerMask seeThroughOccluderMask = -1;
+ [Tooltip("Uses stencil buffers to ensure pixel-accurate occlusion test. If this option is disabled, only physics raycasting is used to test for occlusion.")]
+ public bool seeThroughOccluderMaskAccurate;
+ [Tooltip("A multiplier for the occluder volume size which can be used to reduce the actual size of occluders when Highlight Effect checks if they're occluding this object.")]
+ [Range(0.01f, 0.9f)] public float seeThroughOccluderThreshold = 0.4f;
+ [Tooltip("The interval of time between occlusion tests.")]
+ public float seeThroughOccluderCheckInterval = 1f;
+ [Tooltip("If enabled, occlusion test is performed for each children element. If disabled, the bounds of all children is combined and a single occlusion test is performed for the combined bounds.")]
+ public bool seeThroughOccluderCheckIndividualObjects;
+ [Tooltip("Shows the see-through effect only if the occluder if at this 'offset' distance from the object.")]
+ public float seeThroughDepthOffset;
+ [Tooltip("Hides the see-through effect if the occluder is further than this distance from the object (0 = infinite)")]
+ public float seeThroughMaxDepth;
+ [Range(0, 5f)] public float seeThroughIntensity = 0.8f;
+ [Range(0, 1)] public float seeThroughTintAlpha = 0.5f;
+ public Color seeThroughTintColor = Color.red;
+ [Range(0, 1)] public float seeThroughNoise = 1f;
+ [Range(0, 1)] public float seeThroughBorder;
+ public Color seeThroughBorderColor = Color.black;
+ public float seeThroughBorderWidth = 0.45f;
+ [Tooltip("Only display the border instead of the full see-through effect.")]
+ public bool seeThroughBorderOnly;
+ [Tooltip("Renders see-through effect on overlapping objects in a sequence that's relative to the distance to the camera")]
+ public bool seeThroughOrdered = true;
+ [Tooltip("Optional see-through mask effect texture.")]
+ public Texture2D seeThroughTexture;
+ public TextureUVSpace seeThroughTextureUVSpace;
+ public float seeThroughTextureScale = 1f;
+
+ [Range(0, 1)] public float hitFxInitialIntensity;
+ public HitFxMode hitFxMode = HitFxMode.Overlay;
+ public float hitFxFadeOutDuration = 0.25f;
+ [ColorUsage(true, true)] public Color hitFxColor = Color.white;
+ public float hitFxRadius = 0.5f;
+
+ public void Load(HighlightEffect effect) {
+ effect.effectGroup = effectGroup;
+ effect.effectGroupLayer = effectGroupLayer;
+ effect.effectNameFilter = effectNameFilter;
+ effect.combineMeshes = combineMeshes;
+ effect.alphaCutOff = alphaCutOff;
+ effect.cullBackFaces = cullBackFaces;
+ effect.depthClip = depthClip;
+ effect.normalsOption = normalsOption;
+ effect.fadeInDuration = fadeInDuration;
+ effect.fadeOutDuration = fadeOutDuration;
+ effect.cameraDistanceFade = cameraDistanceFade;
+ effect.cameraDistanceFadeFar = cameraDistanceFadeFar;
+ effect.cameraDistanceFadeNear = cameraDistanceFadeNear;
+ effect.constantWidth = constantWidth;
+ effect.overlay = overlay;
+ effect.overlayMode = overlayMode;
+ effect.overlayColor = overlayColor;
+ effect.overlayAnimationSpeed = overlayAnimationSpeed;
+ effect.overlayMinIntensity = overlayMinIntensity;
+ effect.overlayBlending = overlayBlending;
+ effect.overlayTexture = overlayTexture;
+ effect.overlayTextureUVSpace = overlayTextureUVSpace;
+ effect.overlayTextureScale = overlayTextureScale;
+ effect.outline = outline;
+ effect.outlineColor = outlineColor;
+ effect.outlineColorStyle = outlineColorStyle;
+ effect.outlineGradient = outlineGradient;
+ effect.outlineGradientInLocalSpace = outlineGradientInLocalSpace;
+ effect.outlineWidth = outlineWidth;
+ effect.outlineQuality = outlineQuality;
+ effect.outlineOptimalBlit = outlineOptimalBlit;
+ effect.outlineDownsampling = outlineDownsampling;
+ effect.outlineVisibility = outlineVisibility;
+ effect.outlineIndependent = outlineIndependent;
+ effect.glow = glow;
+ effect.glowWidth = glowWidth;
+ effect.glowQuality = glowQuality;
+ effect.glowOptimalBlit = glowOptimalBlit;
+ effect.glowDownsampling = glowDownsampling;
+ effect.glowHQColor = glowHQColor;
+ effect.glowDithering = glowDithering;
+ effect.glowMagicNumber1 = glowMagicNumber1;
+ effect.glowMagicNumber2 = glowMagicNumber2;
+ effect.glowAnimationSpeed = glowAnimationSpeed;
+ effect.glowVisibility = glowVisibility;
+ effect.glowBlendMode = glowBlendMode;
+ effect.glowBlendPasses = glowBlendPasses;
+ effect.glowPasses = GetGlowPassesCopy(glowPasses);
+ effect.glowIgnoreMask = glowIgnoreMask;
+ effect.innerGlow = innerGlow;
+ effect.innerGlowWidth = innerGlowWidth;
+ effect.innerGlowColor = innerGlowColor;
+ effect.innerGlowVisibility = innerGlowVisibility;
+ effect.targetFX = targetFX;
+ effect.targetFXColor = targetFXColor;
+ effect.targetFXInitialScale = targetFXInitialScale;
+ effect.targetFXEndScale = targetFXEndScale;
+ effect.targetFXScaleToRenderBounds = targetFXScaleToRenderBounds;
+ effect.targetFXAlignToGround = targetFXAlignToGround;
+ effect.targetFXGroundMaxDistance = targetFXGroundMaxDistance;
+ effect.targetFXGroundLayerMask = targetFXGroundLayerMask;
+ effect.targetFXFadePower = targetFXFadePower;
+ effect.targetFXRotationSpeed = targetFXRotationSpeed;
+ effect.targetFXStayDuration = targetFXStayDuration;
+ effect.targetFXTexture = targetFXTexture;
+ effect.targetFXTransitionDuration = targetFXTransitionDuration;
+ effect.targetFXVisibility = targetFXVisibility;
+ effect.seeThrough = seeThrough;
+ effect.seeThroughOccluderMask = seeThroughOccluderMask;
+ effect.seeThroughOccluderMaskAccurate = seeThroughOccluderMaskAccurate;
+ effect.seeThroughOccluderThreshold = seeThroughOccluderThreshold;
+ effect.seeThroughOccluderCheckInterval = seeThroughOccluderCheckInterval;
+ effect.seeThroughOccluderCheckIndividualObjects = seeThroughOccluderCheckIndividualObjects;
+ effect.seeThroughIntensity = seeThroughIntensity;
+ effect.seeThroughTintAlpha = seeThroughTintAlpha;
+ effect.seeThroughTintColor = seeThroughTintColor;
+ effect.seeThroughNoise = seeThroughNoise;
+ effect.seeThroughBorder = seeThroughBorder;
+ effect.seeThroughBorderColor = seeThroughBorderColor;
+ effect.seeThroughBorderWidth = seeThroughBorderWidth;
+ effect.seeThroughBorderOnly = seeThroughBorderOnly;
+ effect.seeThroughDepthOffset = seeThroughDepthOffset;
+ effect.seeThroughMaxDepth = seeThroughMaxDepth;
+ effect.seeThroughOrdered = seeThroughOrdered;
+ effect.seeThroughTexture = seeThroughTexture;
+ effect.seeThroughTextureScale = seeThroughTextureScale;
+ effect.seeThroughTextureUVSpace = seeThroughTextureUVSpace;
+ effect.hitFxInitialIntensity = hitFxInitialIntensity;
+ effect.hitFxMode = hitFxMode;
+ effect.hitFxFadeOutDuration = hitFxFadeOutDuration;
+ effect.hitFxColor = hitFxColor;
+ effect.hitFxRadius = hitFxRadius;
+ effect.UpdateMaterialProperties();
+ }
+
+ public void Save(HighlightEffect effect) {
+ effectGroup = effect.effectGroup;
+ effectGroupLayer = effect.effectGroupLayer;
+ effectNameFilter = effect.effectNameFilter;
+ combineMeshes = effect.combineMeshes;
+ alphaCutOff = effect.alphaCutOff;
+ cullBackFaces = effect.cullBackFaces;
+ depthClip = effect.depthClip;
+ normalsOption = effect.normalsOption;
+ fadeInDuration = effect.fadeInDuration;
+ fadeOutDuration = effect.fadeOutDuration;
+ cameraDistanceFade = effect.cameraDistanceFade;
+ cameraDistanceFadeFar = effect.cameraDistanceFadeFar;
+ cameraDistanceFadeNear = effect.cameraDistanceFadeNear;
+ constantWidth = effect.constantWidth;
+ overlay = effect.overlay;
+ overlayMode = effect.overlayMode;
+ overlayColor = effect.overlayColor;
+ overlayAnimationSpeed = effect.overlayAnimationSpeed;
+ overlayMinIntensity = effect.overlayMinIntensity;
+ overlayBlending = effect.overlayBlending;
+ overlayTexture = effect.overlayTexture;
+ overlayTextureUVSpace = effect.overlayTextureUVSpace;
+ overlayTextureScale = effect.overlayTextureScale;
+ outline = effect.outline;
+ outlineColor = effect.outlineColor;
+ outlineColorStyle = effect.outlineColorStyle;
+ outlineGradient = effect.outlineGradient;
+ outlineGradientInLocalSpace = effect.outlineGradientInLocalSpace;
+ outlineWidth = effect.outlineWidth;
+ outlineQuality = effect.outlineQuality;
+ outlineDownsampling = effect.outlineDownsampling;
+ outlineVisibility = effect.outlineVisibility;
+ outlineIndependent = effect.outlineIndependent;
+ outlineOptimalBlit = effect.outlineOptimalBlit;
+ glow = effect.glow;
+ glowWidth = effect.glowWidth;
+ glowQuality = effect.glowQuality;
+ glowOptimalBlit = effect.glowOptimalBlit;
+ glowDownsampling = effect.glowDownsampling;
+ glowHQColor = effect.glowHQColor;
+ glowDithering = effect.glowDithering;
+ glowMagicNumber1 = effect.glowMagicNumber1;
+ glowMagicNumber2 = effect.glowMagicNumber2;
+ glowAnimationSpeed = effect.glowAnimationSpeed;
+ glowVisibility = effect.glowVisibility;
+ glowBlendMode = effect.glowBlendMode;
+ glowBlendPasses = effect.glowBlendPasses;
+ glowPasses = GetGlowPassesCopy(effect.glowPasses);
+ glowIgnoreMask = effect.glowIgnoreMask;
+ innerGlow = effect.innerGlow;
+ innerGlowWidth = effect.innerGlowWidth;
+ innerGlowColor = effect.innerGlowColor;
+ innerGlowVisibility = effect.innerGlowVisibility;
+ targetFX = effect.targetFX;
+ targetFXColor = effect.targetFXColor;
+ targetFXInitialScale = effect.targetFXInitialScale;
+ targetFXEndScale = effect.targetFXEndScale;
+ targetFXScaleToRenderBounds = effect.targetFXScaleToRenderBounds;
+ targetFXAlignToGround = effect.targetFXAlignToGround;
+ targetFXGroundMaxDistance = effect.targetFXGroundMaxDistance;
+ targetFXGroundLayerMask = effect.targetFXGroundLayerMask;
+ targetFXFadePower = effect.targetFXFadePower;
+ targetFXRotationSpeed = effect.targetFXRotationSpeed;
+ targetFXStayDuration = effect.targetFXStayDuration;
+ targetFXTexture = effect.targetFXTexture;
+ targetFXTransitionDuration = effect.targetFXTransitionDuration;
+ targetFXVisibility = effect.targetFXVisibility;
+ seeThrough = effect.seeThrough;
+ seeThroughOccluderMask = effect.seeThroughOccluderMask;
+ seeThroughOccluderMaskAccurate = effect.seeThroughOccluderMaskAccurate;
+ seeThroughOccluderThreshold = effect.seeThroughOccluderThreshold;
+ seeThroughOccluderCheckInterval = effect.seeThroughOccluderCheckInterval;
+ seeThroughOccluderCheckIndividualObjects = effect.seeThroughOccluderCheckIndividualObjects;
+ seeThroughIntensity = effect.seeThroughIntensity;
+ seeThroughTintAlpha = effect.seeThroughTintAlpha;
+ seeThroughTintColor = effect.seeThroughTintColor;
+ seeThroughNoise = effect.seeThroughNoise;
+ seeThroughBorder = effect.seeThroughBorder;
+ seeThroughBorderColor = effect.seeThroughBorderColor;
+ seeThroughBorderWidth = effect.seeThroughBorderWidth;
+ seeThroughDepthOffset = effect.seeThroughDepthOffset;
+ seeThroughBorderOnly = effect.seeThroughBorderOnly;
+ seeThroughMaxDepth = effect.seeThroughMaxDepth;
+ seeThroughOrdered = effect.seeThroughOrdered;
+ seeThroughTexture = effect.seeThroughTexture;
+ seeThroughTextureScale = effect.seeThroughTextureScale;
+ seeThroughTextureUVSpace = effect.seeThroughTextureUVSpace;
+ hitFxInitialIntensity = effect.hitFxInitialIntensity;
+ hitFxMode = effect.hitFxMode;
+ hitFxFadeOutDuration = effect.hitFxFadeOutDuration;
+ hitFxColor = effect.hitFxColor;
+ hitFxRadius = effect.hitFxRadius;
+ }
+
+ GlowPassData[] GetGlowPassesCopy(GlowPassData[] glowPasses) {
+ if (glowPasses == null) {
+ return new GlowPassData[0];
+ }
+ GlowPassData[] pd = new GlowPassData[glowPasses.Length];
+ for (int k = 0; k < glowPasses.Length; k++) {
+ pd[k].alpha = glowPasses[k].alpha;
+ pd[k].color = glowPasses[k].color;
+ pd[k].offset = glowPasses[k].offset;
+ }
+ return pd;
+ }
+
+ public void OnValidate() {
+ seeThroughDepthOffset = Mathf.Max(0, seeThroughDepthOffset);
+ seeThroughMaxDepth = Mathf.Max(0, seeThroughMaxDepth);
+ seeThroughBorderWidth = Mathf.Max(0, seeThroughBorderWidth);
+ targetFXFadePower = Mathf.Max(0, targetFXFadePower);
+ cameraDistanceFadeNear = Mathf.Max(0, cameraDistanceFadeNear);
+ cameraDistanceFadeFar = Mathf.Max(0, cameraDistanceFadeFar);
+ if (glowPasses == null || glowPasses.Length == 0) {
+ glowPasses = new GlowPassData[4];
+ glowPasses[0] = new GlowPassData() { offset = 4, alpha = 0.1f, color = new Color(0.64f, 1f, 0f, 1f) };
+ glowPasses[1] = new GlowPassData() { offset = 3, alpha = 0.2f, color = new Color(0.64f, 1f, 0f, 1f) };
+ glowPasses[2] = new GlowPassData() { offset = 2, alpha = 0.3f, color = new Color(0.64f, 1f, 0f, 1f) };
+ glowPasses[3] = new GlowPassData() { offset = 1, alpha = 0.4f, color = new Color(0.64f, 1f, 0f, 1f) };
+ }
+ }
+
+ }
+}
+
diff --git a/Assets/Plugins/HighlightPlus/Scripts/HighlightProfile.cs.meta b/Assets/Plugins/HighlightPlus/Scripts/HighlightProfile.cs.meta
new file mode 100644
index 0000000..9238d3e
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/HighlightProfile.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 8e9253636bf2648bd813257f451f8486
+timeCreated: 1549831900
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Scripts/HighlightSeeThroughOccluder.cs b/Assets/Plugins/HighlightPlus/Scripts/HighlightSeeThroughOccluder.cs
new file mode 100644
index 0000000..50fff0c
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/HighlightSeeThroughOccluder.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace HighlightPlus {
+
+ public struct MeshData {
+ public Renderer renderer;
+ public int subMeshCount;
+ }
+
+ public enum OccluderMode {
+ BlocksSeeThrough,
+ TriggersSeeThrough
+ }
+
+ public enum DetectionMethod {
+ Stencil = 0,
+ RayCast = 1
+ }
+ [ExecuteInEditMode]
+ public class HighlightSeeThroughOccluder : MonoBehaviour {
+
+ public OccluderMode mode = OccluderMode.BlocksSeeThrough;
+
+ public DetectionMethod detectionMethod = DetectionMethod.Stencil;
+
+ [NonSerialized]
+ public MeshData[] meshData;
+
+ List rr;
+
+ void OnEnable () {
+ if (gameObject.activeInHierarchy) {
+ Init();
+ }
+ }
+
+ void Init() {
+
+ if (detectionMethod == DetectionMethod.RayCast) {
+ HighlightEffect.RegisterOccluder(this);
+ return;
+ }
+
+ if (rr == null) {
+ rr = new List();
+ } else {
+ rr.Clear();
+ }
+ GetComponentsInChildren(rr);
+ int rrCount = rr.Count;
+ meshData = new MeshData[rrCount];
+ for (int k = 0; k < rrCount; k++) {
+ meshData[k].renderer = rr[k];
+ meshData[k].subMeshCount = 1;
+ if (rr[k] is MeshRenderer) {
+ MeshFilter mf = rr[k].GetComponent();
+ if (mf != null && mf.sharedMesh != null) {
+ meshData[k].subMeshCount = mf.sharedMesh.subMeshCount;
+ }
+ } else if (rr[k] is SkinnedMeshRenderer) {
+ SkinnedMeshRenderer smr = (SkinnedMeshRenderer)rr[k];
+ meshData[k].subMeshCount = smr.sharedMesh.subMeshCount;
+ }
+ }
+ if (rrCount > 0) {
+ HighlightEffect.RegisterOccluder(this);
+ }
+ }
+
+ void OnDisable () {
+ HighlightEffect.UnregisterOccluder(this);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Scripts/HighlightSeeThroughOccluder.cs.meta b/Assets/Plugins/HighlightPlus/Scripts/HighlightSeeThroughOccluder.cs.meta
new file mode 100644
index 0000000..677b0f5
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/HighlightSeeThroughOccluder.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 8dd965ceab19c4729a9dabd8aeb2972a
+timeCreated: 1542876337
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Scripts/HighlightTrigger.cs b/Assets/Plugins/HighlightPlus/Scripts/HighlightTrigger.cs
new file mode 100644
index 0000000..ab642fe
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/HighlightTrigger.cs
@@ -0,0 +1,409 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.EventSystems;
+
+namespace HighlightPlus {
+
+ public enum TriggerMode {
+ ColliderEventsOnlyOnThisObject = 0,
+ RaycastOnThisObjectAndChildren = 1,
+ Volume = 2
+ }
+
+ public enum RayCastSource {
+ MousePosition = 0,
+ CameraDirection = 1
+ }
+
+
+ [RequireComponent(typeof(HighlightEffect))]
+ [ExecuteInEditMode]
+ [HelpURL("https://kronnect.com/guides/highlight-plus-introduction/")]
+ public class HighlightTrigger : MonoBehaviour {
+
+ [Tooltip("Enables highlight when pointer is over this object.")]
+ public bool highlightOnHover = true;
+ [Tooltip("Used to trigger automatic highlighting including children objects.")]
+#if ENABLE_INPUT_SYSTEM
+ public TriggerMode triggerMode = TriggerMode.RaycastOnThisObjectAndChildren;
+#else
+ public TriggerMode triggerMode = TriggerMode.ColliderEventsOnlyOnThisObject;
+#endif
+ public Camera raycastCamera;
+ public RayCastSource raycastSource = RayCastSource.MousePosition;
+ public LayerMask raycastLayerMask = -1;
+ [Tooltip("Minimum distance for target.")]
+ public float minDistance;
+ [Tooltip("Maximum distance for target. 0 = infinity")]
+ public float maxDistance;
+ [Tooltip("Blocks interaction if pointer is over an UI element")]
+ public bool respectUI = true;
+ public LayerMask volumeLayerMask;
+
+ const int MAX_RAYCAST_HITS = 100;
+
+
+ [Tooltip("If the object will be selected by clicking with mouse or tapping on it.")]
+ public bool selectOnClick;
+ [Tooltip("Profile to use when object is selected by clicking on it.")]
+ public HighlightProfile selectedProfile;
+ [Tooltip("Profile to use whtn object is selected and highlighted.")]
+ public HighlightProfile selectedAndHighlightedProfile;
+ [Tooltip("Automatically deselects any other selected object prior selecting this one")]
+ public bool singleSelection;
+ [Tooltip("Toggles selection on/off when clicking object")]
+ public bool toggle;
+ [Tooltip("Keeps current selection when clicking outside of any selectable object")]
+ public bool keepSelection = true;
+
+ [NonSerialized] public Collider[] colliders;
+
+ Collider currentCollider;
+ static RaycastHit[] hits;
+ HighlightEffect hb;
+
+ public HighlightEffect highlightEffect { get { return hb; } }
+
+ public event OnObjectSelectionEvent OnObjectSelected;
+ public event OnObjectSelectionEvent OnObjectUnSelected;
+ public event OnObjectHighlightEvent OnObjectHighlightStart;
+ public event OnObjectHighlightEvent OnObjectHighlightEnd;
+
+ TriggerMode currentTriggerMode;
+
+ [RuntimeInitializeOnLoadMethod]
+ void DomainReloadDisabledSupport() {
+ HighlightManager.selectedObjects.Clear();
+ }
+
+ void OnEnable() {
+ Init();
+ }
+
+ private void OnValidate() {
+ if (currentTriggerMode != triggerMode) {
+ currentTriggerMode = triggerMode;
+ if (currentTriggerMode == TriggerMode.RaycastOnThisObjectAndChildren) {
+ colliders = GetComponentsInChildren();
+ if (hits == null || hits.Length != MAX_RAYCAST_HITS) {
+ hits = new RaycastHit[MAX_RAYCAST_HITS];
+ }
+ if (Application.isPlaying) {
+ StopAllCoroutines();
+ if (gameObject.activeInHierarchy) {
+ StartCoroutine(DoRayCast());
+ }
+ }
+ }
+ }
+ }
+
+ public void Init() {
+ if (raycastCamera == null) {
+ raycastCamera = HighlightManager.GetCamera();
+ }
+ currentTriggerMode = triggerMode;
+ if (triggerMode == TriggerMode.RaycastOnThisObjectAndChildren) {
+ colliders = GetComponentsInChildren();
+ }
+ if (hb == null) {
+ hb = GetComponent();
+ }
+ InputProxy.Init();
+ }
+
+ void Start() {
+ if (triggerMode == TriggerMode.RaycastOnThisObjectAndChildren) {
+ if (raycastCamera == null) {
+ raycastCamera = HighlightManager.GetCamera();
+ if (raycastCamera == null) {
+ Debug.LogError("Highlight Trigger on " + gameObject.name + ": no camera found!");
+ }
+ }
+ if (colliders != null && colliders.Length > 0) {
+ hits = new RaycastHit[MAX_RAYCAST_HITS];
+ if (Application.isPlaying) {
+ StopAllCoroutines();
+ StartCoroutine(DoRayCast());
+ }
+ }
+ } else {
+ Collider collider = GetComponent();
+ if (collider == null) {
+ if (GetComponent() != null) {
+ gameObject.AddComponent();
+ }
+ }
+ }
+ }
+
+
+ IEnumerator DoRayCast() {
+ yield return null;
+ WaitForEndOfFrame w = new WaitForEndOfFrame();
+ while (triggerMode == TriggerMode.RaycastOnThisObjectAndChildren) {
+ if (raycastCamera == null) {
+ yield return null;
+ continue;
+ }
+
+ int hitCount;
+ bool hit = false;
+
+#if ENABLE_INPUT_SYSTEM
+
+ if (respectUI) {
+ EventSystem es = EventSystem.current;
+ if (es == null) {
+ es = CreateEventSystem();
+ }
+ List raycastResults = new List();
+ PointerEventData eventData = new PointerEventData(es);
+ Vector3 cameraPos = raycastCamera.transform.position;
+ if (raycastSource == RayCastSource.MousePosition) {
+ eventData.position = InputProxy.mousePosition;
+ } else {
+ eventData.position = new Vector2(raycastCamera.pixelWidth * 0.5f, raycastCamera.pixelHeight * 0.5f);
+ }
+ es.RaycastAll(eventData, raycastResults);
+ hitCount = raycastResults.Count;
+ // check UI blocker
+ bool blocked = false;
+ for (int k = 0; k < hitCount; k++) {
+ RaycastResult rr = raycastResults[k];
+ if (rr.module is UnityEngine.UI.GraphicRaycaster) {
+ blocked = true;
+ break;
+ }
+ }
+ if (blocked) {
+ yield return null;
+ continue;
+ }
+ // look for our gameobject
+ for (int k = 0; k < hitCount; k++) {
+ RaycastResult rr = raycastResults[k];
+ float distance = Vector3.Distance(rr.worldPosition, cameraPos);
+ if (distance < minDistance || (maxDistance > 0 && distance > maxDistance)) continue;
+
+ GameObject theGameObject = rr.gameObject;
+ for (int c = 0; c < colliders.Length; c++) {
+ if (colliders[c].gameObject == theGameObject) {
+ Collider theCollider = colliders[c];
+ hit = true;
+ if (selectOnClick && InputProxy.GetMouseButtonDown(0)) {
+ ToggleSelection();
+ break;
+ } else if (theCollider != currentCollider) {
+ SwitchCollider(theCollider);
+ k = hitCount;
+ break;
+ }
+ }
+ }
+ }
+ }
+ // if not blocked by UI and no hit found, fallback to raycast (required if no PhysicsRaycaster is present on the camera)
+
+#endif
+ Ray ray;
+ if (raycastSource == RayCastSource.MousePosition) {
+#if !ENABLE_INPUT_SYSTEM
+
+ if (!CanInteract()) {
+ yield return null;
+ continue;
+ }
+#endif
+ ray = raycastCamera.ScreenPointToRay(InputProxy.mousePosition);
+ } else {
+ ray = new Ray(raycastCamera.transform.position, raycastCamera.transform.forward);
+ }
+ if (maxDistance > 0) {
+ hitCount = Physics.RaycastNonAlloc(ray, hits, maxDistance, raycastLayerMask);
+ } else {
+ hitCount = Physics.RaycastNonAlloc(ray, hits, float.MaxValue, raycastLayerMask);
+ }
+ bool isMouseButonDown = InputProxy.GetMouseButtonDown(0);
+ for (int k = 0; k < hitCount; k++) {
+ if (Vector3.Distance(hits[k].point, ray.origin) < minDistance) continue;
+ Collider theCollider = hits[k].collider;
+ for (int c = 0; c < colliders.Length; c++) {
+ if (colliders[c] == theCollider) {
+ hit = true;
+ if (selectOnClick && isMouseButonDown) {
+ ToggleSelection();
+ break;
+ } else if (theCollider != currentCollider) {
+ SwitchCollider(theCollider);
+ k = hitCount;
+ break;
+ }
+ }
+ }
+ }
+
+
+ if (!hit && currentCollider != null) {
+ SwitchCollider(null);
+ }
+
+ if (selectOnClick && isMouseButonDown && !keepSelection && !hit) {
+ yield return w; // wait for other potential triggers to act
+ if (HighlightManager.lastTriggerFrame < Time.frameCount) {
+ HighlightManager.DeselectAll();
+ }
+ }
+
+ yield return null;
+ }
+ }
+
+#if ENABLE_INPUT_SYSTEM
+ EventSystem CreateEventSystem() {
+ GameObject eo = new GameObject("Event System created by Highlight Plus", typeof(EventSystem), typeof(UnityEngine.InputSystem.UI.InputSystemUIInputModule));
+ return eo.GetComponent();
+ }
+#endif
+
+ void SwitchCollider(Collider newCollider) {
+ if (!highlightOnHover && !hb.isSelected) return;
+
+ currentCollider = newCollider;
+ if (currentCollider != null) {
+ Highlight(true);
+ } else {
+ Highlight(false);
+ }
+ }
+
+ bool CanInteract() {
+ if (!respectUI) return true;
+ EventSystem es = EventSystem.current;
+ if (es == null) return true;
+ if (Application.isMobilePlatform && InputProxy.touchCount > 0 && es.IsPointerOverGameObject(InputProxy.GetFingerIdFromTouch(0))) {
+ return false;
+ } else if (es.IsPointerOverGameObject(-1))
+ return false;
+ return true;
+ }
+
+
+ void OnMouseDown() {
+ if (isActiveAndEnabled && triggerMode == TriggerMode.ColliderEventsOnlyOnThisObject) {
+ if (!CanInteract()) return;
+ if (selectOnClick && InputProxy.GetMouseButtonDown(0)) {
+ ToggleSelection();
+ return;
+ }
+ Highlight(true);
+ }
+ }
+
+ void OnMouseEnter() {
+ if (isActiveAndEnabled && triggerMode == TriggerMode.ColliderEventsOnlyOnThisObject) {
+ if (!CanInteract()) return;
+ Highlight(true);
+ }
+ }
+
+ void OnMouseExit() {
+ if (isActiveAndEnabled && triggerMode == TriggerMode.ColliderEventsOnlyOnThisObject) {
+ if (!CanInteract()) return;
+ Highlight(false);
+ }
+ }
+
+ void Highlight(bool state) {
+ if (state) {
+ if (!hb.highlighted) {
+ if (OnObjectHighlightStart != null && hb.target != null) {
+ if (!OnObjectHighlightStart(hb.target.gameObject)) return;
+ }
+ }
+ } else {
+ if (hb.highlighted) {
+ if (OnObjectHighlightEnd != null && hb.target != null) {
+ OnObjectHighlightEnd(hb.target.gameObject);
+ }
+ }
+ }
+ if (selectOnClick || hb.isSelected) {
+ if (hb.isSelected) {
+ if (state && selectedAndHighlightedProfile != null) {
+ selectedAndHighlightedProfile.Load(hb);
+ } else if (selectedProfile != null) {
+ selectedProfile.Load(hb);
+ } else {
+ hb.previousSettings.Load(hb);
+ }
+ if (hb.highlighted) {
+ hb.UpdateMaterialProperties();
+ } else {
+ hb.SetHighlighted(true);
+ }
+ return;
+ } else if (!highlightOnHover) {
+ hb.SetHighlighted(false);
+ return;
+ }
+ }
+ hb.SetHighlighted(state);
+ }
+
+
+ void ToggleSelection() {
+
+ HighlightManager.lastTriggerFrame = Time.frameCount;
+
+ bool newState = toggle ? !hb.isSelected : true;
+ if (newState) {
+ if (OnObjectSelected != null && !OnObjectSelected(gameObject)) return;
+ } else {
+ if (OnObjectUnSelected != null && !OnObjectUnSelected(gameObject)) return;
+ }
+
+ if (singleSelection && newState) {
+ HighlightManager.DeselectAll();
+ }
+ hb.isSelected = newState;
+ if (newState && !HighlightManager.selectedObjects.Contains(hb)) {
+ HighlightManager.selectedObjects.Add(hb);
+ } else if (!newState && HighlightManager.selectedObjects.Contains(hb)) {
+ HighlightManager.selectedObjects.Remove(hb);
+ }
+
+ if (hb.isSelected) {
+ if (hb.previousSettings == null) {
+ hb.previousSettings = ScriptableObject.CreateInstance();
+ }
+ hb.previousSettings.Save(hb);
+ } else {
+ hb.RestorePreviousHighlightEffectSettings();
+ }
+
+ Highlight(true);
+ }
+
+ public void OnTriggerEnter(Collider other) {
+ if (triggerMode == TriggerMode.Volume) {
+ if ((volumeLayerMask & (1 << other.gameObject.layer)) != 0) {
+ Highlight(true);
+ }
+ }
+ }
+
+ public void OnTriggerExit(Collider other) {
+ if (triggerMode == TriggerMode.Volume) {
+ if ((volumeLayerMask & (1 << other.gameObject.layer)) != 0) {
+ Highlight(false);
+ }
+ }
+ }
+
+
+ }
+
+}
\ No newline at end of file
diff --git a/Assets/Plugins/HighlightPlus/Scripts/HighlightTrigger.cs.meta b/Assets/Plugins/HighlightPlus/Scripts/HighlightTrigger.cs.meta
new file mode 100644
index 0000000..614f970
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/HighlightTrigger.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 5009cbb7e54994bb586cde7a70f34e6b
+timeCreated: 1542876337
+licenseType: Pro
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Scripts/InputProxy.cs b/Assets/Plugins/HighlightPlus/Scripts/InputProxy.cs
new file mode 100644
index 0000000..7f29b23
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/InputProxy.cs
@@ -0,0 +1,90 @@
+using UnityEngine;
+
+#if ENABLE_INPUT_SYSTEM
+using UnityEngine.InputSystem;
+using UnityEngine.InputSystem.Controls;
+using EnhancedTouch = UnityEngine.InputSystem.EnhancedTouch;
+#endif
+
+namespace HighlightPlus {
+
+ public static class InputProxy {
+
+#if ENABLE_INPUT_SYSTEM
+
+ static Vector3 lastPointerPosition;
+
+ public static void Init() {
+ if (!EnhancedTouch.EnhancedTouchSupport.enabled) {
+ EnhancedTouch.EnhancedTouchSupport.Enable();
+ }
+ }
+
+ public static Vector3 mousePosition {
+ get {
+ if (touchCount > 0) {
+ lastPointerPosition = EnhancedTouch.Touch.activeTouches[0].screenPosition;
+ } else {
+ Mouse m = Mouse.current;
+ if (m != null) {
+ lastPointerPosition = m.position.ReadValue();
+ }
+ }
+ return lastPointerPosition;
+ }
+ }
+
+ public static bool GetMouseButtonDown(int buttonIndex) {
+ if (touchCount > 0) {
+ return EnhancedTouch.Touch.activeTouches[0].phase == UnityEngine.InputSystem.TouchPhase.Began;
+ } else {
+ Mouse m = Mouse.current;
+ if (m == null) return false;
+ switch (buttonIndex) {
+ case 1: return m.rightButton.wasPressedThisFrame;
+ case 2: return m.middleButton.wasPressedThisFrame;
+ default: return m.leftButton.wasPressedThisFrame;
+ }
+ }
+ }
+
+ public static int touchCount { get { return EnhancedTouch.Touch.activeTouches.Count; } }
+
+ public static int GetFingerIdFromTouch(int touchIndex) {
+ EnhancedTouch.Touch touch = EnhancedTouch.Touch.activeTouches[touchIndex];
+ return touch.finger.index;
+ }
+
+ public static bool GetKeyDown(string name) {
+ return ((KeyControl)Keyboard.current[name]).wasPressedThisFrame;
+ }
+
+#else
+ public static void Init() {}
+
+ public static Vector3 mousePosition {
+ get {
+ return Input.mousePosition;
+ }
+ }
+
+ public static bool GetMouseButtonDown(int buttonIndex) {
+ return Input.GetMouseButtonDown(buttonIndex);
+ }
+
+ public static int touchCount {
+ get { return Input.touchCount; }
+ }
+
+ public static int GetFingerIdFromTouch(int touchIndex) {
+ return Input.GetTouch(touchIndex).fingerId;
+ }
+
+ public static bool GetKeyDown(string name) {
+ return Input.GetKeyDown(name);
+ }
+
+#endif
+
+ }
+}
diff --git a/Assets/Plugins/HighlightPlus/Scripts/InputProxy.cs.meta b/Assets/Plugins/HighlightPlus/Scripts/InputProxy.cs.meta
new file mode 100644
index 0000000..d11561a
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/InputProxy.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: dc62c86f3459d4fc29db51cfe5ecb977
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/HighlightPlus/Scripts/ShaderParams.cs b/Assets/Plugins/HighlightPlus/Scripts/ShaderParams.cs
new file mode 100644
index 0000000..d7e255d
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/ShaderParams.cs
@@ -0,0 +1,84 @@
+using UnityEngine;
+
+namespace HighlightPlus {
+
+ public static class ShaderParams {
+
+ // general uniforms
+ public static int Cull = Shader.PropertyToID("_Cull");
+ public static int BlurScale = Shader.PropertyToID("_BlurScale");
+ public static int Speed = Shader.PropertyToID("_Speed");
+ public static int ConstantWidth = Shader.PropertyToID("_ConstantWidth");
+ public static int CutOff = Shader.PropertyToID("_CutOff");
+ public static int ZTest = Shader.PropertyToID("_ZTest");
+ public static int Flip = Shader.PropertyToID("_Flip");
+ public static int Debug = Shader.PropertyToID("_Debug");
+ public static int Color = Shader.PropertyToID("_Color");
+ public static int MainTex = Shader.PropertyToID("_MainTex");
+ public static int BlendSrc = Shader.PropertyToID("_BlendSrc");
+ public static int BlendDst = Shader.PropertyToID("_BlendDst");
+ public static int FadeFactor = Shader.PropertyToID("_HP_Fade");
+
+ // outline uniforms
+ public static int OutlineWidth = Shader.PropertyToID("_OutlineWidth");
+ public static int OutlineZTest = Shader.PropertyToID("_OutlineZTest");
+ public static int OutlineDirection = Shader.PropertyToID("_OutlineDirection");
+ public static int OutlineColor = Shader.PropertyToID("_OutlineColor");
+ public static int OutlineVertexWidth = Shader.PropertyToID("_OutlineVertexWidth");
+ public static int OutlineGradientTex = Shader.PropertyToID("_OutlineGradientTex");
+ public static int OutlineVertexData = Shader.PropertyToID("_OutlineVertexData");
+
+ // glow uniforms
+ public static int GlowZTest = Shader.PropertyToID("_GlowZTest");
+ public static int GlowStencilComp = Shader.PropertyToID("_GlowStencilComp");
+ public static int GlowStencilOp = Shader.PropertyToID("_GlowStencilOp");
+ public static int GlowDirection = Shader.PropertyToID("_GlowDirection");
+ public static int Glow = Shader.PropertyToID("_Glow");
+ public static int GlowColor = Shader.PropertyToID("_GlowColor");
+ public static int Glow2 = Shader.PropertyToID("_Glow2");
+
+ // see-through uniforms
+ public static int SeeThrough = Shader.PropertyToID("_SeeThrough");
+ public static int SeeThroughNoise = Shader.PropertyToID("_SeeThroughNoise");
+ public static int SeeThroughBorderWidth = Shader.PropertyToID("_SeeThroughBorderWidth");
+ public static int SeeThroughBorderConstantWidth = Shader.PropertyToID("_SeeThroughBorderConstantWidth");
+ public static int SeeThroughTintColor = Shader.PropertyToID("_SeeThroughTintColor");
+ public static int SeeThroughBorderColor = Shader.PropertyToID("_SeeThroughBorderColor");
+ public static int SeeThroughStencilRef = Shader.PropertyToID("_SeeThroughStencilRef");
+ public static int SeeThroughStencilComp = Shader.PropertyToID("_SeeThroughStencilComp");
+ public static int SeeThroughStencilPassOp = Shader.PropertyToID("_SeeThroughStencilPassOp");
+ public static int SeeThroughDepthOffset = Shader.PropertyToID("_SeeThroughDepthOffset");
+ public static int SeeThroughMaxDepth = Shader.PropertyToID("_SeeThroughMaxDepth");
+ public static int SeeThroughOrdered = Shader.PropertyToID("_SeeThroughOrdered");
+ public static int SeeThroughTexture = Shader.PropertyToID("_SeeThroughTexture");
+ public static int SeeThroughTextureScale = Shader.PropertyToID("_SeeThroughTextureScale");
+
+ // inner glow uniforms
+ public static int InnerGlowWidth = Shader.PropertyToID("_InnerGlowWidth");
+ public static int InnerGlowZTest = Shader.PropertyToID("_InnerGlowZTest");
+ public static int InnerGlowColor = Shader.PropertyToID("_InnerGlowColor");
+
+ // overlay uniforms
+ public static int OverlayData = Shader.PropertyToID("_OverlayData");
+ public static int OverlayBackColor = Shader.PropertyToID("_OverlayBackColor");
+ public static int OverlayColor = Shader.PropertyToID("_OverlayColor");
+ public static int OverlayHitPosData = Shader.PropertyToID("_OverlayHitPosData");
+ public static int OverlayHitStartTime = Shader.PropertyToID("_OverlayHitStartTime");
+ public static int OverlayTexture = Shader.PropertyToID("_OverlayTexture");
+
+ // target uniforms
+ public static int TargetFXRenderData = Shader.PropertyToID("_TargetFXRenderData");
+
+ // keywords
+ public const string SKW_ALPHACLIP = "HP_ALPHACLIP";
+ public const string SKW_OUTLINE_GRADIENT_WS = "HP_OUTLINE_GRADIENT_WS";
+ public const string SKW_OUTLINE_GRADIENT_LS = "HP_OUTLINE_GRADIENT_LS";
+ public const string SKW_DEPTHCLIP = "HP_DEPTHCLIP";
+ public const string SKW_DEPTH_OFFSET = "HP_DEPTH_OFFSET";
+ public const string SKW_TEXTURE_TRIPLANAR = "HP_TEXTURE_TRIPLANAR";
+ public const string SKW_TEXTURE_SCREENSPACE = "HP_TEXTURE_SCREENSPACE";
+ public const string SKW_TEXTURE_OBJECTSPACE = "HP_TEXTURE_OBJECTSPACE";
+ public const string SKW_SEETHROUGH_ONLY_BORDER = "HP_SEETHROUGH_ONLY_BORDER";
+ }
+}
+
diff --git a/Assets/Plugins/HighlightPlus/Scripts/ShaderParams.cs.meta b/Assets/Plugins/HighlightPlus/Scripts/ShaderParams.cs.meta
new file mode 100644
index 0000000..e076e9c
--- /dev/null
+++ b/Assets/Plugins/HighlightPlus/Scripts/ShaderParams.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 43d6485e67bc3460fabef0a5962f8e42
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/ModularFirstPersonController.meta b/Assets/Plugins/ModularFirstPersonController.meta
new file mode 100644
index 0000000..a9ddc6c
--- /dev/null
+++ b/Assets/Plugins/ModularFirstPersonController.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: a1a7422012144644d9e8320cc0c03bf1
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/ModularFirstPersonController/FirstPersonController.meta b/Assets/Plugins/ModularFirstPersonController/FirstPersonController.meta
new file mode 100644
index 0000000..985fea4
--- /dev/null
+++ b/Assets/Plugins/ModularFirstPersonController/FirstPersonController.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: f7ee2acc12a8f6346b3c67deacbef990
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/ModularFirstPersonController/FirstPersonController/CircleReticle.png b/Assets/Plugins/ModularFirstPersonController/FirstPersonController/CircleReticle.png
new file mode 100644
index 0000000..bce1203
Binary files /dev/null and b/Assets/Plugins/ModularFirstPersonController/FirstPersonController/CircleReticle.png differ
diff --git a/Assets/Plugins/ModularFirstPersonController/FirstPersonController/CircleReticle.png.meta b/Assets/Plugins/ModularFirstPersonController/FirstPersonController/CircleReticle.png.meta
new file mode 100644
index 0000000..580d294
--- /dev/null
+++ b/Assets/Plugins/ModularFirstPersonController/FirstPersonController/CircleReticle.png.meta
@@ -0,0 +1,116 @@
+fileFormatVersion: 2
+guid: 2ba574d1e6a3b4d469eed23b438f843c
+TextureImporter:
+ internalIDToNameTable: []
+ externalObjects: {}
+ serializedVersion: 11
+ mipmaps:
+ mipMapMode: 0
+ enableMipMap: 0
+ sRGBTexture: 1
+ linearTexture: 0
+ fadeOut: 0
+ borderMipMap: 0
+ mipMapsPreserveCoverage: 0
+ alphaTestReferenceValue: 0.5
+ mipMapFadeDistanceStart: 1
+ mipMapFadeDistanceEnd: 3
+ bumpmap:
+ convertToNormalMap: 0
+ externalNormalMap: 0
+ heightScale: 0.25
+ normalMapFilter: 0
+ isReadable: 0
+ streamingMipmaps: 0
+ streamingMipmapsPriority: 0
+ grayScaleToAlpha: 0
+ generateCubemap: 6
+ cubemapConvolution: 0
+ seamlessCubemap: 0
+ textureFormat: 1
+ maxTextureSize: 2048
+ textureSettings:
+ serializedVersion: 2
+ filterMode: -1
+ aniso: -1
+ mipBias: -100
+ wrapU: 1
+ wrapV: 1
+ wrapW: -1
+ nPOTScale: 0
+ lightmap: 0
+ compressionQuality: 50
+ spriteMode: 1
+ spriteExtrude: 1
+ spriteMeshType: 1
+ alignment: 0
+ spritePivot: {x: 0.5, y: 0.5}
+ spritePixelsToUnits: 100
+ spriteBorder: {x: 0, y: 0, z: 0, w: 0}
+ spriteGenerateFallbackPhysicsShape: 1
+ alphaUsage: 1
+ alphaIsTransparency: 1
+ spriteTessellationDetail: -1
+ textureType: 8
+ textureShape: 1
+ singleChannelComponent: 0
+ maxTextureSizeSet: 0
+ compressionQualitySet: 0
+ textureFormatSet: 0
+ applyGammaDecoding: 0
+ platformSettings:
+ - serializedVersion: 3
+ buildTarget: DefaultTexturePlatform
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: Standalone
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ - serializedVersion: 3
+ buildTarget: WebGL
+ maxTextureSize: 2048
+ resizeAlgorithm: 0
+ textureFormat: -1
+ textureCompression: 1
+ compressionQuality: 50
+ crunchedCompression: 0
+ allowsAlphaSplitting: 0
+ overridden: 0
+ androidETC2FallbackOverride: 0
+ forceMaximumCompressionQuality_BC6H_BC7: 0
+ spriteSheet:
+ serializedVersion: 2
+ sprites: []
+ outline: []
+ physicsShape: []
+ bones: []
+ spriteID: 5e97eb03825dee720800000000000000
+ internalID: 0
+ vertices: []
+ indices:
+ edges: []
+ weights: []
+ secondaryTextures: []
+ spritePackingTag:
+ pSDRemoveMatte: 0
+ pSDShowRemoveMatteOption: 0
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Plugins/ModularFirstPersonController/FirstPersonController/FirstPersonController.cs b/Assets/Plugins/ModularFirstPersonController/FirstPersonController/FirstPersonController.cs
new file mode 100644
index 0000000..e998af0
--- /dev/null
+++ b/Assets/Plugins/ModularFirstPersonController/FirstPersonController/FirstPersonController.cs
@@ -0,0 +1,797 @@
+// CHANGE LOG
+//
+// CHANGES || version VERSION
+//
+// "Enable/Disable Headbob, Changed look rotations - should result in reduced camera jitters" || version 1.0.1
+
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+using UnityEngine.EventSystems;
+using System;
+
+#if UNITY_EDITOR
+using UnityEditor;
+using System.Net;
+#endif
+
+public class FirstPersonController : MonoBehaviour
+{
+ public Rigidbody rb;
+
+ #region Camera Movement Variables
+
+ public Camera playerCamera;
+
+ public float fov = 60f;
+ public bool invertCamera = false;
+ public bool cameraCanMove = true;
+ public float mouseSensitivity = 2f;
+ public float maxLookAngle = 50f;
+
+ // Crosshair
+ public bool lockCursor = true;
+ public bool crosshair = true;
+ public Sprite crosshairImage;
+ public Color crosshairColor = Color.white;
+
+ // Internal Variables
+ public float yaw = 0.0f;
+ public float pitch = 0.0f;
+ private Image crosshairObject;
+
+
+ #region Camera Zoom Variables
+
+ public bool enableZoom = true;
+ public bool holdToZoom = false;
+ public KeyCode zoomKey = KeyCode.Mouse1;
+ public float zoomFOV = 30f;
+ public float zoomStepTime = 5f;
+ public Action zoomAction;
+ public float zoomScale = 1;
+
+ // Internal Variables
+ private bool isZoomed = false;
+
+ #endregion
+ #endregion
+
+ #region Movement Variables
+
+ public bool playerCanMove = true;
+ public bool stopForce = true;
+ public float walkSpeed = 5f;
+ private float defulatWalkSpeed = 5f;
+ public float maxVelocityChange = 10f;
+
+ // Internal Variables
+ private bool isWalking = false;
+
+ #region Sprint
+
+ public bool enableSprint = true;
+ public bool unlimitedSprint = false;
+ public bool enableSprintZoom = false;
+ public KeyCode sprintKey = KeyCode.LeftShift;
+ public float sprintSpeed = 7f;
+ private float defultSprintSpeed = 7f;
+ public float sprintDuration = 5f;
+ public float sprintCooldown = .5f;
+ public float sprintFOV = 80f;
+ public float sprintFOVStepTime = 10f;
+
+ // Sprint Bar
+ public bool useSprintBar = true;
+ public bool hideBarWhenFull = true;
+ public Image sprintBarBG;
+ public Image sprintBar;
+ public float sprintBarWidthPercent = .3f;
+ public float sprintBarHeightPercent = .015f;
+
+ // Internal Variables
+ private CanvasGroup sprintBarCG;
+ private bool isSprinting = false;
+ private float sprintRemaining;
+ private float sprintBarWidth;
+ private float sprintBarHeight;
+ private bool isSprintCooldown = false;
+ private float sprintCooldownReset;
+
+ #endregion
+
+
+ #region Jump
+
+ public bool enableJump = true;
+ public KeyCode jumpKey = KeyCode.Space;
+ public float jumpPower = 5f;
+
+ // Internal Variables
+ private bool isGrounded = false;
+
+ #endregion
+
+ #region Crouch
+
+ public bool enableCrouch = true;
+ public bool holdToCrouch = true;
+ public KeyCode crouchKey = KeyCode.LeftControl;
+ private float crouchHeight = .5f;
+ public float speedReduction = .5f;
+
+ // Internal Variables
+ public bool isCrouched = false;
+ private Vector3 originalScale;
+
+ #endregion
+ #endregion
+
+ #region Head Bob
+
+ public bool enableHeadBob = true;
+ public Transform joint;
+ public float bobSpeed = 10f;
+ public Vector3 bobAmount = new Vector3(.15f, .05f, 0f);
+
+ // Internal Variables
+ private Vector3 jointOriginalPos;
+ private float timer = 0;
+
+ #endregion
+
+
+
+ private void Awake()
+ {
+ rb = GetComponent();
+
+ crosshairObject = GetComponentInChildren(true);
+
+ // Set internal variables
+ playerCamera.fieldOfView = fov;
+ originalScale = transform.localScale;
+ jointOriginalPos = joint.localPosition;
+
+ if (!unlimitedSprint)
+ {
+ sprintRemaining = sprintDuration;
+ sprintCooldownReset = sprintCooldown;
+ }
+ }
+
+ void Start()
+ {
+ if (lockCursor)
+ {
+ Cursor.lockState = CursorLockMode.Locked;
+ }
+
+ //if (crosshair)
+ //{
+ // crosshairObject.sprite = crosshairImage;
+ // crosshairObject.color = crosshairColor;
+ //}
+ //else
+ //{
+ // crosshairObject.gameObject.SetActive(false);
+ //}
+
+ #region Sprint Bar
+
+ //sprintBarCG = GetComponentInChildren();
+
+ //if (useSprintBar)
+ //{
+ // sprintBarBG.gameObject.SetActive(true);
+ // sprintBar.gameObject.SetActive(true);
+
+ // float screenWidth = Screen.width;
+ // float screenHeight = Screen.height;
+
+ // sprintBarWidth = screenWidth * sprintBarWidthPercent;
+ // sprintBarHeight = screenHeight * sprintBarHeightPercent;
+
+ // sprintBarBG.rectTransform.sizeDelta = new Vector3(sprintBarWidth, sprintBarHeight, 0f);
+ // sprintBar.rectTransform.sizeDelta = new Vector3(sprintBarWidth - 2, sprintBarHeight - 2, 0f);
+
+ // if (hideBarWhenFull)
+ // {
+ // sprintBarCG.alpha = 0;
+ // }
+ //}
+ //else
+ //{
+ // sprintBarBG.gameObject.SetActive(false);
+ // sprintBar.gameObject.SetActive(false);
+ //}
+
+ #endregion
+ }
+
+ float camRotation;
+
+ private void Update()
+ {
+ if (EventSystem.current.IsPointerOverGameObject()) return;
+ float scrollValue = Input.GetAxis("Mouse ScrollWheel");
+ if (scrollValue != 0)
+ {
+ playerCamera.fieldOfView = Mathf.Clamp(playerCamera.fieldOfView - scrollValue * 20, 10, 60);
+ zoomScale = Mathf.Clamp(zoomScale - scrollValue * 0.3f, 0.1f, 1);
+ mouseSensitivity = Mathf.Clamp(mouseSensitivity - scrollValue * 0.8f, 0.2f, 2);
+ walkSpeed = Mathf.Clamp(walkSpeed - scrollValue * 2f, 0.5f, 5);
+ zoomAction?.Invoke(zoomScale);
+ }
+ #region Camera
+
+ // Control camera movement
+ if (Input.GetMouseButton(1))
+ {
+ if (cameraCanMove)
+ {
+ yaw = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * mouseSensitivity;
+
+ if (!invertCamera)
+ {
+ pitch -= mouseSensitivity * Input.GetAxis("Mouse Y");
+ }
+ else
+ {
+ // Inverted Y
+ pitch += mouseSensitivity * Input.GetAxis("Mouse Y");
+ }
+
+ // Clamp pitch between lookAngle
+ pitch = Mathf.Clamp(pitch, -maxLookAngle, maxLookAngle);
+
+ transform.localEulerAngles = new Vector3(0, yaw, 0);
+ playerCamera.transform.localEulerAngles = new Vector3(pitch, 0, 0);
+ }
+ }
+
+ #region Camera Zoom
+
+ if (enableZoom)
+ {
+ // Changes isZoomed when key is pressed
+ // Behavior for toogle zoom
+ if (Input.GetKeyDown(zoomKey) && !holdToZoom && !isSprinting)
+ {
+ if (!isZoomed)
+ {
+ isZoomed = true;
+ }
+ else
+ {
+ isZoomed = false;
+ }
+ }
+
+ // Changes isZoomed when key is pressed
+ // Behavior for hold to zoom
+ if (holdToZoom && !isSprinting)
+ {
+ if (Input.GetKeyDown(zoomKey))
+ {
+ isZoomed = true;
+ }
+ else if (Input.GetKeyUp(zoomKey))
+ {
+ isZoomed = false;
+ }
+ }
+
+ // Lerps camera.fieldOfView to allow for a smooth transistion
+ if (isZoomed)
+ {
+ playerCamera.fieldOfView = Mathf.Lerp(playerCamera.fieldOfView, zoomFOV, zoomStepTime * Time.deltaTime);
+ }
+ else if (!isZoomed && !isSprinting)
+ {
+ playerCamera.fieldOfView = Mathf.Lerp(playerCamera.fieldOfView, fov, zoomStepTime * Time.deltaTime);
+ }
+ }
+
+ #endregion
+ #endregion
+
+ #region Sprint
+
+ if (enableSprint)
+ {
+ if (isSprinting)
+ {
+ isZoomed = false;
+
+ if (enableSprintZoom)
+ playerCamera.fieldOfView = Mathf.Lerp(playerCamera.fieldOfView, sprintFOV, sprintFOVStepTime * Time.deltaTime);
+
+ // Drain sprint remaining while sprinting
+ if (!unlimitedSprint)
+ {
+ sprintRemaining -= 1 * Time.deltaTime;
+ if (sprintRemaining <= 0)
+ {
+ isSprinting = false;
+ isSprintCooldown = true;
+ }
+ }
+ }
+ else
+ {
+ // Regain sprint while not sprinting
+ sprintRemaining = Mathf.Clamp(sprintRemaining += 1 * Time.deltaTime, 0, sprintDuration);
+ }
+
+ // Handles sprint cooldown
+ // When sprint remaining == 0 stops sprint ability until hitting cooldown
+ if (isSprintCooldown)
+ {
+ sprintCooldown -= 1 * Time.deltaTime;
+ if (sprintCooldown <= 0)
+ {
+ isSprintCooldown = false;
+ }
+ }
+ else
+ {
+ sprintCooldown = sprintCooldownReset;
+ }
+
+ // Handles sprintBar
+ if (useSprintBar && !unlimitedSprint)
+ {
+ float sprintRemainingPercent = sprintRemaining / sprintDuration;
+ sprintBar.transform.localScale = new Vector3(sprintRemainingPercent, 1f, 1f);
+ }
+ }
+
+ #endregion
+
+ #region Jump
+
+ // Gets input and calls jump method
+ if (enableJump && Input.GetKeyDown(jumpKey) && isGrounded)
+ {
+ Jump();
+ }
+
+ #endregion
+
+ #region Crouch
+
+ if (enableCrouch)
+ {
+ if (Input.GetKeyDown(crouchKey) && !holdToCrouch)
+ {
+ Crouch();
+ }
+
+ if (Input.GetKeyDown(crouchKey) && holdToCrouch)
+ {
+ isCrouched = false;
+ Crouch();
+ }
+ else if (Input.GetKeyUp(crouchKey) && holdToCrouch)
+ {
+ isCrouched = true;
+ Crouch();
+ }
+ }
+
+ #endregion
+
+ CheckGround();
+
+
+
+
+ if (enableHeadBob)
+ {
+ HeadBob();
+ }
+ }
+
+ void FixedUpdate()
+ {
+ #region Movement
+
+ if (playerCanMove)
+ {
+ // Calculate how fast we should be moving
+ if (Input.GetAxis("Horizontal") == 0 && Input.GetAxis("Vertical") == 0) return;
+
+ Vector3 targetVelocity = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
+
+ // Checks if player is walking and isGrounded
+ // Will allow head bob
+ if (targetVelocity.x != 0 || targetVelocity.z != 0 && isGrounded)
+ {
+ isWalking = true;
+ }
+ else
+ {
+ isWalking = false;
+ }
+
+ // All movement calculations shile sprint is active
+ if (enableSprint && Input.GetKey(sprintKey) && sprintRemaining > 0f && !isSprintCooldown)
+ {
+ targetVelocity = transform.TransformDirection(targetVelocity) * sprintSpeed;
+
+ // Apply a force that attempts to reach our target velocity
+ Vector3 velocity = rb.velocity;
+ Vector3 velocityChange = (targetVelocity - velocity);
+ velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
+ velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
+ velocityChange.y = 0;
+
+ // Player is only moving when valocity change != 0
+ // Makes sure fov change only happens during movement
+ if (velocityChange.x != 0 || velocityChange.z != 0)
+ {
+ isSprinting = true;
+
+ if (isCrouched)
+ {
+ Crouch();
+ }
+
+ if (hideBarWhenFull && !unlimitedSprint)
+ {
+ sprintBarCG.alpha += 5 * Time.deltaTime;
+ }
+ }
+
+ rb.AddForce(velocityChange, ForceMode.VelocityChange);
+ }
+ // All movement calculations while walking
+ else
+ {
+ //isSprinting = false;
+
+ //if (hideBarWhenFull && sprintRemaining == sprintDuration)
+ //{
+ // sprintBarCG.alpha -= 3 * Time.deltaTime;
+ //}
+
+ targetVelocity = transform.TransformDirection(targetVelocity) * walkSpeed;
+
+ // Apply a force that attempts to reach our target velocity
+ Vector3 velocity = rb.velocity;
+ Vector3 velocityChange = (targetVelocity - velocity);
+ velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
+ velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
+ velocityChange.y = 0;
+
+ rb.AddForce(velocityChange, ForceMode.VelocityChange);
+ }
+ }
+
+ #endregion
+ }
+
+ // Sets isGrounded based on a raycast sent straigth down from the player object
+ private void CheckGround()
+ {
+ Vector3 origin = new Vector3(transform.position.x, transform.position.y - (transform.localScale.y * .5f), transform.position.z);
+ Vector3 direction = transform.TransformDirection(Vector3.down);
+ float distance = .75f;
+
+ if (Physics.Raycast(origin, direction, out RaycastHit hit, distance))
+ {
+ Debug.DrawRay(origin, direction * distance, Color.red);
+ isGrounded = true;
+ }
+ else
+ {
+ isGrounded = false;
+ }
+ }
+
+ private void Jump()
+ {
+ // Adds force to the player rigidbody to jump
+ if (isGrounded)
+ {
+ rb.AddForce(0f, jumpPower, 0f, ForceMode.Impulse);
+ isGrounded = false;
+ }
+
+ // When crouched and using toggle system, will uncrouch for a jump
+ if (isCrouched && !holdToCrouch)
+ {
+ Crouch();
+ }
+ }
+
+ public void Crouch()
+ {
+ // Stands player up to full height
+ // Brings walkSpeed back up to original speed
+ if (isCrouched)
+ {
+ transform.localScale = new Vector3(originalScale.x, originalScale.y, originalScale.z);
+ walkSpeed /= speedReduction;
+ transform.GetChild(0).localScale = new Vector3(1, 1, 1);
+ isCrouched = false;
+ }
+ // Crouches player down to set height
+ // Reduces walkSpeed
+ else
+ {
+ transform.localScale = new Vector3(originalScale.x, crouchHeight, originalScale.z);
+ walkSpeed *= speedReduction;
+ transform.GetChild(0).localScale = new Vector3(1, 2, 1);
+ isCrouched = true;
+ }
+ }
+
+ private void HeadBob()
+ {
+ if (isWalking)
+ {
+ // Calculates HeadBob speed during sprint
+ if (isSprinting)
+ {
+ timer += Time.deltaTime * (bobSpeed + sprintSpeed);
+ }
+ // Calculates HeadBob speed during crouched movement
+ else if (isCrouched)
+ {
+ timer += Time.deltaTime * (bobSpeed * speedReduction);
+ }
+ // Calculates HeadBob speed during walking
+ else
+ {
+ timer += Time.deltaTime * bobSpeed;
+ }
+ // Applies HeadBob movement
+ joint.localPosition = new Vector3(jointOriginalPos.x + Mathf.Sin(timer) * bobAmount.x, jointOriginalPos.y + Mathf.Sin(timer) * bobAmount.y, jointOriginalPos.z + Mathf.Sin(timer) * bobAmount.z);
+ }
+ else
+ {
+ // Resets when play stops moving
+ timer = 0;
+ joint.localPosition = new Vector3(Mathf.Lerp(joint.localPosition.x, jointOriginalPos.x, Time.deltaTime * bobSpeed), Mathf.Lerp(joint.localPosition.y, jointOriginalPos.y, Time.deltaTime * bobSpeed), Mathf.Lerp(joint.localPosition.z, jointOriginalPos.z, Time.deltaTime * bobSpeed));
+ }
+ }
+
+
+ private void OnCollisionEnter(Collision collision)
+ {
+ stopForce = true;
+ }
+
+ public void ChangeSpped(float para)
+ {
+ walkSpeed = para * defulatWalkSpeed;
+ sprintSpeed = para * defultSprintSpeed;
+ }
+ ///
+ /// 改变fpc 上下视角范围
+ ///
+ ///
+ ///
+ public void ChangeViewLowLimt(bool cancle, float para)
+ {
+ walkSpeed = para * defulatWalkSpeed;
+ sprintSpeed = para * defultSprintSpeed;
+ }
+}
+
+
+
+// Custom Editor
+#if UNITY_EDITOR
+[CustomEditor(typeof(FirstPersonController)), InitializeOnLoadAttribute]
+public class FirstPersonControllerEditor : Editor
+{
+ FirstPersonController fpc;
+ SerializedObject SerFPC;
+
+ private void OnEnable()
+ {
+ fpc = (FirstPersonController)target;
+ SerFPC = new SerializedObject(fpc);
+ }
+
+ public override void OnInspectorGUI()
+ {
+ SerFPC.Update();
+
+ EditorGUILayout.Space();
+ GUILayout.Label("Modular First Person Controller", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontStyle = FontStyle.Bold, fontSize = 16 });
+ GUILayout.Label("By Jess Case", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontStyle = FontStyle.Normal, fontSize = 12 });
+ GUILayout.Label("version 1.0.1", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontStyle = FontStyle.Normal, fontSize = 12 });
+ EditorGUILayout.Space();
+
+ #region Camera Setup
+
+ EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
+ GUILayout.Label("Camera Setup", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontStyle = FontStyle.Bold, fontSize = 13 }, GUILayout.ExpandWidth(true));
+ EditorGUILayout.Space();
+
+ fpc.playerCamera = (Camera)EditorGUILayout.ObjectField(new GUIContent("Camera", "Camera attached to the controller."), fpc.playerCamera, typeof(Camera), true);
+ fpc.fov = EditorGUILayout.Slider(new GUIContent("Field of View", "The camera’s view angle. Changes the player camera directly."), fpc.fov, fpc.zoomFOV, 179f);
+ fpc.cameraCanMove = EditorGUILayout.ToggleLeft(new GUIContent("Enable Camera Rotation", "Determines if the camera is allowed to move."), fpc.cameraCanMove);
+
+ GUI.enabled = fpc.cameraCanMove;
+ fpc.invertCamera = EditorGUILayout.ToggleLeft(new GUIContent("Invert Camera Rotation", "Inverts the up and down movement of the camera."), fpc.invertCamera);
+ fpc.mouseSensitivity = EditorGUILayout.Slider(new GUIContent("Look Sensitivity", "Determines how sensitive the mouse movement is."), fpc.mouseSensitivity, .1f, 10f);
+ fpc.maxLookAngle = EditorGUILayout.Slider(new GUIContent("Max Look Angle", "Determines the max and min angle the player camera is able to look."), fpc.maxLookAngle, 40, 90);
+ GUI.enabled = true;
+
+ fpc.lockCursor = EditorGUILayout.ToggleLeft(new GUIContent("Lock and Hide Cursor", "Turns off the cursor visibility and locks it to the middle of the screen."), fpc.lockCursor);
+
+ fpc.crosshair = EditorGUILayout.ToggleLeft(new GUIContent("Auto Crosshair", "Determines if the basic crosshair will be turned on, and sets is to the center of the screen."), fpc.crosshair);
+
+ // Only displays crosshair options if crosshair is enabled
+ if (fpc.crosshair)
+ {
+ EditorGUI.indentLevel++;
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.PrefixLabel(new GUIContent("Crosshair Image", "Sprite to use as the crosshair."));
+ fpc.crosshairImage = (Sprite)EditorGUILayout.ObjectField(fpc.crosshairImage, typeof(Sprite), false);
+ EditorGUILayout.EndHorizontal();
+
+ EditorGUILayout.BeginHorizontal();
+ fpc.crosshairColor = EditorGUILayout.ColorField(new GUIContent("Crosshair Color", "Determines the color of the crosshair."), fpc.crosshairColor);
+ EditorGUILayout.EndHorizontal();
+ EditorGUI.indentLevel--;
+ }
+
+ EditorGUILayout.Space();
+
+ #region Camera Zoom Setup
+
+ GUILayout.Label("Zoom", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleLeft, fontStyle = FontStyle.Bold, fontSize = 13 }, GUILayout.ExpandWidth(true));
+
+ fpc.enableZoom = EditorGUILayout.ToggleLeft(new GUIContent("Enable Zoom", "Determines if the player is able to zoom in while playing."), fpc.enableZoom);
+
+ GUI.enabled = fpc.enableZoom;
+ fpc.holdToZoom = EditorGUILayout.ToggleLeft(new GUIContent("Hold to Zoom", "Requires the player to hold the zoom key instead if pressing to zoom and unzoom."), fpc.holdToZoom);
+ fpc.zoomKey = (KeyCode)EditorGUILayout.EnumPopup(new GUIContent("Zoom Key", "Determines what key is used to zoom."), fpc.zoomKey);
+ fpc.zoomFOV = EditorGUILayout.Slider(new GUIContent("Zoom FOV", "Determines the field of view the camera zooms to."), fpc.zoomFOV, .1f, fpc.fov);
+ fpc.zoomStepTime = EditorGUILayout.Slider(new GUIContent("Step Time", "Determines how fast the FOV transitions while zooming in."), fpc.zoomStepTime, .1f, 10f);
+ GUI.enabled = true;
+
+ #endregion
+
+ #endregion
+
+ #region Movement Setup
+
+ EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
+ GUILayout.Label("Movement Setup", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontStyle = FontStyle.Bold, fontSize = 13 }, GUILayout.ExpandWidth(true));
+ EditorGUILayout.Space();
+
+ fpc.playerCanMove = EditorGUILayout.ToggleLeft(new GUIContent("Enable Player Movement", "Determines if the player is allowed to move."), fpc.playerCanMove);
+
+ GUI.enabled = fpc.playerCanMove;
+ fpc.walkSpeed = EditorGUILayout.Slider(new GUIContent("Walk Speed", "Determines how fast the player will move while walking."), fpc.walkSpeed, .1f, fpc.sprintSpeed);
+ GUI.enabled = true;
+
+ EditorGUILayout.Space();
+
+ #region Sprint
+
+ GUILayout.Label("Sprint", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleLeft, fontStyle = FontStyle.Bold, fontSize = 13 }, GUILayout.ExpandWidth(true));
+
+ fpc.enableSprint = EditorGUILayout.ToggleLeft(new GUIContent("Enable Sprint", "Determines if the player is allowed to sprint."), fpc.enableSprint);
+
+ GUI.enabled = fpc.enableSprint;
+ fpc.enableSprintZoom = EditorGUILayout.ToggleLeft(new GUIContent("Enable Sprint Zoom", "Enable zoom while sprinting,\"Enable Zoom\" to resume while zoomed"), fpc.enableSprintZoom);
+ fpc.unlimitedSprint = EditorGUILayout.ToggleLeft(new GUIContent("Unlimited Sprint", "Determines if 'Sprint Duration' is enabled. Turning this on will allow for unlimited sprint."), fpc.unlimitedSprint);
+ fpc.sprintKey = (KeyCode)EditorGUILayout.EnumPopup(new GUIContent("Sprint Key", "Determines what key is used to sprint."), fpc.sprintKey);
+ fpc.sprintSpeed = EditorGUILayout.Slider(new GUIContent("Sprint Speed", "Determines how fast the player will move while sprinting."), fpc.sprintSpeed, fpc.walkSpeed, 20f);
+
+ //GUI.enabled = !fpc.unlimitedSprint;
+ fpc.sprintDuration = EditorGUILayout.Slider(new GUIContent("Sprint Duration", "Determines how long the player can sprint while unlimited sprint is disabled."), fpc.sprintDuration, 1f, 20f);
+ fpc.sprintCooldown = EditorGUILayout.Slider(new GUIContent("Sprint Cooldown", "Determines how long the recovery time is when the player runs out of sprint."), fpc.sprintCooldown, .1f, fpc.sprintDuration);
+ //GUI.enabled = true;
+
+ fpc.sprintFOV = EditorGUILayout.Slider(new GUIContent("Sprint FOV", "Determines the field of view the camera changes to while sprinting."), fpc.sprintFOV, fpc.fov, 179f);
+ fpc.sprintFOVStepTime = EditorGUILayout.Slider(new GUIContent("Step Time", "Determines how fast the FOV transitions while sprinting."), fpc.sprintFOVStepTime, .1f, 20f);
+
+ fpc.useSprintBar = EditorGUILayout.ToggleLeft(new GUIContent("Use Sprint Bar", "Determines if the default sprint bar will appear on screen."), fpc.useSprintBar);
+
+ // Only displays sprint bar options if sprint bar is enabled
+ if (fpc.useSprintBar)
+ {
+ EditorGUI.indentLevel++;
+
+ EditorGUILayout.BeginHorizontal();
+ fpc.hideBarWhenFull = EditorGUILayout.ToggleLeft(new GUIContent("Hide Full Bar", "Hides the sprint bar when sprint duration is full, and fades the bar in when sprinting. Disabling this will leave the bar on screen at all times when the sprint bar is enabled."), fpc.hideBarWhenFull);
+ EditorGUILayout.EndHorizontal();
+
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.PrefixLabel(new GUIContent("Bar BG", "Object to be used as sprint bar background."));
+ fpc.sprintBarBG = (Image)EditorGUILayout.ObjectField(fpc.sprintBarBG, typeof(Image), true);
+ EditorGUILayout.EndHorizontal();
+
+ EditorGUILayout.BeginHorizontal();
+ EditorGUILayout.PrefixLabel(new GUIContent("Bar", "Object to be used as sprint bar foreground."));
+ fpc.sprintBar = (Image)EditorGUILayout.ObjectField(fpc.sprintBar, typeof(Image), true);
+ EditorGUILayout.EndHorizontal();
+
+
+ EditorGUILayout.BeginHorizontal();
+ fpc.sprintBarWidthPercent = EditorGUILayout.Slider(new GUIContent("Bar Width", "Determines the width of the sprint bar."), fpc.sprintBarWidthPercent, .1f, .5f);
+ EditorGUILayout.EndHorizontal();
+
+ EditorGUILayout.BeginHorizontal();
+ fpc.sprintBarHeightPercent = EditorGUILayout.Slider(new GUIContent("Bar Height", "Determines the height of the sprint bar."), fpc.sprintBarHeightPercent, .001f, .025f);
+ EditorGUILayout.EndHorizontal();
+ EditorGUI.indentLevel--;
+ }
+ GUI.enabled = true;
+
+ EditorGUILayout.Space();
+
+ #endregion
+
+ #region Jump
+
+ GUILayout.Label("Jump", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleLeft, fontStyle = FontStyle.Bold, fontSize = 13 }, GUILayout.ExpandWidth(true));
+
+ fpc.enableJump = EditorGUILayout.ToggleLeft(new GUIContent("Enable Jump", "Determines if the player is allowed to jump."), fpc.enableJump);
+
+ GUI.enabled = fpc.enableJump;
+ fpc.jumpKey = (KeyCode)EditorGUILayout.EnumPopup(new GUIContent("Jump Key", "Determines what key is used to jump."), fpc.jumpKey);
+ fpc.jumpPower = EditorGUILayout.Slider(new GUIContent("Jump Power", "Determines how high the player will jump."), fpc.jumpPower, .1f, 20f);
+ GUI.enabled = true;
+
+ EditorGUILayout.Space();
+
+ #endregion
+
+ #region Crouch
+
+ GUILayout.Label("Crouch", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleLeft, fontStyle = FontStyle.Bold, fontSize = 13 }, GUILayout.ExpandWidth(true));
+
+ fpc.enableCrouch = EditorGUILayout.ToggleLeft(new GUIContent("Enable Crouch", "Determines if the player is allowed to crouch."), fpc.enableCrouch);
+
+ GUI.enabled = fpc.enableCrouch;
+ fpc.holdToCrouch = EditorGUILayout.ToggleLeft(new GUIContent("Hold To Crouch", "Requires the player to hold the crouch key instead if pressing to crouch and uncrouch."), fpc.holdToCrouch);
+ fpc.crouchKey = (KeyCode)EditorGUILayout.EnumPopup(new GUIContent("Crouch Key", "Determines what key is used to crouch."), fpc.crouchKey);
+ //fpc.crouchHeight = EditorGUILayout.Slider(new GUIContent("Crouch Height", "Determines the y scale of the player object when crouched."), fpc.crouchHeight, .1f, 1);
+ fpc.speedReduction = EditorGUILayout.Slider(new GUIContent("Speed Reduction", "Determines the percent 'Walk Speed' is reduced by. 1 being no reduction, and .5 being half."), fpc.speedReduction, .1f, 1);
+ GUI.enabled = true;
+
+ #endregion
+
+ #endregion
+
+ #region Head Bob
+
+ EditorGUILayout.Space();
+ EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);
+ GUILayout.Label("Head Bob Setup", new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontStyle = FontStyle.Bold, fontSize = 13 }, GUILayout.ExpandWidth(true));
+ EditorGUILayout.Space();
+
+ fpc.enableHeadBob = EditorGUILayout.ToggleLeft(new GUIContent("Enable Head Bob", "Determines if the camera will bob while the player is walking."), fpc.enableHeadBob);
+
+
+ GUI.enabled = fpc.enableHeadBob;
+ fpc.joint = (Transform)EditorGUILayout.ObjectField(new GUIContent("Camera Joint", "Joint object position is moved while head bob is active."), fpc.joint, typeof(Transform), true);
+ fpc.bobSpeed = EditorGUILayout.Slider(new GUIContent("Speed", "Determines how often a bob rotation is completed."), fpc.bobSpeed, 1, 20);
+ fpc.bobAmount = EditorGUILayout.Vector3Field(new GUIContent("Bob Amount", "Determines the amount the joint moves in both directions on every axes."), fpc.bobAmount);
+ GUI.enabled = true;
+
+ #endregion
+
+ //Sets any changes from the prefab
+ if (GUI.changed)
+ {
+ EditorUtility.SetDirty(fpc);
+ Undo.RecordObject(fpc, "FPC Change");
+ SerFPC.ApplyModifiedProperties();
+ }
+ }
+
+}
+
+#endif
\ No newline at end of file
diff --git a/Assets/Plugins/ModularFirstPersonController/FirstPersonController/FirstPersonController.cs.meta b/Assets/Plugins/ModularFirstPersonController/FirstPersonController/FirstPersonController.cs.meta
new file mode 100644
index 0000000..9609b17
--- /dev/null
+++ b/Assets/Plugins/ModularFirstPersonController/FirstPersonController/FirstPersonController.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1b8d6eacc93b3ae45b4311a5bb6a7fbe
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scenes/ToolMaterialScene.unity b/Assets/Scenes/ToolMaterialScene.unity
new file mode 100644
index 0000000..9d95f37
--- /dev/null
+++ b/Assets/Scenes/ToolMaterialScene.unity
@@ -0,0 +1,526 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!29 &1
+OcclusionCullingSettings:
+ m_ObjectHideFlags: 0
+ serializedVersion: 2
+ m_OcclusionBakeSettings:
+ smallestOccluder: 5
+ smallestHole: 0.25
+ backfaceThreshold: 100
+ m_SceneGUID: 00000000000000000000000000000000
+ m_OcclusionCullingData: {fileID: 0}
+--- !u!104 &2
+RenderSettings:
+ m_ObjectHideFlags: 0
+ serializedVersion: 9
+ m_Fog: 0
+ m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
+ m_FogMode: 3
+ m_FogDensity: 0.01
+ m_LinearFogStart: 0
+ m_LinearFogEnd: 300
+ m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
+ m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
+ m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
+ m_AmbientIntensity: 1
+ m_AmbientMode: 0
+ m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
+ m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
+ m_HaloStrength: 0.5
+ m_FlareStrength: 1
+ m_FlareFadeSpeed: 3
+ m_HaloTexture: {fileID: 0}
+ m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
+ m_DefaultReflectionMode: 0
+ m_DefaultReflectionResolution: 128
+ m_ReflectionBounces: 1
+ m_ReflectionIntensity: 1
+ m_CustomReflection: {fileID: 0}
+ m_Sun: {fileID: 0}
+ m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1}
+ m_UseRadianceAmbientProbe: 0
+--- !u!157 &3
+LightmapSettings:
+ m_ObjectHideFlags: 0
+ serializedVersion: 12
+ m_GIWorkflowMode: 1
+ m_GISettings:
+ serializedVersion: 2
+ m_BounceScale: 1
+ m_IndirectOutputScale: 1
+ m_AlbedoBoost: 1
+ m_EnvironmentLightingMode: 0
+ m_EnableBakedLightmaps: 1
+ m_EnableRealtimeLightmaps: 0
+ m_LightmapEditorSettings:
+ serializedVersion: 12
+ m_Resolution: 2
+ m_BakeResolution: 40
+ m_AtlasSize: 1024
+ m_AO: 0
+ m_AOMaxDistance: 1
+ m_CompAOExponent: 1
+ m_CompAOExponentDirect: 0
+ m_ExtractAmbientOcclusion: 0
+ m_Padding: 2
+ m_LightmapParameters: {fileID: 0}
+ m_LightmapsBakeMode: 1
+ m_TextureCompression: 1
+ m_FinalGather: 0
+ m_FinalGatherFiltering: 1
+ m_FinalGatherRayCount: 256
+ m_ReflectionCompression: 2
+ m_MixedBakeMode: 2
+ m_BakeBackend: 1
+ m_PVRSampling: 1
+ m_PVRDirectSampleCount: 32
+ m_PVRSampleCount: 512
+ m_PVRBounces: 2
+ m_PVREnvironmentSampleCount: 256
+ m_PVREnvironmentReferencePointCount: 2048
+ m_PVRFilteringMode: 1
+ m_PVRDenoiserTypeDirect: 1
+ m_PVRDenoiserTypeIndirect: 1
+ m_PVRDenoiserTypeAO: 1
+ m_PVRFilterTypeDirect: 0
+ m_PVRFilterTypeIndirect: 0
+ m_PVRFilterTypeAO: 0
+ m_PVREnvironmentMIS: 1
+ m_PVRCulling: 1
+ m_PVRFilteringGaussRadiusDirect: 1
+ m_PVRFilteringGaussRadiusIndirect: 5
+ m_PVRFilteringGaussRadiusAO: 2
+ m_PVRFilteringAtrousPositionSigmaDirect: 0.5
+ m_PVRFilteringAtrousPositionSigmaIndirect: 2
+ m_PVRFilteringAtrousPositionSigmaAO: 1
+ m_ExportTrainingData: 0
+ m_TrainingDataDestination: TrainingData
+ m_LightProbeSampleCountMultiplier: 4
+ m_LightingDataAsset: {fileID: 0}
+ m_LightingSettings: {fileID: 0}
+--- !u!196 &4
+NavMeshSettings:
+ serializedVersion: 2
+ m_ObjectHideFlags: 0
+ m_BuildSettings:
+ serializedVersion: 2
+ agentTypeID: 0
+ agentRadius: 0.5
+ agentHeight: 2
+ agentSlope: 45
+ agentClimb: 0.4
+ ledgeDropHeight: 0
+ maxJumpAcrossDistance: 0
+ minRegionArea: 2
+ manualCellSize: 0
+ cellSize: 0.16666667
+ manualTileSize: 0
+ tileSize: 256
+ accuratePlacement: 0
+ maxJobWorkers: 0
+ preserveTilesOutsideBounds: 0
+ debug:
+ m_Flags: 0
+ m_NavMeshData: {fileID: 0}
+--- !u!1 &437018757
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 437018760}
+ - component: {fileID: 437018759}
+ - component: {fileID: 437018758}
+ m_Layer: 0
+ m_Name: EventSystem
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!114 &437018758
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 437018757}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_SendPointerHoverToParent: 1
+ m_HorizontalAxis: Horizontal
+ m_VerticalAxis: Vertical
+ m_SubmitButton: Submit
+ m_CancelButton: Cancel
+ m_InputActionsPerSecond: 10
+ m_RepeatDelay: 0.5
+ m_ForceModuleActive: 0
+--- !u!114 &437018759
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 437018757}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_FirstSelected: {fileID: 0}
+ m_sendNavigationEvents: 1
+ m_DragThreshold: 10
+--- !u!4 &437018760
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 437018757}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_RootOrder: 4
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1223469925
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1223469928}
+ - component: {fileID: 1223469927}
+ - component: {fileID: 1223469926}
+ m_Layer: 0
+ m_Name: Main Camera
+ m_TagString: MainCamera
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 0
+--- !u!81 &1223469926
+AudioListener:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1223469925}
+ m_Enabled: 1
+--- !u!20 &1223469927
+Camera:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1223469925}
+ m_Enabled: 1
+ serializedVersion: 2
+ m_ClearFlags: 1
+ m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
+ m_projectionMatrixMode: 1
+ m_GateFitMode: 2
+ m_FOVAxisMode: 0
+ m_SensorSize: {x: 36, y: 24}
+ m_LensShift: {x: 0, y: 0}
+ m_FocalLength: 50
+ m_NormalizedViewPortRect:
+ serializedVersion: 2
+ x: 0
+ y: 0
+ width: 1
+ height: 1
+ near clip plane: 0.3
+ far clip plane: 1000
+ field of view: 60
+ orthographic: 0
+ orthographic size: 5
+ m_Depth: -1
+ m_CullingMask:
+ serializedVersion: 2
+ m_Bits: 4294967295
+ m_RenderingPath: -1
+ m_TargetTexture: {fileID: 0}
+ m_TargetDisplay: 0
+ m_TargetEye: 3
+ m_HDR: 1
+ m_AllowMSAA: 1
+ m_AllowDynamicResolution: 0
+ m_ForceIntoRT: 0
+ m_OcclusionCulling: 1
+ m_StereoConvergence: 10
+ m_StereoSeparation: 0.022
+--- !u!4 &1223469928
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1223469925}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 1, z: -10}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1 &1412159801
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1412159805}
+ - component: {fileID: 1412159804}
+ - component: {fileID: 1412159803}
+ - component: {fileID: 1412159802}
+ m_Layer: 0
+ m_Name: Plane
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!64 &1412159802
+MeshCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1412159801}
+ m_Material: {fileID: 0}
+ m_IsTrigger: 0
+ m_Enabled: 1
+ serializedVersion: 4
+ m_Convex: 0
+ m_CookingOptions: 30
+ m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!23 &1412159803
+MeshRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1412159801}
+ m_Enabled: 1
+ m_CastShadows: 1
+ m_ReceiveShadows: 1
+ m_DynamicOccludee: 1
+ m_StaticShadowCaster: 0
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RayTracingMode: 2
+ m_RayTraceProcedural: 0
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ m_StaticBatchRoot: {fileID: 0}
+ m_ProbeAnchor: {fileID: 0}
+ m_LightProbeVolumeOverride: {fileID: 0}
+ m_ScaleInLightmap: 1
+ m_ReceiveGI: 1
+ m_PreserveUVs: 0
+ m_IgnoreNormalsForChartDetection: 0
+ m_ImportantGI: 0
+ m_StitchLightmapSeams: 1
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+ m_AdditionalVertexStreams: {fileID: 0}
+--- !u!33 &1412159804
+MeshFilter:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1412159801}
+ m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!4 &1412159805
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1412159801}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_RootOrder: 3
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!1001 &1439261909
+PrefabInstance:
+ m_ObjectHideFlags: 0
+ serializedVersion: 2
+ m_Modification:
+ m_TransformParent: {fileID: 0}
+ m_Modifications:
+ - target: {fileID: 2399593117452945565, guid: 86a8666f9623b6b46b8f4b860a11546f, type: 3}
+ propertyPath: m_Name
+ value: Player
+ objectReference: {fileID: 0}
+ - target: {fileID: 2399593117452945566, guid: 86a8666f9623b6b46b8f4b860a11546f, type: 3}
+ propertyPath: m_RootOrder
+ value: 2
+ objectReference: {fileID: 0}
+ - target: {fileID: 2399593117452945566, guid: 86a8666f9623b6b46b8f4b860a11546f, type: 3}
+ propertyPath: m_LocalPosition.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 2399593117452945566, guid: 86a8666f9623b6b46b8f4b860a11546f, type: 3}
+ propertyPath: m_LocalPosition.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 2399593117452945566, guid: 86a8666f9623b6b46b8f4b860a11546f, type: 3}
+ propertyPath: m_LocalPosition.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 2399593117452945566, guid: 86a8666f9623b6b46b8f4b860a11546f, type: 3}
+ propertyPath: m_LocalRotation.w
+ value: 1
+ objectReference: {fileID: 0}
+ - target: {fileID: 2399593117452945566, guid: 86a8666f9623b6b46b8f4b860a11546f, type: 3}
+ propertyPath: m_LocalRotation.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 2399593117452945566, guid: 86a8666f9623b6b46b8f4b860a11546f, type: 3}
+ propertyPath: m_LocalRotation.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 2399593117452945566, guid: 86a8666f9623b6b46b8f4b860a11546f, type: 3}
+ propertyPath: m_LocalRotation.z
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 2399593117452945566, guid: 86a8666f9623b6b46b8f4b860a11546f, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.x
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 2399593117452945566, guid: 86a8666f9623b6b46b8f4b860a11546f, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.y
+ value: 0
+ objectReference: {fileID: 0}
+ - target: {fileID: 2399593117452945566, guid: 86a8666f9623b6b46b8f4b860a11546f, type: 3}
+ propertyPath: m_LocalEulerAnglesHint.z
+ value: 0
+ objectReference: {fileID: 0}
+ m_RemovedComponents: []
+ m_SourcePrefab: {fileID: 100100000, guid: 86a8666f9623b6b46b8f4b860a11546f, type: 3}
+--- !u!1 &2055337780
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2055337782}
+ - component: {fileID: 2055337781}
+ m_Layer: 0
+ m_Name: Directional Light
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!108 &2055337781
+Light:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2055337780}
+ m_Enabled: 1
+ serializedVersion: 10
+ m_Type: 1
+ m_Shape: 0
+ m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
+ m_Intensity: 1
+ m_Range: 10
+ m_SpotAngle: 30
+ m_InnerSpotAngle: 21.80208
+ m_CookieSize: 10
+ m_Shadows:
+ m_Type: 2
+ m_Resolution: -1
+ m_CustomResolution: -1
+ m_Strength: 1
+ m_Bias: 0.05
+ m_NormalBias: 0.4
+ m_NearPlane: 0.2
+ m_CullingMatrixOverride:
+ e00: 1
+ e01: 0
+ e02: 0
+ e03: 0
+ e10: 0
+ e11: 1
+ e12: 0
+ e13: 0
+ e20: 0
+ e21: 0
+ e22: 1
+ e23: 0
+ e30: 0
+ e31: 0
+ e32: 0
+ e33: 1
+ m_UseCullingMatrixOverride: 0
+ m_Cookie: {fileID: 0}
+ m_DrawHalo: 0
+ m_Flare: {fileID: 0}
+ m_RenderMode: 0
+ m_CullingMask:
+ serializedVersion: 2
+ m_Bits: 4294967295
+ m_RenderingLayerMask: 1
+ m_Lightmapping: 4
+ m_LightShadowCasterMode: 0
+ m_AreaSize: {x: 1, y: 1}
+ m_BounceIntensity: 1
+ m_ColorTemperature: 6570
+ m_UseColorTemperature: 0
+ m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
+ m_UseBoundingSphereOverride: 0
+ m_UseViewFrustumForShadowCasterCull: 1
+ m_ShadowRadius: 0
+ m_ShadowAngle: 0
+--- !u!4 &2055337782
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2055337780}
+ m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
+ m_LocalPosition: {x: 0, y: 3, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 0}
+ m_RootOrder: 1
+ m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
diff --git a/Assets/Scenes/ToolMaterialScene.unity.meta b/Assets/Scenes/ToolMaterialScene.unity.meta
new file mode 100644
index 0000000..f981237
--- /dev/null
+++ b/Assets/Scenes/ToolMaterialScene.unity.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 37d899cece6e6a44a9eca3211bd8b650
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Template.meta b/Assets/Template.meta
new file mode 100644
index 0000000..1b08048
--- /dev/null
+++ b/Assets/Template.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3bdba010de5626c4294995787149ea8c
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Template/ArtRes.meta b/Assets/Template/ArtRes.meta
new file mode 100644
index 0000000..13e1d5a
--- /dev/null
+++ b/Assets/Template/ArtRes.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: f54508db67be12441aeed03c59c590ca
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Template/ArtRes/Prefabs.meta b/Assets/Template/ArtRes/Prefabs.meta
new file mode 100644
index 0000000..05c5a6e
--- /dev/null
+++ b/Assets/Template/ArtRes/Prefabs.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: bc2c013caf99c78448d42fd49cd70371
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Template/ArtRes/Prefabs/Player.prefab b/Assets/Template/ArtRes/Prefabs/Player.prefab
new file mode 100644
index 0000000..4785ef8
--- /dev/null
+++ b/Assets/Template/ArtRes/Prefabs/Player.prefab
@@ -0,0 +1,666 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!1 &1162072256
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1162072258}
+ - component: {fileID: 1162072257}
+ m_Layer: 0
+ m_Name: UseTips
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &1162072258
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1162072256}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: -0.0269, y: 0, z: 0}
+ m_LocalScale: {x: 0.01977546, y: 0.019775452, z: 0.01977546}
+ m_ConstrainProportionsScale: 0
+ m_Children: []
+ m_Father: {fileID: 1180096483}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: -90, z: 0}
+--- !u!212 &1162072257
+SpriteRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1162072256}
+ m_Enabled: 1
+ m_CastShadows: 0
+ m_ReceiveShadows: 0
+ m_DynamicOccludee: 1
+ m_StaticShadowCaster: 0
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RayTracingMode: 0
+ m_RayTraceProcedural: 0
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ m_StaticBatchRoot: {fileID: 0}
+ m_ProbeAnchor: {fileID: 0}
+ m_LightProbeVolumeOverride: {fileID: 0}
+ m_ScaleInLightmap: 1
+ m_ReceiveGI: 1
+ m_PreserveUVs: 0
+ m_IgnoreNormalsForChartDetection: 0
+ m_ImportantGI: 0
+ m_StitchLightmapSeams: 1
+ m_SelectedEditorRenderState: 0
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+ m_Sprite: {fileID: 21300000, guid: 67466abc96c66754e962908c818b8331, type: 3}
+ m_Color: {r: 1, g: 1, b: 1, a: 1}
+ m_FlipX: 0
+ m_FlipY: 0
+ m_DrawMode: 0
+ m_Size: {x: 2, y: 0.64}
+ m_AdaptiveModeThreshold: 0.5
+ m_SpriteTileMode: 0
+ m_WasSpriteAssigned: 1
+ m_MaskInteraction: 0
+ m_SpriteSortPoint: 0
+--- !u!1 &1180096482
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1180096483}
+ - component: {fileID: 8259647949277795141}
+ - component: {fileID: 7561753228374517298}
+ m_Layer: 0
+ m_Name: TMDUseTips
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 0
+--- !u!4 &1180096483
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1180096482}
+ m_LocalRotation: {x: 0.61311585, y: 0.19189872, z: -0.18822931, w: 0.74285513}
+ m_LocalPosition: {x: -0.0207, y: -0.0071, z: -0.0338}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 1162072258}
+ m_Father: {fileID: 1927580343}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &8259647949277795141
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1180096482}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 72e625028bd8c8849b766981a28d3303, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ profile: {fileID: 0}
+ profileSync: 0
+ camerasLayerMask:
+ serializedVersion: 2
+ m_Bits: 4294967295
+ effectGroup: 0
+ effectGroupLayer:
+ serializedVersion: 2
+ m_Bits: 4294967295
+ effectNameFilter:
+ combineMeshes: 0
+ alphaCutOff: 0
+ cullBackFaces: 1
+ ignoreObjectVisibility: 0
+ reflectionProbes: 0
+ GPUInstancing: 1
+ optimizeSkinnedMesh: 1
+ depthClip: 0
+ cameraDistanceFade: 0
+ cameraDistanceFadeNear: 0
+ cameraDistanceFadeFar: 1000
+ normalsOption: 0
+ ignore: 0
+ _highlighted: 0
+ fadeInDuration: 0
+ fadeOutDuration: 0
+ flipY: 0
+ constantWidth: 1
+ subMeshMask: -1
+ overlay: 0
+ overlayMode: 0
+ overlayColor: {r: 1, g: 0.92156863, b: 0.015686275, a: 1}
+ overlayAnimationSpeed: 1
+ overlayMinIntensity: 0.5
+ overlayBlending: 1
+ overlayTexture: {fileID: 0}
+ overlayTextureUVSpace: 0
+ overlayTextureScale: 1
+ overlayVisibility: 0
+ outline: 1
+ outlineColor: {r: 0.8080046, g: 1.6417967, b: 0.36961916, a: 1}
+ outlineColorStyle: 0
+ outlineGradient:
+ serializedVersion: 2
+ key0: {r: 1, g: 1, b: 1, a: 1}
+ key1: {r: 1, g: 1, b: 1, a: 1}
+ key2: {r: 0, g: 0, b: 0, a: 0}
+ key3: {r: 0, g: 0, b: 0, a: 0}
+ key4: {r: 0, g: 0, b: 0, a: 0}
+ key5: {r: 0, g: 0, b: 0, a: 0}
+ key6: {r: 0, g: 0, b: 0, a: 0}
+ key7: {r: 0, g: 0, b: 0, a: 0}
+ ctime0: 0
+ ctime1: 65535
+ ctime2: 0
+ ctime3: 0
+ ctime4: 0
+ ctime5: 0
+ ctime6: 0
+ ctime7: 0
+ atime0: 0
+ atime1: 65535
+ atime2: 0
+ atime3: 0
+ atime4: 0
+ atime5: 0
+ atime6: 0
+ atime7: 0
+ m_Mode: 0
+ m_NumColorKeys: 2
+ m_NumAlphaKeys: 2
+ outlineGradientInLocalSpace: 0
+ outlineWidth: 0.4
+ outlineBlurPasses: 2
+ outlineQuality: 3
+ outlineEdgeMode: 0
+ outlineEdgeThreshold: 0.995
+ outlineDownsampling: 1
+ outlineVisibility: 0
+ glowBlendMode: 0
+ outlineBlitDebug: 0
+ outlineIndependent: 0
+ outlineContourStyle: 0
+ glow: 0
+ glowWidth: 0.4
+ glowQuality: 3
+ glowBlurMethod: 0
+ glowDownsampling: 2
+ glowHQColor: {r: 0.64, g: 1, b: 0, a: 1}
+ glowDithering: 1
+ glowMagicNumber1: 0.75
+ glowMagicNumber2: 0.5
+ glowAnimationSpeed: 1
+ glowVisibility: 0
+ glowBlitDebug: 0
+ glowBlendPasses: 1
+ glowPasses: []
+ glowIgnoreMask: 0
+ innerGlow: 0
+ innerGlowWidth: 1
+ innerGlowColor: {r: 1, g: 1, b: 1, a: 1}
+ innerGlowBlendMode: 0
+ innerGlowVisibility: 0
+ targetFX: 0
+ targetFXTexture: {fileID: 0}
+ targetFXColor: {r: 1, g: 1, b: 1, a: 1}
+ targetFXCenter: {fileID: 0}
+ targetFXRotationSpeed: 50
+ targetFXInitialScale: 4
+ targetFXEndScale: 1.5
+ targetFXScaleToRenderBounds: 1
+ targetFXAlignToGround: 0
+ targetFXFadePower: 32
+ targetFXGroundMaxDistance: 10
+ targetFXGroundLayerMask:
+ serializedVersion: 2
+ m_Bits: 4294967295
+ targetFXTransitionDuration: 0.5
+ targetFXStayDuration: 1.5
+ targetFXVisibility: 1
+ seeThrough: 2
+ seeThroughOccluderMask:
+ serializedVersion: 2
+ m_Bits: 4294967295
+ seeThroughOccluderThreshold: 0.3
+ seeThroughOccluderMaskAccurate: 0
+ seeThroughOccluderCheckInterval: 1
+ seeThroughOccluderCheckIndividualObjects: 0
+ seeThroughDepthOffset: 0
+ seeThroughMaxDepth: 0
+ seeThroughIntensity: 0.8
+ seeThroughTintAlpha: 0.5
+ seeThroughTintColor: {r: 1, g: 0, b: 0, a: 1}
+ seeThroughNoise: 1
+ seeThroughBorder: 0
+ seeThroughBorderColor: {r: 0, g: 0, b: 0, a: 1}
+ seeThroughBorderOnly: 0
+ seeThroughBorderWidth: 0.45
+ seeThroughOrdered: 0
+ seeThroughTexture: {fileID: 0}
+ seeThroughTextureUVSpace: 0
+ seeThroughTextureScale: 1
+ rmsCount: 0
+ hitFxInitialIntensity: 0
+ hitFxMode: 0
+ hitFxFadeOutDuration: 0.25
+ hitFxColor: {r: 1, g: 1, b: 1, a: 1}
+ hitFxRadius: 0.5
+--- !u!114 &7561753228374517298
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1180096482}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 3cee7d4640c932e4da6cc65da03af2d7, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ triggerID: 0
+ triggerName: "\u6536\u56DE\u5DE5\u5177"
+ _highlight: {fileID: 0}
+--- !u!1 &1927580342
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 1927580343}
+ m_Layer: 0
+ m_Name: SpawnToolPos
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 0
+--- !u!4 &1927580343
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 1927580342}
+ m_LocalRotation: {x: -0.6074237, y: -0.17036365, z: 0.20585874, w: 0.7480876}
+ m_LocalPosition: {x: 0.110000744, y: 0.04099995, z: 0.32999933}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 1180096483}
+ m_Father: {fileID: 2399593117623680742}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: -57, y: -68, z: 71}
+--- !u!1 &2399593117452945565
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2399593117452945566}
+ - component: {fileID: 2399593117452945567}
+ - component: {fileID: 2399593117452945568}
+ - component: {fileID: 3910755197489471127}
+ - component: {fileID: 7005868485670428847}
+ m_Layer: 9
+ m_Name: Player
+ m_TagString: Player
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &2399593117452945566
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2399593117452945565}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 1.184, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 2399593117846495248}
+ m_Father: {fileID: 0}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!114 &2399593117452945567
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2399593117452945565}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: 1b8d6eacc93b3ae45b4311a5bb6a7fbe, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ rb: {fileID: 0}
+ playerCamera: {fileID: 2399593117623680741}
+ fov: 60
+ invertCamera: 0
+ cameraCanMove: 1
+ mouseSensitivity: 2
+ maxLookAngle: 50
+ lockCursor: 0
+ crosshair: 1
+ crosshairImage: {fileID: 21300000, guid: 2ba574d1e6a3b4d469eed23b438f843c, type: 3}
+ crosshairColor: {r: 1, g: 1, b: 1, a: 1}
+ yaw: 0
+ pitch: 0
+ enableZoom: 0
+ holdToZoom: 1
+ zoomKey: 324
+ zoomFOV: 30
+ zoomStepTime: 5
+ zoomScale: 1
+ playerCanMove: 1
+ stopForce: 1
+ walkSpeed: 5
+ maxVelocityChange: 10
+ enableSprint: 1
+ unlimitedSprint: 1
+ enableSprintZoom: 0
+ sprintKey: 304
+ sprintSpeed: 7
+ sprintDuration: 5
+ sprintCooldown: 0.5
+ sprintFOV: 80
+ sprintFOVStepTime: 10
+ useSprintBar: 1
+ hideBarWhenFull: 1
+ sprintBarBG: {fileID: 0}
+ sprintBar: {fileID: 0}
+ sprintBarWidthPercent: 0.3
+ sprintBarHeightPercent: 0.015
+ enableJump: 0
+ jumpKey: 32
+ jumpPower: 5
+ enableCrouch: 0
+ holdToCrouch: 1
+ crouchKey: 306
+ speedReduction: 0.5
+ isCrouched: 0
+ enableHeadBob: 0
+ joint: {fileID: 2399593117846495248}
+ bobSpeed: 10
+ bobAmount: {x: 0.15, y: 0.05, z: 0}
+--- !u!54 &2399593117452945568
+Rigidbody:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2399593117452945565}
+ serializedVersion: 2
+ m_Mass: 1
+ m_Drag: 0
+ m_AngularDrag: 0.05
+ m_UseGravity: 1
+ m_IsKinematic: 0
+ m_Interpolate: 0
+ m_Constraints: 112
+ m_CollisionDetection: 0
+--- !u!136 &3910755197489471127
+CapsuleCollider:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2399593117452945565}
+ m_Material: {fileID: 0}
+ m_IsTrigger: 0
+ m_Enabled: 1
+ m_Radius: 0.4
+ m_Height: 1.7
+ m_Direction: 1
+ m_Center: {x: 0, y: 0, z: 0}
+--- !u!33 &7005868485670428847
+MeshFilter:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2399593117452945565}
+ m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!1 &2399593117623680739
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2399593117623680742}
+ - component: {fileID: 2399593117623680741}
+ - component: {fileID: 2399593117623680740}
+ - component: {fileID: 2399593117623680743}
+ m_Layer: 9
+ m_Name: Main Camera
+ m_TagString: MainCamera
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &2399593117623680742
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2399593117623680739}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+ m_LocalPosition: {x: 0, y: 0.769, z: -0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 1927580343}
+ m_Father: {fileID: 2399593117846495248}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!20 &2399593117623680741
+Camera:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2399593117623680739}
+ m_Enabled: 1
+ serializedVersion: 2
+ m_ClearFlags: 1
+ m_BackGroundColor: {r: 0, g: 0, b: 0, a: 1}
+ m_projectionMatrixMode: 1
+ m_GateFitMode: 2
+ m_FOVAxisMode: 0
+ m_SensorSize: {x: 36, y: 24}
+ m_LensShift: {x: 0, y: 0}
+ m_FocalLength: 50
+ m_NormalizedViewPortRect:
+ serializedVersion: 2
+ x: 0
+ y: 0
+ width: 1
+ height: 1
+ near clip plane: 0.01
+ far clip plane: 1000
+ field of view: 60
+ orthographic: 0
+ orthographic size: 5
+ m_Depth: -1
+ m_CullingMask:
+ serializedVersion: 2
+ m_Bits: 4294967295
+ m_RenderingPath: -1
+ m_TargetTexture: {fileID: 0}
+ m_TargetDisplay: 0
+ m_TargetEye: 3
+ m_HDR: 1
+ m_AllowMSAA: 1
+ m_AllowDynamicResolution: 0
+ m_ForceIntoRT: 0
+ m_OcclusionCulling: 1
+ m_StereoConvergence: 10
+ m_StereoSeparation: 0.022
+--- !u!81 &2399593117623680740
+AudioListener:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2399593117623680739}
+ m_Enabled: 1
+--- !u!114 &2399593117623680743
+MonoBehaviour:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2399593117623680739}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_RenderShadows: 1
+ m_RequiresDepthTextureOption: 2
+ m_RequiresOpaqueTextureOption: 2
+ m_CameraType: 0
+ m_Cameras: []
+ m_RendererIndex: 1
+ m_VolumeLayerMask:
+ serializedVersion: 2
+ m_Bits: 1
+ m_VolumeTrigger: {fileID: 0}
+ m_VolumeFrameworkUpdateModeOption: 2
+ m_RenderPostProcessing: 1
+ m_Antialiasing: 2
+ m_AntialiasingQuality: 2
+ m_StopNaN: 0
+ m_Dithering: 0
+ m_ClearDepth: 1
+ m_AllowXRRendering: 1
+ m_RequiresDepthTexture: 0
+ m_RequiresColorTexture: 0
+ m_Version: 2
+--- !u!1 &2399593117846495247
+GameObject:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ serializedVersion: 6
+ m_Component:
+ - component: {fileID: 2399593117846495248}
+ - component: {fileID: 2399593117846495251}
+ - component: {fileID: 2399593117846495250}
+ m_Layer: 9
+ m_Name: Capsule
+ m_TagString: Untagged
+ m_Icon: {fileID: 0}
+ m_NavMeshLayer: 0
+ m_StaticEditorFlags: 0
+ m_IsActive: 1
+--- !u!4 &2399593117846495248
+Transform:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2399593117846495247}
+ m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalPosition: {x: 0, y: 0, z: 0}
+ m_LocalScale: {x: 1, y: 1, z: 1}
+ m_ConstrainProportionsScale: 0
+ m_Children:
+ - {fileID: 2399593117623680742}
+ m_Father: {fileID: 2399593117452945566}
+ m_RootOrder: 0
+ m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+--- !u!33 &2399593117846495251
+MeshFilter:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2399593117846495247}
+ m_Mesh: {fileID: 10208, guid: 0000000000000000e000000000000000, type: 0}
+--- !u!23 &2399593117846495250
+MeshRenderer:
+ m_ObjectHideFlags: 0
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 2399593117846495247}
+ m_Enabled: 0
+ m_CastShadows: 1
+ m_ReceiveShadows: 1
+ m_DynamicOccludee: 1
+ m_StaticShadowCaster: 0
+ m_MotionVectors: 1
+ m_LightProbeUsage: 1
+ m_ReflectionProbeUsage: 1
+ m_RayTracingMode: 2
+ m_RayTraceProcedural: 0
+ m_RenderingLayerMask: 1
+ m_RendererPriority: 0
+ m_Materials:
+ - {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
+ m_StaticBatchInfo:
+ firstSubMesh: 0
+ subMeshCount: 0
+ m_StaticBatchRoot: {fileID: 0}
+ m_ProbeAnchor: {fileID: 0}
+ m_LightProbeVolumeOverride: {fileID: 0}
+ m_ScaleInLightmap: 1
+ m_ReceiveGI: 1
+ m_PreserveUVs: 0
+ m_IgnoreNormalsForChartDetection: 0
+ m_ImportantGI: 0
+ m_StitchLightmapSeams: 1
+ m_SelectedEditorRenderState: 3
+ m_MinimumChartSize: 4
+ m_AutoUVMaxDistance: 0.5
+ m_AutoUVMaxAngle: 89
+ m_LightmapParameters: {fileID: 0}
+ m_SortingLayerID: 0
+ m_SortingLayer: 0
+ m_SortingOrder: 0
+ m_AdditionalVertexStreams: {fileID: 0}
diff --git a/Assets/Template/ArtRes/Prefabs/Player.prefab.meta b/Assets/Template/ArtRes/Prefabs/Player.prefab.meta
new file mode 100644
index 0000000..a729f84
--- /dev/null
+++ b/Assets/Template/ArtRes/Prefabs/Player.prefab.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 86a8666f9623b6b46b8f4b860a11546f
+PrefabImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant: