Skip to content

Commit c4e8495

Browse files
committed
Merge branch 'main' into feature/convert-array
2 parents 8391e5c + b016a57 commit c4e8495

File tree

13 files changed

+168
-82
lines changed

13 files changed

+168
-82
lines changed

Editor/Tools/Characters/Animation/ClipReplacer/Editor/AnimationClipReplacementEditor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ private void DrawClipReplacementsList()
110110
}
111111
}
112112

113-
if (GUILayout.Button("Remove Clips"))
113+
if (GUILayout.Button("Restore Original Clips"))
114114
{
115115
var replacer = (AnimatorClipReplacer)target;
116116

Runtime/Code/Luau/LuauCoreCallbacks.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,10 +1601,13 @@ private static int InvokeMethodAsync(LuauContext context, IntPtr thread, Type ty
16011601
Method = method,
16021602
Context = context,
16031603
};
1604-
1604+
16051605
if (task.IsCompleted) {
1606-
ResumeAsyncTask(awaitingTask, true);
16071606
shouldYield = false;
1607+
if (task.IsFaulted) {
1608+
return LuauError(thread, $"Error: Exception thrown in {type.Name} {method.Name}: {task.Exception.Message}");
1609+
}
1610+
ResumeAsyncTask(awaitingTask, true);
16081611
return 0;
16091612
}
16101613

Runtime/Code/Luau/ReflectionList.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using UnityEngine.Animations.Rigging;
1010
using UnityEngine.EventSystems;
1111
using UnityEngine.Experimental.GlobalIllumination;
12+
using UnityEngine.Experimental.Rendering;
1213
using UnityEngine.Rendering;
1314
using UnityEngine.Rendering.Universal;
1415
using UnityEngine.SceneManagement;
@@ -49,6 +50,8 @@ public static class ReflectionList {
4950
[typeof(Scene)] = LuauContextAll,
5051
[typeof(SceneManager)] = LuauContext.Protected,
5152
[typeof(UnityEngine.Profiling.Profiler)] = LuauContextAll,
53+
[typeof(ShaderWarmup)] = LuauContextAll,
54+
[typeof(ShaderVariantCollection)] = LuauContextAll,
5255

5356
// Navmesh
5457
[typeof(NavMesh)] = LuauContextAll,

Runtime/Code/Player/Character/Animation/AnimationEventListener.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Collections.Generic;
22
using UnityEngine;
33

4+
[LuauAPI]
45
public class AnimationEventListener : MonoBehaviour {
56

67
[Tooltip("If identical events come in within this threshold only 1 will fire. In seconds.")]

Runtime/Code/Player/Character/Animation/CharacterAnimationHelper.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,20 +61,20 @@ private void Awake() {
6161
slideVfx.Stop();
6262
}
6363

64-
// Make a new instance of the animator override controller
65-
if (!this.animatorOverride) {
66-
if (this.animator.runtimeAnimatorController is AnimatorOverrideController over) {
67-
// Copy all the overrides if we already have an override controller in use
68-
var overrides = new List<KeyValuePair<AnimationClip, AnimationClip>>(over.overridesCount);
69-
over.GetOverrides(overrides);
70-
this.animatorOverride = new AnimatorOverrideController(animator.runtimeAnimatorController);
71-
this.animator.runtimeAnimatorController = this.animatorOverride;
72-
this.animatorOverride.ApplyOverrides(overrides);
73-
} else {
74-
this.animatorOverride = new AnimatorOverrideController(animator.runtimeAnimatorController);
75-
this.animator.runtimeAnimatorController = this.animatorOverride;
76-
}
77-
}
64+
// // Make a new instance of the animator override controller
65+
// if (!this.animatorOverride) {
66+
// if (this.animator.runtimeAnimatorController is AnimatorOverrideController over) {
67+
// // Copy all the overrides if we already have an override controller in use
68+
// var overrides = new List<KeyValuePair<AnimationClip, AnimationClip>>(over.overridesCount);
69+
// over.GetOverrides(overrides);
70+
// this.animatorOverride = new AnimatorOverrideController(animator.runtimeAnimatorController);
71+
// this.animator.runtimeAnimatorController = this.animatorOverride;
72+
// this.animatorOverride.ApplyOverrides(overrides);
73+
// } else {
74+
// this.animatorOverride = new AnimatorOverrideController(animator.runtimeAnimatorController);
75+
// this.animator.runtimeAnimatorController = this.animatorOverride;
76+
// }
77+
// }
7878
}
7979

8080
private void Start() {

Runtime/Code/Player/Character/Animation/ClipReplacer/AnimatorClipReplacer.cs

Lines changed: 63 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public Object AnimatorController
3232
/// </summary>
3333
public List<BaseClipPreset> baseClipSelectionPresets = new List<BaseClipPreset>();
3434

35+
private List<KeyValuePair<AnimationClip, AnimationClip>> originalOverrides;
36+
3537
private void Awake()
3638
{
3739
var components = GetComponents<AnimatorClipReplacer>();
@@ -102,6 +104,8 @@ private void ReplaceClipsInternal(AnimatorOverrideController overrideController)
102104
return;
103105
}
104106

107+
SaveOriginalOverrides(overrideController);
108+
105109
// Checks for duplicates in the clipReplacements list
106110
var duplicateClips = clipReplacements
107111
.GroupBy(clip => clip.baseClipName)
@@ -177,7 +181,6 @@ private void ReplaceClipsInternal(AnimatorOverrideController overrideController)
177181
/// <param name="controller">The AnimatorOverrideController to apply the replacements to.</param>
178182
public void RemoveClips(Object controller)
179183
{
180-
181184
AnimatorOverrideController overrideController = null;
182185

183186
if (controller == null)
@@ -186,12 +189,6 @@ public void RemoveClips(Object controller)
186189
return;
187190
}
188191

189-
if (clipReplacements.Count == 0)
190-
{
191-
Debug.LogError("No clips has been removed as the overrider list is empty");
192-
return;
193-
}
194-
195192
if (controller is Animator animator)
196193
{
197194
overrideController = animator.runtimeAnimatorController as AnimatorOverrideController;
@@ -210,33 +207,65 @@ public void RemoveClips(Object controller)
210207
return;
211208
}
212209

213-
// Creates the animation map without duplicates
214-
var animationMap = clipReplacements.ToDictionary(
215-
clip => clip.baseClipName,
216-
clip => clip.replacementClip
217-
);
210+
if (overrideController == null)
211+
{
212+
Debug.LogError("No valid AnimatorOverrideController found.");
213+
return;
214+
}
218215

219-
var overrides = new List<KeyValuePair<AnimationClip, AnimationClip>>(overrideController.overridesCount);
220-
overrideController.GetOverrides(overrides);
216+
if (originalOverrides == null || originalOverrides.Count == 0)
217+
{
218+
Debug.LogWarning("No original overrides found to restore.");
219+
return;
220+
}
221221

222-
// Overwriting null clips in the overrider list
223-
for (int i = 0; i < overrides.Count; i++)
222+
if (clipReplacements == null || clipReplacements.Count == 0)
224223
{
225-
var originalClip = overrides[i].Key;
226-
if (animationMap.TryGetValue(originalClip.name, out var newClip))
224+
Debug.LogWarning("No clip replacements configured to restore.");
225+
return;
226+
}
227+
228+
// Get the current overrides from the AnimatorOverrideController
229+
var currentOverrides = new List<KeyValuePair<AnimationClip, AnimationClip>>(overrideController.overridesCount);
230+
overrideController.GetOverrides(currentOverrides);
231+
232+
// Create a new list to store the restored overrides
233+
var restoredOverrides = new List<KeyValuePair<AnimationClip, AnimationClip>>(currentOverrides);
234+
235+
// Restore only the clips configured in clipReplacements
236+
foreach (var replacement in clipReplacements)
237+
{
238+
var baseClipName = replacement.baseClipName;
239+
var originalOverride = originalOverrides.FirstOrDefault(o => o.Key.name == baseClipName);
240+
241+
if (originalOverride.Key != null)
227242
{
228-
overrides[i] = new KeyValuePair<AnimationClip, AnimationClip>(originalClip, null);
243+
// Replace the current clip with the original
244+
for (int i = 0; i < restoredOverrides.Count; i++)
245+
{
246+
if (restoredOverrides[i].Key.name == baseClipName)
247+
{
248+
restoredOverrides[i] = originalOverride;
249+
break;
250+
}
251+
}
252+
}
253+
else
254+
{
255+
Debug.LogWarning($"Original clip for {baseClipName} not found in saved overrides.");
229256
}
230257
}
231258

232-
// Apply the updated overrides
233-
overrideController.ApplyOverrides(overrides);
259+
// Apply the restored overrides to the AnimatorOverrideController
260+
overrideController.ApplyOverrides(restoredOverrides);
234261

235262
if (!Application.isPlaying)
236263
{
237-
Debug.Log("Clips Overrides have been removed");
264+
Debug.Log("Specified clips have been restored.");
238265
}
239266
}
267+
268+
240269
/// <summary>
241270
/// Attempts to extract an AnimatorOverrideController from the given object.
242271
/// </summary>
@@ -250,6 +279,7 @@ private bool TryGetOverrideController(Object controller, out AnimatorOverrideCon
250279

251280
if (Application.isPlaying)
252281
{
282+
SaveOriginalOverrides(overrideController);
253283
AnimatorOverrideController instanaceAnimator = new(animator.runtimeAnimatorController);
254284
var overrides = new List<KeyValuePair<AnimationClip, AnimationClip>>(overrideController.overridesCount);
255285
overrideController.GetOverrides(overrides);
@@ -269,6 +299,7 @@ private bool TryGetOverrideController(Object controller, out AnimatorOverrideCon
269299

270300
if (Application.isPlaying)
271301
{
302+
SaveOriginalOverrides(overrideController);
272303
AnimatorOverrideController instanaceAnimator = new(animatorComponent.runtimeAnimatorController);
273304
var overrides = new List<KeyValuePair<AnimationClip, AnimationClip>>(overrideController.overridesCount);
274305
overrideController.GetOverrides(overrides);
@@ -318,6 +349,16 @@ public RuntimeAnimatorController RuntimeAnimator
318349
return null;
319350
}
320351
}
352+
353+
private void SaveOriginalOverrides(AnimatorOverrideController overrideController)
354+
{
355+
if (originalOverrides == null)
356+
{
357+
originalOverrides = new List<KeyValuePair<AnimationClip, AnimationClip>>(overrideController.overridesCount);
358+
overrideController.GetOverrides(originalOverrides);
359+
}
360+
}
361+
321362
}
322363

323364
/// <summary>

Runtime/Code/Player/Character/MovementSystem/CharacterAnimationSyncData.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ public class CharacterAnimationSyncData {
77
public bool sprinting = false;
88
public bool crouching = false;
99
public Vector3 localVelocity = Vector3.zero;
10-
public Vector3 lookVector = Vector3.zero;
11-
12-
//Just for observers in predicted mode
13-
public Vector3 position = Vector3.zero;
10+
public Vector3 lookVector = Vector3.zero;
1411

1512

1613
// override object.Equals
@@ -32,7 +29,6 @@ public override int GetHashCode() {
3229
hashCode = (hashCode * 397) ^ crouching.GetHashCode();
3330
hashCode = (hashCode * 397) ^ lookVector.GetHashCode();
3431
hashCode = (hashCode * 397) ^ localVelocity.GetHashCode();
35-
hashCode = (hashCode * 397) ^ position.GetHashCode();
3632
return hashCode;
3733
}
3834
}

Runtime/Code/Player/Character/MovementSystem/CharacterMovement.cs

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ public class CharacterMovement : NetworkBehaviour {
2828
[Header("Visual Variables")]
2929
public bool autoCalibrateSkiddingSpeed = true;
3030
public float observerRotationLerpMod = 1;
31-
[Tooltip("Only used for Server Authoritative observers")]
32-
public float observerLerpDuration = .1f;
3331
[Tooltip("If true animations will be played on the server. This should be true if you care about character movement animations server-side (like for hit boxes).")]
3432
public bool playAnimationOnServer = true;
3533
#endregion
@@ -126,10 +124,6 @@ public bool disableInput {
126124
//Prediction
127125
private bool queueReplay = false;
128126

129-
//Prediction Observers
130-
private Vector3 prevObserverPosition;
131-
private Vector3 nextObserverPosition;
132-
private float lastObserverTime;
133127
#endregion
134128

135129
#region SYNC DATA
@@ -231,24 +225,30 @@ public void ForceToNewMoveState(CharacterMovementState newState){
231225
SetMoveInputData(newState.currentMoveInput);
232226

233227
this.currentMoveState = new CharacterMovementState(newState);
234-
235-
// apply the state to the Rigidbody instantly
236-
rigidbody.position = newState.position;
237228

238-
// Set the velocity
239-
if (!rigidbody.isKinematic) {
240-
rigidbody.velocity = newState.velocity;
241-
}
229+
if(IsObserver()){
230+
//Update visuals to match new state
231+
animationHelper.SetState(new CharacterAnimationSyncData() {
232+
state = newState.state,
233+
grounded = newState.timeSinceBecameGrounded > 0,
234+
sprinting = newState.currentMoveInput.sprint,
235+
crouching = newState.currentMoveInput.crouch,
236+
localVelocity = graphicTransform.InverseTransformDirection(newState.velocity),
237+
lookVector = newState.currentMoveInput.lookVector,
238+
});
239+
} else{
240+
// apply the state to the Rigidbody instantly
241+
rigidbody.position = newState.position;
242+
243+
// Set the velocity
244+
if (!rigidbody.isKinematic) {
245+
rigidbody.velocity = newState.velocity;
246+
}
247+
}
242248
}
243249
#endregion
244250

245251
#region UPDATE
246-
private void Update(){
247-
if(IsObserver() && isServerAuth){
248-
var delta = Mathf.Clamp01((Time.time - lastObserverTime) / this.observerLerpDuration);
249-
this.rigidbody.position = Vector3.Lerp(prevObserverPosition, nextObserverPosition, delta);
250-
}
251-
}
252252

253253
//Every frame update the calculated look vector and the visual state of the movement
254254
private void LateUpdate(){
@@ -864,7 +864,6 @@ private void Move(MoveInputData md) {
864864
crouching = isCrouching,
865865
localVelocity = currentLocalVelocity,
866866
lookVector = lookVector,
867-
position = transform.position,
868867
});
869868

870869
if (didJump){
@@ -1161,11 +1160,13 @@ private void CommandSetFlying(bool flyModeEnabled) {
11611160
}
11621161

11631162
private void TrySetState(CharacterAnimationSyncData newStateData) {
1163+
11641164
bool isNewState = newStateData.state != this.stateSyncData.state;
1165-
bool isNewData = !newStateData.Equals(this.stateSyncData) || (isServerAuth && stateSyncData.position != newStateData.position);
1165+
bool isNewData = !newStateData.Equals(this.stateSyncData);
11661166

11671167
// If new value in the state
1168-
if (isNewData) {
1168+
if (isNewData && !isServerAuth) {
1169+
//NOTE: Server Auth syncs animation data along with the predicted inputs so we don't need to also send data through RPCs
11691170
this.stateSyncData = newStateData;
11701171
if(hasMovementAuth){
11711172
if(isClientOnly){
@@ -1187,6 +1188,7 @@ private void TrySetState(CharacterAnimationSyncData newStateData) {
11871188
stateChanged?.Invoke((int)newStateData.state);
11881189
}
11891190

1191+
//Update our local visuals
11901192
animationHelper.SetState(newStateData);
11911193
}
11921194

@@ -1218,14 +1220,6 @@ private void ApplyNonLocalStateData(CharacterAnimationSyncData data) {
12181220
stateChanged?.Invoke((int)data.state);
12191221
}
12201222

1221-
//In server auth we don't sync position with the NetworkTransform so I am doing it here
1222-
if(this.IsObserver() && isServerAuth){
1223-
//Store prev and next positions so we can lerp between the two to account for network lag
1224-
lastObserverTime = Time.time;
1225-
prevObserverPosition = nextObserverPosition;
1226-
nextObserverPosition = data.position;
1227-
}
1228-
12291223
animationHelper.SetState(data);
12301224
}
12311225

Runtime/Code/Player/Character/MovementSystem/ClientPrediction/AirshipPredictedController.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -552,15 +552,15 @@ public override void OnDeserialize(NetworkReader reader, bool initialState) {
552552
// we don't know why yet, so keep this as an option for now.
553553
// possibly because client captures at the beginning of the frame,
554554
// with physics happening at the end of the frame?
555-
serverTick += serverSerializationOffset;
555+
tick += serverSerializationOffset;
556556

557557
//Let the child class deserialize its data
558-
T newState = DeserializeState(reader, serverTick);
558+
T newState = DeserializeState(reader, tick);
559559

560560
//print("Deserialize time: " + timestamp + " readerTime: " + serverDeltaTime);
561561
// process received state
562562
try{
563-
OnReceivedState(serverTick, newState, forceReplay);
563+
OnReceivedState(tick, newState, forceReplay);
564564
}catch(Exception e){
565565
Debug.LogError("Error on recieved state: " + e.Message + " trace: " + e.StackTrace);
566566
}

0 commit comments

Comments
 (0)