相机操作脚本

This commit is contained in:
Afeijia 2023-08-28 15:46:07 +08:00
parent 8278a08c0d
commit bee9bcfc50
79 changed files with 5792 additions and 163 deletions

View File

@ -1,21 +1,22 @@
fileFormatVersion: 2
guid: a811bde74b26b53498b4f6d872b09b6d
PluginImporter:
externalObjects: {}
serializedVersion: 2
serializedVersion: 1
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,21 +1,22 @@
fileFormatVersion: 2
guid: 45d5034162d6cf04dbe46da84fc7d074
PluginImporter:
externalObjects: {}
serializedVersion: 2
serializedVersion: 1
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
enabled: 0
settings: {}
Editor:
enabled: 1
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,11 +1,8 @@
fileFormatVersion: 2
guid: b766d08851589514b97afb23c6f30a70
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -135,7 +135,7 @@ namespace DG.Tweening
/// If you plan to publish there you should use a regular transform.DOPath.</para></summary>
/// <param name="path">The waypoints to go through</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="pathType">The type of path: Linear (straight path) or CatmullRom (curved CatmullRom path)</param>
/// <param name="pathType">The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points)</param>
/// <param name="pathMode">The path mode: 3D, side-scroller 2D, top-down 2D</param>
/// <param name="resolution">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</param>
@ -160,7 +160,7 @@ namespace DG.Tweening
/// If you plan to publish there you should use a regular transform.DOLocalPath.</para></summary>
/// <param name="path">The waypoint to go through</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="pathType">The type of path: Linear (straight path) or CatmullRom (curved CatmullRom path)</param>
/// <param name="pathType">The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points)</param>
/// <param name="pathMode">The path mode: 3D, side-scroller 2D, top-down 2D</param>
/// <param name="resolution">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</param>

View File

@ -1,11 +1,8 @@
fileFormatVersion: 2
guid: dae9aa560b4242648a3affa2bfabc365
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -4,6 +4,8 @@
#if true && (UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_5 || UNITY_2017_1_OR_NEWER) // 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;
@ -97,6 +99,90 @@ namespace DG.Tweening
return s;
}
/// <summary>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.
/// <para>NOTE: to tween a Rigidbody2D correctly it should be set to kinematic at least while being tweened.</para>
/// <para>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.</para></summary>
/// <param name="path">The waypoints to go through</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="pathType">The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points)</param>
/// <param name="pathMode">The path mode: 3D, side-scroller 2D, top-down 2D</param>
/// <param name="resolution">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</param>
/// <param name="gizmoColor">The color of the path (shown when gizmos are active in the Play panel and the tween is running)</param>
public static TweenerCore<Vector3, Path, PathOptions> 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<Vector3, Path, PathOptions> 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;
}
/// <summary>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
/// <para>NOTE: to tween a Rigidbody2D correctly it should be set to kinematic at least while being tweened.</para>
/// <para>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.</para></summary>
/// <param name="path">The waypoint to go through</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="pathType">The type of path: Linear (straight path), CatmullRom (curved CatmullRom path) or CubicBezier (curved with control points)</param>
/// <param name="pathMode">The path mode: 3D, side-scroller 2D, top-down 2D</param>
/// <param name="resolution">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</param>
/// <param name="gizmoColor">The color of the path (shown when gizmos are active in the Play panel and the tween is running)</param>
public static TweenerCore<Vector3, Path, PathOptions> 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<Vector3, Path, PathOptions> 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<Vector3, Path, PathOptions> DOPath(
this Rigidbody2D target, Path path, float duration, PathMode pathMode = PathMode.Full3D
)
{
TweenerCore<Vector3, Path, PathOptions> 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<Vector3, Path, PathOptions> DOLocalPath(
this Rigidbody2D target, Path path, float duration, PathMode pathMode = PathMode.Full3D
)
{
Transform trans = target.transform;
TweenerCore<Vector3, Path, PathOptions> 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

View File

@ -1,11 +1,8 @@
fileFormatVersion: 2
guid: 230fe34542e175245ba74b4659dae700
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -56,6 +56,7 @@ namespace DG.Tweening
: 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;
}

View File

@ -1,11 +1,8 @@
fileFormatVersion: 2
guid: 188918ab119d93148aa0de59ccf5286b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -2,12 +2,17 @@
// Created: 2018/07/13
#if true && (UNITY_4_6 || UNITY_5 || UNITY_2017_1_OR_NEWER) // 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
@ -108,6 +113,7 @@ namespace DG.Tweening
: 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;
}
@ -480,6 +486,29 @@ namespace DG.Tweening
return t;
}
/// <summary>
/// Tweens a Text's text from one integer to another, with options for thousands separators
/// </summary>
/// <param name="fromValue">The value to start from</param>
/// <param name="endValue">The end value to reach</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="addThousandsSeparator">If TRUE (default) also adds thousands separators</param>
/// <param name="culture">The <see cref="CultureInfo"/> to use (InvariantCulture if NULL)</param>
public static TweenerCore<int, int, NoOptions> 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<int, int, NoOptions> t = DOTween.To(() => v, x => {
v = x;
target.text = addThousandsSeparator
? v.ToString("N0", cInfo)
: v.ToString();
}, endValue, duration);
t.SetTarget(target);
return t;
}
/// <summary>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</summary>
/// <param name="endValue">The end value to reach</param><param name="duration">The duration of the tween</param>
@ -501,6 +530,10 @@ namespace DG.Tweening
/// Leave it to NULL (default) to use default ones</param>
public static TweenerCore<string, string, StringOptions> 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<string, string, StringOptions> t = DOTween.To(() => target.text, x => target.text = x, endValue, duration);
t.SetOptions(richTextEnabled, scrambleMode, scrambleChars)
.SetTarget(target);
@ -576,6 +609,29 @@ namespace DG.Tweening
#endregion
#region Shapes
/// <summary>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.<para/>
/// IMPORTANT: SetFrom(value) requires a <see cref="Vector2"/> instead of a float, where the X property represents the "from degrees value"</summary>
/// <param name="center">Circle-center/pivot around which to rotate (in UI anchoredPosition coordinates)</param>
/// <param name="endValueDegrees">The end value degrees to reach (to rotate counter-clockwise pass a negative value)</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="relativeCenter">If TRUE the <see cref="center"/> coordinates will be considered as relative to the target's current anchoredPosition</param>
/// <param name="snapping">If TRUE the tween will smoothly snap all values to integers</param>
public static TweenerCore<Vector2, Vector2, CircleOptions> DOShapeCircle(
this RectTransform target, Vector2 center, float endValueDegrees, float duration, bool relativeCenter = false, bool snapping = false
)
{
TweenerCore<Vector2, Vector2, CircleOptions> t = DOTween.To(
CirclePlugin.Get(), () => target.anchoredPosition, x => target.anchoredPosition = x, center, duration
);
t.SetOptions(endValueDegrees, relativeCenter, snapping).SetTarget(target);
return t;
}
#endregion
#endregion
// █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████

View File

@ -1,11 +1,8 @@
fileFormatVersion: 2
guid: a060394c03331a64392db53a10e7f2d1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -5,6 +5,9 @@ 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
@ -40,6 +43,7 @@ namespace DG.Tweening
: 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;
}
/// <summary>Tweens a Material's named color property using the given gradient
@ -64,6 +68,7 @@ namespace DG.Tweening
: 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;
}
@ -135,7 +140,8 @@ namespace DG.Tweening
}
/// <summary>
/// Returns a <see cref="CustomYieldInstruction"/> that waits until the tween is killed or has reached the given position (loops included, delays excluded).
/// Returns a <see cref="CustomYieldInstruction"/> 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.
/// <para>Example usage:</para><code>yield return myTween.WaitForPosition(2.5f);</code>
/// </summary>
@ -208,6 +214,104 @@ namespace DG.Tweening
#endregion
#region .NET 4.6 or Newer
#if UNITY_2018_1_OR_NEWER && (NET_4_6 || NET_STANDARD_2_0)
#region Async Instructions
/// <summary>
/// Returns an async <see cref="System.Threading.Tasks.Task"/> that waits until the tween is killed or complete.
/// It can be used inside an async operation.
/// <para>Example usage:</para><code>await myTween.WaitForCompletion();</code>
/// </summary>
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();
}
/// <summary>
/// Returns an async <see cref="System.Threading.Tasks.Task"/> that waits until the tween is killed or rewinded.
/// It can be used inside an async operation.
/// <para>Example usage:</para><code>await myTween.AsyncWaitForRewind();</code>
/// </summary>
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();
}
/// <summary>
/// Returns an async <see cref="System.Threading.Tasks.Task"/> that waits until the tween is killed.
/// It can be used inside an async operation.
/// <para>Example usage:</para><code>await myTween.AsyncWaitForKill();</code>
/// </summary>
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();
}
/// <summary>
/// Returns an async <see cref="System.Threading.Tasks.Task"/> that waits until the tween is killed or has gone through the given amount of loops.
/// It can be used inside an async operation.
/// <para>Example usage:</para><code>await myTween.AsyncWaitForElapsedLoops();</code>
/// </summary>
/// <param name="elapsedLoops">Elapsed loops to wait for</param>
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();
}
/// <summary>
/// Returns an async <see cref="System.Threading.Tasks.Task"/> 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.
/// <para>Example usage:</para><code>await myTween.AsyncWaitForPosition();</code>
/// </summary>
/// <param name="position">Position (loops included, delays excluded) to wait for</param>
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();
}
/// <summary>
/// Returns an async <see cref="System.Threading.Tasks.Task"/> that waits until the tween is killed.
/// It can be used inside an async operation.
/// <para>Example usage:</para><code>await myTween.AsyncWaitForKill();</code>
/// </summary>
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
}

View File

@ -1,11 +1,8 @@
fileFormatVersion: 2
guid: 63c02322328255542995bd02b47b0457
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -129,23 +129,35 @@ namespace DG.Tweening
public static TweenerCore<Vector3, Path, PathOptions> CreateDOTweenPathTween(
MonoBehaviour target, bool tweenRigidbody, bool isLocal, Path path, float duration, PathMode pathMode
){
TweenerCore<Vector3, Path, PathOptions> t;
TweenerCore<Vector3, Path, PathOptions> t = null;
bool rBodyFoundAndTweened = false;
#if true // PHYSICS_MARKER
Rigidbody rBody = tweenRigidbody ? target.GetComponent<Rigidbody>() : null;
if (tweenRigidbody && rBody != null) {
if (tweenRigidbody) {
Rigidbody rBody = target.GetComponent<Rigidbody>();
if (rBody != null) {
rBodyFoundAndTweened = true;
t = isLocal
? rBody.DOLocalPath(path, duration, pathMode)
: rBody.DOPath(path, duration, pathMode);
} else {
}
}
#endif
#if true // PHYSICS2D_MARKER
if (!rBodyFoundAndTweened && tweenRigidbody) {
Rigidbody2D rBody2D = target.GetComponent<Rigidbody2D>();
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);
}
#else
t = isLocal
? target.transform.DOLocalPath(path, duration, pathMode)
: target.transform.DOPath(path, duration, pathMode);
#endif
return t;
}

View File

