/// <summary> /// If this Tweener contains a <see cref="PlugVector3Path"/> tween, /// defines a portion of that path to use and re-adapt to, /// and rewinds/restarts the tween in its partial form (depending if it was paused or not). /// </summary> /// <param name="p_waypointId0"> /// Id of the new starting waypoint on the current path. /// If you want to be sure you're targeting the first point in the path, pass -1 /// (this is because the first waypoint of the path might be different from the first waypoint you passed, /// in case the target Transform was not already on the starting position, and thus needed to reach it). /// </param> /// <param name="p_waypointId1"> /// Id of the new ending waypoint on the current path /// (-1 in case you want to target the ending waypoint of a closed path) /// </param> /// <param name="p_newDuration"> /// Tween duration of the partial path (if -1 auto-calculates the correct partial based on the original duration) /// </param> /// <param name="p_newEaseType">New EaseType to apply</param> public Tweener UsePartialPath(int p_waypointId0, int p_waypointId1, float p_newDuration, EaseType p_newEaseType) { if (plugins.Count > 1) { TweenWarning.Log("Applying a partial path on a Tweener (" + _target + ") with more than one plugin/property being tweened is not allowed"); return(this); } if (pv3Path == null) { // Get eventual plugVector3Path plugin pv3Path = GetPlugVector3PathPlugin(); if (pv3Path == null) { TweenWarning.Log("Tweener for " + _target + " contains no PlugVector3Path plugin"); return(this); } } // Startup the tween (if not already started) to store the path data. Startup(); // Store original duration and easeType (if not already stored). if (!isPartialled) { isPartialled = true; _originalDuration = _duration; _originalEaseType = _easeType; } // Convert waypoints ids to path ids int pathWaypointId0 = ConvertWaypointIdToPathId(pv3Path, p_waypointId0, true); int pathWaypointId1 = ConvertWaypointIdToPathId(pv3Path, p_waypointId1, false); // Get waypoints length percentage (needed for auto-duration and calculation of lookAhed) float partialPerc = pv3Path.GetWaypointsLengthPercentage(pathWaypointId0, pathWaypointId1); float partialStartPerc = pathWaypointId0 == 0 ? 0 : pv3Path.GetWaypointsLengthPercentage(0, pathWaypointId0); // Assign new duration and ease _duration = p_newDuration >= 0 ? p_newDuration : _originalDuration * partialPerc; _easeType = p_newEaseType; // Convert path to partial pv3Path.SwitchToPartialPath(_duration, p_newEaseType, partialStartPerc, partialPerc); // Re-Startup and restart Startup(true); if (!_isPaused) { Restart(true); } else { Rewind(true, true); } return(this); // Returns this so it can be directly used with WaitForCompletion coroutines }
/// <summary> /// Init override. /// Used to check that isRelative is FALSE, /// and otherwise use the given parameters to send a decent warning message. /// </summary> internal override void Init(Tweener p_tweenObj, string p_propertyName, EaseType p_easeType, Type p_targetType, PropertyInfo p_propertyInfo, FieldInfo p_fieldInfo) { if (isRelative && p_tweenObj.isFrom) { isRelative = false; TweenWarning.Log("\"" + p_tweenObj.target + "." + p_propertyName + "\": PlugVector3Path \"isRelative\" parameter is incompatible with HOTween.From. The tween will be treated as absolute."); } usesLocalPosition = p_propertyName == "localPosition"; base.Init(p_tweenObj, p_propertyName, p_easeType, p_targetType, p_propertyInfo, p_fieldInfo); }
/// <summary> /// Starts up the plugin, getting the actual start and change values. /// Called by Tweener right before starting the effective animations. /// </summary> /// <param name="p_onlyCalcSpeedBasedDur"> /// Set to <c>true</c> by <see cref="ForceSetSpeedBasedDuration"/>, /// to calculate only the speed based duration and then reset any startup changes /// (so Startup can be called from scratch when truly starting up). /// </param> internal void Startup(bool p_onlyCalcSpeedBasedDur) { if (wasStarted) { TweenWarning.Log("Startup() for plugin " + this + " (target: " + tweenObj.target + ") has already been called. Startup() won't execute twice."); return; // Startup can't be executed twice otherwise some typedEndVal (like for PlugColor) will be set incorrectly } object orStartVal = null, orEndVal = null; if (p_onlyCalcSpeedBasedDur) { if (tweenObj.speedBased && !speedBasedDurationWasSet) { // Get original values so they can be reset. orStartVal = _startVal; orEndVal = _endVal; } } else { wasStarted = true; } // Manage TO or FROM. if (tweenObj.isFrom) { // Order is fundamental (otherwise setters for isRelative get messed up). object prevEndVal = _endVal; endVal = GetValue(); startVal = prevEndVal; } else { endVal = _endVal; startVal = GetValue(); } // Set changeVal. SetChangeVal(); if (tweenObj.speedBased && !speedBasedDurationWasSet) { // Get duration based on speed. // Can't be done earlier because it needs changeVal to be set. _duration = GetSpeedBasedDuration(_duration); speedBasedDurationWasSet = true; // Reset. if (p_onlyCalcSpeedBasedDur) { _startVal = orStartVal; _endVal = orEndVal; } } }
/// <summary> /// Completely resets the Tweener except its target, /// and applies a new <see cref="TweenType"/>, duration, and <see cref="TweenParms"/>. /// </summary> /// <param name="p_tweenType">New tween type (to/from)</param> /// <param name="p_newDuration">New duration</param> /// <param name="p_newParms">New parameters</param> public void ResetAndChangeParms(TweenType p_tweenType, float p_newDuration, TweenParms p_newParms) { if (_destroyed) { TweenWarning.Log("ResetAndChangeParms can't run because the tween was destroyed - set AutoKill or autoKillOnComplete to FALSE if you want to avoid destroying a tween after completion"); return; } Reset(); _duration = p_newDuration; if (p_tweenType == TweenType.From) { p_newParms = p_newParms.IsFrom(); } p_newParms.InitializeObject(this, _target); if (plugins != null && plugins.Count > 0) { // Valid plugins were added: mark this as not empty anymore. _isEmpty = false; } SetFullDuration(); }
// *********************************************************************************** // INIT // *********************************************************************************** /// <summary> /// Initializes the given <see cref="Tweener"/> with the stored parameters. /// </summary> /// <param name="p_tweenObj"> /// The <see cref="Tweener"/> to initialize. /// </param> /// <param name="p_target"> /// The <see cref="Tweener"/> target. /// </param> internal void InitializeObject(Tweener p_tweenObj, object p_target) { InitializeOwner(p_tweenObj); if (speedBased && !easeSet) { easeType = EaseType.Linear; } p_tweenObj._pixelPerfect = pixelPerfect; p_tweenObj._speedBased = speedBased; p_tweenObj._easeType = easeType; p_tweenObj._easeAnimationCurve = easeAnimCurve; p_tweenObj._easeOvershootOrAmplitude = easeOvershootOrAmplitude; p_tweenObj._easePeriod = easePeriod; p_tweenObj._delay = p_tweenObj.delayCount = delay; p_tweenObj.isFrom = isFrom; p_tweenObj.onPluginOverwritten = onPluginOverwritten; p_tweenObj.onPluginOverwrittenWParms = onPluginOverwrittenWParms; p_tweenObj.onPluginOverwrittenParms = onPluginOverwrittenParms; // Parse properties and create/set plugins. p_tweenObj.plugins = new List <ABSTweenPlugin>(); Type targetType = p_target.GetType(); FieldInfo fieldInfo = null; int propDatasCount = propDatas.Count; for (int i = 0; i < propDatasCount; ++i) { HOTPropData data = propDatas[i]; // Store propInfo and fieldInfo to see if they exist, and then pass them to plugin init. PropertyInfo propInfo = targetType.GetProperty(data.propName); if (propInfo == null) { fieldInfo = targetType.GetField(data.propName); if (fieldInfo == null) { TweenWarning.Log("\"" + p_target + "." + data.propName + "\" is missing, static, or not public. The tween for this property will not be created."); continue; } } // Store correct plugin. ABSTweenPlugin plug; ABSTweenPlugin absTweenPlugin = data.endValOrPlugin as ABSTweenPlugin; if (absTweenPlugin != null) { // Use existing plugin. plug = absTweenPlugin; if (plug.ValidateTarget(p_target)) { if (plug.initialized) { // This plugin was already initialized with another Tweener. Clone it. plug = plug.CloneBasic(); // OPTIMIZE Uses Activator, which is slow. } } else { // Invalid target. TweenWarning.Log(Utils.SimpleClassName(plug.GetType()) + " : Invalid target (" + p_target + "). The tween for this property will not be created."); continue; } } else { // Parse value to find correct plugin to use. plug = null; // string propType = (propInfo != null ? propInfo.PropertyType.ToString() : fieldInfo.FieldType.ToString()); // string shortPropType = propType.Substring(propType.IndexOf(".") + 1); string shortPropType = propInfo != null ? _TypeToShortString.ContainsKey(propInfo.PropertyType) ? _TypeToShortString[propInfo.PropertyType] : "" : _TypeToShortString.ContainsKey(fieldInfo.FieldType) ? _TypeToShortString[fieldInfo.FieldType] : ""; switch (shortPropType) { case "Vector2": if (!ValidateValue(data.endValOrPlugin, PlugVector2.validValueTypes)) { break; } plug = new PlugVector2((Vector2)data.endValOrPlugin, data.isRelative); break; case "Vector3": if (!ValidateValue(data.endValOrPlugin, PlugVector3.validValueTypes)) { break; } plug = new PlugVector3((Vector3)data.endValOrPlugin, data.isRelative); break; case "Vector4": if (!ValidateValue(data.endValOrPlugin, PlugVector4.validValueTypes)) { break; } plug = new PlugVector4((Vector4)data.endValOrPlugin, data.isRelative); break; case "Quaternion": if (!ValidateValue(data.endValOrPlugin, PlugQuaternion.validValueTypes)) { break; } if (data.endValOrPlugin is Vector3) { plug = new PlugQuaternion((Vector3)data.endValOrPlugin, data.isRelative); } else { plug = new PlugQuaternion((Quaternion)data.endValOrPlugin, data.isRelative); } break; case "Color": if (!ValidateValue(data.endValOrPlugin, PlugColor.validValueTypes)) { break; } plug = new PlugColor((Color)data.endValOrPlugin, data.isRelative); break; case "Color32": if (!ValidateValue(data.endValOrPlugin, PlugColor32.validValueTypes)) { break; } plug = new PlugColor32((Color32)data.endValOrPlugin, data.isRelative); break; case "Rect": if (!ValidateValue(data.endValOrPlugin, PlugRect.validValueTypes)) { break; } plug = new PlugRect((Rect)data.endValOrPlugin, data.isRelative); break; case "String": if (!ValidateValue(data.endValOrPlugin, PlugString.validValueTypes)) { break; } plug = new PlugString(data.endValOrPlugin.ToString(), data.isRelative); break; case "Int32": if (!ValidateValue(data.endValOrPlugin, PlugInt.validValueTypes)) { break; } plug = new PlugInt((int)data.endValOrPlugin, data.isRelative); break; case "UInt32": if (!ValidateValue(data.endValOrPlugin, PlugUInt.validValueTypes)) { break; } plug = new PlugUInt(Convert.ToUInt32(data.endValOrPlugin), data.isRelative); break; default: if (data.endValOrPlugin.GetType() != typeof(Boolean)) { try { plug = new PlugFloat(Convert.ToSingle(data.endValOrPlugin), data.isRelative); } catch (Exception) { TweenWarning.Log("No valid plugin for animating \"" + p_target + "." + data.propName + "\" (of type " + (propInfo != null ? propInfo.PropertyType : fieldInfo.FieldType) + "). The tween for this property will not be created."); continue; } } break; } if (plug == null) { TweenWarning.Log("The end value set for \"" + p_target + "." + data.propName + "\" tween is invalid. The tween for this property will not be created."); continue; } } plug.Init(p_tweenObj, data.propName, easeType, targetType, propInfo, fieldInfo); p_tweenObj.plugins.Add(plug); } }