Skip to content

Commit

Permalink
translate pickup animation into dotween
Browse files Browse the repository at this point in the history
  • Loading branch information
stilnat committed Oct 22, 2024
1 parent 98e167a commit 103f850
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 70 deletions.
2 changes: 1 addition & 1 deletion Assets/Scripts/SS3D/Systems/Animations/HitAnimation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ private void HitAnimate(Vector3 hitTargetPosition)

Vector3 fromHandToHit = hitTargetPosition - _hands.SelectedHand.HandBone.position;

float duration = 0.7f * Mathf.Min(fromHandToHit.magnitude, 0.7f);
float duration = 3f * Mathf.Min(fromHandToHit.magnitude, 0.7f);

Vector3 directionFromTransformToTarget = hitTargetPosition - transform.position;
directionFromTransformToTarget.y = 0f;
Expand Down
113 changes: 44 additions & 69 deletions Assets/Scripts/SS3D/Systems/Animations/PickUpAnimation.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using DG.Tweening;
using FishNet.Object;
using SS3D.Systems.Entities.Humanoid;
using SS3D.Systems.Inventory.Containers;
Expand Down Expand Up @@ -32,7 +33,7 @@ public class PickUpAnimation : NetworkBehaviour
[SerializeField]
private Transform _lookAtTargetLocker;

private Coroutine _pickupCoroutine;
private Sequence _pickUpSequence;

public bool IsPicking { get; private set; }

Expand All @@ -52,21 +53,19 @@ public void CancelPickup(Hand hand)
private void ObserverCancelPickUp(Hand hand)
{
Debug.Log("cancel pick up animation");
StopCoroutine(_pickupCoroutine);

_pickUpSequence?.Kill();

Sequence sequence = DOTween.Sequence();

// Those times are to keep the speed of movements pretty much the same as when it was reaching
float timeToCancelHold = (1 - hand.HoldIkConstraint.weight) * _itemReachDuration;
float timeToCancelLookAt = (1 - _lookAtConstraint.weight) * _itemReachDuration;
float timeToCancelPickup = (1 - hand.PickupIkConstraint.weight) * _itemReachDuration;

// Change hold constraint weight of the main hand from 0 to 1
StartCoroutine(CoroutineHelper.ModifyValueOverTime(x => hand.HoldIkConstraint.weight = x, hand.HoldIkConstraint.weight, 0f, timeToCancelHold));

// Start looking at item
StartCoroutine(CoroutineHelper.ModifyValueOverTime(x => _lookAtConstraint.weight = x, _lookAtConstraint.weight, 0f, timeToCancelLookAt));

StartCoroutine(CoroutineHelper.ModifyValueOverTime(x => hand.PickupIkConstraint.weight = x, hand.PickupIkConstraint.weight, 0f, timeToCancelPickup));

sequence.Append(DOTween.To(() => hand.HoldIkConstraint.weight, x => hand.HoldIkConstraint.weight = x, 0f, timeToCancelHold));
sequence.Join(DOTween.To(() => _lookAtConstraint.weight, x => _lookAtConstraint.weight = x, 0f, timeToCancelLookAt));
sequence.Join(DOTween.To(() => hand.PickupIkConstraint.weight, x => hand.PickupIkConstraint.weight = x, 0f, timeToCancelPickup));
GetComponent<HumanoidAnimatorController>().Crouch(false);
}