@ -1,11 +1,8 @@
fileFormatVersion: 2
guid: 7bcaf917d9cf5b84090421a5a2abe42e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -66,7 +66,7 @@ namespace DG.Tweening
public bool targetIsSelf = true; // If FALSE allows to set the target manually
public GameObject targetGO = null; // Used in case targetIsSelf is FALSE
// If TRUE always uses the GO containing this DOTweenAnimation (and not the one containing the target) as DOTween's SetTarget target
// If FALSE always uses the GO containing this DOTweenAnimation (and not the one containing the target) as DOTween's SetTarget target
public bool tweenTargetIsTargetGO = true;
public float delay;
@ -80,6 +80,7 @@ namespace DG.Tweening
public bool isFrom;
public bool isIndependentUpdate = false;
public bool autoKill = true;
public bool autoGenerate = true; // If TRUE automatically creates the tween at startup
public bool isActive = true;
public bool isValid;
@ -98,36 +99,36 @@ namespace DG.Tweening
public Rect endValueRect = new Rect(0, 0, 0, 0);
public Transform endValueTransform;
public bool optionalBool0;
public bool optionalBool0, optionalBool1;
public float optionalFloat0;
public int optionalInt0;
public RotateMode optionalRotationMode = RotateMode.Fast;
public ScrambleMode optionalScrambleMode = ScrambleMode.None;
public string optionalString;
bool _tweenCreated; // TRUE after the tweens have been created
bool _tweenAutoGenerationCalled; // TRUE after the tweens have been autoGenerated
int _playCount = -1; // Used when calling DOPlayNext
#region Unity Methods
void Awake()
{
if (!isActive || !isValid) return;
if (!isActive || !autoGenerate) return;
if (animationType != AnimationType.Move || !useTargetAsV3) {
// Don't create tweens if we're using a RectTransform as a Move target,
// because that will work only inside Start
CreateTween();
_tweenCreated = true;
CreateTween(false, autoPlay);
_tweenAutoGenerationCalled = true;
}
}
void Start()
{
if (_tweenCreated || !isActive || !isValid) return;
if (_tweenAutoGenerationCalled || !isActive || !autoGenerate) return;
CreateTween();
_tweenCreated = true;
CreateTween(false, autoPlay);
_tweenAutoGenerationCalled = true;
}
void Reset()
@ -137,13 +138,60 @@ namespace DG.Tweening
void OnDestroy()
{
if (tween != null && tween.IsActive()) tween.Kill();
if (tween != null && tween.active) tween.Kill();
tween = null;
}
// Used also by DOTweenAnimationInspector when applying runtime changes and restarting
public void CreateTween()
/// <summary>
/// Creates/recreates the tween without playing it, but first rewinding and killing the existing one if present.
/// </summary>
public void RewindThenRecreateTween()
{
if (tween != null && tween.active) tween.Rewind();
CreateTween(true, false);
}
/// <summary>
/// Creates/recreates the tween and plays it, first rewinding and killing the existing one if present.
/// </summary>
public void RewindThenRecreateTweenAndPlay()
{
if (tween != null && tween.active) tween.Rewind();
CreateTween(true, true);
}
/// <summary>
/// Creates/recreates the tween from its target's current value without playing it, but first killing the existing one if present.
/// </summary>
public void RecreateTween()
{ CreateTween(true, false); }
/// <summary>
/// Creates/recreates the tween from its target's current value and plays it, first killing the existing one if present.
/// </summary>
public void RecreateTweenAndPlay()
{ CreateTween(true, true); }
// Used also by DOTweenAnimationInspector when applying runtime changes and restarting
/// <summary>
/// Creates the tween manually (called automatically if AutoGenerate is set in the Inspector)
/// from its target's current value.
/// </summary>
/// <param name="regenerateIfExists">If TRUE and an existing tween was already created (and not killed), kills it and recreates it with the current
/// parameters. Otherwise, if a tween already exists, does nothing.</param>
/// <param name="andPlay">If TRUE also plays the tween, otherwise only creates it</param>
public void CreateTween(bool regenerateIfExists = false, bool andPlay = true)
{
if (!isValid) {
if (regenerateIfExists) { // Called manually: warn users
Debug.LogWarning(string.Format("{0} :: This DOTweenAnimation isn't valid and its tween won't be created", this.gameObject.name), this.gameObject);
}
return;
}
if (tween != null) {
if (tween.active) {
if (regenerateIfExists) tween.Kill();
else return;
}
tween = null;
}
// if (target == null) {
// Debug.LogWarning(string.Format("{0} :: This DOTweenAnimation's target is NULL, because the animation was created with a DOTween Pro version older than 0.9.255. To fix this, exit Play mode then simply select this object, and it will update automatically", this.gameObject.name), this.gameObject);
// return;
@ -401,20 +449,20 @@ namespace DG.Tweening
case AnimationType.ShakePosition:
switch (targetType) {
case TargetType.Transform:
tween = ((Transform)target).DOShakePosition(duration, endValueV3, optionalInt0, optionalFloat0, optionalBool0);
tween = ((Transform)target).DOShakePosition(duration, endValueV3, optionalInt0, optionalFloat0, optionalBool0, optionalBool1);
break;
#if true // UI_MARKER
case TargetType.RectTransform:
tween = ((RectTransform)target).DOShakeAnchorPos(duration, endValueV3, optionalInt0, optionalFloat0, optionalBool0);
tween = ((RectTransform)target).DOShakeAnchorPos(duration, endValueV3, optionalInt0, optionalFloat0, optionalBool0, optionalBool1);
break;
#endif
}
break;
case AnimationType.ShakeScale:
tween = tweenGO.transform.DOShakeScale(duration, endValueV3, optionalInt0, optionalFloat0);
tween = tweenGO.transform.DOShakeScale(duration, endValueV3, optionalInt0, optionalFloat0, optionalBool1);
break;
case AnimationType.ShakeRotation:
tween = tweenGO.transform.DOShakeRotation(duration, endValueV3, optionalInt0, optionalFloat0);
tween = tweenGO.transform.DOShakeRotation(duration, endValueV3, optionalInt0, optionalFloat0, optionalBool1);
break;
case AnimationType.CameraAspect:
tween = ((Camera)target).DOAspect(endValueFloat, duration);
@ -438,12 +486,14 @@ namespace DG.Tweening
if (tween == null) return;
// Created
if (isFrom) {
((Tweener)tween).From(isRelative);
} else {
tween.SetRelative(isRelative);
}
GameObject setTarget = targetIsSelf || !tweenTargetIsTargetGO ? this.gameObject : targetGO;
GameObject setTarget = GetTweenTarget();
tween.SetTarget(setTarget).SetDelay(delay).SetLoops(loops, loopType).SetAutoKill(autoKill)
.OnKill(()=> tween = null);
if (isSpeedBased) tween.SetSpeedBased();
@ -471,7 +521,7 @@ namespace DG.Tweening
if (onRewind != null) tween.OnRewind(onRewind.Invoke);
} else onRewind = null;
if (autoPlay) tween.Play();
if (andPlay) tween.Play();
else tween.Pause();
if (hasOnTweenCreated && onTweenCreated != null) onTweenCreated.Invoke();
@ -481,33 +531,94 @@ namespace DG.Tweening
#region Public Methods
// These methods are here so they can be called directly via Unity's UGUI event system
#region Special
/// <summary>
/// Returns the tweens (if generated and not killed) created by all DOTweenAnimations on this gameObject,
/// in the same order as they appear in the Inspector (top to bottom).<para/>
/// Note that a tween is generated inside the Awake call (except RectTransform tweens which are generated inside Start),
/// so this method won't return them before that
/// </summary>
public List<Tween> GetTweens()
{
List<Tween> result = new List<Tween>();
DOTweenAnimation[] anims = this.GetComponents<DOTweenAnimation>();
foreach (DOTweenAnimation anim in anims) {
if (anim.tween != null && anim.tween.active) result.Add(anim.tween);
}
return result;
}
/// <summary>
/// Sets the animation target (which must be of the same type of the one set in the Inspector).
/// This is useful if you want to change it BEFORE this <see cref="DOTweenAnimation"/>
/// creates a tween, while after that it won't have any effect.<para/>
/// Consider that a <see cref="DOTweenAnimation"/> creates its tween inside its Awake (except for special tweens),
/// so you will need to sure your code runs before this object's Awake (via ScriptExecutionOrder or enabling/disabling methods)
/// </summary>
/// <param name="tweenTarget">
/// New target for the animation (must be of the same type of the previous one)</param>
/// <param name="useTweenTargetGameObjectForGroupOperations">If TRUE also uses tweenTarget's gameObject when settings the target-ID of the tween
/// (which is used with DOPlay/DORestart/etc to apply the same operation on all tweens that have the same target-id).<para/>
/// You should usually leave this to TRUE if you change the target.
/// </param>
public void SetAnimationTarget(Component tweenTarget, bool useTweenTargetGameObjectForGroupOperations = true)
{
TargetType newTargetType = TypeToDOTargetType(target.GetType());
if (newTargetType != targetType) {
Debug.LogError("DOTweenAnimation ► SetAnimationTarget: the new target is of a different type from the one set in the Inspector");
return;
}
target = tweenTarget;
targetGO = target.gameObject;
tweenTargetIsTargetGO = useTweenTargetGameObjectForGroupOperations;
}
#endregion
/// <summary>
/// Plays all tweens whose target-id is the same as the one set by this animation
/// </summary>
public override void DOPlay()
{
DOTween.Play(this.gameObject);
DOTween.Play(GetTweenTarget());
}
/// <summary>
/// Plays backwards all tweens whose target-id is the same as the one set by this animation
/// </summary>
public override void DOPlayBackwards()
{
DOTween.PlayBackwards(this.gameObject);
DOTween.PlayBackwards(GetTweenTarget());
}
/// <summary>
/// Plays foward all tweens whose target-id is the same as the one set by this animation
/// </summary>
public override void DOPlayForward()
{
DOTween.PlayForward(this.gameObject);
DOTween.PlayForward(GetTweenTarget());
}
/// <summary>
/// Pauses all tweens whose target-id is the same as the one set by this animation
/// </summary>
public override void DOPause()
{
DOTween.Pause(this.gameObject);
DOTween.Pause(GetTweenTarget());
}
/// <summary>
/// Pauses/unpauses (depending on the current state) all tweens whose target-id is the same as the one set by this animation
/// </summary>
public override void DOTogglePause()
{
DOTween.TogglePause(this.gameObject);
DOTween.TogglePause(GetTweenTarget());
}
/// <summary>
/// Rewinds all tweens created by this animation in the correct order
/// </summary>
public override void DORewind()
{
_playCount = -1;
@ -517,16 +628,16 @@ namespace DG.Tweening
Tween t = anims[i].tween;
if (t != null && t.IsInitialized()) anims[i].tween.Rewind();
}
// DOTween.Rewind(this.gameObject);
// DOTween.Rewind(GetTweenTarget());
}
/// <summary>
/// Restarts the tween
/// Restarts all tweens whose target-id is the same as the one set by this animation
/// </summary>
public override void DORestart()
{ DORestart(false); }
/// <summary>
/// Restarts the tween
/// Restarts all tweens whose target-id is the same as the one set by this animation
/// </summary>
/// <param name="fromHere">If TRUE, re-evaluates the tween's start and end values from its current position.
/// Set it to TRUE when spawning the same DOTweenAnimation in different positions (like when using a pooling system)</param>
@ -537,85 +648,128 @@ namespace DG.Tweening
if (Debugger.logPriority > 1) Debugger.LogNullTween(tween); return;
}
if (fromHere && isRelative) ReEvaluateRelativeTween();
DOTween.Restart(this.gameObject);
DOTween.Restart(GetTweenTarget());
}
/// <summary>
/// Completes all tweens whose target-id is the same as the one set by this animation
/// </summary>
public override void DOComplete()
{
DOTween.Complete(this.gameObject);
DOTween.Complete(GetTweenTarget());
}
/// <summary>
/// Kills all tweens whose target-id is the same as the one set by this animation
/// </summary>
public override void DOKill()
{
DOTween.Kill(this.gameObject);
DOTween.Kill(GetTweenTarget());
tween = null;
}
#region Specifics
/// <summary>
/// Plays all tweens with the given ID and whose target-id is the same as the one set by this animation
/// </summary>
public void DOPlayById(string id)
{
DOTween.Play(this.gameObject, id);
DOTween.Play(GetTweenTarget(), id);
}
/// <summary>
/// Plays all tweens with the given ID (regardless of their target gameObject)
/// </summary>
public void DOPlayAllById(string id)
{
DOTween.Play(id);
}
/// <summary>
/// Pauses all tweens that with the given ID (regardless of their target gameObject)
/// </summary>
public void DOPauseAllById(string id)
{
DOTween.Pause(id);
}
/// <summary>
/// Plays backwards all tweens with the given ID and whose target-id is the same as the one set by this animation
/// </summary>
public void DOPlayBackwardsById(string id)
{
DOTween.PlayBackwards(this.gameObject, id);
DOTween.PlayBackwards(GetTweenTarget(), id);
}
/// <summary>
/// Plays backwards all tweens with the given ID (regardless of their target gameObject)
/// </summary>
public void DOPlayBackwardsAllById(string id)
{
DOTween.PlayBackwards(id);
}
/// <summary>
/// Plays forward all tweens with the given ID and whose target-id is the same as the one set by this animation
/// </summary>
public void DOPlayForwardById(string id)
{
DOTween.PlayForward(this.gameObject, id);
DOTween.PlayForward(GetTweenTarget(), id);
}
/// <summary>
/// Plays forward all tweens with the given ID (regardless of their target gameObject)
/// </summary>
public void DOPlayForwardAllById(string id)
{
DOTween.PlayForward(id);
}
/// <summary>
/// Plays the next animation on this animation's gameObject (if any)
/// </summary>
public void DOPlayNext()
{
DOTweenAnimation[] anims = this.GetComponents<DOTweenAnimation>();
while (_playCount < anims.Length - 1) {
_playCount++;
DOTweenAnimation anim = anims[_playCount];
if (anim != null && anim.tween != null && !anim.tween.IsPlaying() && !anim.tween.IsComplete()) {
if (anim != null && anim.tween != null && anim.tween.active && !anim.tween.IsPlaying() && !anim.tween.IsComplete()) {
anim.tween.Play();
break;
}
}
}
/// <summary>
/// Rewinds all tweens with the given ID and whose target-id is the same as the one set by this animation,
/// then plays the next animation on this animation's gameObject (if any)
/// </summary>
public void DORewindAndPlayNext()
{
_playCount = -1;
DOTween.Rewind(this.gameObject);
DOTween.Rewind(GetTweenTarget());
DOPlayNext();
}
/// <summary>
/// Rewinds all tweens with the given ID (regardless of their target gameObject)
/// </summary>
public void DORewindAllById(string id)
{
_playCount = -1;
DOTween.Rewind(id);
}
/// <summary>
/// Restarts all tweens with the given ID and whose target-id is the same as the one set by this animation
/// </summary>
public void DORestartById(string id)
{
_playCount = -1;
DOTween.Restart(this.gameObject, id);
DOTween.Restart(GetTweenTarget(), id);
}
/// <summary>
/// Restarts all tweens with the given ID (regardless of their target gameObject)
/// </summary>
public void DORestartAllById(string id)
{
_playCount = -1;
@ -623,16 +777,18 @@ namespace DG.Tweening
}
/// <summary>
/// Returns the tweens created by this DOTweenAnimation, in the same order as they appear in the Inspector (top to bottom)
/// Kills all tweens with the given ID and whose target-id is the same as the one set by this animation
/// </summary>
public List<Tween> GetTweens()
public void DOKillById(string id)
{
// return DOTween.TweensByTarget(this.gameObject);
List<Tween> result = new List<Tween>();
DOTweenAnimation[] anims = this.GetComponents<DOTweenAnimation>();
foreach (DOTweenAnimation anim in anims) result.Add(anim.tween);
return result;
DOTween.Kill(GetTweenTarget(), id);
}
/// <summary>
/// Kills all tweens with the given ID (regardless of their target gameObject)
/// </summary>
public void DOKillAllById(string id)
{
DOTween.Kill(id);
}
#endregion
@ -653,7 +809,7 @@ namespace DG.Tweening
//#endif
#if true // UI_MARKER
// if (str == "RectTransform") str = "Transform";
if (str == "RawImage") str = "Image"; // RawImages are managed like Images for DOTweenAnimation (color and fade use Graphic target anyway)
if (str == "RawImage" || str == "Graphic") str = "Image"; // RawImages/Graphics are managed like Images for DOTweenAnimation (color and fade use Graphic target anyway)
#endif
return (TargetType)Enum.Parse(typeof(TargetType), str);
}
@ -666,7 +822,8 @@ namespace DG.Tweening
{
if (Application.isPlaying) return null;
CreateTween();
// CHANGE: first param switched to TRUE otherwise changing an animation and replaying in editor would still play old one
CreateTween(true, autoPlay);
return tween;
}
@ -676,12 +833,23 @@ namespace DG.Tweening
#region Private
// Returns the gameObject whose target component should be animated
/// <summary>
/// Returns the gameObject whose target component should be animated
/// </summary>
/// <returns></returns>
GameObject GetTweenGO()
{
return targetIsSelf ? this.gameObject : targetGO;
}
/// <summary>
/// Returns the GameObject which should be used/retrieved for SetTarget
/// </summary>
GameObject GetTweenTarget()
{
return targetIsSelf || !tweenTargetIsTargetGO ? this.gameObject : targetGO;
}
// Re-evaluate relative position of path
void ReEvaluateRelativeTween()
{

View File

@ -1,11 +1,8 @@
fileFormatVersion: 2
guid: 4d0390bd8b8ffd640b34fe25065ff1df
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,21 +1,22 @@
fileFormatVersion: 2
guid: aa0b1eebb5db27a419fa4564bbe5c9c5
PluginImporter:
externalObjects: {}
serializedVersion: 2
serializedVersion: 1
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,11 +1,8 @@
fileFormatVersion: 2
guid: 1c3190a1a1c53f449926f6d5542b4ce5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,17 +1,30 @@
// Author: Daniele Giardini - http://www.demigiant.com
// Author: Daniele Giardini - http://www.demigiant.com
// Created: 2015/03/27 19:02
//
// License Copyright (c) Daniele Giardini.
// This work is subject to the terms at http://dotween.demigiant.com/license.php
#if false // MODULE_MARKER
using System;
using System.Globalization;
using System.Collections.Generic;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using UnityEngine;
using TMPro;
using Object = UnityEngine.Object;
namespace DG.Tweening
{
public enum TMPSkewSpanMode
{
/// <summary>Applies the skew as-is (like normal skew works): the longer the text-span the higher the last character will be</summary>
Default,
/// <summary>Applies the skew scaled by the size of the text-span: the max skew/displacement will be the given skew factor</summary>
AsMaxSkewFactor
}
/// <summary>
/// Methods that extend TMP_Text objects and allow to directly create and control tweens from their instances.
/// </summary>
@ -98,6 +111,29 @@ namespace DG.Tweening
return t;
}
/// <summary>
/// Tweens a TextMeshPro's text from one integer to another, with options for thousands separators
/// </summary>
/// <param name="fromValue">The value to start from</param>
/// <param name="endValue">The end value to reach</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="addThousandsSeparator">If TRUE (default) also adds thousands separators</param>
/// <param name="culture">The <see cref="CultureInfo"/> to use (InvariantCulture if NULL)</param>
public static TweenerCore<int, int, NoOptions> DOCounter(
this TMP_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<int, int, NoOptions> t = DOTween.To(() => v, x => {
v = x;
target.text = addThousandsSeparator
? v.ToString("N0", cInfo)
: v.ToString();
}, endValue, duration);
t.SetTarget(target);
return t;
}
/// <summary>Tweens a TextMeshPro's fontSize to the given value.
/// Also stores the TextMeshPro as the tween's target so it can be used for filtered operations</summary>
/// <param name="endValue">The end value to reach</param><param name="duration">The duration of the tween</param>
@ -137,5 +173,865 @@ namespace DG.Tweening
#endregion
}
#region DOTweenTMPAnimator
// █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
// ███ CLASS ███████████████████████████████████████████████████████████████████████████████████████████████████████████
// █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
/// <summary>
/// Wrapper for <see cref="TMP_Text"/> objects that enables per-character tweening
/// (you don't need this if instead you want to animate the whole text object).
/// It also contains various handy methods to simply deform text without animating it ;)
/// <para><code>EXAMPLE:<para/>
/// DOTweenTMPAnimator animator = new DOTweenTMPAnimator(myTextMeshProTextField);<para/>
/// Tween tween = animator.DOCharScale(characterIndex, scaleValue, duration);
/// </code></para>
/// </summary>
public class DOTweenTMPAnimator : IDisposable
{
static readonly Dictionary<TMP_Text,DOTweenTMPAnimator> _targetToAnimator = new Dictionary<TMP_Text,DOTweenTMPAnimator>();
/// <summary><see cref="TMP_Text"/> that this animator is linked to</summary>
public TMP_Text target { get; private set; }
public TMP_TextInfo textInfo { get; private set; }
readonly List<CharTransform> _charTransforms = new List<CharTransform>();
TMP_MeshInfo[] _cachedMeshInfos;
bool _ignoreTextChangedEvent;
/// <summary>
/// Creates a new instance of the <see cref="DOTweenTMPAnimator"/>, which is necessary to animate <see cref="TMP_Text"/> by single characters.<para/>
/// If a <see cref="DOTweenTMPAnimator"/> already exists for the same <see cref="TMP_Text"/> object it will be disposed
/// (but not its tweens, those you will have to kill manually).
/// If you want to animate the whole text object you don't need this, and you can use direct <see cref="TMP_Text"/> DO shortcuts instead.<para/>
/// IMPORTANT: the <see cref="TMP_Text"/> target must have been enabled/activated at least once before you can use it with this
/// </summary>
/// <param name="target">The <see cref="TMP_Text"/> that will be linked to this animator</param>
public DOTweenTMPAnimator(TMP_Text target)
{
if (target == null) {
Debugger.LogError("DOTweenTMPAnimator target can't be null");
return;
}
if (!target.gameObject.activeInHierarchy) {
Debugger.LogError("You can't create a DOTweenTMPAnimator if its target is disabled");
return;
}
// Verify that there's no other animators for the same target, and in case dispose them
if (_targetToAnimator.ContainsKey(target)) {
if (Debugger.logPriority >= 2) {
Debugger.Log(string.Format(
"A DOTweenTMPAnimator for \"{0}\" already exists: disposing it because you can't have more than one DOTweenTMPAnimator" +
" for the same TextMesh Pro object. If you have tweens running on the disposed DOTweenTMPAnimator you should kill them manually",
target
));
}
_targetToAnimator[target].Dispose();
_targetToAnimator.Remove(target);
}
//
this.target = target;
_targetToAnimator.Add(target, this);
Refresh();
// Listeners
TMPro_EventManager.TEXT_CHANGED_EVENT.Add(OnTextChanged);
}
/// <summary>
/// If a <see cref="DOTweenTMPAnimator"/> instance exists for the given target disposes it
/// </summary>
public static void DisposeInstanceFor(TMP_Text target)
{
if (!_targetToAnimator.ContainsKey(target)) return;
_targetToAnimator[target].Dispose();
_targetToAnimator.Remove(target);
}
/// <summary>
/// Clears and disposes of this object
/// </summary>
public void Dispose()
{
target = null;
_charTransforms.Clear();
textInfo = null;
_cachedMeshInfos = null;
TMPro_EventManager.TEXT_CHANGED_EVENT.Remove(OnTextChanged);
}
/// <summary>
/// Refreshes the animator text data and resets all transformation data. Call this after you change the target <see cref="TMP_Text"/>
/// </summary>
public void Refresh()
{
_ignoreTextChangedEvent = true;
target.ForceMeshUpdate(true);
textInfo = target.textInfo;
_cachedMeshInfos = textInfo.CopyMeshInfoVertexData();
int totChars = textInfo.characterCount;
int totCurrent = _charTransforms.Count;
if (totCurrent > totChars) {
_charTransforms.RemoveRange(totChars, totCurrent - totChars);
totCurrent = totChars;
}
for (int i = 0; i < totCurrent; ++i) {
CharTransform c = _charTransforms[i];
c.ResetTransformationData();
c.Refresh(textInfo, _cachedMeshInfos);
_charTransforms[i] = c;
}
for (int i = totCurrent; i < totChars; ++i) _charTransforms.Add(new CharTransform(i, textInfo, _cachedMeshInfos));
_ignoreTextChangedEvent = false;
}
/// <summary>
/// Resets all deformations
/// </summary>
public void Reset()
{
int totCurrent = _charTransforms.Count;
for (int i = 0; i < totCurrent; ++i) _charTransforms[i].ResetAll(target, textInfo.meshInfo, _cachedMeshInfos);
}
void OnTextChanged(Object obj)
{
if (_ignoreTextChangedEvent || target == null || obj != target) return;
Refresh();
}
bool ValidateChar(int charIndex, bool isTween = true)
{
if (textInfo.characterCount <= charIndex) {
Debugger.LogError(string.Format("CharIndex {0} doesn't exist", charIndex));
return false;
}
if (!textInfo.characterInfo[charIndex].isVisible) {
if (Debugger.logPriority > 1) {
if (isTween) {
Debugger.Log(string.Format(
"CharIndex {0} isn't visible, ignoring it and returning an empty tween (TextMesh Pro will behave weirdly if invisible chars are included in the animation)",
charIndex
));
} else {
Debugger.Log(string.Format("CharIndex {0} isn't visible, ignoring it", charIndex));
}
}
return false;
}
return true;
}
bool ValidateSpan(int fromCharIndex, int toCharIndex, out int firstVisibleCharIndex, out int lastVisibleCharIndex)
{
firstVisibleCharIndex = -1; // First visible/existing charIndex from given index
lastVisibleCharIndex = -1; // Last visible/existing charIndex backwards from given index
int charCount = textInfo.characterCount;
if (fromCharIndex >= charCount) return false;
if (toCharIndex >= charCount) toCharIndex = charCount - 1;
for (int i = fromCharIndex; i < toCharIndex + 1; ++i) {
if (!_charTransforms[i].isVisible) continue;
firstVisibleCharIndex = i;
break;
}
if (firstVisibleCharIndex == -1) return false;
for (int i = toCharIndex; i > firstVisibleCharIndex - 1; --i) {
if (!_charTransforms[i].isVisible) continue;
lastVisibleCharIndex = i;
break;
}
if (lastVisibleCharIndex == -1) return false;
return true;
}
#region Word Setters
/// <summary>
/// Skews a span of characters uniformly (like normal skew works in graphic applications)
/// </summary>
/// <param name="fromCharIndex">First char index of the span to skew</param>
/// <param name="toCharIndex">Last char index of the span to skew</param>
/// <param name="skewFactor">Skew factor</param>
/// <param name="skewTop">If TRUE skews the top side of the span, otherwise the bottom one</param>
public void SkewSpanX(int fromCharIndex, int toCharIndex, float skewFactor, bool skewTop = true)
{
int firstVisibleCharIndex, lastVisibleCharIndex;
if (!ValidateSpan(fromCharIndex, toCharIndex, out firstVisibleCharIndex, out lastVisibleCharIndex)) return;
for (int i = firstVisibleCharIndex; i < lastVisibleCharIndex + 1; ++i) {
if (!_charTransforms[i].isVisible) continue;
CharVertices v = _charTransforms[i].GetVertices();
float skew = SkewCharX(i, skewFactor, skewTop);
}
}
/// <summary>
/// Skews a span of characters uniformly (like normal skew works in graphic applications)
/// </summary>
/// <param name="fromCharIndex">First char index of the span to skew</param>
/// <param name="toCharIndex">Last char index of the span to skew</param>
/// <param name="skewFactor">Skew factor</param>
/// <param name="mode">Skew mode</param>
/// <param name="skewRight">If TRUE skews the right side of the span, otherwise the left one</param>
public void SkewSpanY(
int fromCharIndex, int toCharIndex, float skewFactor,
TMPSkewSpanMode mode = TMPSkewSpanMode.Default, bool skewRight = true
){
int firstVisibleCharIndex, lastVisibleCharIndex;
if (!ValidateSpan(fromCharIndex, toCharIndex, out firstVisibleCharIndex, out lastVisibleCharIndex)) return;
if (mode == TMPSkewSpanMode.AsMaxSkewFactor) {
CharVertices firstVisibleCharVertices = _charTransforms[firstVisibleCharIndex].GetVertices();
CharVertices lastVisibleCharVertices = _charTransforms[lastVisibleCharIndex].GetVertices();
float spanW = Mathf.Abs(lastVisibleCharVertices.bottomRight.x - firstVisibleCharVertices.bottomLeft.x);
float spanH = Mathf.Abs(lastVisibleCharVertices.topRight.y - lastVisibleCharVertices.bottomRight.y);
float ratio = spanH / spanW;
skewFactor *= ratio;
}
float offsetY = 0;
CharVertices prevCharVertices = new CharVertices();
float prevCharSkew = 0;
if (skewRight) {
for (int i = firstVisibleCharIndex; i < lastVisibleCharIndex + 1; ++i) {
if (!_charTransforms[i].isVisible) continue;
CharVertices v = _charTransforms[i].GetVertices();
float skew = SkewCharY(i, skewFactor, skewRight);
if (i > firstVisibleCharIndex) {
float prevCharW = Mathf.Abs(prevCharVertices.bottomLeft.x - prevCharVertices.bottomRight.x);
float charsDist = Mathf.Abs(v.bottomLeft.x - prevCharVertices.bottomRight.x);
offsetY += prevCharSkew + (prevCharSkew * charsDist) / prevCharW;
SetCharOffset(i, new Vector3(0, _charTransforms[i].offset.y + offsetY, 0));
}
prevCharVertices = v;
prevCharSkew = skew;
}
} else {
for (int i = lastVisibleCharIndex; i > firstVisibleCharIndex - 1; --i) {
if (!_charTransforms[i].isVisible) continue;
CharVertices v = _charTransforms[i].GetVertices();
float skew = SkewCharY(i, skewFactor, skewRight);
if (i < lastVisibleCharIndex) {
float prevCharW = Mathf.Abs(prevCharVertices.bottomLeft.x - prevCharVertices.bottomRight.x);
float charsDist = Mathf.Abs(v.bottomRight.x - prevCharVertices.bottomLeft.x);
offsetY += prevCharSkew + (prevCharSkew * charsDist) / prevCharW;
SetCharOffset(i, new Vector3(0, _charTransforms[i].offset.y + offsetY, 0));
}
prevCharVertices = v;
prevCharSkew = skew;
}
}
}
#endregion
#region Char Getters
/// <summary>
/// Returns the current color of the given character, if it exists and is visible.
/// </summary>
/// <param name="charIndex">Character index</param>
public Color GetCharColor(int charIndex)
{
if (!ValidateChar(charIndex)) return Color.white;
return _charTransforms[charIndex].GetColor(textInfo.meshInfo);
}
/// <summary>
/// Returns the current offset of the given character, if it exists and is visible.
/// </summary>
/// <param name="charIndex">Character index</param>
public Vector3 GetCharOffset(int charIndex)
{
if (!ValidateChar(charIndex)) return Vector3.zero;
return _charTransforms[charIndex].offset;
}
/// <summary>
/// Returns the current rotation of the given character, if it exists and is visible.
/// </summary>
/// <param name="charIndex">Character index</param>
public Vector3 GetCharRotation(int charIndex)
{
if (!ValidateChar(charIndex)) return Vector3.zero;
return _charTransforms[charIndex].rotation.eulerAngles;
}
/// <summary>
/// Returns the current scale of the given character, if it exists and is visible.
/// </summary>
/// <param name="charIndex">Character index</param>
public Vector3 GetCharScale(int charIndex)
{
if (!ValidateChar(charIndex)) return Vector3.zero;
return _charTransforms[charIndex].scale;
}
#endregion
#region Char Setters
/// <summary>
/// Immediately sets the color of the given character.
/// Will do nothing if the <see cref="charIndex"/> is invalid or the character isn't visible
/// </summary>
/// <param name="charIndex">Character index</param>
/// <param name="color">Color to set</param>
public void SetCharColor(int charIndex, Color32 color)
{
if (!ValidateChar(charIndex)) return;
CharTransform c = _charTransforms[charIndex];
c.UpdateColor(target, color, textInfo.meshInfo);
_charTransforms[charIndex] = c;
}
/// <summary>
/// Immediately sets the offset of the given character.
/// Will do nothing if the <see cref="charIndex"/> is invalid or the character isn't visible
/// </summary>
/// <param name="charIndex">Character index</param>
/// <param name="offset">Offset to set</param>
public void SetCharOffset(int charIndex, Vector3 offset)
{
if (!ValidateChar(charIndex)) return;
CharTransform c = _charTransforms[charIndex];
c.UpdateGeometry(target, offset, c.rotation, c.scale, _cachedMeshInfos);
_charTransforms[charIndex] = c;
}
/// <summary>
/// Immediately sets the rotation of the given character.
/// Will do nothing if the <see cref="charIndex"/> is invalid or the character isn't visible
/// </summary>
/// <param name="charIndex">Character index</param>
/// <param name="rotation">Rotation to set</param>
public void SetCharRotation(int charIndex, Vector3 rotation)
{
if (!ValidateChar(charIndex)) return;
CharTransform c = _charTransforms[charIndex];
c.UpdateGeometry(target, c.offset, Quaternion.Euler(rotation), c.scale, _cachedMeshInfos);
_charTransforms[charIndex] = c;
}
/// <summary>
/// Immediately sets the scale of the given character.
/// Will do nothing if the <see cref="charIndex"/> is invalid or the character isn't visible
/// </summary>
/// <param name="charIndex">Character index</param>
/// <param name="scale">Scale to set</param>
public void SetCharScale(int charIndex, Vector3 scale)
{
if (!ValidateChar(charIndex)) return;
CharTransform c = _charTransforms[charIndex];
c.UpdateGeometry(target, c.offset, c.rotation, scale, _cachedMeshInfos);
_charTransforms[charIndex] = c;
}
/// <summary>
/// Immediately shifts the vertices of the given character by the given factor.
/// Will do nothing if the <see cref="charIndex"/> is invalid or the character isn't visible
/// </summary>
/// <param name="charIndex">Character index</param>
/// <param name="topLeftShift">Top left offset</param>
/// <param name="topRightShift">Top right offset</param>
/// <param name="bottomLeftShift">Bottom left offset</param>
/// <param name="bottomRightShift">Bottom right offset</param>
public void ShiftCharVertices(int charIndex, Vector3 topLeftShift, Vector3 topRightShift, Vector3 bottomLeftShift, Vector3 bottomRightShift)
{
if (!ValidateChar(charIndex)) return;
CharTransform c = _charTransforms[charIndex];
c.ShiftVertices(target, topLeftShift, topRightShift, bottomLeftShift, bottomRightShift);
_charTransforms[charIndex] = c;
}
/// <summary>
/// Skews the given character horizontally along the X axis and returns the skew amount applied (based on the character's size)
/// </summary>
/// <param name="charIndex">Character index</param>
/// <param name="skewFactor">skew amount</param>
/// <param name="skewTop">If TRUE skews the top side of the character, otherwise the bottom one</param>
public float SkewCharX(int charIndex, float skewFactor, bool skewTop = true)
{
if (!ValidateChar(charIndex)) return 0;
Vector3 skewV = new Vector3(skewFactor, 0, 0);
CharTransform c = _charTransforms[charIndex];
if (skewTop) c.ShiftVertices(target, skewV, skewV, Vector3.zero, Vector3.zero);
else c.ShiftVertices(target, Vector3.zero, Vector3.zero, skewV, skewV);
_charTransforms[charIndex] = c;
return skewFactor;
}
/// <summary>
/// Skews the given character vertically along the Y axis and returns the skew amount applied (based on the character's size)
/// </summary>
/// <param name="charIndex">Character index</param>
/// <param name="skewFactor">skew amount</param>
/// <param name="skewRight">If TRUE skews the right side of the character, otherwise the left one</param>
/// <param name="fixedSkew">If TRUE applies exactly the given <see cref="skewFactor"/>,
/// otherwise modifies it based on the aspectRation of the character</param>
public float SkewCharY(int charIndex, float skewFactor, bool skewRight = true, bool fixedSkew = false)
{
if (!ValidateChar(charIndex)) return 0;
float skew = fixedSkew ? skewFactor : skewFactor * textInfo.characterInfo[charIndex].aspectRatio;
Vector3 skewV = new Vector3(0, skew, 0);
CharTransform c = _charTransforms[charIndex];
if (skewRight) c.ShiftVertices(target, Vector3.zero, skewV, Vector3.zero, skewV);
else c.ShiftVertices(target, skewV, Vector3.zero, skewV, Vector3.zero);
_charTransforms[charIndex] = c;
return skew;
}
/// <summary>
/// Resets the eventual vertices shift applied to the given character via <see cref="ShiftCharVertices"/>.
/// Will do nothing if the <see cref="charIndex"/> is invalid or the character isn't visible
/// </summary>
/// <param name="charIndex">Character index</param>
public void ResetVerticesShift(int charIndex)
{
if (!ValidateChar(charIndex)) return;
CharTransform c = _charTransforms[charIndex];
c.ResetVerticesShift(target);
_charTransforms[charIndex] = c;
}
#endregion
#region Char Tweens
/// <summary>Tweens a character's alpha to the given value and returns the <see cref="Tween"/>.
/// Will return NULL if the <see cref="charIndex"/> is invalid or the character isn't visible.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="endValue">The end value to reach</param><param name="duration">The duration of the tween</param>
public TweenerCore<Color, Color, ColorOptions> DOFadeChar(int charIndex, float endValue, float duration)
{
if (!ValidateChar(charIndex)) return null;
TweenerCore<Color, Color, ColorOptions> t = DOTween.ToAlpha(() => _charTransforms[charIndex].GetColor(textInfo.meshInfo), x => {
_charTransforms[charIndex].UpdateAlpha(target, x, textInfo.meshInfo);
}, endValue, duration);
return t;
}
/// <summary>Tweens a character's color to the given value and returns the <see cref="Tween"/>.
/// Will return NULL if the <see cref="charIndex"/> is invalid or the character isn't visible.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="endValue">The end value to reach</param><param name="duration">The duration of the tween</param>
public TweenerCore<Color, Color, ColorOptions> DOColorChar(int charIndex, Color endValue, float duration)
{
if (!ValidateChar(charIndex)) return null;
TweenerCore<Color, Color, ColorOptions> t = DOTween.To(() => _charTransforms[charIndex].GetColor(textInfo.meshInfo), x => {
_charTransforms[charIndex].UpdateColor(target, x, textInfo.meshInfo);
}, endValue, duration);
return t;
}
/// <summary>Tweens a character's offset to the given value and returns the <see cref="Tween"/>.
/// Will return NULL if the <see cref="charIndex"/> is invalid or the character isn't visible.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="endValue">The end value to reach</param><param name="duration">The duration of the tween</param>
public TweenerCore<Vector3, Vector3, VectorOptions> DOOffsetChar(int charIndex, Vector3 endValue, float duration)
{
if (!ValidateChar(charIndex)) return null;
TweenerCore<Vector3, Vector3, VectorOptions> t = DOTween.To(() => _charTransforms[charIndex].offset, x => {
CharTransform charT = _charTransforms[charIndex];
charT.UpdateGeometry(target, x, charT.rotation, charT.scale, _cachedMeshInfos);
_charTransforms[charIndex] = charT;
}, endValue, duration);
return t;
}
/// <summary>Tweens a character's rotation to the given value and returns the <see cref="Tween"/>.
/// Will return NULL if the <see cref="charIndex"/> is invalid or the character isn't visible.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="endValue">The end value to reach</param><param name="duration">The duration of the tween</param>
/// <param name="mode">Rotation mode</param>
public TweenerCore<Quaternion, Vector3, QuaternionOptions> DORotateChar(int charIndex, Vector3 endValue, float duration, RotateMode mode = RotateMode.Fast)
{
if (!ValidateChar(charIndex)) return null;
TweenerCore<Quaternion, Vector3, QuaternionOptions> t = DOTween.To(() => _charTransforms[charIndex].rotation, x => {
CharTransform charT = _charTransforms[charIndex];
charT.UpdateGeometry(target, charT.offset, x, charT.scale, _cachedMeshInfos);
_charTransforms[charIndex] = charT;
}, endValue, duration);
t.plugOptions.rotateMode = mode;
return t;
}
/// <summary>Tweens a character's scale to the given value and returns the <see cref="Tween"/>.
/// Will return NULL if the <see cref="charIndex"/> is invalid or the character isn't visible.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="endValue">The end value to reach</param><param name="duration">The duration of the tween</param>
public TweenerCore<Vector3, Vector3, VectorOptions> DOScaleChar(int charIndex, float endValue, float duration)
{
return DOScaleChar(charIndex, new Vector3(endValue, endValue, endValue), duration);
}
/// <summary>Tweens a character's color to the given value and returns the <see cref="Tween"/>.
/// Will return NULL if the <see cref="charIndex"/> is invalid or the character isn't visible.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="endValue">The end value to reach</param><param name="duration">The duration of the tween</param>
public TweenerCore<Vector3, Vector3, VectorOptions> DOScaleChar(int charIndex, Vector3 endValue, float duration)
{
if (!ValidateChar(charIndex)) return null;
TweenerCore<Vector3, Vector3, VectorOptions> t = DOTween.To(() => _charTransforms[charIndex].scale, x => {
CharTransform charT = _charTransforms[charIndex];
charT.UpdateGeometry(target, charT.offset, charT.rotation, x, _cachedMeshInfos);
_charTransforms[charIndex] = charT;
}, endValue, duration);
return t;
}
/// <summary>Punches a character's offset towards the given direction and then back to the starting one
/// as if it was connected to the starting position via an elastic.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="punch">The punch strength</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="vibrato">Indicates how much will the punch vibrate per second</param>
/// <param name="elasticity">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 offset and the opposite offset,
/// while 0 oscillates only between the punch offset and the start offset</param>
public Tweener DOPunchCharOffset(int charIndex, Vector3 punch, float duration, int vibrato = 10, float elasticity = 1)
{
if (!ValidateChar(charIndex)) return null;
if (duration <= 0) {
if (Debugger.logPriority > 0) Debug.LogWarning("Duration can't be 0, returning NULL without creating a tween");
return null;
}
return DOTween.Punch(() => _charTransforms[charIndex].offset, x => {
CharTransform charT = _charTransforms[charIndex];
charT.UpdateGeometry(target, x, charT.rotation, charT.scale, _cachedMeshInfos);
_charTransforms[charIndex] = charT;
}, punch, duration, vibrato, elasticity);
}
/// <summary>Punches a character's rotation towards the given direction and then back to the starting one
/// as if it was connected to the starting position via an elastic.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="punch">The punch strength</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="vibrato">Indicates how much will the punch vibrate per second</param>
/// <param name="elasticity">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 rotation and the opposite rotation,
/// while 0 oscillates only between the punch rotation and the start rotation</param>
public Tweener DOPunchCharRotation(int charIndex, Vector3 punch, float duration, int vibrato = 10, float elasticity = 1)
{
if (!ValidateChar(charIndex)) return null;
if (duration <= 0) {
if (Debugger.logPriority > 0) Debug.LogWarning("Duration can't be 0, returning NULL without creating a tween");
return null;
}
return DOTween.Punch(() => _charTransforms[charIndex].rotation.eulerAngles, x => {
CharTransform charT = _charTransforms[charIndex];
charT.UpdateGeometry(target, charT.offset, Quaternion.Euler(x), charT.scale, _cachedMeshInfos);
_charTransforms[charIndex] = charT;
}, punch, duration, vibrato, elasticity);
}
/// <summary>Punches a character's scale towards the given direction and then back to the starting one
/// as if it was connected to the starting position via an elastic.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="punch">The punch strength (added to the character's current scale)</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="vibrato">Indicates how much will the punch vibrate per second</param>
/// <param name="elasticity">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</param>
public Tweener DOPunchCharScale(int charIndex, float punch, float duration, int vibrato = 10, float elasticity = 1)
{
return DOPunchCharScale(charIndex, new Vector3(punch, punch, punch), duration, vibrato, elasticity);
}
/// <summary>Punches a character's scale towards the given direction and then back to the starting one
/// as if it was connected to the starting position via an elastic.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="punch">The punch strength (added to the character's current scale)</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="vibrato">Indicates how much will the punch vibrate per second</param>
/// <param name="elasticity">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</param>
public Tweener DOPunchCharScale(int charIndex, Vector3 punch, float duration, int vibrato = 10, float elasticity = 1)
{
if (!ValidateChar(charIndex)) return null;
if (duration <= 0) {
if (Debugger.logPriority > 0) Debug.LogWarning("Duration can't be 0, returning NULL without creating a tween");
return null;
}
return DOTween.Punch(() => _charTransforms[charIndex].scale, x => {
CharTransform charT = _charTransforms[charIndex];
charT.UpdateGeometry(target, charT.offset, charT.rotation, x, _cachedMeshInfos);
_charTransforms[charIndex] = charT;
}, punch, duration, vibrato, elasticity);
}
/// <summary>Shakes a character's offset with the given values.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="strength">The shake strength</param>
/// <param name="vibrato">Indicates how much will the shake vibrate</param>
/// <param name="randomness">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.</param>
/// <param name="fadeOut">If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not</param>
public Tweener DOShakeCharOffset(int charIndex, float duration, float strength, int vibrato = 10, float randomness = 90, bool fadeOut = true)
{
return DOShakeCharOffset(charIndex, duration, new Vector3(strength, strength, strength), vibrato, randomness, fadeOut);
}
/// <summary>Shakes a character's offset with the given values.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="strength">The shake strength</param>
/// <param name="vibrato">Indicates how much will the shake vibrate</param>
/// <param name="randomness">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.</param>
/// <param name="fadeOut">If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not</param>
public Tweener DOShakeCharOffset(int charIndex, float duration, Vector3 strength, int vibrato = 10, float randomness = 90, bool fadeOut = true)
{
if (!ValidateChar(charIndex)) return null;
if (duration <= 0) {
if (Debugger.logPriority > 0) Debug.LogWarning("Duration can't be 0, returning NULL without creating a tween");
return null;
}
return DOTween.Shake(() => _charTransforms[charIndex].offset, x => {
CharTransform charT = _charTransforms[charIndex];
charT.UpdateGeometry(target, x, charT.rotation, charT.scale, _cachedMeshInfos);
_charTransforms[charIndex] = charT;
}, duration, strength, vibrato, randomness, fadeOut);
}
/// <summary>Shakes a character's rotation with the given values.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="strength">The shake strength</param>
/// <param name="vibrato">Indicates how much will the shake vibrate</param>
/// <param name="randomness">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.</param>
/// <param name="fadeOut">If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not</param>
public Tweener DOShakeCharRotation(int charIndex, float duration, Vector3 strength, int vibrato = 10, float randomness = 90, bool fadeOut = true)
{
if (!ValidateChar(charIndex)) return null;
if (duration <= 0) {
if (Debugger.logPriority > 0) Debug.LogWarning("Duration can't be 0, returning NULL without creating a tween");
return null;
}
return DOTween.Shake(() => _charTransforms[charIndex].rotation.eulerAngles, x => {
CharTransform charT = _charTransforms[charIndex];
charT.UpdateGeometry(target, charT.offset, Quaternion.Euler(x), charT.scale, _cachedMeshInfos);
_charTransforms[charIndex] = charT;
}, duration, strength, vibrato, randomness, fadeOut);
}
/// <summary>Shakes a character's scale with the given values.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="strength">The shake strength</param>
/// <param name="vibrato">Indicates how much will the shake vibrate</param>
/// <param name="randomness">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.</param>
/// <param name="fadeOut">If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not</param>
public Tweener DOShakeCharScale(int charIndex, float duration, float strength, int vibrato = 10, float randomness = 90, bool fadeOut = true)
{
return DOShakeCharScale(charIndex, duration, new Vector3(strength, strength, strength), vibrato, randomness, fadeOut);
}
/// <summary>Shakes a character's scale with the given values.</summary>
/// <param name="charIndex">The index of the character to tween (will throw an error if it doesn't exist)</param>
/// <param name="duration">The duration of the tween</param>
/// <param name="strength">The shake strength</param>
/// <param name="vibrato">Indicates how much will the shake vibrate</param>
/// <param name="randomness">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.</param>
/// <param name="fadeOut">If TRUE the shake will automatically fadeOut smoothly within the tween's duration, otherwise it will not</param>
public Tweener DOShakeCharScale(int charIndex, float duration, Vector3 strength, int vibrato = 10, float randomness = 90, bool fadeOut = true)
{
if (!ValidateChar(charIndex)) return null;
if (duration <= 0) {
if (Debugger.logPriority > 0) Debug.LogWarning("Duration can't be 0, returning NULL without creating a tween");
return null;
}
return DOTween.Shake(() => _charTransforms[charIndex].scale, x => {
CharTransform charT = _charTransforms[charIndex];
charT.UpdateGeometry(target, charT.offset, charT.rotation, x, _cachedMeshInfos);
_charTransforms[charIndex] = charT;
}, duration, strength, vibrato, randomness, fadeOut);
}
#endregion
// ███ INTERNAL CLASSES ████████████████████████████████████████████████████████████████████████████████████████████████
struct CharVertices
{
public Vector3 bottomLeft, topLeft, topRight, bottomRight;
public CharVertices(Vector3 bottomLeft, Vector3 topLeft, Vector3 topRight, Vector3 bottomRight)
{
this.bottomLeft = bottomLeft;
this.topLeft = topLeft;
this.topRight = topRight;
this.bottomRight = bottomRight;
}
}
// █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
// Vertices of each character are:
// 0 : bottom left, 1 : top left, 2 : top right, 3 : bottom right
struct CharTransform
{
public int charIndex;
public bool isVisible { get; private set; } // FALSE both if it's invisible or if it's a space
public Vector3 offset;
public Quaternion rotation;
public Vector3 scale;
Vector3 _topLeftShift, _topRightShift, _bottomLeftShift, _bottomRightShift;
Vector3 _charMidBaselineOffset;
int _matIndex, _firstVertexIndex;
TMP_MeshInfo _meshInfo;
public CharTransform(int charIndex, TMP_TextInfo textInfo, TMP_MeshInfo[] cachedMeshInfos) : this()
{
this.charIndex = charIndex;
offset = Vector3.zero;
rotation = Quaternion.identity;
scale = Vector3.one;
Refresh(textInfo, cachedMeshInfos);
}
public void Refresh(TMP_TextInfo textInfo, TMP_MeshInfo[] cachedMeshInfos)
{
TMP_CharacterInfo charInfo = textInfo.characterInfo[charIndex];
bool isSpaceChar = charInfo.character == ' ';
isVisible = charInfo.isVisible && !isSpaceChar;
_matIndex = charInfo.materialReferenceIndex;
_firstVertexIndex = charInfo.vertexIndex;
_meshInfo = textInfo.meshInfo[_matIndex];
Vector3[] cachedVertices = cachedMeshInfos[_matIndex].vertices;
_charMidBaselineOffset = isSpaceChar
? Vector3.zero
: (cachedVertices[_firstVertexIndex] + cachedVertices[_firstVertexIndex + 2]) * 0.5f;
}
public void ResetAll(TMP_Text target, TMP_MeshInfo[] meshInfos, TMP_MeshInfo[] cachedMeshInfos)
{
ResetGeometry(target, cachedMeshInfos);
ResetColors(target, meshInfos);
}
public void ResetTransformationData()
{
offset = Vector3.zero;
rotation = Quaternion.identity;
scale = Vector3.one;
_topLeftShift = _topRightShift = _bottomLeftShift = _bottomRightShift = Vector3.zero;
}
public void ResetGeometry(TMP_Text target, TMP_MeshInfo[] cachedMeshInfos)
{
ResetTransformationData();
Vector3[] destinationVertices = _meshInfo.vertices;
Vector3[] cachedVertices = cachedMeshInfos[_matIndex].vertices;
destinationVertices[_firstVertexIndex + 0] = cachedVertices[_firstVertexIndex + 0];
destinationVertices[_firstVertexIndex + 1] = cachedVertices[_firstVertexIndex + 1];
destinationVertices[_firstVertexIndex + 2] = cachedVertices[_firstVertexIndex + 2];
destinationVertices[_firstVertexIndex + 3] = cachedVertices[_firstVertexIndex + 3];
_meshInfo.mesh.vertices = _meshInfo.vertices;
target.UpdateGeometry(_meshInfo.mesh, _matIndex);
}
public void ResetColors(TMP_Text target, TMP_MeshInfo[] meshInfos)
{
Color color = target.color;
Color32[] vertexCols = meshInfos[_matIndex].colors32;
vertexCols[_firstVertexIndex] = color;
vertexCols[_firstVertexIndex + 1] = color;
vertexCols[_firstVertexIndex + 2] = color;
vertexCols[_firstVertexIndex + 3] = color;
target.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
}
public Color32 GetColor(TMP_MeshInfo[] meshInfos)
{
return meshInfos[_matIndex].colors32[_firstVertexIndex];
}
public CharVertices GetVertices()
{
return new CharVertices(
_meshInfo.vertices[_firstVertexIndex], _meshInfo.vertices[_firstVertexIndex + 1],
_meshInfo.vertices[_firstVertexIndex + 2], _meshInfo.vertices[_firstVertexIndex + 3]
);
}
public void UpdateAlpha(TMP_Text target, Color alphaColor, TMP_MeshInfo[] meshInfos, bool apply = true)
{
byte alphaByte = (byte)(alphaColor.a * 255);
Color32[] vertexCols = meshInfos[_matIndex].colors32;
vertexCols[_firstVertexIndex].a = alphaByte;
vertexCols[_firstVertexIndex + 1].a = alphaByte;
vertexCols[_firstVertexIndex + 2].a = alphaByte;
vertexCols[_firstVertexIndex + 3].a = alphaByte;
if (apply) target.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
}
public void UpdateColor(TMP_Text target, Color32 color, TMP_MeshInfo[] meshInfos, bool apply = true)
{
Color32[] vertexCols = meshInfos[_matIndex].colors32;
vertexCols[_firstVertexIndex] = color;
vertexCols[_firstVertexIndex + 1] = color;
vertexCols[_firstVertexIndex + 2] = color;
vertexCols[_firstVertexIndex + 3] = color;
if (apply) target.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
}
public void UpdateGeometry(TMP_Text target, Vector3 offset, Quaternion rotation, Vector3 scale, TMP_MeshInfo[] cachedMeshInfos, bool apply = true)
{
this.offset = offset;
this.rotation = rotation;
this.scale = scale;
if (!apply) return;
Vector3[] destinationVertices = _meshInfo.vertices;
Vector3[] cachedVertices = cachedMeshInfos[_matIndex].vertices;
destinationVertices[_firstVertexIndex] = cachedVertices[_firstVertexIndex + 0] - _charMidBaselineOffset;
destinationVertices[_firstVertexIndex + 1] = cachedVertices[_firstVertexIndex + 1] - _charMidBaselineOffset;
destinationVertices[_firstVertexIndex + 2] = cachedVertices[_firstVertexIndex + 2] - _charMidBaselineOffset;
destinationVertices[_firstVertexIndex + 3] = cachedVertices[_firstVertexIndex + 3] - _charMidBaselineOffset;
Matrix4x4 matrix = Matrix4x4.TRS(this.offset, this.rotation, this.scale);
destinationVertices[_firstVertexIndex]
= matrix.MultiplyPoint3x4(destinationVertices[_firstVertexIndex + 0]) + _charMidBaselineOffset + _bottomLeftShift;
destinationVertices[_firstVertexIndex + 1]
= matrix.MultiplyPoint3x4(destinationVertices[_firstVertexIndex + 1]) + _charMidBaselineOffset + _topLeftShift;
destinationVertices[_firstVertexIndex + 2]
= matrix.MultiplyPoint3x4(destinationVertices[_firstVertexIndex + 2]) + _charMidBaselineOffset + _topRightShift;
destinationVertices[_firstVertexIndex + 3]
= matrix.MultiplyPoint3x4(destinationVertices[_firstVertexIndex + 3]) + _charMidBaselineOffset + _bottomRightShift;
_meshInfo.mesh.vertices = _meshInfo.vertices;
target.UpdateGeometry(_meshInfo.mesh, _matIndex);
}
public void ShiftVertices(TMP_Text target, Vector3 topLeftShift, Vector3 topRightShift, Vector3 bottomLeftShift, Vector3 bottomRightShift)
{
_topLeftShift += topLeftShift;
_topRightShift += topRightShift;
_bottomLeftShift += bottomLeftShift;
_bottomRightShift += bottomRightShift;
Vector3[] destinationVertices = _meshInfo.vertices;
destinationVertices[_firstVertexIndex] = destinationVertices[_firstVertexIndex] + _bottomLeftShift;
destinationVertices[_firstVertexIndex + 1] = destinationVertices[_firstVertexIndex + 1] + _topLeftShift;
destinationVertices[_firstVertexIndex + 2] = destinationVertices[_firstVertexIndex + 2] + _topRightShift;
destinationVertices[_firstVertexIndex + 3] = destinationVertices[_firstVertexIndex + 3] + _bottomRightShift;
_meshInfo.mesh.vertices = _meshInfo.vertices;
target.UpdateGeometry(_meshInfo.mesh, _matIndex);
}
public void ResetVerticesShift(TMP_Text target)
{
Vector3[] destinationVertices = _meshInfo.vertices;
destinationVertices[_firstVertexIndex] = destinationVertices[_firstVertexIndex] - _bottomLeftShift;
destinationVertices[_firstVertexIndex + 1] = destinationVertices[_firstVertexIndex + 1] - _topLeftShift;
destinationVertices[_firstVertexIndex + 2] = destinationVertices[_firstVertexIndex + 2] - _topRightShift;
destinationVertices[_firstVertexIndex + 3] = destinationVertices[_firstVertexIndex + 3] - _bottomRightShift;
_meshInfo.mesh.vertices = _meshInfo.vertices;
target.UpdateGeometry(_meshInfo.mesh, _matIndex);
_topLeftShift = _topRightShift = _bottomLeftShift = _bottomRightShift = Vector3.zero;
}
}
}
#endregion
}
#endif

