using System; using System.Collections; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(Rigidbody))] public class vp_Grab : vp_Interactable { public string OnGrabText = string.Empty; public Texture GrabStateCrosshair; public float FootstepForce = 0.015f; public float Kneeling = 5f; public float Stiffness = 0.5f; public float ShakeSpeed = 0.1f; public Vector3 ShakeAmplitude = Vector3.one; public float ThrowStrength = 6f; public bool AllowThrowRotation = true; public float Burden; public int MaxCollisionCount = 20; protected Vector3 m_CurrentShake = Vector3.zero; protected Vector3 m_CurrentRotationSway = Vector3.zero; protected Vector2 m_CurrentMouseMove; protected Vector3 m_CurrentSwayForce; protected Vector3 m_CurrentSwayTorque; protected float m_CurrentFootstepForce; protected Vector3 m_CurrentHoldAngle = Vector3.one; protected Collider m_LastExternalCollider; protected int m_CollisionCount; public Vector3 CarryingOffset = new Vector3(0f, -0.5f, 1.5f); public float CameraPitchDownLimit; protected Vector3 m_TempCarryingOffset = Vector3.zero; protected bool m_IsFetching; protected float duration; protected float m_FetchProgress; protected vp_FPInteractManager m_InteractManager; protected AudioSource m_Audio; protected int m_LastWeaponEquipped; protected bool m_IsGrabbed; protected float m_OriginalPitchDownLimit; protected bool m_DefaultGravity; protected float m_DefaultDrag; protected float m_DefaultAngularDrag; public Vector2 SoundsPitch = new Vector2(1f, 1.5f); public List GrabSounds = new List(); public List DropSounds = new List(); public List ThrowSounds = new List(); protected vp_Timer.Handle m_DisableAngleSwayTimer = new vp_Timer.Handle(); private vp_FPPlayerEventHandler m_FPPlayer; private vp_FPPlayerEventHandler FPPlayer { get { if (m_FPPlayer == null) { m_FPPlayer = m_Player as vp_FPPlayerEventHandler; } return m_FPPlayer; } } protected override void Start() { base.Start(); if (!GetComponent() || !GetComponent()) { base.enabled = false; } if (GetComponent() != null) { m_DefaultGravity = GetComponent().useGravity; m_DefaultDrag = m_Transform.GetComponent().drag; m_DefaultAngularDrag = m_Transform.GetComponent().angularDrag; } InteractType = vp_InteractType.Normal; m_InteractManager = UnityEngine.Object.FindObjectOfType(typeof(vp_FPInteractManager)) as vp_FPInteractManager; } protected virtual void FixedUpdate() { if (m_IsGrabbed && !(m_Transform.parent == null)) { UpdateShake(); UpdatePosition(); UpdateRotation(); UpdateBurden(); DampenForces(); } } protected virtual void Update() { if (m_IsGrabbed && !(m_Transform.parent == null)) { UpdateInput(); } } protected virtual void UpdateInput() { m_CurrentMouseMove.x = FPPlayer.InputRawLook.Get().x * Time.timeScale; m_CurrentMouseMove.y = FPPlayer.InputRawLook.Get().y * Time.timeScale; if (FPPlayer.InputGetButtonDown.Send("Attack")) { FPPlayer.Interact.TryStart(); } else if (m_Player.CurrentWeaponIndex.Get() != 0) { m_Player.SetWeapon.TryStart(0); } } protected virtual void UpdateShake() { m_CurrentShake = Vector3.Scale(vp_SmoothRandom.GetVector3Centered(ShakeSpeed), ShakeAmplitude); m_Transform.localEulerAngles += m_CurrentShake; } protected virtual void UpdatePosition() { m_CurrentSwayForce += m_Player.Velocity.Get() * 0.005f; m_CurrentSwayForce.y += m_CurrentFootstepForce; m_CurrentSwayForce += m_Camera.Transform.TransformDirection(new Vector3(m_CurrentMouseMove.x * 0.05f, (!(m_Player.Rotation.Get().x > m_Camera.RotationPitchLimit.y)) ? (m_CurrentMouseMove.y * 0.05f) : (m_CurrentMouseMove.y * 0.015f), 0f)); m_TempCarryingOffset = ((!m_Player.IsFirstPerson.Get()) ? (CarryingOffset - m_Camera.Position3rdPersonOffset) : CarryingOffset); m_Transform.position = Vector3.Lerp(m_Transform.position, m_Camera.Transform.position - m_CurrentSwayForce + m_Camera.Transform.right * m_TempCarryingOffset.x + m_Camera.Transform.up * m_Transform.localScale.y * (m_TempCarryingOffset.y + m_CurrentShake.y * 0.5f) + m_Camera.Transform.forward * m_TempCarryingOffset.z, (!(m_FetchProgress < 1f)) ? (Time.deltaTime * (Stiffness * 60f)) : m_FetchProgress); } protected virtual void UpdateRotation() { m_Camera.RotationPitchLimit = Vector2.Lerp(m_Camera.RotationPitchLimit, new Vector2(m_Camera.RotationPitchLimit.x, CameraPitchDownLimit), m_FetchProgress); if (!m_DisableAngleSwayTimer.Active) { m_CurrentSwayTorque += m_Player.Velocity.Get() * 0.005f; m_CurrentRotationSway = m_Camera.Transform.InverseTransformDirection(m_CurrentSwayTorque * 1.5f); m_CurrentRotationSway.y = m_CurrentRotationSway.z; m_CurrentRotationSway.z = m_CurrentRotationSway.x; m_CurrentRotationSway.x = (0f - m_CurrentRotationSway.y) * 0.5f; m_CurrentRotationSway.y = 0f; Quaternion localRotation = m_Transform.localRotation; m_Transform.Rotate(m_Camera.transform.forward, m_CurrentRotationSway.z * -0.5f * Time.timeScale); m_Transform.Rotate(m_Camera.transform.right, m_CurrentRotationSway.x * -0.5f * Time.timeScale); Quaternion localRotation2 = m_Transform.localRotation; m_Transform.localRotation = localRotation; m_Transform.localRotation = Quaternion.Slerp(localRotation2, Quaternion.Euler(m_CurrentHoldAngle + m_CurrentShake * 50f), Time.deltaTime * (Stiffness * 60f)); } } protected virtual void UpdateBurden() { if (!(Burden <= 0f)) { m_Player.MotorThrottle.Set(m_Player.MotorThrottle.Get() * (1f - Mathf.Clamp01(Burden))); } } protected virtual void DampenForces() { m_CurrentSwayForce *= 0.9f; m_CurrentSwayTorque *= 0.9f; m_CurrentFootstepForce *= 0.9f; } public override bool TryInteract(vp_PlayerEventHandler player) { if (!(player is vp_FPPlayerEventHandler)) { return false; } if (m_Player == null) { m_Player = player; } if (player == null) { return false; } if (m_Controller == null) { m_Controller = m_Player.GetComponent(); } if (m_Controller == null) { return false; } if (m_Camera == null) { m_Camera = m_Player.GetComponentInChildren(); } if (m_Camera == null) { return false; } if (m_WeaponHandler == null) { m_WeaponHandler = m_Player.GetComponentInChildren(); } if (m_Audio == null) { m_Audio = m_Player.GetComponent(); } m_Player.Register(this); if (!m_IsGrabbed) { StartGrab(); } else { StopGrab(); } m_Player.Interactable.Set(this); if (GrabStateCrosshair != null) { FPPlayer.Crosshair.Set(GrabStateCrosshair); } else { FPPlayer.Crosshair.Set(new Texture2D(0, 0)); } return true; } protected virtual void StartGrab() { vp_AudioUtility.PlayRandomSound(m_Audio, GrabSounds, SoundsPitch); if (!string.IsNullOrEmpty(OnGrabText)) { FPPlayer.HUDText.Send(OnGrabText); } vp_FPCamera camera = m_Camera; camera.BobStepCallback = (vp_FPCamera.BobStepDelegate)Delegate.Combine(camera.BobStepCallback, new vp_FPCamera.BobStepDelegate(Footstep)); m_LastWeaponEquipped = m_Player.CurrentWeaponIndex.Get(); m_OriginalPitchDownLimit = m_Camera.RotationPitchLimit.y; m_FetchProgress = 0f; if (m_LastWeaponEquipped != 0) { m_Player.SetWeapon.TryStart(0); } else if (!m_IsFetching) { StartCoroutine("Fetch"); } if (m_Transform.GetComponent() != null) { m_Transform.GetComponent().useGravity = false; m_Transform.GetComponent().drag = Stiffness * 60f; m_Transform.GetComponent().angularDrag = Stiffness * 60f; } if (m_Controller.Transform.GetComponent().enabled && m_Transform.GetComponent().enabled) { Physics.IgnoreCollision(m_Controller.Transform.GetComponent(), m_Transform.GetComponent(), true); } m_Transform.parent = m_Camera.Transform; m_CurrentHoldAngle = m_Transform.localEulerAngles; m_IsGrabbed = true; } protected virtual void StopGrab() { m_IsGrabbed = false; m_FetchProgress = 1f; vp_FPCamera camera = m_Camera; camera.BobStepCallback = (vp_FPCamera.BobStepDelegate)Delegate.Remove(camera.BobStepCallback, new vp_FPCamera.BobStepDelegate(Footstep)); m_Player.SetWeapon.TryStart(m_LastWeaponEquipped); if (m_Transform.GetComponent() != null) { m_Transform.GetComponent().useGravity = m_DefaultGravity; m_Transform.GetComponent().drag = m_DefaultDrag; m_Transform.GetComponent().angularDrag = m_DefaultAngularDrag; } if (!m_Player.Dead.Active && vp_Utility.IsActive(m_Transform.gameObject) && m_Controller.Transform.GetComponent().enabled && m_Transform.GetComponent().enabled) { Physics.IgnoreCollision(m_Controller.Transform.GetComponent(), m_Transform.GetComponent(), false); } Vector3 eulerAngles = m_Transform.eulerAngles; m_Transform.parent = null; m_Transform.eulerAngles = eulerAngles; if (m_Transform.GetComponent() != null) { m_Transform.GetComponent().velocity = Vector3.zero; m_Transform.GetComponent().angularVelocity = Vector3.zero; } if (FPPlayer.InputGetButtonDown.Send("Attack")) { vp_AudioUtility.PlayRandomSound(m_Audio, ThrowSounds, SoundsPitch); if (m_Transform.GetComponent() != null) { m_Transform.GetComponent().AddForce(m_Player.Velocity.Get() + FPPlayer.CameraLookDirection.Get() * ThrowStrength, ForceMode.Impulse); if (AllowThrowRotation) { m_Transform.GetComponent().AddTorque(m_Camera.Transform.forward * ((!(UnityEngine.Random.value > 0.5f)) ? (-0.5f) : 0.5f) + m_Camera.Transform.right * ((!(UnityEngine.Random.value > 0.5f)) ? (-0.5f) : 0.5f), ForceMode.Impulse); } } } else { vp_AudioUtility.PlayRandomSound(m_Audio, DropSounds, SoundsPitch); if (m_Transform.GetComponent() != null) { m_Transform.GetComponent().AddForce(m_Player.Velocity.Get() + FPPlayer.CameraLookDirection.Get(), ForceMode.Impulse); } } if (m_InteractManager == null) { m_InteractManager = UnityEngine.Object.FindObjectOfType(typeof(vp_FPInteractManager)) as vp_FPInteractManager; } m_InteractManager.CrosshairTimeoutTimer = Time.time + 0.5f; vp_Timer.In(0.1f, delegate { m_Camera.RotationPitchLimit.y = m_OriginalPitchDownLimit; }); } public override void FinishInteraction() { if (m_IsGrabbed) { StopGrab(); } } protected virtual IEnumerator Fetch() { m_IsFetching = true; m_CurrentSwayForce = Vector3.zero; m_CurrentSwayTorque = Vector3.zero; m_CurrentFootstepForce = 0f; m_FetchProgress = 0f; duration = Vector3.Distance(m_Camera.Transform.position, m_Transform.position) * 0.5f; vp_Timer.In(duration + 1f, delegate { }, m_DisableAngleSwayTimer); while (m_FetchProgress < 1f) { m_FetchProgress += Time.deltaTime / duration; yield return new WaitForEndOfFrame(); } m_IsFetching = false; } protected virtual void OnCollisionEnter(Collision col) { if (m_IsGrabbed) { if (m_FetchProgress < 1f) { m_FetchProgress *= 1.2f; } vp_Timer.In(2f, delegate { }, m_DisableAngleSwayTimer); } } protected virtual void OnCollisionStay(Collision col) { if (!m_IsGrabbed || MaxCollisionCount == 0) { return; } if (col.collider != m_LastExternalCollider) { if (!col.collider.GetComponent() || col.collider.GetComponent().isKinematic) { m_LastExternalCollider = col.collider; m_CollisionCount = 1; } return; } RaycastHit hitInfo; if (Physics.Raycast(m_Transform.position, m_Camera.Transform.forward, out hitInfo, 1f) && hitInfo.collider == m_LastExternalCollider && m_FetchProgress >= 1f) { m_CollisionCount = MaxCollisionCount; } m_CollisionCount++; if (m_CollisionCount > MaxCollisionCount && (!Physics.Raycast(col.contacts[0].point + Vector3.up * 0.1f, -Vector3.up, out hitInfo, 0.2f) || !(hitInfo.collider == m_LastExternalCollider))) { m_CollisionCount = 0; m_FetchProgress = 1f; m_LastExternalCollider = null; if (m_Player != null) { m_Player.Interact.TryStart(); } } } protected virtual void OnCollisionExit() { m_CurrentHoldAngle = m_Transform.localEulerAngles; } protected virtual void Footstep() { m_CurrentFootstepForce += FootstepForce; } protected virtual void OnMessage_FallImpact(float impact) { m_CurrentSwayForce.y += impact * Kneeling; } protected virtual void OnStop_SetWeapon() { if (m_IsGrabbed && !m_IsFetching) { StartCoroutine("Fetch"); } } protected virtual bool CanStart_SetWeapon() { int num = (int)m_Player.SetWeapon.Argument; if (!m_IsGrabbed || num == 0) { return true; } return false; } }