552 lines
16 KiB
C#
552 lines
16 KiB
C#
using DG.Tweening;
|
|
using ECM2.Examples.FirstPerson;
|
|
using Obvious.Soap;
|
|
using SoapCustomVariable;
|
|
using UnityEngine;
|
|
|
|
public class PlayerHandsController : MonoBehaviour
|
|
{
|
|
public FSMVariable PlayerState;
|
|
|
|
public BoolVariable IsLeftButtonPressed;
|
|
|
|
public BoolVariable IsRightButtonPressed;
|
|
|
|
public BoolVariable IsRunButtonPressed;
|
|
|
|
public Vector2Variable RodPosition;
|
|
|
|
public FloatVariable LineTension;
|
|
|
|
public FloatVariable ReelSpeed;
|
|
|
|
public FloatVariable PlayerArmsStrength;
|
|
|
|
public FloatVariable ThrowDistance;
|
|
|
|
public FloatVariable CastPower;
|
|
|
|
public FloatVariable DragSettingInput;
|
|
|
|
public ScriptableEventBool OnFishingSetEquiped;
|
|
|
|
public Waga waga;
|
|
|
|
public float PullUpRodSpeed;
|
|
|
|
public float pullDownRodSpeed;
|
|
|
|
[SerializeField]
|
|
private float _LineRollSpeedMultiplier = 5f;
|
|
|
|
private PlayerFishingGearController _Equipment;
|
|
|
|
private bool _IsHandsControllsEnabled;
|
|
|
|
[SerializeField]
|
|
private HoldAction _HoldAction;
|
|
|
|
private PlayerIK _IK;
|
|
|
|
public Transform HandPreciseThrowTarget;
|
|
|
|
public Rigidbody PrecisePickBone;
|
|
|
|
private TrajectoryThrow _TrajectoryThrow;
|
|
|
|
public AnimationCurve PreciseThrowCurve;
|
|
|
|
private PlayerAnimator _playerAnimator;
|
|
|
|
private CharacterLook _characterLook;
|
|
|
|
private bool isFishingSeat;
|
|
|
|
private bool isInVehicle;
|
|
|
|
private bool isThrowLoad;
|
|
|
|
private bool isPreciseCast;
|
|
|
|
private bool lureInHand;
|
|
|
|
private Vector3 lastPosition;
|
|
|
|
private float handReelingStrength = 30f;
|
|
|
|
private float minReelRatio = 0.125f;
|
|
|
|
private string sfxReelingName = "Reeling 2";
|
|
|
|
private float pullingStrength = 25f;
|
|
|
|
private float minPullingStrength = 0.125f;
|
|
|
|
public AimTarget aimTarget;
|
|
|
|
private bool isPreciseCastingInProgress;
|
|
|
|
[SerializeField]
|
|
private Vector2 _RangeMin;
|
|
|
|
[SerializeField]
|
|
private Vector2 _RangeMax;
|
|
|
|
[SerializeField]
|
|
private Vector2 _RodDefaultPosition = Vector2.zero;
|
|
|
|
[SerializeField]
|
|
private Vector2 _RodNeutralPosition = Vector2.zero;
|
|
|
|
private float undwindLineOnPrecise => _Equipment.EquipedFishingSet.AttachedRod.Length;
|
|
|
|
[SerializeField]
|
|
private Vector3 _RodCatchPosition => new Vector2(0f, 1f);
|
|
|
|
private void Awake()
|
|
{
|
|
_characterLook = GetComponent<CharacterLook>();
|
|
_playerAnimator = GetComponentInChildren<PlayerAnimator>();
|
|
_TrajectoryThrow = GetComponentInChildren<TrajectoryThrow>();
|
|
_IK = GetComponentInChildren<PlayerIK>();
|
|
_Equipment = GetComponent<PlayerFishingGearController>();
|
|
_Equipment.OnFishingSetEquiped += delegate
|
|
{
|
|
OnFishingSetEquiped.Raise(param: true);
|
|
};
|
|
_Equipment.OnFishingSetUnequip += delegate
|
|
{
|
|
OnFishingSetEquiped.Raise(param: false);
|
|
};
|
|
_Equipment.OnGearDestroyed += delegate
|
|
{
|
|
if (isFishingSeat)
|
|
{
|
|
PlayerState.Value = State.vehicleFishing;
|
|
}
|
|
else if (isInVehicle && !isFishingSeat)
|
|
{
|
|
PlayerState.Value = State.vehicle;
|
|
}
|
|
else
|
|
{
|
|
PlayerState.Value = State.idle;
|
|
}
|
|
};
|
|
_Equipment.OnLinePulled += delegate
|
|
{
|
|
if (isFishingSeat)
|
|
{
|
|
PlayerState.Value = State.vehicleFishing;
|
|
}
|
|
else if (isInVehicle && !isFishingSeat)
|
|
{
|
|
PlayerState.Value = State.vehicle;
|
|
}
|
|
else
|
|
{
|
|
PlayerState.Value = State.idle;
|
|
}
|
|
};
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
PlayerState.OnValueChanged += PlayerStateOnOnValueChanged;
|
|
DragSettingInput.OnValueChanged += DragSettingInputOnOnValueChanged;
|
|
IsRightButtonPressed.OnValueChanged += OnPreciseCast_ButtonPressed;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
PlayerState.OnValueChanged -= PlayerStateOnOnValueChanged;
|
|
DragSettingInput.OnValueChanged -= DragSettingInputOnOnValueChanged;
|
|
IsRightButtonPressed.OnValueChanged -= OnPreciseCast_ButtonPressed;
|
|
}
|
|
|
|
private void ResetToIdle()
|
|
{
|
|
State state = (isInVehicle ? State.vehicle : State.idle);
|
|
state = (isFishingSeat ? State.vehicleFishing : state);
|
|
PlayerState.Value = state;
|
|
}
|
|
|
|
private void OnPreciseCast_ButtonPressed(bool isPressed)
|
|
{
|
|
switch (PlayerState.Value)
|
|
{
|
|
case State.idle:
|
|
case State.move:
|
|
case State.vehicleFishing:
|
|
if (isPressed && (bool)_Equipment.EquipedFishingSet)
|
|
{
|
|
isPreciseCast = true;
|
|
PlayerState.Value = State.preciseCastIdle;
|
|
}
|
|
break;
|
|
case State.preciseCastIdle:
|
|
if (isPressed && !isPreciseCastingInProgress)
|
|
{
|
|
ResetToIdle();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void DragSettingInputOnOnValueChanged(float value)
|
|
{
|
|
switch (PlayerState.Value)
|
|
{
|
|
case State.idle:
|
|
case State.move:
|
|
case State.fishing:
|
|
case State.fight:
|
|
case State.vehicle:
|
|
case State.vehicleFishing:
|
|
if (_Equipment.IsEquipped.Value)
|
|
{
|
|
if (IsRunButtonPressed.Value)
|
|
{
|
|
ReelSpeed.Value += value * 0.015f;
|
|
}
|
|
else
|
|
{
|
|
_Equipment.EquipedFishingSet?.AddDrag(value * 0.015f);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void PlayerStateOnOnValueChanged(State state)
|
|
{
|
|
switch (PlayerState.PreviousValue)
|
|
{
|
|
case State.baitFlies:
|
|
_HoldAction.ResetHold();
|
|
break;
|
|
case State.fishing:
|
|
ThrowDistance.Value = 0f;
|
|
_IK.SetBipedLeftHandIK(enabled: false);
|
|
_IK.SetAimIK(enabled: false);
|
|
if (SFXGameManagement.IsSoundPlaying(sfxReelingName))
|
|
{
|
|
SFXGameManagement.StopSound(sfxReelingName);
|
|
}
|
|
break;
|
|
case State.fight:
|
|
if (SFXGameManagement.IsSoundPlaying(sfxReelingName))
|
|
{
|
|
SFXGameManagement.StopSound(sfxReelingName);
|
|
}
|
|
_IK.SetAimIK(enabled: false);
|
|
break;
|
|
case State.vehicleFishing:
|
|
isInVehicle = false;
|
|
break;
|
|
case State.vehicle:
|
|
isInVehicle = false;
|
|
break;
|
|
case State.preciseCastIdle:
|
|
isPreciseCast = false;
|
|
_TrajectoryThrow.targetCylinderEnabled = false;
|
|
if (state != State.fishing)
|
|
{
|
|
_Equipment.EquipedFishingSet.SetLineLength(0.5f);
|
|
}
|
|
_Equipment.EquipedFishingSet.AttachedLure.SetJoint(_Equipment.EquipedFishingSet.AttachedRod.RodTipBone);
|
|
_Equipment.EquipedFishingSet.AttachedLure.EnableCollision(enable: true);
|
|
_Equipment.EquipedFishingSet.AttachedLure.SetKinematic(value: false);
|
|
_Equipment.EquipedFishingSet.attachedBobber?.SetDetectCollisionEnabled(enabled: true);
|
|
_IK.SetFishingLeftArm(enabled: false, _Equipment.EquipedFishingSet.AttachedReel.FingersIKAnchor);
|
|
isPreciseCastingInProgress = false;
|
|
lureInHand = false;
|
|
break;
|
|
case State.collectFish:
|
|
_Equipment.EquipedFishingSet?.AttachedLure?.SetRenderersVisbile(isVisbile: true);
|
|
waga.gameObject.SetActive(value: false);
|
|
_Equipment.EquipedFishingSet.AttachedLure.EnableCollision(enable: true);
|
|
_Equipment.EquipedFishingSet.attachedBobber?.SetDetectCollisionEnabled(enabled: true);
|
|
break;
|
|
}
|
|
switch (state)
|
|
{
|
|
case State.idle:
|
|
isInVehicle = false;
|
|
if (SFXGameManagement.IsSoundPlaying(sfxReelingName))
|
|
{
|
|
SFXGameManagement.StopSound(sfxReelingName);
|
|
}
|
|
isFishingSeat = false;
|
|
LineTension.Value = 0f;
|
|
RodPosition.Value = Vector3.zero;
|
|
_IK.SetAimIK(enabled: false);
|
|
_IK.SetBipedLeftHandIK(enabled: false);
|
|
_IK.SetFishingLeftArm(enabled: false);
|
|
break;
|
|
case State.vehicle:
|
|
isInVehicle = true;
|
|
isFishingSeat = false;
|
|
break;
|
|
case State.prepare:
|
|
if (SFXGameManagement.IsSoundPlaying(sfxReelingName))
|
|
{
|
|
SFXGameManagement.StopSound(sfxReelingName);
|
|
}
|
|
break;
|
|
case State.vehicleFishing:
|
|
if (SFXGameManagement.IsSoundPlaying(sfxReelingName))
|
|
{
|
|
SFXGameManagement.StopSound(sfxReelingName);
|
|
}
|
|
isFishingSeat = true;
|
|
isInVehicle = true;
|
|
_IK.SetFishingLeftArm(enabled: false);
|
|
break;
|
|
case State.preciseCastIdle:
|
|
_TrajectoryThrow.targetCylinderEnabled = true;
|
|
_IK.SetBipedRightHandIK(enabled: false, null);
|
|
_Equipment.EquipedFishingSet.SetLineLength(SetLineLengthBasedOnGround());
|
|
_Equipment.EquipedFishingSet.AttachedLure.EnableCollision(enable: false);
|
|
_Equipment.EquipedFishingSet.attachedBobber?.SetDetectCollisionEnabled(enabled: false);
|
|
lureInHand = true;
|
|
break;
|
|
case State.fishing:
|
|
case State.fight:
|
|
_IK.SetBipedRightHandIK(enabled: false, null);
|
|
_IK.SetFishingLeftArm(enabled: true, _Equipment.EquipedFishingSet.AttachedReel.FingersIKAnchor);
|
|
_IK.SetAimIK(enabled: true);
|
|
break;
|
|
case State.casting:
|
|
isThrowLoad = true;
|
|
_Equipment.EquipedFishingSet.OpenBail();
|
|
break;
|
|
case State.baitFlies:
|
|
_Equipment.EquipedFishingSet.Cast(base.transform);
|
|
break;
|
|
case State.collectFish:
|
|
waga.gameObject.SetActive(value: true);
|
|
waga.SetText(_Equipment.EquipedFishingSet.HookedFish.Mass);
|
|
_Equipment.EquipedFishingSet.HookedFish.SetJoint(waga.hookRbody);
|
|
_Equipment.EquipedFishingSet.AttachedLure.EnableCollision(enable: false);
|
|
_Equipment.EquipedFishingSet.attachedBobber?.SetDetectCollisionEnabled(enabled: false);
|
|
break;
|
|
case State.move:
|
|
case State.fishView:
|
|
case State.throwFish:
|
|
case State.swiming:
|
|
case State.flyModeDebug:
|
|
break;
|
|
}
|
|
}
|
|
|
|
private float SetLineLengthBasedOnGround()
|
|
{
|
|
float value = _Equipment.EquipedFishingSet.groundSetting.Value;
|
|
Vector3 position = _Equipment.EquipedFishingSet.AttachedRod.RodTipBone.position;
|
|
Vector3 position2 = PrecisePickBone.position;
|
|
return Mathf.Clamp(Vector3.Distance(position, position2) - value, 0.51f, 50f);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (_Equipment.EquipedFishingSet == null)
|
|
{
|
|
return;
|
|
}
|
|
_ = CastPower.Value;
|
|
switch (PlayerState.Value)
|
|
{
|
|
case State.idle:
|
|
case State.move:
|
|
case State.vehicleFishing:
|
|
if (IsLeftButtonPressed.Value && _HoldAction.IsZero())
|
|
{
|
|
isPreciseCast = false;
|
|
PlayerState.Value = State.prepare;
|
|
}
|
|
break;
|
|
case State.prepare:
|
|
if (!IsLeftButtonPressed.Value && !isPreciseCast)
|
|
{
|
|
ResetToIdle();
|
|
}
|
|
break;
|
|
case State.casting:
|
|
if (isThrowLoad)
|
|
{
|
|
_HoldAction.Hold();
|
|
ThrowDistance.Value = Mathf.Lerp(0f, CastPower.Value, _HoldAction.CurrentValue * 1.35f);
|
|
}
|
|
if (!IsLeftButtonPressed.Value && _HoldAction.CurrentValue > 0.1f)
|
|
{
|
|
isThrowLoad = false;
|
|
}
|
|
break;
|
|
case State.fishing:
|
|
case State.fight:
|
|
RodControllClassicMethod();
|
|
UnwindFishingLine();
|
|
break;
|
|
case State.preciseCastIdle:
|
|
{
|
|
Lure lure = _Equipment.EquipedFishingSet.AttachedLure;
|
|
BobberController bobber = _Equipment.EquipedFishingSet.attachedBobber;
|
|
float delay = 0.95f;
|
|
lastPosition = lure.transform.position;
|
|
float distance = 0f;
|
|
float lineMinus = ((bobber != null) ? (0f - _Equipment.EquipedFishingSet.groundSetting.Value) : 0f);
|
|
if (!isPreciseCastingInProgress)
|
|
{
|
|
_Equipment.EquipedFishingSet.SetLineLength(SetLineLengthBasedOnGround());
|
|
}
|
|
else if (_Equipment.EquipedFishingSet.AttachedLure.IsCollide())
|
|
{
|
|
lure.transform.DOKill();
|
|
float magnitude = (_Equipment.EquipedFishingSet.AttachedRod.RodTipBone.position - lure.transform.position).magnitude;
|
|
lure.RBody.detectCollisions = true;
|
|
lure.RBody.freezeRotation = false;
|
|
lure.RBody.linearVelocity = Vector3.zero;
|
|
lure.SetKinematic(value: false);
|
|
if ((bool)bobber)
|
|
{
|
|
bobber.transform.position = lure.transform.position;
|
|
bobber.SetVelocity(Vector3.zero);
|
|
}
|
|
_Equipment.EquipedFishingSet.SetLineLength(magnitude + lineMinus + 0.5f);
|
|
_Equipment.EquipedFishingSet.AttachedLine.SetObiRopeStretch(magnitude + lineMinus + 0.5f);
|
|
PlayerState.Value = State.fishing;
|
|
}
|
|
if (IsLeftButtonPressed.Value && !isPreciseCastingInProgress)
|
|
{
|
|
isPreciseCastingInProgress = true;
|
|
_characterLook.isLookingEnabled = false;
|
|
_playerAnimator.PlayPreciseCastAnimation();
|
|
lure.transform.DOJump(_TrajectoryThrow.cylinderPosition, 1f, 1, 1f).OnStart(delegate
|
|
{
|
|
lure.SetJoint(_Equipment.EquipedFishingSet.AttachedRod.RodTipBone);
|
|
lure.RBody.freezeRotation = true;
|
|
lureInHand = false;
|
|
_characterLook.isLookingEnabled = true;
|
|
_TrajectoryThrow.targetCylinderEnabled = false;
|
|
SFXGameManagement.PlaySound("hand throw", base.transform);
|
|
}).SetDelay(delay, asPrependedIntervalIfSequence: false)
|
|
.OnUpdate(delegate
|
|
{
|
|
distance = Vector3.Distance(lure.transform.position, lastPosition);
|
|
lastPosition = lure.transform.position;
|
|
float magnitude2 = (_Equipment.EquipedFishingSet.AttachedRod.RodTipBone.position - lure.transform.position).magnitude;
|
|
_Equipment.EquipedFishingSet.SetLineLength(magnitude2 + lineMinus);
|
|
_Equipment.EquipedFishingSet.AttachedLine.SetObiRopeStretch(0f);
|
|
})
|
|
.OnComplete(delegate
|
|
{
|
|
float magnitude2 = (_Equipment.EquipedFishingSet.AttachedRod.RodTipBone.position - lure.transform.position).magnitude;
|
|
_Equipment.EquipedFishingSet.SetLineLength(magnitude2 + lineMinus);
|
|
_Equipment.EquipedFishingSet.AttachedLine.SetObiRopeStretch(magnitude2 + lineMinus);
|
|
lure.RBody.detectCollisions = true;
|
|
lure.RBody.freezeRotation = false;
|
|
lure.RBody.linearVelocity = Vector3.zero;
|
|
lure.SetKinematic(value: false);
|
|
if ((bool)bobber)
|
|
{
|
|
bobber.transform.position = lure.transform.position;
|
|
bobber.SetVelocity(Vector3.zero);
|
|
}
|
|
PlayerState.Value = State.fishing;
|
|
});
|
|
}
|
|
if (lureInHand)
|
|
{
|
|
lure.transform.position = PrecisePickBone.transform.position;
|
|
if ((bool)bobber)
|
|
{
|
|
lure.RBody.isKinematic = true;
|
|
lure.RBody.detectCollisions = false;
|
|
lure.transform.position = PrecisePickBone.transform.position;
|
|
lure.transform.rotation = PrecisePickBone.transform.rotation;
|
|
}
|
|
else if (lure.Joint.connectedBody != PrecisePickBone)
|
|
{
|
|
lure.SetJoint(PrecisePickBone);
|
|
lure.SetLureJointDistance(0f);
|
|
lure.RBody.linearVelocity = Vector3.zero;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case State.collectFish:
|
|
{
|
|
Vector3 eulerAngles = waga.transform.eulerAngles;
|
|
RodPosition.Value = Vector3.MoveTowards(RodPosition.Value, _RodCatchPosition, Time.deltaTime);
|
|
waga.transform.eulerAngles = new Vector3(eulerAngles.x, PrecisePickBone.transform.eulerAngles.y, eulerAngles.z);
|
|
break;
|
|
}
|
|
case State.baitFlies:
|
|
case State.fishView:
|
|
case State.throwFish:
|
|
case State.vehicle:
|
|
case State.swiming:
|
|
case State.flyModeDebug:
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void UnwindFishingLine()
|
|
{
|
|
if (!IsLeftButtonPressed.Value)
|
|
{
|
|
if (SFXGameManagement.IsSoundPlaying(sfxReelingName))
|
|
{
|
|
SFXGameManagement.StopSound(sfxReelingName);
|
|
}
|
|
return;
|
|
}
|
|
float num = Mathf.Lerp(1f, minReelRatio, LineTension.Value / handReelingStrength);
|
|
float num2 = (IsRunButtonPressed.Value ? 1f : ReelSpeed.Value);
|
|
float num3 = (0f - Time.deltaTime) * num2 * _LineRollSpeedMultiplier * num;
|
|
float lineLength = _Equipment.EquipedFishingSet.AttachedLine.LineLength;
|
|
float lureDistance = _Equipment.EquipedFishingSet.LureDistance;
|
|
float num4 = lineLength - lureDistance;
|
|
num = num3 * Mathf.Clamp01(1f + Mathf.Clamp(num4 * 1f, -0.9f, 0f) + Random.Range(0f, 0.1f));
|
|
_Equipment.EquipedFishingSet.UnwindLine(num, useReel: true);
|
|
float t = (0f - num) * 100f;
|
|
float pitchValue = Mathf.Lerp(0.4f, 1.2f, t);
|
|
if (!SFXGameManagement.IsSoundPlaying(sfxReelingName))
|
|
{
|
|
SFXGameManagement.PlaySound(sfxReelingName, base.transform);
|
|
}
|
|
SFXGameManagement.ChangePitch(sfxReelingName, pitchValue);
|
|
}
|
|
|
|
private void RodControllClassicMethod()
|
|
{
|
|
FishController hookedFish = _Equipment.EquipedFishingSet.HookedFish;
|
|
float num = 0f;
|
|
if ((bool)hookedFish)
|
|
{
|
|
Vector3 normalized = (hookedFish.transform.position - _Equipment.EquipedFishingSet.transform.position).normalized;
|
|
Vector3 vector = Vector3.Cross(base.transform.forward, normalized);
|
|
num = vector.y;
|
|
_ = vector.y;
|
|
_ = 0f;
|
|
}
|
|
float num2 = Mathf.Lerp(1.75f, minPullingStrength, LineTension.Value / pullingStrength);
|
|
if (IsRightButtonPressed.Value)
|
|
{
|
|
RodPosition.Value = Vector3.MoveTowards(RodPosition.Value, new Vector3(0f, 1f, 0f), Time.deltaTime * num2);
|
|
Mathf.Lerp(aimTarget.pullPower, 1f, Time.deltaTime * num2);
|
|
aimTarget.Pull(RodPosition.Value.y, (LineTension.Value > 0f) ? (num * 1f) : 0f);
|
|
}
|
|
else
|
|
{
|
|
RodPosition.Value = Vector3.MoveTowards(RodPosition.Value, new Vector3(0f, 0f, 0f), Time.deltaTime * 5f);
|
|
}
|
|
_Equipment.EquipedFishingSet.rodPullValue = RodPosition.Value.y;
|
|
}
|
|
|
|
private void HandsMovementHandler(bool value, bool isFishOnHook = false)
|
|
{
|
|
}
|
|
}
|