View File

@ -1,11 +1,8 @@
fileFormatVersion: 2
guid: 8fb0d65aa5b048649a3a785b82b8f8db
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -98,6 +98,7 @@ namespace DG.Tweening
: 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;
}
@ -219,6 +220,7 @@ namespace DG.Tweening
: 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;
}

View File

@ -1,11 +1,8 @@
fileFormatVersion: 2
guid: b590cd7c24ffa5d4faa5b6fa993cccad
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -67,7 +67,7 @@ namespace DG.DOTweenEditor
typeof(SpriteRenderer),
#endif
#if true // UI_MARKER
typeof(Image), typeof(Text), typeof(RawImage),
typeof(Image), typeof(Text), typeof(RawImage), typeof(Graphic),
#endif
typeof(Renderer),
}},
@ -77,7 +77,7 @@ namespace DG.DOTweenEditor
typeof(SpriteRenderer),
#endif
#if true // UI_MARKER
typeof(Image), typeof(Text), typeof(CanvasGroup), typeof(RawImage),
typeof(Image), typeof(Text), typeof(CanvasGroup), typeof(RawImage), typeof(Graphic),
#endif
typeof(Renderer),
}},
@ -336,7 +336,10 @@ namespace DG.DOTweenEditor
// _src.animationType = (DOTweenAnimation.AnimationType)EditorGUILayout.EnumPopup(_src.animationType, EditorGUIUtils.popupButton);
GUI.enabled = GUI.enabled && _src.isActive;
_src.animationType = AnimationToDOTweenAnimationType(_AnimationType[EditorGUILayout.Popup(DOTweenAnimationTypeToPopupId(_src.animationType), _AnimationType)]);
_src.autoGenerate = DeGUILayout.ToggleButton(_src.autoGenerate, new GUIContent("AutoGenerate", "If selected, the tween will be generated at startup (during Start for RectTransform position tween, Awake for all the others)"));
if (_src.autoGenerate) {
_src.autoPlay = DeGUILayout.ToggleButton(_src.autoPlay, new GUIContent("AutoPlay", "If selected, the tween will play automatically"));
}
_src.autoKill = DeGUILayout.ToggleButton(_src.autoKill, new GUIContent("AutoKill", "If selected, the tween will be killed when it completes, and won't be reusable"));
GUILayout.EndHorizontal();
if (prevAnimType != _src.animationType) {
@ -381,6 +384,7 @@ namespace DG.DOTweenEditor
_src.optionalInt0 = 10;
_src.optionalFloat0 = 90;
_src.optionalBool0 = false;
_src.optionalBool1 = true;
break;
case DOTweenAnimation.AnimationType.CameraAspect:
case DOTweenAnimation.AnimationType.CameraFieldOfView:
@ -463,7 +467,7 @@ namespace DG.DOTweenEditor
_src.delay = EditorGUILayout.FloatField("Delay", _src.delay);
if (_src.delay < 0) _src.delay = 0;
_src.isIndependentUpdate = EditorGUILayout.Toggle("Ignore TimeScale", _src.isIndependentUpdate);
_src.easeType = EditorGUIUtils.FilteredEasePopup(_src.easeType);
_src.easeType = EditorGUIUtils.FilteredEasePopup("Ease", _src.easeType);
if (_src.easeType == Ease.INTERNAL_Custom) {
_src.easeCurve = EditorGUILayout.CurveField(" Ease Curve", _src.easeCurve);
}
@ -533,6 +537,7 @@ namespace DG.DOTweenEditor
canBeRelative = false;
_src.optionalInt0 = EditorGUILayout.IntSlider(new GUIContent(" Vibrato", "How much will the shake vibrate"), _src.optionalInt0, 1, 50);
_src.optionalFloat0 = EditorGUILayout.Slider(new GUIContent(" Randomness", "The shake randomness"), _src.optionalFloat0, 0, 90);
_src.optionalBool1 = EditorGUILayout.Toggle(new GUIContent(" FadeOut", "If selected the shake will fade out, otherwise it will constantly play with full force"), _src.optionalBool1);
if (_src.animationType == DOTweenAnimation.AnimationType.ShakePosition) _src.optionalBool0 = EditorGUILayout.Toggle(" Snapping", _src.optionalBool0);
break;
case DOTweenAnimation.AnimationType.CameraAspect:

View File

@ -1,11 +1,8 @@
fileFormatVersion: 2
guid: e0203fd81362bab4d842d87ad09ee76e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,11 +1,8 @@
fileFormatVersion: 2
guid: 22292a5f27a9a644ba9e6ad1bf863531
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,21 +1,22 @@
fileFormatVersion: 2
guid: a6402d4311c862b4eb1325590d6466af
PluginImporter:
externalObjects: {}
serializedVersion: 2
serializedVersion: 1
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
enabled: 0
settings: {}
Editor:
enabled: 1
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,21 +1,22 @@
fileFormatVersion: 2
guid: 54be29b67d0d29a478da2c6e5c62f091
PluginImporter:
externalObjects: {}
serializedVersion: 2
serializedVersion: 1
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
Editor:
enabled: 0
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,21 +1,22 @@
fileFormatVersion: 2
guid: 202f9ddaf2c1a8a429504f7f3cd7b84f
PluginImporter:
externalObjects: {}
serializedVersion: 2
serializedVersion: 1
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
enabled: 0
settings: {}
Editor:
enabled: 1
settings:
DefaultValueInitialized: true
WindowsStoreApps:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e96abeb1f09348347b332c382de47ebf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a17218ae3d0bbc443956d5db81e3e367
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d51d58128dcf97146aec2b9e6a077dcc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 68f34ce47fd3f724cabb4cba78a0ddcf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,142 @@
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<float, float, FloatOptions> 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<Color, Color, ColorOptions> 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<Color, Color, ColorOptions> 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<Vector4, Vector4, VectorOptions> 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<float, float, FloatOptions> 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<Color, Color, ColorOptions> 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<Color, Color, ColorOptions> 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<Vector4, Vector4, VectorOptions> 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);
}
public static TweenerCore<Color, Color, ColorOptions> 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;
}
public static TweenerCore<Color, Color, ColorOptions> 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;
}
public static TweenerCore<float, float, FloatOptions> 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;
}
public static TweenerCore<float, float, FloatOptions> 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;
}
public static TweenerCore<float, float, FloatOptions> 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;
}
public static TweenerCore<float, float, FloatOptions> 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;
}
public static TweenerCore<float, float, FloatOptions> DOInfoRendererScale(this Outliner target, float endValue, float duration, bool snapping = false)
{
var tweener = DOTween.To(() => target.InfoRendererScale, x => target.InfoRendererScale = x, endValue, duration);
tweener.SetOptions(snapping).SetTarget(target);
return tweener;
}
public static TweenerCore<float, float, FloatOptions> DOPrimaryRendererScale(this Outliner target, float endValue, float duration, bool snapping = false)
{
var tweener = DOTween.To(() => target.PrimaryRendererScale, x => target.PrimaryRendererScale = x, endValue, duration);
tweener.SetOptions(snapping).SetTarget(target);
return tweener;
}
}
}
#endif

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e944529dcaee98f4e9498d80e541d93e
timeCreated: 1602593330
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0dd3254dc63d66b459aefa5689ecf2b4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
// Author: Daniele Giardini - http://www.demigiant.com
// Created: 2015/03/27 19:02
//
// License Copyright (c) Daniele Giardini.
// This work is subject to the terms at http://dotween.demigiant.com/license.php
#if false // MODULE_MARKER
#endif

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1d1aa01bacf85c04ea18116651a7f0db
timeCreated: 1587116610
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,9 @@
// Author: Daniele Giardini - http://www.demigiant.com
// Created: 2015/03/27 19:02
//
// License Copyright (c) Daniele Giardini.
// This work is subject to the terms at http://dotween.demigiant.com/license.php
#if false // MODULE_MARKER
#endif

