using System; using Obvious.Soap; using UnityEngine; using UnityWaterTools; public class AttachmentBody : MonoBehaviour { private Rigidbody rbody; private WaterFloater waterFloater; [SerializeField] private FloatVariable bodySpeed; [SerializeField] private FloatVariable lineLength; [SerializeField] private BoolVariable isBailOpen; [SerializeField] private Vector3Variable playerForward; [SerializeField] private bool isHeadingAttach; [SerializeField] private ScriptableEventNoParam onWaterEnter; [SerializeField] private ScriptableEventNoParam onWaterExit; [SerializeField] private ScriptableEventNoParam onGroundEnter; [SerializeField] private ScriptableEventNoParam onGroundExit; [SerializeField] private FloatVariable attachedTotalMass; [SerializeField] private float attachedMass; private SpringJoint springJoint; public Rigidbody RBody => rbody; public bool IsHeadingAttach => isHeadingAttach; public event Action OnCollide; private void Awake() { waterFloater = GetComponent(); rbody = GetComponent(); waterFloater.OnWaterEnter += WaterFloater_OnWaterEnter; springJoint = GetComponent(); } private void OnEnable() { if (isHeadingAttach) { attachedTotalMass.Value += attachedMass; } if (isHeadingAttach) { lineLength.OnValueChanged += LineLength_OnValueChanged; } } private void OnDisable() { if (isHeadingAttach) { attachedTotalMass.Value -= attachedMass; } if (isHeadingAttach) { lineLength.OnValueChanged -= LineLength_OnValueChanged; } } private void LineLength_OnValueChanged(float length) { springJoint.maxDistance = length; } private void WaterFloater_OnWaterEnter(bool obj) { if (isHeadingAttach) { if (obj) { rbody.linearDamping = 4f; onWaterEnter.Raise(); } else { rbody.linearDamping = 0.1f; onWaterExit.Raise(); } this.OnCollide?.Invoke(); } } private void FixedUpdate() { if (waterFloater.InWater) { rbody.AddForce(Vector3.up * 10f, ForceMode.Acceleration); } if ((bool)isBailOpen && isHeadingAttach) { bodySpeed.Value = rbody.linearVelocity.magnitude; } } private void OnCollisionEnter(Collision collision) { if (isHeadingAttach && collision.gameObject.layer == LayerMask.NameToLayer("Terrain")) { onGroundEnter.Raise(); this.OnCollide?.Invoke(); } } private void OnCollisionExit(Collision collision) { if (isHeadingAttach && collision.gameObject.layer == LayerMask.NameToLayer("Terrain")) { onGroundExit.Raise(); this.OnCollide?.Invoke(); } } }