A game about forced loneliness, made by TACStudios
at master 439 lines 14 kB view raw
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using UnityEngine; 5using UnityEngine.Timeline; 6 7namespace UnityEditor.Timeline 8{ 9 enum CurveChangeType 10 { 11 None, 12 CurveModified, 13 CurveAddedOrRemoved 14 } 15 16 abstract class CurveDataSource 17 { 18 public static CurveDataSource Create(IRowGUI trackGUI) 19 { 20 if (trackGUI.asset is AnimationTrack) 21 return new InfiniteClipCurveDataSource(trackGUI); 22 23 return new TrackParametersCurveDataSource(trackGUI); 24 } 25 26 public static CurveDataSource Create(TimelineClipGUI clipGUI) 27 { 28 if (clipGUI.clip.animationClip != null) 29 return new ClipAnimationCurveDataSource(clipGUI); 30 31 return new ClipParametersCurveDataSource(clipGUI); 32 } 33 34 int? m_ID = null; 35 public int id 36 { 37 get 38 { 39 if (!m_ID.HasValue) 40 m_ID = CreateHashCode(); 41 42 return m_ID.Value; 43 } 44 } 45 46 readonly IRowGUI m_TrackGUI; 47 protected CurveDataSource(IRowGUI trackGUI) 48 { 49 m_TrackGUI = trackGUI; 50 } 51 52 public abstract AnimationClip animationClip { get; } 53 54 public abstract float start { get; } 55 public abstract float timeScale { get; } 56 public abstract string groupingName { get; } 57 58 // Applies changes from the visual curve in the curve wrapper back to the animation clips 59 public virtual void ApplyCurveChanges(IEnumerable<CurveWrapper> updatedCurves) 60 { 61 Undo.RegisterCompleteObjectUndo(animationClip, "Edit Clip Curve"); 62 foreach (CurveWrapper c in updatedCurves) 63 { 64 if (c.curve.length > 0) 65 AnimationUtility.SetEditorCurve(animationClip, c.binding, c.curve); 66 else 67 RemoveCurves(new[] { c.binding }); 68 c.changed = false; 69 } 70 } 71 72 /// <summary>The clip version is a value that will change when a curve gets updated. 73 /// it's used to detect when an animation clip has been changed externally </summary> 74 /// <returns>A versioning value indicating the state of the curve. If the curve is updated externally this value will change. </returns> 75 public virtual UInt64 GetClipVersion() 76 { 77 return animationClip.ClipVersion(); 78 } 79 80 /// <summary>Call this method to check if the underlying clip has changed</summary> 81 /// <param name="curveVersion">A versioning value. This will be updated to the latest version</param> 82 /// <returns>A value indicating how the clip has changed</returns> 83 public virtual CurveChangeType UpdateExternalChanges(ref UInt64 curveVersion) 84 { 85 return animationClip.GetChangeType(ref curveVersion); 86 } 87 88 public virtual string ModifyPropertyDisplayName(string path, string propertyName) => propertyName; 89 90 public virtual void RemoveCurves(IEnumerable<EditorCurveBinding> bindings) 91 { 92 Undo.RegisterCompleteObjectUndo(animationClip, "Remove Curve(s)"); 93 foreach (var binding in bindings) 94 { 95 if (binding.isPPtrCurve) 96 AnimationUtility.SetObjectReferenceCurve(animationClip, binding, null); 97 else 98 AnimationUtility.SetEditorCurve(animationClip, binding, null); 99 } 100 } 101 102 public Rect GetBackgroundRect(WindowState state) 103 { 104 var trackRect = m_TrackGUI.boundingRect; 105 return new Rect( 106 state.timeAreaTranslation.x + trackRect.xMin, 107 trackRect.y, 108 (float)state.editSequence.asset.duration * state.timeAreaScale.x, 109 trackRect.height 110 ); 111 } 112 113 public List<CurveWrapper> GenerateWrappers(IEnumerable<EditorCurveBinding> bindings) 114 { 115 var wrappers = new List<CurveWrapper>(bindings.Count()); 116 int curveWrapperId = 0; 117 118 foreach (EditorCurveBinding b in bindings) 119 { 120 // General configuration 121 var wrapper = new CurveWrapper 122 { 123 id = curveWrapperId++, 124 binding = b, 125 groupId = -1, 126 hidden = false, 127 readOnly = false, 128 getAxisUiScalarsCallback = () => new Vector2(1, 1) 129 }; 130 131 // Specific configuration 132 ConfigureCurveWrapper(wrapper); 133 134 wrappers.Add(wrapper); 135 } 136 137 return wrappers; 138 } 139 140 protected virtual void ConfigureCurveWrapper(CurveWrapper wrapper) 141 { 142 wrapper.color = CurveUtility.GetPropertyColor(wrapper.binding.propertyName); 143 wrapper.renderer = new NormalCurveRenderer(AnimationUtility.GetEditorCurve(animationClip, wrapper.binding)); 144 wrapper.renderer.SetCustomRange(0.0f, animationClip.length); 145 } 146 147 protected virtual int CreateHashCode() 148 { 149 return m_TrackGUI.asset.GetHashCode(); 150 } 151 } 152 153 class ClipAnimationCurveDataSource : CurveDataSource 154 { 155 static readonly string k_GroupingName = L10n.Tr("Animated Values"); 156 157 readonly TimelineClipGUI m_ClipGUI; 158 159 public ClipAnimationCurveDataSource(TimelineClipGUI clipGUI) : base(clipGUI.parent) 160 { 161 m_ClipGUI = clipGUI; 162 } 163 164 public override AnimationClip animationClip 165 { 166 get { return m_ClipGUI.clip.animationClip; } 167 } 168 169 public override float start 170 { 171 get { return (float)m_ClipGUI.clip.FromLocalTimeUnbound(0.0); } 172 } 173 174 public override float timeScale 175 { 176 get { return (float)m_ClipGUI.clip.timeScale; } 177 } 178 179 public override string groupingName 180 { 181 get { return k_GroupingName; } 182 } 183 184 protected override int CreateHashCode() 185 { 186 return base.CreateHashCode().CombineHash(m_ClipGUI.clip.GetHashCode()); 187 } 188 189 public override string ModifyPropertyDisplayName(string path, string propertyName) 190 { 191 if (!AnimatedPropertyUtility.IsMaterialProperty(propertyName)) 192 return propertyName; 193 194 var track = m_ClipGUI.clip.GetParentTrack(); 195 if (track == null) 196 return propertyName; 197 198 var gameObjectBinding = TimelineUtility.GetSceneGameObject(TimelineEditor.inspectedDirector, track); 199 if (gameObjectBinding == null) 200 return propertyName; 201 202 if (!string.IsNullOrEmpty(path)) 203 { 204 var transform = gameObjectBinding.transform.Find(path); 205 if (transform == null) 206 return propertyName; 207 gameObjectBinding = transform.gameObject; 208 } 209 210 return AnimatedPropertyUtility.RemapMaterialName(gameObjectBinding, propertyName); 211 } 212 } 213 214 class ClipParametersCurveDataSource : CurveDataSource 215 { 216 static readonly string k_GroupingName = L10n.Tr("Clip Properties"); 217 218 readonly TimelineClipGUI m_ClipGUI; 219 readonly CurvesProxy m_CurvesProxy; 220 221 private int m_ClipDirtyVersion; 222 223 public ClipParametersCurveDataSource(TimelineClipGUI clipGUI) : base(clipGUI.parent) 224 { 225 m_ClipGUI = clipGUI; 226 m_CurvesProxy = new CurvesProxy(clipGUI.clip); 227 } 228 229 public override AnimationClip animationClip 230 { 231 get { return m_CurvesProxy.curves; } 232 } 233 234 public override UInt64 GetClipVersion() 235 { 236 return sourceAnimationClip.ClipVersion(); 237 } 238 239 public override CurveChangeType UpdateExternalChanges(ref ulong curveVersion) 240 { 241 if (m_ClipGUI == null || m_ClipGUI.clip == null) 242 return CurveChangeType.None; 243 244 var changeType = sourceAnimationClip.GetChangeType(ref curveVersion); 245 if (changeType != CurveChangeType.None) 246 { 247 m_CurvesProxy.ApplyExternalChangesToProxy(); 248 } 249 else if (m_ClipDirtyVersion != m_ClipGUI.clip.DirtyIndex) 250 { 251 m_CurvesProxy.UpdateProxyCurves(); 252 if (changeType == CurveChangeType.None) 253 changeType = CurveChangeType.CurveModified; 254 } 255 m_ClipDirtyVersion = m_ClipGUI.clip.DirtyIndex; 256 return changeType; 257 } 258 259 public override float start 260 { 261 get { return (float)m_ClipGUI.clip.FromLocalTimeUnbound(0.0); } 262 } 263 264 public override float timeScale 265 { 266 get { return (float)m_ClipGUI.clip.timeScale; } 267 } 268 269 public override string groupingName 270 { 271 get { return k_GroupingName; } 272 } 273 274 public override void RemoveCurves(IEnumerable<EditorCurveBinding> bindings) 275 { 276 m_CurvesProxy.RemoveCurves(bindings); 277 } 278 279 public override void ApplyCurveChanges(IEnumerable<CurveWrapper> updatedCurves) 280 { 281 m_CurvesProxy.UpdateCurves(updatedCurves); 282 } 283 284 protected override void ConfigureCurveWrapper(CurveWrapper wrapper) 285 { 286 m_CurvesProxy.ConfigureCurveWrapper(wrapper); 287 } 288 289 protected override int CreateHashCode() 290 { 291 return base.CreateHashCode().CombineHash(m_ClipGUI.clip.GetHashCode()); 292 } 293 294 private AnimationClip sourceAnimationClip 295 { 296 get 297 { 298 if (m_ClipGUI == null || m_ClipGUI.clip == null || m_ClipGUI.clip.curves == null) 299 return null; 300 return m_ClipGUI.clip.curves; 301 } 302 } 303 } 304 305 class InfiniteClipCurveDataSource : CurveDataSource 306 { 307 static readonly string k_GroupingName = L10n.Tr("Animated Values"); 308 309 readonly AnimationTrack m_AnimationTrack; 310 311 public InfiniteClipCurveDataSource(IRowGUI trackGui) : base(trackGui) 312 { 313 m_AnimationTrack = trackGui.asset as AnimationTrack; 314 } 315 316 public override AnimationClip animationClip 317 { 318 get { return m_AnimationTrack.infiniteClip; } 319 } 320 321 public override float start 322 { 323 get { return 0.0f; } 324 } 325 326 public override float timeScale 327 { 328 get { return 1.0f; } 329 } 330 331 public override string groupingName 332 { 333 get { return k_GroupingName; } 334 } 335 336 public override string ModifyPropertyDisplayName(string path, string propertyName) 337 { 338 if (m_AnimationTrack == null || !AnimatedPropertyUtility.IsMaterialProperty(propertyName)) 339 return propertyName; 340 341 var binding = m_AnimationTrack.GetBinding(TimelineEditor.inspectedDirector); 342 if (binding == null) 343 return propertyName; 344 345 var target = binding.transform; 346 if (!string.IsNullOrEmpty(path)) 347 target = target.Find(path); 348 349 if (target == null) 350 return propertyName; 351 352 return AnimatedPropertyUtility.RemapMaterialName(target.gameObject, propertyName); 353 } 354 } 355 356 class TrackParametersCurveDataSource : CurveDataSource 357 { 358 static readonly string k_GroupingName = L10n.Tr("Track Properties"); 359 360 readonly CurvesProxy m_CurvesProxy; 361 private int m_TrackDirtyVersion; 362 363 public TrackParametersCurveDataSource(IRowGUI trackGui) : base(trackGui) 364 { 365 m_CurvesProxy = new CurvesProxy(trackGui.asset); 366 } 367 368 public override AnimationClip animationClip 369 { 370 get { return m_CurvesProxy.curves; } 371 } 372 373 public override UInt64 GetClipVersion() 374 { 375 return sourceAnimationClip.ClipVersion(); 376 } 377 378 public override CurveChangeType UpdateExternalChanges(ref ulong curveVersion) 379 { 380 if (m_CurvesProxy.targetTrack == null) 381 return CurveChangeType.None; 382 383 var changeType = sourceAnimationClip.GetChangeType(ref curveVersion); 384 if (changeType != CurveChangeType.None) 385 { 386 m_CurvesProxy.ApplyExternalChangesToProxy(); 387 } 388 // track property has changed externally, update the curve proxies 389 else if (m_TrackDirtyVersion != m_CurvesProxy.targetTrack.DirtyIndex) 390 { 391 if (changeType == CurveChangeType.None) 392 changeType = CurveChangeType.CurveModified; 393 m_CurvesProxy.UpdateProxyCurves(); 394 } 395 m_TrackDirtyVersion = m_CurvesProxy.targetTrack.DirtyIndex; 396 return changeType; 397 } 398 399 public override float start 400 { 401 get { return 0.0f; } 402 } 403 404 public override float timeScale 405 { 406 get { return 1.0f; } 407 } 408 409 public override string groupingName 410 { 411 get { return k_GroupingName; } 412 } 413 414 public override void RemoveCurves(IEnumerable<EditorCurveBinding> bindings) 415 { 416 m_CurvesProxy.RemoveCurves(bindings); 417 } 418 419 public override void ApplyCurveChanges(IEnumerable<CurveWrapper> updatedCurves) 420 { 421 m_CurvesProxy.UpdateCurves(updatedCurves); 422 } 423 424 protected override void ConfigureCurveWrapper(CurveWrapper wrapper) 425 { 426 m_CurvesProxy.ConfigureCurveWrapper(wrapper); 427 } 428 429 private AnimationClip sourceAnimationClip 430 { 431 get 432 { 433 if (m_CurvesProxy.targetTrack == null || m_CurvesProxy.targetTrack.curves == null) 434 return null; 435 return m_CurvesProxy.targetTrack.curves; 436 } 437 } 438 } 439}