View File

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0a0cc3e90c4a6ea41bb14d7f35c577c3
timeCreated: 1587116610
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c2898cf3244165c46ab193903225f80f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,150 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &8992645734443754309
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8992645734443754306}
- component: {fileID: 8992645734443754307}
m_Layer: 0
m_Name: GameObject
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &8992645734443754306
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8992645734443754309}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0.499, z: 0}
m_LocalScale: {x: 0.22218, y: 0.22218, z: 0.22218}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 8992645734844834622}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!212 &8992645734443754307
SpriteRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8992645734443754309}
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: 1705ebcb01175a54ba549314203ad4fc, type: 3}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_FlipX: 0
m_FlipY: 0
m_DrawMode: 0
m_Size: {x: 1, y: 1}
m_AdaptiveModeThreshold: 0.5
m_SpriteTileMode: 0
m_WasSpriteAssigned: 1
m_MaskInteraction: 0
m_SpriteSortPoint: 0
--- !u!1 &8992645734844834592
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8992645734844834622}
- component: {fileID: 8992645734844834593}
- component: {fileID: 355914467147041394}
m_Layer: 0
m_Name: StationInformation
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &8992645734844834622
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8992645734844834592}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 1.419, y: 0.423, z: 0.909}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 8992645734443754306}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &8992645734844834593
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8992645734844834592}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 58e2fbd82adbcd14aac54bb85f5464ce, type: 3}
m_Name:
m_EditorClassIdentifier:
worldOrLocal: 0
lockXZ: 0
onClick:
m_PersistentCalls:
m_Calls: []
--- !u!65 &355914467147041394
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8992645734844834592}
m_Material: {fileID: 0}
m_IsTrigger: 0
m_Enabled: 1
serializedVersion: 2
m_Size: {x: 1, y: 1, z: 0.3}
m_Center: {x: 0, y: 0.5, z: 0}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6fe0e639b544b9b44aa22ea2bb34e59c
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c5968322b51b24a4699568f3b5fe636c
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5642be0605a7d4c4699bd28d3f564520
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,86 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
// [SerializeField] private bool _isLoadNotDestory = true;
private static T instance;
private static object locker = new object();
public static T Instance
{
get
{
if (instance == null)
{
lock (locker)
{
T[] instances = FindObjectsOfType<T>();
if (FindObjectsOfType<T>().Length >= 1)
{
instance = instances[0];
for (int i = 1; i < instances.Length; i++)
{
#if UNITY_EDITOR
Debug.LogError($"{typeof(T)} 不应该存在多个单例!{instances[i].name}");
#endif
Destroy(instances[i]);
}
return instance;
}
if (instance == null && Application.isPlaying)
{
var singleton = new GameObject();
instance = singleton.AddComponent<T>();
singleton.name = "(singleton)_" + typeof(T);
}
else
{
// DontDestroyOnLoad(instance.gameObject);
}
}
// instance.hideFlags = HideFlags.None;
}
return instance;
}
}
// public static bool IsInitialized
// {
// get
// {
// return instance != null;
// }
// }
protected virtual void Awake()
{
// if (_isLoadNotDestory)
// {
// DontDestroyOnLoad(this);
// }
// if (instance != null)
// {
// Debug.LogErrorFormat("Trying to instantiate a second instance of singleton class {0}", GetType().Name);
// }
// else
// {
// instance = (T)this;
// }
}
// public virtual void OnDestroy()
// {
// if (instance == this)
// {
// instance = null;
// }
// }
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 940d26f8b14309d4196d0b4b9adb88f6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 351698f4b841690479b9d88c8dd264e5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,102 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class CameraMgr : MonoSingleton<CameraMgr>
{
CameraRT camera_Rt;
Vector3 originPos;
Vector3 originRot;
// [Header("业务视角点")]
public List<Transform> logicViewList = new List<Transform>();
private void Awake()
{
camera_Rt = GetComponent<CameraRT>();
}
public void SetOrigin()
{
originPos = Camera.main.transform.position;
originRot = Camera.main.transform.localEulerAngles;
}
public void GotoView(string viewName)
{
Transform viewTarget = logicViewList.Find(x => x.name == viewName);
camera_Rt.SetTarget(viewTarget);
}
public void GotoView(string viewName, float _distance)
{
Transform viewTarget = logicViewList.Find(x => x.name == viewName);
camera_Rt.SetTarget(viewTarget, _distance);
}
public void GotoView(Transform viewTarget, float _distance)
{
camera_Rt.SetTarget(viewTarget, _distance);
}
public void GotoView(Vector3 viewTarget, float _distance)
{
camera_Rt.SetTarget(viewTarget, _distance);
}
public void ReturnToMain()
{
Camera.main.transform.DORotate(originRot, 1);
Camera.main.transform.DOMove(originPos, 1);
}
#region
//[Header("漫游视角自动切换")]
//public bool autoChangeView = false;
//public float changeViewTimer;
//public List<Transform> autoChangeViewList;
//int index = 0;
//void ChangeView()
//{
// if (!autoChangeView)
// return;
// if (index > autoChangeViewList.Count - 1)
// {
// index = 0;
// ReturnToMain();
// return;
// }
// Camera.main.transform.position = autoChangeViewList[index].position;
// Camera.main.transform.localEulerAngles = autoChangeViewList[index].localEulerAngles;
// index++;
//}
//public void AutoChangeView_Open()
//{
// autoChangeView = true;
// CancelInvoke("ChangeView");
// InvokeRepeating("ChangeView", 15, 15);
//}
//public void AutoChangeView_Close()
//{
// autoChangeView = false;
//}
#endregion
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3eb4821edfbe33540a04ab32d1cf7212
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,271 @@
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;
using UnityEngine.EventSystems;
/// <summary>
/// 相机控制
/// </summary>
public class CameraRT : MonoBehaviour
{
public Camera cam;
[Header("目标物体")]
Transform target;
[Header("旋转角度")]
public float x = 0f;
public float y = 0f;
public float z = 0f;
[Header("移动、旋转、缩放速度值")]
public float xSpeed_move = 600;
public float ySpeed_move = 600;
public float xSpeed_rotate = 2;
public float ySpeed_rotate = 2;
public float mSpeed_scale = 150;
[Header("y轴角度限制")]
public float yMinLimit = 2;
public float yMaxLimit = 90;
[Header("x轴角度限制")]
public float leftMax = -365;
public float rightMax = 365;
[Header("距离限制")]
public float distance = 400;
public float minDistance = 10f;
public float maxDistance = 400f;
[Header("阻尼设置")]
public bool needDamping = true;
public float damping = 6f;
[Header("相机活动范围")]
public bool isRangeClamped;
public float xMinValue = -100f;
public float xMaxValue = 100f;
public float zMinValue = -100f;
public float zMaxValue = 100f;
[Header("自动旋转")]
public bool autoRotate;
public float rotateTimer = 15;
public float rotateSpeed = 5;
float rotateTimer_temp;
bool isAutoRotating = false;
//动态调节相机缩放的灵敏度
float tempSpeed;
private void Start()
{
if (cam == null)
{
cam = Camera.main;
}
target = transform.GetChild(0);
target.gameObject.AddComponent<CameraTargetFollowCam>();
x = cam.transform.localEulerAngles.y;
y = cam.transform.localEulerAngles.x;
tempSpeed = xSpeed_move;
rotateTimer_temp = rotateTimer;
}
public void SetTarget(Transform _target)
{
target.position = _target.position;
distance = _target.localScale.x;
y = _target.eulerAngles.x;
x = _target.eulerAngles.y;
}
public void SetTarget(Transform _target, float _distance)
{
target.position = _target.position;
distance = _distance;
y = _target.eulerAngles.x;
x = _target.eulerAngles.y;
}
public void SetTarget(Vector3 _target, float _distance)
{
target.position = _target;
distance = _distance;
//y = _target.eulerAngles.x;
//x = _target.eulerAngles.y;
}
Vector3 oldMousePos;
void Update()
{
if (!autoRotate)
return;
if (oldMousePos != Input.mousePosition || Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1) || Input.GetMouseButtonDown(2))
{
rotateTimer = rotateTimer_temp;
if (isAutoRotating)
{
x = cam.transform.eulerAngles.y;
y = cam.transform.eulerAngles.x;
}
}
oldMousePos = Input.mousePosition;
if (rotateTimer <= 0)
{
isAutoRotating = true;
//cam.transform.LookAt(target);
//cam.transform.RotateAround(target.position, Vector3.up, -Time.deltaTime * rotateSpeed);
rotateTimer = rotateTimer_temp;
}
else
{
rotateTimer -= Time.deltaTime;
isAutoRotating = false;
}
}
void LateUpdate()
{
if (isAutoRotating)
return;
if (target)
{
Scroll();
Move();
Rotate();
Quaternion rotation = Quaternion.Euler(y, x, z);
Vector3 disVector = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * disVector + target.position;
// 阻尼感
if (needDamping)
{
cam.transform.rotation = Quaternion.Lerp(cam.transform.rotation, rotation, Time.deltaTime * damping);
cam.transform.position = Vector3.Lerp(cam.transform.position, position, Time.deltaTime * damping);
}
else
{
cam.transform.rotation = rotation;
cam.transform.position = position;
}
}
}
void Move()
{
if (EventSystem.current.IsPointerOverGameObject())
return;
if (Input.GetMouseButton(0))
{
float h = Input.GetAxis("Mouse X") * Time.deltaTime * xSpeed_move;
float v = Input.GetAxis("Mouse Y") * Time.deltaTime * ySpeed_move;
target.Translate(-h, 0, -v);
if (!isRangeClamped)
return;
float targetX = target.position.x;
targetX = Mathf.Clamp(targetX, xMinValue, xMaxValue);
float targetZ = target.position.z;
targetZ = Mathf.Clamp(targetZ, zMinValue, zMaxValue);
target.position = new Vector3(targetX, target.position.y, targetZ);
}
}
void Rotate()
{
if (Input.GetMouseButton(1))
{
// 判断是否需要反向旋转
if ((y > 90f && y < 270f) || (y < -90 && y > -270f))
{
x -= Input.GetAxis("Mouse X") * xSpeed_rotate;
}
else
{
x += Input.GetAxis("Mouse X") * xSpeed_rotate;
}
y -= Input.GetAxis("Mouse Y") * ySpeed_rotate;
x = ClampAngle(x, leftMax, rightMax);
y = ClampAngle(y, yMinLimit, yMaxLimit);
}
}
void Scroll()
{
distance -= Input.GetAxis("Mouse ScrollWheel") * mSpeed_scale;
distance = Mathf.Clamp(distance, minDistance, maxDistance);
xSpeed_move = distance / maxDistance * tempSpeed;
ySpeed_move = distance / maxDistance * tempSpeed;
}
// 对数值进行限制
float ClampAngle(float angle, float min, float max)
{
if (angle < -360)
angle += 360;
if (angle > 360)
angle -= 360;
return Mathf.Clamp(angle, min, max);
}
#if UNITY_EDITOR
private void OnDrawGizmosSelected()
{
//如果限制活动范围 将区域范围绘制出来
if (isRangeClamped)
{
Handles.color = Color.cyan;
Vector3[] points = new Vector3[8]
{
new Vector3(xMinValue, 0, zMinValue),
new Vector3(xMaxValue, 0, zMinValue),
new Vector3(xMaxValue, 0, zMaxValue),
new Vector3(xMinValue, 0, zMaxValue),
new Vector3(xMinValue, 0, zMinValue),
new Vector3(xMaxValue, 0, zMinValue),
new Vector3(xMaxValue, 0, zMaxValue),
new Vector3(xMinValue, 0, zMaxValue)
};
for (int i = 0; i < 4; i++)
{
int start = i % 4;
int end = (i + 1) % 4;
Handles.DrawLine(points[start], points[end]);
Handles.DrawLine(points[start + 4], points[end + 4]);
Handles.DrawLine(points[start], points[i + 4]);
}
}
}
#endif
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b0b9e0f8345b2384394ba306242cd2a4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraTargetFollowCam : MonoBehaviour
{
void Update()
{
transform.localEulerAngles = new Vector3(0, Camera.main.transform.localEulerAngles.y, Camera.main.transform.localEulerAngles.z);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5dd7a8c053d2b724197101a3ce4d0f94
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,61 @@
using UnityEngine;
/// <summary>
/// 面向相机
/// </summary>
public class Face2Camera : MonoBehaviour
{
//主相机
public Camera mainCamera;
//翻转背面
public bool invertBack;
//是否启用垂直方向上的朝向
//设为false时 仅在水平方向上面向相机
public bool isEnableVertical = true;
//是否启用插值运算
public bool isEnableLerp;
//插值到目标值所需的时间 isEnableLerp为true时起作用
[Range(0.01f, 1f), SerializeField] private float lerpTime = 1f;
public float _distance;//最大距离
Vector3 initScale;
private void Start()
{
if (mainCamera == null)
{
mainCamera = Camera.main ?? FindObjectOfType<Camera>();
}
initScale = transform.localScale;
}
private void Update()
{
if (mainCamera == null)
return;
Vector3 forward = (isEnableVertical
? -mainCamera.transform.forward
: Vector3.ProjectOnPlane((mainCamera.transform.position - transform.position).normalized, Vector3.up))
* (invertBack ? 1 : -1);
transform.forward = !isEnableLerp ? forward
: Vector3.Lerp(transform.forward, forward, 1f - Mathf.Exp(Mathf.Log(1f - .99f) / lerpTime * Time.deltaTime));
float distance = Vector3.Distance(Camera.main.transform.position, transform.position);//不断变化的距离
float scale = distance / _distance;
if (scale > 1f)
scale = 1f;
transform.localScale = initScale * scale;
}
//public Face2Camera Set(Camera mainCamera, bool invertBack, bool isEnableVertical)
//{
// this.mainCamera = mainCamera;
// this.invertBack = invertBack;
// this.isEnableVertical = isEnableVertical;
// return this;
//}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ddfad4468ea99f145bc0b1cd5782d954
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ca8e16717c0394248b3589cd866cc7e5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,23 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//============================================================
//支持中文文件使用UTF-8编码
//@author YangHua
//@create 20230531
//@company Adam
//
//@description:
//============================================================
namespace Focus
{
public class ModelClick : MonoBehaviour
{
private void OnMouseDown()
{
CameraMgr.Instance.GotoView(transform, 10f);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: eb2c3e0639c2b164d9cad2af0bb107ad
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,34 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//============================================================
//支持中文文件使用UTF-8编码
//@author #AUTHOR#
//@create #CREATEDATE#
//@company #COMPANY#
//
//@description:
//============================================================
public enum Status
{
Normal,
Warn,
}
public class SwitchStatus : MonoBehaviour
{
public Status status = Status.Normal;
private void Update()
{
if (status == Status.Warn)
{
gameObject.GetComponent<Renderer>().material.color = Color.yellow;
}
else
{
gameObject.GetComponent<Renderer>().material.color = Color.green;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f1f347c5db58cd2448b4b926d5f2d5f5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,109 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//============================================================
//支持中文文件使用UTF-8编码
//@author YangHua
//@create 20230531
//@company Adam
//
//@description:
//============================================================
namespace Focus
{
public class SwitchViews : MonoBehaviour
{
public Transform viewOne;
public Transform viewTwo;
public List<SwitchStatus> warns = new List<SwitchStatus>();
public List<GameObject> warnning = new List<GameObject>();
public int count = 0;
public void OnViewOneClick()
{
CameraMgr.Instance.GotoView(viewOne, 10f);
}
public void OnViewTwoClick()
{
CameraMgr.Instance.GotoView(viewTwo, 10f);
}
public void TestWarn()
{
int index = Random.Range(0, warns.Count);
warns[index].status = Status.Warn;
}
public void FixeWarn()
{
for (int i = 0; i < warns.Count; i++)
{
warns[i].status = Status.Normal;
}
}
public void Update()
{
SwitchWarn();
if (warnning.Count > count)
{
CameraMgr.Instance.GotoView(CalculateBounding(warnning).center, 15f);
Debug.Log("once");
}
count = warnning.Count;
}
/// <summary>
/// 监视报警状态
/// </summary>
public void SwitchWarn()
{
for (int i = 0; i < warns.Count; i++)
{
if (warns[i].status == Status.Warn && !warnning.Contains(warns[i].gameObject))
warnning.Add(warns[i].gameObject);
else if (warns[i].status == Status.Normal && warnning.Contains(warns[i].gameObject))
warnning.Remove(warns[i].gameObject);
}
}
public Bounds CalculateBounding(List<GameObject> objs)
{
if (objs.Count > 0)
{
Bounds b = objs[0].GetComponent<Renderer>().bounds;
if (objs.Count > 1)
{
for (int i = 1; i < objs.Count; i++)
{
b.Encapsulate(objs[i].GetComponent<Renderer>().bounds);
}
return b;
}
else
{
return b;
}
}
return new Bounds();
}
private void OnDrawGizmos()
{
if (warnning.Count > 0)
{
var bounds = CalculateBounding(warnning);
Gizmos.color = Color.red;
Gizmos.DrawWireCube(center: bounds.center, size: bounds.size);
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d1adfbb027f8d39459702be3e8fb2b14
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,36 @@
using Adam;
using HUD;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//============================================================
//支持中文文件使用UTF-8编码
//@author YangHua
//@create 20230531
//@company Adam
//
//@description:
//============================================================
namespace Focus
{
public class ThreeDUIClick : MonoBehaviour
{
public HUDController hudController;
// Use this for initialization
private void Start()
{
for (int i = 0; i < hudController.modelInformations.Count; i++)
{
for (int j = 0; j < hudController.modelInformations[i].tations.Count; j++)
{
int modelIndex = i;
int tationIndex = j;
hudController.modelInformations[i].tations[j].transform.GetChild(0).GetComponent<StationInformation>().onClick.AddListener(() =>
{
CameraMgr.Instance.GotoView(hudController.modelInformations[modelIndex].tations[tationIndex].transform, 20f);
});
}
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fcd3914edcdca4049a13e3cea681062d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4e8b5aea9cd4868428e02fdddacd61b5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,62 @@
using HUD;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//============================================================
//支持中文文件使用UTF-8编码
//@author YangHua
//@create 20230426
//@company Adam
//
//@description:
//============================================================
namespace Adam
{
[Serializable]
public struct ModelInformation
{
public StationInformation stationInformation;
public List<GameObject> tations;
}
public class HUDController : MonoBehaviour
{
public List<ModelInformation> modelInformations = new List<ModelInformation>();
// Use this for initialization
private void Awake()
{
for (int i = 0; i < modelInformations.Count; i++)
{
for (int j = 0; j < modelInformations[i].tations.Count; j++)
{
StationInformation si = Instantiate(modelInformations[i].stationInformation);
GameObject go = modelInformations[i].tations[j];
si.SetTarget(Camera.main.transform);
si.Init(go.transform, GetBounds(go));
}
}
}
private Bounds GetBounds(GameObject obj)
{
Bounds bounds = new Bounds();
if (obj.transform.childCount != 0)
{
Renderer[] renderers = obj.GetComponentsInChildren<Renderer>();
for (int i = 0; i < renderers.Length; i++)
{
bounds.Encapsulate(renderers[i].bounds);
}
}
else
{
bounds = obj.GetComponent<Renderer>().bounds;
}
return bounds;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e2d77674999936547b8cbaec26ef8322
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,82 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
//============================================================
//支持中文文件使用UTF-8编码
//@author YangHua
//@create 20230426
//@company Adam
//
//@description:
//============================================================
namespace HUD
{
public enum WorldOrLocal
{
World,
Local
}
public class StationInformation : MonoBehaviour
{
//public float offsetY = 1f;
public WorldOrLocal worldOrLocal = WorldOrLocal.World;
public bool lockXZ = false;
public UnityEvent onClick;
private Transform lookAtTarget;
public void SetTarget(Transform target)
{
lookAtTarget = target;
}
public void Init(Transform parent, Bounds b)
{
transform.SetParent(parent);
transform.localPosition = Vector3.zero;
Vector3 pos = b.center;
Vector3 extentsPos = b.extents;
if (worldOrLocal == WorldOrLocal.Local)
{
//transform.localEulerAngles = Vector3.zero;
Vector3 localPos = transform.InverseTransformPoint(pos);
transform.localPosition = new Vector3(localPos.x, localPos.y + extentsPos.y, localPos.z);
}
else if (worldOrLocal == WorldOrLocal.World)
{
Vector3 localPos = transform.InverseTransformPoint(pos);
Vector3 worldPos = transform.TransformPoint(localPos);
transform.position = new Vector3(worldPos.x, worldPos.y + extentsPos.y + 1f, worldPos.z);
}
else
{
}
}
private void Update()
{
if (lookAtTarget != null)
{
Vector3 pos;
if (lockXZ)
{
pos = new Vector3(lookAtTarget.localPosition.x, 0, lookAtTarget.localPosition.z);
}
else
{
pos = lookAtTarget.localPosition;
}
transform.LookAt(pos);
}
}
private void OnMouseDown()
{
onClick?.Invoke();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 58e2fbd82adbcd14aac54bb85f5464ce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,91 @@
fileFormatVersion: 2
guid: 1705ebcb01175a54ba549314203ad4fc
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 10
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
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: -1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: 16
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
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
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant: