mirror of
https://github.com/Project-Redacted/Highscores-Server.git
synced 2025-05-21 02:44:53 +00:00
Add example Unity Project
This commit is contained in:
parent
fda7ff28dd
commit
e3acdb9d6b
7122 changed files with 505543 additions and 2 deletions
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
using UnityEngine.Playables;
|
||||
|
||||
namespace UnityEngine.Timeline
|
||||
{
|
||||
/// <summary>
|
||||
/// Runtime clip customized for 'infinite' tracks playables.
|
||||
/// Used for clips whose time needs to match the timelines exactly
|
||||
/// </summary>
|
||||
class InfiniteRuntimeClip : RuntimeElement
|
||||
{
|
||||
private Playable m_Playable;
|
||||
private static readonly Int64 kIntervalEnd = DiscreteTime.GetNearestTick(TimelineClip.kMaxTimeValue);
|
||||
|
||||
public InfiniteRuntimeClip(Playable playable)
|
||||
{
|
||||
m_Playable = playable;
|
||||
}
|
||||
|
||||
public override Int64 intervalStart
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
|
||||
public override Int64 intervalEnd
|
||||
{
|
||||
get { return kIntervalEnd; }
|
||||
}
|
||||
|
||||
public override bool enable
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
m_Playable.Play();
|
||||
else
|
||||
m_Playable.Pause();
|
||||
}
|
||||
}
|
||||
|
||||
public override void EvaluateAt(double localTime, FrameData frameData)
|
||||
{
|
||||
m_Playable.SetTime(localTime);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9b5abcb38bac0c54794ad732a3fa0de3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,271 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEngine.Timeline
|
||||
{
|
||||
interface IInterval
|
||||
{
|
||||
Int64 intervalStart { get; }
|
||||
Int64 intervalEnd { get; }
|
||||
}
|
||||
|
||||
struct IntervalTreeNode // interval node,
|
||||
{
|
||||
public Int64 center; // midpoint for this node
|
||||
public int first; // index of first element of this node in m_Entries
|
||||
public int last; // index of the last element of this node in m_Entries
|
||||
public int left; // index in m_Nodes of the left subnode
|
||||
public int right; // index in m_Nodes of the right subnode
|
||||
}
|
||||
|
||||
class IntervalTree<T> where T : IInterval
|
||||
{
|
||||
internal struct Entry
|
||||
{
|
||||
public Int64 intervalStart;
|
||||
public Int64 intervalEnd;
|
||||
public T item;
|
||||
}
|
||||
|
||||
const int kMinNodeSize = 10; // the minimum number of entries to have subnodes
|
||||
const int kInvalidNode = -1;
|
||||
const Int64 kCenterUnknown = Int64.MaxValue; // center hasn't been calculated. indicates no children
|
||||
|
||||
readonly List<Entry> m_Entries = new List<Entry>();
|
||||
readonly List<IntervalTreeNode> m_Nodes = new List<IntervalTreeNode>();
|
||||
|
||||
/// <summary>
|
||||
/// Whether the tree will be rebuilt on the next query
|
||||
/// </summary>
|
||||
public bool dirty { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Add an IInterval to the tree
|
||||
/// </summary>
|
||||
public void Add(T item)
|
||||
{
|
||||
if (item == null)
|
||||
return;
|
||||
|
||||
m_Entries.Add(
|
||||
new Entry()
|
||||
{
|
||||
intervalStart = item.intervalStart,
|
||||
intervalEnd = item.intervalEnd,
|
||||
item = item
|
||||
}
|
||||
);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Query the tree at a particular time
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="results"></param>
|
||||
public void IntersectsWith(Int64 value, List<T> results)
|
||||
{
|
||||
if (m_Entries.Count == 0)
|
||||
return;
|
||||
|
||||
if (dirty)
|
||||
{
|
||||
Rebuild();
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
if (m_Nodes.Count > 0)
|
||||
Query(m_Nodes[0], value, results);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Query the tree at a particular range of time
|
||||
/// </summary>
|
||||
/// <param name="start"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <param name="results"></param>
|
||||
public void IntersectsWithRange(Int64 start, Int64 end, List<T> results)
|
||||
{
|
||||
if (start > end)
|
||||
return;
|
||||
|
||||
if (m_Entries.Count == 0)
|
||||
return;
|
||||
|
||||
if (dirty)
|
||||
{
|
||||
Rebuild();
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
if (m_Nodes.Count > 0)
|
||||
QueryRange(m_Nodes[0], start, end, results);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the intervals from their source. Use this to detect if the data in the tree
|
||||
/// has changed.
|
||||
/// </summary>
|
||||
public void UpdateIntervals()
|
||||
{
|
||||
bool isDirty = false;
|
||||
for (int i = 0; i < m_Entries.Count; i++)
|
||||
{
|
||||
var n = m_Entries[i];
|
||||
var s = n.item.intervalStart;
|
||||
var e = n.item.intervalEnd;
|
||||
|
||||
isDirty |= n.intervalStart != s;
|
||||
isDirty |= n.intervalEnd != e;
|
||||
|
||||
m_Entries[i] = new Entry()
|
||||
{
|
||||
intervalStart = s,
|
||||
intervalEnd = e,
|
||||
item = n.item
|
||||
};
|
||||
}
|
||||
|
||||
dirty |= isDirty;
|
||||
}
|
||||
|
||||
private void Query(IntervalTreeNode intervalTreeNode, Int64 value, List<T> results)
|
||||
{
|
||||
for (int i = intervalTreeNode.first; i <= intervalTreeNode.last; i++)
|
||||
{
|
||||
var entry = m_Entries[i];
|
||||
if (value >= entry.intervalStart && value < entry.intervalEnd)
|
||||
{
|
||||
results.Add(entry.item);
|
||||
}
|
||||
}
|
||||
|
||||
if (intervalTreeNode.center == kCenterUnknown)
|
||||
return;
|
||||
if (intervalTreeNode.left != kInvalidNode && value < intervalTreeNode.center)
|
||||
Query(m_Nodes[intervalTreeNode.left], value, results);
|
||||
if (intervalTreeNode.right != kInvalidNode && value > intervalTreeNode.center)
|
||||
Query(m_Nodes[intervalTreeNode.right], value, results);
|
||||
}
|
||||
|
||||
private void QueryRange(IntervalTreeNode intervalTreeNode, Int64 start, Int64 end, List<T> results)
|
||||
{
|
||||
for (int i = intervalTreeNode.first; i <= intervalTreeNode.last; i++)
|
||||
{
|
||||
var entry = m_Entries[i];
|
||||
if (end >= entry.intervalStart && start < entry.intervalEnd)
|
||||
{
|
||||
results.Add(entry.item);
|
||||
}
|
||||
}
|
||||
|
||||
if (intervalTreeNode.center == kCenterUnknown)
|
||||
return;
|
||||
if (intervalTreeNode.left != kInvalidNode && start < intervalTreeNode.center)
|
||||
QueryRange(m_Nodes[intervalTreeNode.left], start, end, results);
|
||||
if (intervalTreeNode.right != kInvalidNode && end > intervalTreeNode.center)
|
||||
QueryRange(m_Nodes[intervalTreeNode.right], start, end, results);
|
||||
}
|
||||
|
||||
private void Rebuild()
|
||||
{
|
||||
m_Nodes.Clear();
|
||||
m_Nodes.Capacity = m_Entries.Capacity;
|
||||
Rebuild(0, m_Entries.Count - 1);
|
||||
}
|
||||
|
||||
private int Rebuild(int start, int end)
|
||||
{
|
||||
IntervalTreeNode intervalTreeNode = new IntervalTreeNode();
|
||||
|
||||
// minimum size, don't subdivide
|
||||
int count = end - start + 1;
|
||||
if (count < kMinNodeSize)
|
||||
{
|
||||
intervalTreeNode = new IntervalTreeNode() {center = kCenterUnknown, first = start, last = end, left = kInvalidNode, right = kInvalidNode};
|
||||
m_Nodes.Add(intervalTreeNode);
|
||||
return m_Nodes.Count - 1;
|
||||
}
|
||||
|
||||
var min = Int64.MaxValue;
|
||||
var max = Int64.MinValue;
|
||||
|
||||
for (int i = start; i <= end; i++)
|
||||
{
|
||||
var o = m_Entries[i];
|
||||
min = Math.Min(min, o.intervalStart);
|
||||
max = Math.Max(max, o.intervalEnd);
|
||||
}
|
||||
|
||||
var center = (max + min) / 2;
|
||||
intervalTreeNode.center = center;
|
||||
|
||||
// first pass, put every thing left of center, left
|
||||
int x = start;
|
||||
int y = end;
|
||||
while (true)
|
||||
{
|
||||
while (x <= end && m_Entries[x].intervalEnd < center)
|
||||
x++;
|
||||
|
||||
while (y >= start && m_Entries[y].intervalEnd >= center)
|
||||
y--;
|
||||
|
||||
if (x > y)
|
||||
break;
|
||||
|
||||
var nodeX = m_Entries[x];
|
||||
var nodeY = m_Entries[y];
|
||||
|
||||
m_Entries[y] = nodeX;
|
||||
m_Entries[x] = nodeY;
|
||||
}
|
||||
|
||||
intervalTreeNode.first = x;
|
||||
|
||||
// second pass, put every start passed the center right
|
||||
y = end;
|
||||
while (true)
|
||||
{
|
||||
while (x <= end && m_Entries[x].intervalStart <= center)
|
||||
x++;
|
||||
|
||||
while (y >= start && m_Entries[y].intervalStart > center)
|
||||
y--;
|
||||
|
||||
if (x > y)
|
||||
break;
|
||||
|
||||
var nodeX = m_Entries[x];
|
||||
var nodeY = m_Entries[y];
|
||||
|
||||
m_Entries[y] = nodeX;
|
||||
m_Entries[x] = nodeY;
|
||||
}
|
||||
|
||||
intervalTreeNode.last = y;
|
||||
|
||||
// reserve a place
|
||||
m_Nodes.Add(new IntervalTreeNode());
|
||||
int index = m_Nodes.Count - 1;
|
||||
|
||||
intervalTreeNode.left = kInvalidNode;
|
||||
intervalTreeNode.right = kInvalidNode;
|
||||
|
||||
if (start < intervalTreeNode.first)
|
||||
intervalTreeNode.left = Rebuild(start, intervalTreeNode.first - 1);
|
||||
|
||||
if (end > intervalTreeNode.last)
|
||||
intervalTreeNode.right = Rebuild(intervalTreeNode.last + 1, end);
|
||||
|
||||
m_Nodes[index] = intervalTreeNode;
|
||||
return index;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
m_Entries.Clear();
|
||||
m_Nodes.Clear();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8f74c99a65464bb4b86ccb314ee95a7f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,110 @@
|
|||
using UnityEngine;
|
||||
using UnityEngine.Playables;
|
||||
|
||||
namespace UnityEngine.Timeline
|
||||
{
|
||||
// The RuntimeClip wraps a single clip in an instantiated sequence.
|
||||
// It supports the IInterval interface so that it can be stored in the interval tree
|
||||
// It is this class that is returned by an interval tree query.
|
||||
class RuntimeClip : RuntimeClipBase
|
||||
{
|
||||
TimelineClip m_Clip;
|
||||
Playable m_Playable;
|
||||
Playable m_ParentMixer;
|
||||
|
||||
public override double start
|
||||
{
|
||||
get { return m_Clip.extrapolatedStart; }
|
||||
}
|
||||
|
||||
public override double duration
|
||||
{
|
||||
get { return m_Clip.extrapolatedDuration; }
|
||||
}
|
||||
|
||||
public RuntimeClip(TimelineClip clip, Playable clipPlayable, Playable parentMixer)
|
||||
{
|
||||
Create(clip, clipPlayable, parentMixer);
|
||||
}
|
||||
|
||||
void Create(TimelineClip clip, Playable clipPlayable, Playable parentMixer)
|
||||
{
|
||||
m_Clip = clip;
|
||||
m_Playable = clipPlayable;
|
||||
m_ParentMixer = parentMixer;
|
||||
clipPlayable.Pause();
|
||||
}
|
||||
|
||||
public TimelineClip clip
|
||||
{
|
||||
get { return m_Clip; }
|
||||
}
|
||||
|
||||
public Playable mixer
|
||||
{
|
||||
get { return m_ParentMixer; }
|
||||
}
|
||||
|
||||
public Playable playable
|
||||
{
|
||||
get { return m_Playable; }
|
||||
}
|
||||
|
||||
public override bool enable
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value && m_Playable.GetPlayState() != PlayState.Playing)
|
||||
{
|
||||
m_Playable.Play();
|
||||
SetTime(m_Clip.clipIn);
|
||||
}
|
||||
else if (!value && m_Playable.GetPlayState() != PlayState.Paused)
|
||||
{
|
||||
m_Playable.Pause();
|
||||
if (m_ParentMixer.IsValid())
|
||||
m_ParentMixer.SetInputWeight(m_Playable, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetTime(double time)
|
||||
{
|
||||
m_Playable.SetTime(time);
|
||||
}
|
||||
|
||||
public void SetDuration(double duration)
|
||||
{
|
||||
m_Playable.SetDuration(duration);
|
||||
}
|
||||
|
||||
public override void EvaluateAt(double localTime, FrameData frameData)
|
||||
{
|
||||
enable = true;
|
||||
|
||||
float weight = 1.0f;
|
||||
if (clip.IsPreExtrapolatedTime(localTime))
|
||||
weight = clip.EvaluateMixIn((float)clip.start);
|
||||
else if (clip.IsPostExtrapolatedTime(localTime))
|
||||
weight = clip.EvaluateMixOut((float)clip.end);
|
||||
else
|
||||
weight = clip.EvaluateMixIn(localTime) * clip.EvaluateMixOut(localTime);
|
||||
|
||||
if (mixer.IsValid())
|
||||
mixer.SetInputWeight(playable, weight);
|
||||
|
||||
// localTime of the sequence to localtime of the clip
|
||||
double clipTime = clip.ToLocalTime(localTime);
|
||||
if (clipTime >= -DiscreteTime.tickValue/2 )
|
||||
{
|
||||
SetTime(clipTime);
|
||||
}
|
||||
SetDuration(clip.extrapolatedDuration);
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
SetTime(m_Clip.clipIn);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 70a190a1b304d1e43995af35d09231d6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEngine.Timeline
|
||||
{
|
||||
internal abstract class RuntimeClipBase : RuntimeElement
|
||||
{
|
||||
public abstract double start { get; }
|
||||
public abstract double duration { get; }
|
||||
|
||||
public override Int64 intervalStart
|
||||
{
|
||||
get { return DiscreteTime.GetNearestTick(start); }
|
||||
}
|
||||
|
||||
public override Int64 intervalEnd
|
||||
{
|
||||
get { return DiscreteTime.GetNearestTick(start + duration); }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 70f955bbb437a494888ef54d97abb474
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using UnityEngine.Playables;
|
||||
|
||||
namespace UnityEngine.Timeline
|
||||
{
|
||||
abstract class RuntimeElement : IInterval
|
||||
{
|
||||
public abstract Int64 intervalStart { get; }
|
||||
public abstract Int64 intervalEnd { get; }
|
||||
public int intervalBit { get; set; }
|
||||
|
||||
public abstract bool enable { set; }
|
||||
public abstract void EvaluateAt(double localTime, FrameData frameData);
|
||||
|
||||
public virtual void Reset() {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 76b6bf32a6fcf934aab8c529bddccc81
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Audio;
|
||||
using UnityEngine.Playables;
|
||||
|
||||
namespace UnityEngine.Timeline
|
||||
{
|
||||
// Special runtime clip implementation that handles playables that use a scheduling system
|
||||
// such as Audio
|
||||
internal class ScheduleRuntimeClip : RuntimeClipBase
|
||||
{
|
||||
private TimelineClip m_Clip;
|
||||
private Playable m_Playable;
|
||||
private Playable m_ParentMixer;
|
||||
private double m_StartDelay;
|
||||
private double m_FinishTail;
|
||||
private bool m_Started = false;
|
||||
|
||||
// represents the start point when we want to start getting updated
|
||||
public override double start
|
||||
{
|
||||
get { return Math.Max(0, m_Clip.start - m_StartDelay); }
|
||||
}
|
||||
|
||||
public override double duration
|
||||
{
|
||||
get { return m_Clip.duration + m_FinishTail + m_Clip.start - start; }
|
||||
}
|
||||
|
||||
public void SetTime(double time)
|
||||
{
|
||||
m_Playable.SetTime(time);
|
||||
}
|
||||
|
||||
public TimelineClip clip { get { return m_Clip; } }
|
||||
public Playable mixer { get { return m_ParentMixer; } }
|
||||
public Playable playable { get { return m_Playable; } }
|
||||
|
||||
public ScheduleRuntimeClip(TimelineClip clip, Playable clipPlayable,
|
||||
Playable parentMixer, double startDelay = 0.2, double finishTail = 0.1)
|
||||
{
|
||||
Create(clip, clipPlayable, parentMixer, startDelay, finishTail);
|
||||
}
|
||||
|
||||
private void Create(TimelineClip clip, Playable clipPlayable, Playable parentMixer,
|
||||
double startDelay, double finishTail)
|
||||
{
|
||||
m_Clip = clip;
|
||||
m_Playable = clipPlayable;
|
||||
m_ParentMixer = parentMixer;
|
||||
m_StartDelay = startDelay;
|
||||
m_FinishTail = finishTail;
|
||||
clipPlayable.Pause();
|
||||
}
|
||||
|
||||
public override bool enable
|
||||
{
|
||||
set
|
||||
{
|
||||
if (value && m_Playable.GetPlayState() != PlayState.Playing)
|
||||
{
|
||||
m_Playable.Play();
|
||||
}
|
||||
else if (!value && m_Playable.GetPlayState() != PlayState.Paused)
|
||||
{
|
||||
m_Playable.Pause();
|
||||
if (m_ParentMixer.IsValid())
|
||||
m_ParentMixer.SetInputWeight(m_Playable, 0.0f);
|
||||
}
|
||||
|
||||
m_Started &= value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void EvaluateAt(double localTime, FrameData frameData)
|
||||
{
|
||||
if (frameData.timeHeld)
|
||||
{
|
||||
enable = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool forceSeek = frameData.seekOccurred || frameData.timeLooped || frameData.evaluationType == FrameData.EvaluationType.Evaluate;
|
||||
|
||||
// If we are in the tail region of the clip, then dont do anything
|
||||
if (localTime > start + duration - m_FinishTail)
|
||||
return;
|
||||
|
||||
// this may set the weight to 1 in a delay, but it will avoid missing the start
|
||||
float weight = clip.EvaluateMixIn(localTime) * clip.EvaluateMixOut(localTime);
|
||||
if (mixer.IsValid())
|
||||
mixer.SetInputWeight(playable, weight);
|
||||
|
||||
// localTime of the sequence to localtime of the clip
|
||||
if (!m_Started || forceSeek)
|
||||
{
|
||||
// accounts for clip in and speed
|
||||
double clipTime = clip.ToLocalTime(Math.Max(localTime, clip.start));
|
||||
// multiply by the time scale so the delay is local to the clip
|
||||
// Audio will rescale based on it's effective time scale (which includes the parent)
|
||||
double startDelay = Math.Max(clip.start - localTime, 0) * clip.timeScale;
|
||||
double durationLocal = m_Clip.duration * clip.timeScale;
|
||||
if (m_Playable.IsPlayableOfType<AudioClipPlayable>())
|
||||
((AudioClipPlayable)m_Playable).Seek(clipTime, startDelay, durationLocal);
|
||||
|
||||
m_Started = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b250be9db55288b48ac121c074d795e6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue