Files
Ultimate-Fishing-Simulator-…/Assets/Scripts/Assembly-CSharp/Lure.cs
2026-03-04 09:37:33 +08:00

380 lines
8.2 KiB
C#

using System;
using System.Collections;
using System.Linq;
using Obvious.Soap;
using Obvious.Soap.Attributes;
using UFS3;
using UnityEngine;
using UnityWaterTools;
public class Lure : MonoBehaviour, IInitializable<LureData>
{
private static readonly int Speed = Animator.StringToHash("speed");
public MeshRenderer lureMeshRenderer;
public float lureSize;
public Transform lookTarget;
[SerializeField]
private FloatVariable lineLength;
[Tooltip("This variable defines is main lure for raising events")]
[SerializeField]
private bool isHeadingAttach;
[ShowIf("isHeadingAttach")]
[SerializeField]
private ConfigurableJoint joint;
[ShowIf("isHeadingAttach")]
[SerializeField]
private GameObjectVariable rodTip;
[ShowIf("isHeadingAttach")]
[SerializeField]
private GameObjectVariable lureCurrent;
[ShowIf("isHeadingAttach")]
[SerializeField]
private Vector3Variable lurePosition;
[ShowIf("isHeadingAttach")]
[SerializeField]
private FloatVariable lureDistanceToTip;
[ShowIf("isHeadingAttach")]
[SerializeField]
private GameObjectVariable fishCatchLureTarget;
[ShowIf("isHeadingAttach")]
[SerializeField]
private ScriptableEventNoParam onGroundEnter;
[ShowIf("isHeadingAttach")]
[SerializeField]
private ScriptableEventNoParam onGroundExit;
private SphereCollider collider;
private Animator _lureAnimator;
private Rigidbody rBody;
private WaterFloater waterFloater;
private LureData _LureData;
private BaitData _BaitData;
private Quaternion lureRotation = Quaternion.identity;
private MeshRenderer[] lureMeshRenderers;
private FishController _hookedToFish;
private Vector3 _lastPosition;
private Vector3 _linearDirection;
private bool _wasRenderersLoaded;
private bool _isAnimated;
private bool _isGrounded;
private float _efficiency;
private float _moveSpeed;
public float moveSpeed => _moveSpeed;
public bool isGrounded => _isGrounded;
public LureData LureData
{
get
{
return _LureData;
}
private set
{
_LureData = value;
}
}
public BaitData BaitData => _BaitData;
public bool IsFishConnected => _hookedToFish != null;
public bool IsBait => _BaitData != null;
public bool IsLure => _LureData != null;
public bool isInWater => waterFloater.InWater;
public Vector3 Velocity => rBody.linearVelocity;
public Rigidbody RBody => rBody;
public ConfigurableJoint Joint => joint;
public event Action OnDestroyRaised;
public event Action<bool> OnWaterStateChanged;
public event Action<bool> OnGroundCollisionChangeState;
public event Action onBoatTouched;
public event Action<FishController> OnFishEat;
public event Action OnFishSpit;
private void Awake()
{
waterFloater = GetComponent<WaterFloater>();
rBody = GetComponent<Rigidbody>();
collider = GetComponent<SphereCollider>();
waterFloater.OnWaterEnter += WaterFloater_OnWaterEnter;
waterFloater.OnWaterEnter += delegate(bool x)
{
this.OnWaterStateChanged?.Invoke(x);
};
WaterFloater_OnWaterEnter(waterFloater.InWater);
}
private IEnumerator Start()
{
if (isHeadingAttach)
{
lureCurrent.Value = base.gameObject;
}
joint = ((joint == null) ? GetComponent<ConfigurableJoint>() : joint);
SetLureJointDistance(lineLength.Value);
rBody.detectCollisions = false;
waterFloater.enabled = false;
yield return new WaitForSeconds(2f);
waterFloater.enabled = true;
rBody.detectCollisions = true;
}
public bool IsCollide()
{
return Physics.OverlapSphere(base.transform.position, 0.2f, LayerMask.GetMask("Terrain", "BoatStatic", "Water Reflections", "Default")).Length != 0;
}
public bool IsCollide(Vector3 direction)
{
return Physics.Raycast(base.transform.position, direction.normalized, direction.magnitude, LayerMask.GetMask("Terrain", "BoatStatic", "Water Reflections"));
}
public void SetRenderersVisbile(bool isVisbile)
{
if (lureMeshRenderers != null)
{
lureMeshRenderers.ToList().ForEach(delegate(MeshRenderer x)
{
x.enabled = isVisbile;
});
}
}
public void ConnectFish(FishController fish)
{
if (fish == null)
{
this.OnFishSpit?.Invoke();
_hookedToFish = null;
SetRenderersVisbile(isVisbile: true);
}
else
{
this.OnFishEat?.Invoke(fish);
_hookedToFish = fish;
rBody.linearDamping = 0.1f;
SetRenderersVisbile(isVisbile: false);
}
}
private void WaterFloater_OnWaterEnter(bool inWater)
{
if (isHeadingAttach)
{
if (inWater)
{
SFXGameManagement.PlaySound("splash lure", base.transform);
rBody.linearDamping = ((_hookedToFish == null) ? 3f : 0.1f);
rBody.angularDamping = 2f;
}
else
{
rBody.linearDamping = 1f;
rBody.angularDamping = 1f;
}
}
}
public void SetLureJointDistance(float limit)
{
joint.linearLimit = new SoftJointLimit
{
limit = limit
};
}
private void LateUpdate()
{
if (!isHeadingAttach)
{
return;
}
if (!_wasRenderersLoaded)
{
GetRendereres();
_lureAnimator = GetComponentInChildren<Animator>();
_isAnimated = (object)_lureAnimator != null;
_wasRenderersLoaded = true;
}
_efficiency = Mathf.Clamp01(_efficiency);
if (_isGrounded || !waterFloater.InWater)
{
_efficiency = 0f;
}
_efficiency += Time.deltaTime * 0.1f;
collider.radius = _efficiency * 3f;
lurePosition.Value = base.transform.position;
_linearDirection = base.transform.position - _lastPosition;
_lastPosition = base.transform.position;
_moveSpeed = _linearDirection.magnitude;
Transform child = base.transform.GetChild(0);
if (IsLure && waterFloater.InWater)
{
if (!_isGrounded && _hookedToFish == null)
{
rBody.freezeRotation = true;
if (moveSpeed > 0.0001f)
{
lureRotation = Quaternion.LookRotation(_linearDirection.normalized, Vector3.up);
}
float value = Mathf.Clamp(moveSpeed / Time.deltaTime, 0f, 1f) * _LureData.twitchySpeed;
_lureAnimator?.SetFloat(Speed, value);
if (_LureData.axisNormal != Vector3.zero)
{
lureRotation = AlignToSurfaceAndForward(_LureData.axisNormal, child.forward);
}
}
else if (_hookedToFish != null)
{
rBody.freezeRotation = true;
child.rotation = _hookedToFish.transform.rotation;
_lureAnimator?.SetFloat(Speed, 0f);
}
else
{
_lureAnimator?.SetFloat(Speed, 0f);
rBody.freezeRotation = false;
}
}
else
{
rBody.freezeRotation = false;
_lureAnimator?.SetFloat(Speed, 0f);
}
child.rotation = Quaternion.Slerp(child.rotation, lureRotation, Time.deltaTime * 2f);
static Quaternion AlignToSurfaceAndForward(Vector3 surfaceNormal, Vector3 desiredForward)
{
return Quaternion.LookRotation(Vector3.ProjectOnPlane(desiredForward, surfaceNormal).normalized, surfaceNormal);
}
}
private void OnDrawGizmos()
{
if (rBody != null)
{
Gizmos.color = Color.green;
Vector3 position = base.transform.position;
Vector3 vector = _linearDirection * 10f;
Gizmos.DrawLine(position, position + vector);
Gizmos.DrawSphere(position + vector, 0.035f);
}
}
private void OnDestroy()
{
this.OnDestroyRaised?.Invoke();
}
private void PhysicsHandler()
{
if (waterFloater.InWater)
{
rBody.AddForce(Vector3.up * 14f, ForceMode.Acceleration);
}
}
private void OnCollisionEnter(Collision collision)
{
if (isHeadingAttach)
{
if (collision.gameObject.layer == LayerMask.NameToLayer("Terrain"))
{
this.OnGroundCollisionChangeState?.Invoke(obj: true);
onGroundEnter.Raise();
_isGrounded = true;
}
if (collision.gameObject.layer == LayerMask.NameToLayer("BoatStatic"))
{
this.onBoatTouched?.Invoke();
_isGrounded = true;
}
}
}
private void OnCollisionExit(Collision collision)
{
if (isHeadingAttach && collision.gameObject.layer == LayerMask.NameToLayer("Terrain"))
{
this.OnGroundCollisionChangeState?.Invoke(obj: false);
onGroundExit.Raise();
_isGrounded = false;
}
}
public void SetJoint(Rigidbody rb)
{
joint.connectedBody = rb;
}
public void EnableCollision(bool enable)
{
if (rBody == null)
{
rBody = GetComponent<Rigidbody>();
}
rBody.detectCollisions = enable;
}
public void SetKinematic(bool value)
{
rBody.isKinematic = value;
}
private void GetRendereres()
{
lureMeshRenderers = GetComponentsInChildren<MeshRenderer>();
}
public void Initialize(LureData Value)
{
LureData = Value;
lureSize = Value.size;
}
public void Initialize(BaitData Value)
{
_BaitData = Value;
}
}