Expand All @@ -75,33 +74,21 @@ private void ObserverPickUp(Item item, float timeToMoveBackItem, float timeToRe
{
_itemMoveDuration = timeToMoveBackItem;
_itemReachDuration = timeToReachItem;
_pickupCoroutine = StartCoroutine(PickupAnimate(item, delay));
PickupAnimate(item, delay);
}


[Client]
private IEnumerator PickupAnimate(Item item, float delay)
private void PickupAnimate(Item item, float delay)
{
if (delay > 0f)
{
yield return new WaitForSeconds(delay);
}
_hands.TryGetOppositeHand(_hands.SelectedHand, out Hand secondaryHand);

IsPicking = true;

if (!_hands.TryGetOppositeHand(_hands.SelectedHand, out Hand secondaryHand))
{
yield break;
}

bool withTwoHands = secondaryHand.Empty && item.Holdable.CanHoldTwoHand;
bool withTwoHands = secondaryHand != null && secondaryHand.Empty && item.Holdable.CanHoldTwoHand;

SetUpPickup(_hands.SelectedHand, secondaryHand, withTwoHands, item);

yield return PickupReach(item, _hands.SelectedHand, secondaryHand, withTwoHands);
PickupReach(item, _hands.SelectedHand, secondaryHand, withTwoHands, delay);

yield return PickupPullBack(item, _hands.SelectedHand, secondaryHand, withTwoHands);
IsPicking = false;
}

[Client]
Expand Down Expand Up @@ -142,7 +129,7 @@ private void SetUpPickup(Hand mainHand, Hand secondaryHand, bool withTwoHands, I
}

[Client]
private IEnumerator PickupReach(Item item, Hand mainHand, Hand secondaryHand, bool withTwoHands)
private void PickupReach(Item item, Hand mainHand, Hand secondaryHand, bool withTwoHands, float delay)
{
// Rotate player toward item
if (GetComponent<PositionController>().Position != PositionType.Sitting)
Expand All @@ -156,64 +143,52 @@ private IEnumerator PickupReach(Item item, Hand mainHand, Hand secondaryHand, bo
GetComponent<HumanoidAnimatorController>().Crouch(true);
}

// Change hold constraint weight of the main hand from 0 to 1
StartCoroutine(CoroutineHelper.ModifyValueOverTime(x => mainHand.HoldIkConstraint.weight = x, 0f, 1f, _itemReachDuration));
_pickUpSequence = DOTween.Sequence();

// Start looking at item
StartCoroutine(CoroutineHelper.ModifyValueOverTime(x => _lookAtConstraint.weight = x, 0f, 1f, _itemReachDuration));
_pickUpSequence.Append(DOTween.To(() => _lookAtConstraint.weight, x => _lookAtConstraint.weight = x, 1f, _itemReachDuration));

// At the same time change hold and pickup constraint weight of the main hand from 0 to 1
_pickUpSequence.Join(DOTween.To(() => mainHand.HoldIkConstraint.weight, x => mainHand.HoldIkConstraint.weight = x, 1f, _itemReachDuration));

// When reached for the item, parent it to the item position target locker
_pickUpSequence.Join(DOTween.To(() => mainHand.PickupIkConstraint.weight, x => mainHand.PickupIkConstraint.weight = x, 1f, _itemReachDuration).OnComplete(() => item.transform.parent = mainHand.ItemPositionTargetLocker));

// Reproduce changes on second hand if picking up with two hands
if (withTwoHands)
{
StartCoroutine(CoroutineHelper.ModifyValueOverTime(x => secondaryHand.HoldIkConstraint.weight = x, 0f, 1f, _itemReachDuration));
StartCoroutine(CoroutineHelper.ModifyValueOverTime(x => secondaryHand.PickupIkConstraint.weight = x, 0f, 1f, _itemReachDuration));
_pickUpSequence.Join(DOTween.To(() => secondaryHand.HoldIkConstraint.weight, x => secondaryHand.HoldIkConstraint.weight = x, 1f, _itemReachDuration));
_pickUpSequence.Join(DOTween.To(() => secondaryHand.PickupIkConstraint.weight, x =>secondaryHand.PickupIkConstraint.weight = x, 1f, _itemReachDuration));
}

// Change pickup constraint weight of the main hand from 0 to 1
yield return CoroutineHelper.ModifyValueOverTime(
x => mainHand.PickupIkConstraint.weight = x, 0f, 1f, _itemReachDuration);
}
// Once reached, start moving and rotating item toward its constrained position.
_pickUpSequence.Append(item.transform.DOLocalMove(Vector3.zero, _itemMoveDuration));
_pickUpSequence.Join(item.transform.DOLocalRotate(Quaternion.identity.eulerAngles, _itemMoveDuration));

[Client]
private IEnumerator PickupPullBack(Item item, Hand mainHand, Hand secondaryHand, bool withTwoHands)
{
GetComponent<HumanoidAnimatorController>().Crouch(false);

// Move item toward its constrained position.
StartCoroutine(TransformHelper.LerpTransform(item.transform, _hands.SelectedHand.ItemPositionTargetLocker, _itemMoveDuration));

// if an item held with two hands in the unselected hand, change it with a single hand hold
if (secondaryHand.Full && secondaryHand.ItemInHand.Holdable != null && secondaryHand.ItemInHand.Holdable.CanHoldTwoHand)
{
_holdController.UpdateItemPositionConstraintAndRotation(
secondaryHand, secondaryHand.ItemInHand.Holdable, false, _itemMoveDuration, false);
}
// At the same time stop looking at the item and uncrouch
_pickUpSequence.Join(DOTween.To(() => _lookAtConstraint.weight, x => _lookAtConstraint.weight = x, 0f, _itemMoveDuration).OnStart(Uncrouch));

// Stop looking at item
StartCoroutine(CoroutineHelper.ModifyValueOverTime(x => _lookAtConstraint.weight = x, 1f, 0f, _itemReachDuration));
// At the same time start getting the right rotation for the hand
_pickUpSequence.Join(DOTween.To(() => mainHand.HoldIkConstraint.data.targetRotationWeight, x => mainHand.HoldIkConstraint.data.targetRotationWeight = x, 1f, _itemMoveDuration));

// increase hold constraint rotation
StartCoroutine(CoroutineHelper.ModifyValueOverTime(x => mainHand.HoldIkConstraint.data.targetRotationWeight = x, 0f, 1f, _itemReachDuration));
// At the same time, remove the pickup constraint
_pickUpSequence.Join(DOTween.To(() => mainHand.PickupIkConstraint.weight, x => mainHand.PickupIkConstraint.weight = x, 0f, _itemMoveDuration));

// Reproduce changes on second hand if picking up with two hands
if (withTwoHands)
{
StartCoroutine(CoroutineHelper.ModifyValueOverTime(x => secondaryHand.HoldIkConstraint.data.targetRotationWeight = x, 0f, 1f, _itemReachDuration));
}

// Get hand back at its hold position.
if (withTwoHands)
{
StartCoroutine(CoroutineHelper.ModifyValueOverTime(x => secondaryHand.PickupIkConstraint.weight = x, 1f, 0f, _itemMoveDuration));
_pickUpSequence.Join(DOTween.To(() => secondaryHand.HoldIkConstraint.data.targetRotationWeight, x => secondaryHand.HoldIkConstraint.data.targetRotationWeight = x, 1f, _itemMoveDuration));
_pickUpSequence.Join(DOTween.To(() => secondaryHand.PickupIkConstraint.weight, x => secondaryHand.PickupIkConstraint.weight = x, 0f, _itemMoveDuration));
}

yield return CoroutineHelper.ModifyValueOverTime(x => mainHand.PickupIkConstraint.weight = x, 1f, 0f, _itemMoveDuration);

// Place item on constrained item position
item.transform.parent = mainHand.ItemPositionTargetLocker;
item.transform.localPosition = Vector3.zero;
item.transform.localRotation = Quaternion.identity;
_pickUpSequence.SetDelay(delay);
_pickUpSequence.OnStart(() => IsPicking = true);
_pickUpSequence.OnComplete(() => IsPicking = false);
}

_lookAtConstraint.weight = 0f;
private void Uncrouch()
{
GetComponent<HumanoidAnimatorController>().Crouch(false);
}

/// <summary>
Expand Down

0 comments on commit 103f850

Please sign in to comment.