//====== override: GameObject protected override void UpdateImpl() { int currentScore = scoreStatus.Value; if (displayedScore == currentScore) { return; } if (toScore != currentScore) { fromScore = displayedScore; toScore = currentScore; delay = new GameTimeDelay(gameTime, TimeSpan.FromSeconds(TransitionDurationInSecs)); } if (delay == null) { return; // TODO: Range.Map utility could be nice } int maxScoreToAdd = toScore - fromScore; double scoreToAdd = maxScoreToAdd * (delay.PercentageDone / 100d); displayedScore = fromScore + MiscUtils.Clamp((int)scoreToAdd, 0, maxScoreToAdd); }
private void DrawThrustCone() { var startPt = this.transform.position; var endPt = startPt - GetThrustVector(); // The thrust vect is pointing "up", but visually it makes sense to show it downwards as a repeling force Gizmos.color = BaseColor; Gizmos.DrawLine(startPt, endPt); Handles.color = BaseColor; Handles.DrawWireDisc(endPt, this.transform.up, MiscUtils.Clamp(this.PeakThrustForce * 0.1f, 0.5f, 15f)); }
/// <summary> /// beginObject will already be called on the keyframe so it can be differentiated with /// a non animated value. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="composition"></param> /// <param name="reader"></param> /// <param name="scale"></param> /// <param name="valueParser"></param> /// <returns></returns> private static Keyframe <T> ParseKeyframe <T>(LottieComposition composition, JsonReader reader, float scale, IValueParser <T> valueParser) { Vector2? cp1 = null; Vector2? cp2 = null; float startFrame = 0; T startValue = default; var endValue = default(T); var hold = false; IInterpolator interpolator; // Only used by PathKeyframe Vector2?pathCp1 = null; Vector2?pathCp2 = null; reader.BeginObject(); while (reader.HasNext()) { switch (reader.NextName()) { case "t": startFrame = reader.NextDouble(); break; case "s": startValue = valueParser.Parse(reader, scale); break; case "e": endValue = valueParser.Parse(reader, scale); break; case "o": cp1 = JsonUtils.JsonToPoint(reader, scale); break; case "i": cp2 = JsonUtils.JsonToPoint(reader, scale); break; case "h": hold = reader.NextInt() == 1; break; case "to": pathCp1 = JsonUtils.JsonToPoint(reader, scale); break; case "ti": pathCp2 = JsonUtils.JsonToPoint(reader, scale); break; default: reader.SkipValue(); break; } } reader.EndObject(); if (hold) { endValue = startValue; // TODO: create a HoldInterpolator so progress changes don't invalidate. interpolator = LinearInterpolator; } else if (cp1 != null && cp2 != null) { cp1 = new Vector2(MiscUtils.Clamp(cp1.Value.X, -scale, scale), MiscUtils.Clamp(cp1.Value.Y, -MaxCpValue, MaxCpValue)); cp2 = new Vector2(MiscUtils.Clamp(cp2.Value.X, -scale, scale), MiscUtils.Clamp(cp2.Value.Y, -MaxCpValue, MaxCpValue)); var hash = Utils.Utils.HashFor(cp1.Value.X, cp1.Value.Y, cp2.Value.X, cp2.Value.Y); if (GetInterpolator(hash, out var interpolatorRef) == false || interpolatorRef.TryGetTarget(out interpolator) == false) { interpolator = new PathInterpolator(cp1.Value.X / scale, cp1.Value.Y / scale, cp2.Value.X / scale, cp2.Value.Y / scale); try { PutInterpolator(hash, new WeakReference <IInterpolator>(interpolator)); } catch { // It is not clear why but SparseArrayCompat sometimes fails with this: // https://github.com/airbnb/lottie-android/issues/452 // Because this is not a critical operation, we can safely just ignore it. // I was unable to repro this to attempt a proper fix. } } } else { interpolator = LinearInterpolator; } var keyframe = new Keyframe <T>(composition, startValue, endValue, interpolator, startFrame, null) { PathCp1 = pathCp1, PathCp2 = pathCp2 }; return(keyframe); }
internal static Keyframe <T> NewInstance(JsonObject json, LottieComposition composition, float scale, IAnimatableValueFactory <T> valueFactory) { Vector2? cp1 = null; Vector2? cp2 = null; float startFrame = 0; var startValue = default(T); var endValue = default(T); IInterpolator interpolator = null; if (json.ContainsKey("t")) { startFrame = (float)json.GetNamedNumber("t", 0); if (json.TryGetValue("s", out var startValueJson)) { startValue = valueFactory.ValueFromObject(startValueJson, scale); } if (json.TryGetValue("e", out var endValueJson)) { endValue = valueFactory.ValueFromObject(endValueJson, scale); } var cp1Json = json.GetNamedObject("o", null); var cp2Json = json.GetNamedObject("i", null); if (cp1Json != null && cp2Json != null) { cp1 = JsonUtils.PointFromJsonObject(cp1Json, scale); cp2 = JsonUtils.PointFromJsonObject(cp2Json, scale); } var hold = (int)json.GetNamedNumber("h", 0) == 1; if (hold) { endValue = startValue; // TODO: create a HoldInterpolator so progress changes don't invalidate. interpolator = LinearInterpolator; } else if (cp1 != null) { cp1 = new Vector2(MiscUtils.Clamp(cp1.Value.X, -scale, scale), MiscUtils.Clamp(cp1.Value.Y, -MaxCpValue, MaxCpValue)); cp2 = new Vector2(MiscUtils.Clamp(cp2.Value.X, -scale, scale), MiscUtils.Clamp(cp2.Value.Y, -MaxCpValue, MaxCpValue)); int hash = Utils.Utils.HashFor(cp1.Value.X, cp1.Value.Y, cp2.Value.X, cp2.Value.Y); if (PathInterpolatorCache.TryGetValue(hash, out var interpolatorRef) == false || interpolatorRef.TryGetTarget(out interpolator) == false) { interpolator = new PathInterpolator(cp1.Value.X / scale, cp1.Value.Y / scale, cp2.Value.X / scale, cp2.Value.Y / scale); PathInterpolatorCache[hash] = new WeakReference <IInterpolator>(interpolator); } } else { interpolator = LinearInterpolator; } } else { startValue = valueFactory.ValueFromObject(json, scale); endValue = startValue; } return(new Keyframe <T>(composition, startValue, endValue, interpolator, startFrame, null)); }