Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
b2b86ad
Added BezierEasing to allow Custom Easing Function
Kulltero Oct 31, 2022
2f08c9d
Fixed Class name
Kulltero Oct 31, 2022
c369398
Added a MouseListener Component
Kulltero Oct 31, 2022
d2754b0
Add the Animation Component
Kulltero Oct 31, 2022
cd23e8d
Added Animation, RectMask & Mask Components
Kulltero Oct 31, 2022
5d2e043
Added HasForCondition
Kulltero Oct 31, 2022
e3820e1
Uploaded Animation Test (Feature Showcase) & AnimationExample (usecas…
Kulltero Oct 31, 2022
470b173
Merge branch 'Facepunch:master' into Animation
Kulltero Nov 11, 2022
a0ea130
Implement IMouseListener in Animation behaviour
Kulltero Nov 11, 2022
dd756d3
Abstract receivers into an interface
Kulltero Nov 11, 2022
978c186
Refactor Code to support multiple Animation Components
Kulltero Nov 21, 2022
88a245f
Adjusted RPC call behaviour
Kulltero Nov 21, 2022
2b2bac3
test recreation for the latest test
Kulltero Nov 23, 2022
6768b67
Renaming, Refactoring based on Jake's Feedback
Kulltero Nov 28, 2022
0abb224
changed condition to trigger
Kulltero Dec 1, 2022
c36996e
Refactoring Initialization Logic
Kulltero Dec 18, 2022
bbe0b90
Major Refactor & Generalization
Kulltero Dec 25, 2022
d2f5bbf
Change to Structs (thanks @WheteThunger)
Kulltero Dec 26, 2022
cf46eb6
move Examples to folder
Kulltero Jan 5, 2023
d49f7f2
Added DynamicVector Capacity
Kulltero Jan 10, 2023
7f803e4
Comments, Cleanup & Merging Enable/DisableGraphic
Kulltero Jan 12, 2023
bc7679a
Merge branch 'master' into Animation
Kulltero May 14, 2023
00aa987
Removed Interface
Kulltero May 16, 2023
370f963
Changed MouseListener to work without interface
Kulltero May 16, 2023
5d055df
Made a single Animation Component handle all animations on an object …
Kulltero May 16, 2023
4a64bc4
Removed Support for Multiple Animation Components,
Kulltero May 16, 2023
1209381
Remove old FadeOut Component
Kulltero May 16, 2023
c7c100f
remove old meta file
Kulltero May 16, 2023
f0daa49
Updated Example for recent commits
Kulltero May 16, 2023
9aceac4
Fixed Animations not stopping
Kulltero May 17, 2023
4da3a1d
Indent fix
Kulltero May 17, 2023
7c9a981
Added maskSoftness to RectMask2D JSON api
Kulltero May 17, 2023
1feddd6
Fixed for update
Kulltero May 17, 2023
95e8c78
Delete Old incompatible example
Kulltero May 17, 2023
e09a937
FadeOut not FadeIn
Kulltero May 17, 2023
4f8d779
easing default fix
Kulltero May 17, 2023
eff31d5
Fix CanvasGroup sometimes not getting created
Kulltero May 19, 2023
e199196
Fix Mask & RectMask2D cases
Kulltero Aug 13, 2023
93bd1d7
Client Test changes
Kulltero Aug 14, 2023
1fd91f3
Fix culture dependant float parsing
Kulltero Aug 22, 2023
e262652
Fix RawImage sprite
Kulltero Aug 22, 2023
341b9e0
Fix Invalid JSON
Kulltero Aug 22, 2023
af91ea0
continue instead of return
Kulltero Aug 22, 2023
f7606ae
Simplified Bezier Easing Implementation
Kulltero Aug 23, 2023
88657c8
Comment fixes
Kulltero Aug 23, 2023
6f7c165
add == operator overrides
Kulltero Aug 23, 2023
56e28c7
Refactor to use BezierPoints
Kulltero Aug 23, 2023
5d020b9
Update CommunityEntity.UI.Animation.cs
Kulltero Aug 25, 2023
f3d5fc9
Update ParseAnimation Class
Kulltero Aug 25, 2023
d61c8bd
Fix not supplying panel to OnDrag Trigger start
Kulltero Oct 4, 2023
817502d
add shouldRaycast to graphic
Kulltero Oct 11, 2023
0c655c8
Re-Introduce shouldRaycast tracking
Kulltero Oct 11, 2023
9ca0603
Merge branch 'master' into Animation
Kulltero Jul 7, 2024
377aab8
Move examples into Test folder
Kulltero Jul 7, 2024
f1964d9
Merge branch 'master' into Animation
Kulltero Aug 30, 2024
ca639b4
Merge branch 'master' into Animation
Kulltero Feb 7, 2025
3edde1e
Minor Cleanup
Kulltero Feb 7, 2025
e61d304
Comment out DragNDrop integrations
Kulltero Feb 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
964 changes: 964 additions & 0 deletions CommunityEntity.UI.Animation.cs

Large diffs are not rendered by default.

210 changes: 210 additions & 0 deletions CommunityEntity.UI.BezierEasing.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Facepunch.Extend;
using System.IO;

#if CLIENT

public partial class CommunityEntity
{

public class BezierEasing
{
// the same process browsers use for the cubic-bezier css timing function
// from the spec:
// "A cubic Bézier easing function is a type of easing function defined by four real numbers that specify the two control points, P1 and P2,
// of a cubic Bézier curve whose end points P0 and P3 are fixed at (0, 0) and (1, 1) respectively.
// The x coordinates of P1 and P2 are restricted to the range [0, 1]."
// NOTE: Loosely based on https://github.com/gre/bezier-easing

static Dictionary<BezierPoints, BezierEasing> cache = new Dictionary<BezierPoints, BezierEasing>();

// these values modify the accuracy & performance of the curve's evaluation
// while these are the values used in the javascript library you may find better values that produce good enough results with better performance
static int NewtonItterations = 4;

public float firstX = 0f;
public float firstY = 0f;
public float secondX = 1f;
public float secondY = 1f;
float[] _precomputedSections;

static int _precomputeSize = 11;
static float _precomputeStepSize = 1.0f / (_precomputeSize - 1.0f);
bool _precomputed = false;


// its beneficial to call this when we want to reset our session, like when leaving/switching servers
public static void Clear()
{
cache.Clear();
}

// Helper function that caches BezierEasing Instances. supplying 4 points & time between 0 & 1 generates the curve & caches it, returning the value for time
public static float Ease(float X1, float Y1, float X2, float Y2, float time)
{
var key = new BezierPoints(X1, Y1, X2, Y2);
return Ease(key, time);
}


public static float Ease(BezierPoints points, float time)
{
if (!cache.TryGetValue(points, out BezierEasing easing))
cache[points] = easing = new BezierEasing(points);

return easing.GetPosition(time);
}

public BezierEasing(BezierPoints points) : this(points.P1, points.P2, points.P3, points.P4)
{

}

public BezierEasing(float X1, float Y1, float X2, float Y2)
{
firstX = X1;
firstY = Y1;
secondX = X2;
secondY = Y2;
_precomputedSections = new float[_precomputeSize];
}



// returns the value on the curve for the unscaled time
public float GetPosition(float unscaledTime)
{
if (!_precomputed) PreCompute();
if (firstX == firstY && secondX == secondY) return unscaledTime; // linear
if (unscaledTime == 0f) return 0f;
if (unscaledTime == 1f) return 1f;
return CalcBezier(ScaleTime(unscaledTime), firstY, secondY);
}

// the following 2 functions are part of a single math formula split up into 2 steps for clarity
float StepA(float aA1, float aA2) { return 1.0f - 3.0f * aA2 + 3.0f * aA1; }
float StepB(float aA1, float aA2) { return 3.0f * aA2 - 6.0f * aA1; }

float CalcBezier(float time, float point1, float point2)
{
return ((StepA(point1, point2) * time + StepB(point1, point2)) * time + (3f * point1)) * time;
}

// Returns the estimated slope of the curve at the supplied time
float GetSlope(float time)
{
return 3.0f * StepA(firstX, secondX) * time * time + 2.0f * StepB(firstX, secondX) * time + (3f * firstX);
}

// pre-calculates a set amount of points to spped up calculation
void CalcSampleValues()
{
for (var i = 0; i < _precomputeSize; ++i)
{
_precomputedSections[i] = CalcBezier(i * _precomputeStepSize, firstX, secondX);
}
}

// finds the surrounding pre-calculated sections around our unscaled time and refines it using NewtonRaphson's method
float ScaleTime(float unscaledTime)
{
float intervalStart = 0.0f;
int currentSample = 1;
int lastSample = _precomputeSize - 1;

// find the last precomputed section before unscaledTime
for (; currentSample != lastSample && _precomputedSections[currentSample] <= unscaledTime; ++currentSample)
{
intervalStart += _precomputeStepSize;
}
--currentSample;

// divide distance from last section by distance between last and next section
float distance = (unscaledTime - _precomputedSections[currentSample]) / (_precomputedSections[currentSample + 1] - _precomputedSections[currentSample]);
float timeGuess = intervalStart + distance * _precomputeStepSize;
float initialSlope = GetSlope(timeGuess);
if (initialSlope == 0.0f)
{
return timeGuess;
}
else
{
return NewtonRaphsonIterate(unscaledTime, timeGuess);
}
}

void PreCompute()
{
_precomputed = true;
if (firstX != firstY || secondX != secondY)
CalcSampleValues();
}

// approximates the value for X using the Newton-Raphson Method
float NewtonRaphsonIterate(float aX, float timeGuess)
{
for (var i = 0; i < NewtonItterations; ++i)
{
float currentSlope = GetSlope(timeGuess);
if (currentSlope == 0.0f) return timeGuess;
var currentX = CalcBezier(timeGuess, firstX, secondX) - aX;
timeGuess -= currentX / currentSlope;
}
return timeGuess;
}

// used as a key for the cache
public struct BezierPoints : IEquatable<BezierPoints>
{
public static readonly BezierPoints LINEAR = new BezierPoints(0f, 0f, 0f, 0f);
public static readonly BezierPoints EASE_IN = new BezierPoints(0.42f, 0f, 1f, 1f);
public static readonly BezierPoints EASE_OUT = new BezierPoints(0f, 0f, 0.58f, 1f);
public static readonly BezierPoints EASE_IN_OUT = new BezierPoints(0.42f, 0f, 0.58f, 1f);

public float P1;
public float P2;
public float P3;
public float P4;

public BezierPoints(float X1, float Y1, float X2, float Y2)
{
P1 = X1;
P2 = Y1;
P3 = X2;
P4 = Y2;
}

public bool Equals(BezierPoints other)
{
return P1 == other.P1 && P2 == other.P2 && P2 == other.P2 && P3 == other.P3 && P4 == other.P4;
}

public override bool Equals(object obj)
{
return obj is BezierPoints points && Equals(points);
}

public override int GetHashCode()
{
return HashCode.Combine(P1, P2, P3, P4);
}

public static bool operator == (BezierPoints p1, BezierPoints p2)
{
return p1.Equals(p2);
}

public static bool operator != (BezierPoints p1, BezierPoints p2)
{
return !p1.Equals(p2);
}
}
}

}

#endif
27 changes: 0 additions & 27 deletions CommunityEntity.UI.FadeOut.cs

This file was deleted.

12 changes: 0 additions & 12 deletions CommunityEntity.UI.FadeOut.cs.meta

This file was deleted.

50 changes: 50 additions & 0 deletions CommunityEntity.UI.MouseListener.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Object = UnityEngine.Object;
using UnityEngine;
using UnityEngine.EventSystems;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Facepunch.Extend;
using System.IO;

#if CLIENT


public partial class CommunityEntity
{

public class MouseListener : UIBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler {

public string name;
public Action<string> onEnter;
public Action<string> onExit;
public Action<string> onClick;

void Awake(){
name = gameObject.name;
}

public virtual void OnPointerClick(PointerEventData eventData)
{
if(onClick != null) onClick(name);
// Manually Bubble it up
ExecuteEvents.ExecuteHierarchy(transform.parent.gameObject, eventData, ExecuteEvents.pointerClickHandler);
}

public virtual void OnPointerEnter(PointerEventData eventData)
{
if(onEnter != null) onEnter(name);
// Manually Bubble it up
ExecuteEvents.ExecuteHierarchy(transform.parent.gameObject, eventData, ExecuteEvents.pointerEnterHandler);
}

public virtual void OnPointerExit(PointerEventData eventData)
{
if(onExit != null) onExit(name);
// Manually Bubble it up
ExecuteEvents.ExecuteHierarchy(transform.parent.gameObject, eventData, ExecuteEvents.pointerExitHandler);
}
}
}
#endif
Loading