using SHADE; using SHADE_Scripting; using SHADE_Scripting.Audio; using System; using System.Collections.Generic; using static PlayerController; using static Item; public class PickAndThrow : Script { public Vector3 throwForce = new Vector3(10.0f, 8.0f, 10.0f); public Vector3 cameraArmOffSet = new Vector3(0.0f, 0.25f, 0.0f); public GameObject item { get; set; } public float delayTimer = 1.0f; public float aimingLength = 1.5f; private float timer; private PlayerController pc; private Transform itemTransform; private RigidBody itemRidigBody; private Collider itemCollider; private Item itemScript; private Transform raccoonHoldLocation; public ThirdPersonCamera tpc { get; set; } private float lastXDir; private float lastZDir; private bool inRange = false; public bool throwItem = false; public Vector3 prevTargetOffSet { get; set; } [Tooltip("Lenght of ray")] public float rayDistance = 1; [Tooltip("Height of ray")] public float rayHeight = 0.1f; [NonSerialized] private TweenThread camArmTween; [NonSerialized] private TweenThreadVec3 offSetCamTween; [NonSerialized] private TweenThread FOVTween; public float lerpPickUpDuration = 0.75f; private float pickUptimer = 0.0f; private bool foodHoldReach = false; public float tweenAimDuration = 0.3f; private bool camTweenUpdate = false; public float aimingFOV = 15.0f; private TrajectoryRenderable trajComp; private Vector3 currThrowForce; private float currentItemMass; public uint trajMaxSteps = 50; public float trajTimeSteps = 0.03f; protected override void awake() { pc = GetScript(); if (!pc) Debug.LogError("PLAYER CONTROLLER EMPTY"); raccoonHoldLocation = GetComponentInChildren(); if (!raccoonHoldLocation) Debug.LogError("CHILD EMPTY"); tpc = GetScriptInChildren(); if (!tpc) Debug.LogError("TPC EMPTY"); AudioHandler.audioClipHandlers["SFXThrowLarge"] = Audio.CreateAudioClip("event:/Raccoon/raccoon_throw_large"); AudioHandler.audioClipHandlers["SFXThrowMedium"] = Audio.CreateAudioClip("event:/Raccoon/raccoon_throw_medium"); AudioHandler.audioClipHandlers["SFXThrowSmall"] = Audio.CreateAudioClip("event:/Raccoon/raccoon_throw_small"); timer = delayTimer; trajComp = GetComponentInChildren(); if (!trajComp) Debug.LogError("TrajectoryRenderable MISSING"); } protected override void start() { } protected override void update() { if (GameManager.Instance.GamePause || !GameManager.Instance.stealFoodPopUpDone) { return; } if (timer <= delayTimer) timer += Time.DeltaTimeF; CalculateDir(); CastRay(); if (camTweenUpdate) { pc.camArm.TargetOffset = offSetCamTween.GetValue(); pc.camArm.ArmLength = camArmTween.GetValue(); pc.cam.FOV = FOVTween.GetValue(); if (offSetCamTween.IsCompleted() && camArmTween.IsCompleted() && FOVTween.IsCompleted()) camTweenUpdate = false; } if (pc && itemRidigBody && itemTransform && itemCollider) { if (pc.holdItem) { TweenFood(); itemTransform.LocalRotation = pc.tranform.LocalRotation; itemRidigBody.ClearForces(); itemRidigBody.ClearTorque(); itemRidigBody.LinearVelocity = Vector3.Zero; itemRidigBody.AngularVelocity = Vector3.Zero; if (Input.GetMouseButtonDown(Input.MouseCode.LeftButton)) { pc.isAiming = true; TweenAimCamArm(true); } if (Input.GetMouseButtonUp(Input.MouseCode.LeftButton) && pc.isAiming) { if (itemScript.currCategory == ItemCategory.LIGHT) AudioHandler.audioClipHandlers["SFXThrowSmall"].Play(); else if (itemScript.currCategory == ItemCategory.MEDIUM) AudioHandler.audioClipHandlers["SFXThrowMedium"].Play(); else AudioHandler.audioClipHandlers["SFXThrowLarge"].Play(); itemRidigBody.IsGravityEnabled = true; itemCollider.GetCollisionShape(0).IsTrigger = false; pc.isAiming = false; TweenAimCamArm(false); pc.holdItem = false; foodHoldReach = false; inRange = false; throwItem = true; PlayThrowAnimation(); timer = 0.0f; } if (Input.GetMouseButtonDown(Input.MouseCode.RightButton) && !pc.isAiming) { pc.holdItem = false; foodHoldReach = false; inRange = false; itemRidigBody.IsGravityEnabled = true; itemCollider.GetCollisionShape(0).IsTrigger = false; ResetItemObject(); } if (Input.GetMouseButtonDown(Input.MouseCode.RightButton) && pc.isAiming) { pc.isAiming = false; pc.cam.FOV = Settings.cameraFOV; TweenAimCamArm(false); } } else if (!pc.holdItem) { itemRidigBody.IsGravityEnabled = true; itemCollider.GetCollisionShape(0).IsTrigger = false; } } if (timer > delayTimer && pc && !pc.holdItem && inRange && Input.GetMouseButtonDown(Input.MouseCode.LeftButton)) { if (pc.currentState == RaccoonStates.WALKING || pc.currentState == RaccoonStates.IDLE) { pc.holdItem = true; RetrieveItemComponets(); PlayPickUpAnimation(); } } if (pc.isAiming && itemScript) { if (itemScript.currCategory == ItemCategory.LIGHT) currThrowForce = new Vector3(throwForce.x * lastXDir, throwForce.y + (throwForce.y * GetPitchRatioRange()), throwForce.z * lastZDir) * 0.2f; else if (itemScript.currCategory == ItemCategory.MEDIUM) currThrowForce = new Vector3(throwForce.x * lastXDir, throwForce.y + (throwForce.y * GetPitchRatioRange()), throwForce.z * lastZDir) * 0.75f; else currThrowForce = new Vector3(throwForce.x * lastXDir, throwForce.y + (throwForce.y * GetPitchRatioRange()), throwForce.z * lastZDir); if (pc.holdItem && trajComp) trajComp.SimulateTrajectory(item.EntityId, currentItemMass, currThrowForce, trajTimeSteps, trajMaxSteps); } } protected override void fixedUpdate() { if (GameManager.Instance.GamePause || !GameManager.Instance.stealFoodPopUpDone) { return; } if (throwItem && itemRidigBody && pc) { itemRidigBody.AddForce(currThrowForce); itemRidigBody.LinearVelocity += pc.rb.LinearVelocity; throwItem = false; ResetItemObject(); } } public void SetItemGravityBack() { if(itemRidigBody) itemRidigBody.IsGravityEnabled = true; if(itemCollider) itemCollider.GetCollisionShape(0).IsTrigger = false; } public void ResetItemObject() { itemRidigBody = null; itemTransform = null; itemCollider = null; itemScript = null; item = new GameObject(); } private void RetrieveItemComponets() { //get the transform of the given item if (item.GetScript() && !itemTransform && !itemRidigBody) { itemRidigBody = item.GetComponent(); if (!itemRidigBody) Debug.Log("Item rb EMPTY"); else { currentItemMass = itemRidigBody.Mass; itemRidigBody.IsGravityEnabled = false; } itemTransform = item.GetComponent(); if (!itemTransform) Debug.Log("Item transform EMPTY"); else { itemTransform.LocalEulerAngles = Vector3.Zero; } itemCollider = item.GetComponent(); if (!itemCollider) Debug.Log("Item collider EMPTY"); else { itemCollider.GetCollisionShape(0).IsTrigger = true; } itemScript = item.GetScript(); if(!itemScript) Debug.Log("Item script EMPTY"); } } private void CalculateDir() { if (pc && pc.cam) { Vector3 camerAixs = pc.cam.GetForward(); camerAixs.y = 0; camerAixs.Normalise(); lastXDir = camerAixs.x; lastZDir = camerAixs.z; } } private void CastRay() { if (pc != null) { Vector3 dirNor = pc.tranform.Forward; Vector3 playerRayPos = pc.tranform.GlobalPosition; playerRayPos.y += rayHeight; dirNor.Normalise(); List rayList1 = Physics.Raycast(new Ray(playerRayPos, Vector3.RotateY(dirNor, SHADE.Math.DegreesToRadians(25.0f))), rayDistance, false, (ushort)65535); List rayList2 = Physics.Raycast(new Ray(playerRayPos, Vector3.RotateY(dirNor, SHADE.Math.DegreesToRadians(-25.0f))), rayDistance, false, (ushort)65535); List rayList3 = Physics.Raycast(new Ray(playerRayPos, Vector3.RotateY(dirNor, SHADE.Math.DegreesToRadians(12.5f))), rayDistance, false, (ushort)65535); List rayList4 = Physics.Raycast(new Ray(playerRayPos, Vector3.RotateY(dirNor, SHADE.Math.DegreesToRadians(-12.5f))), rayDistance, false, (ushort)65535); List rayList5 = Physics.Raycast(new Ray(playerRayPos, dirNor), rayDistance , false, (ushort)65535); if (rayList1.Count > 0) { RaycastHit ray1 = rayList1[0]; inRange = CheckForItem(ray1); return; } else if (rayList2.Count > 0) { RaycastHit ray2 = rayList2[0]; inRange = CheckForItem(ray2); return; } else if (rayList3.Count > 0) { RaycastHit ray3 = rayList3[0]; inRange = CheckForItem(ray3); return; } else if (rayList4.Count > 0) { RaycastHit ray4 = rayList4[0]; inRange = CheckForItem(ray4); return; } else if (rayList5.Count > 0) { RaycastHit ray5 = rayList5[0]; inRange = CheckForItem(ray5); return; } else { inRange = false; } } } private bool CheckForItem(RaycastHit ray) { if (ray.Hit) { if (ray.Other.Value.GetScript() && !pc.holdItem) { item = ray.Other.Value; return true; } else return false; } return false; } private float GetPitchRatioRange() { return (pc.camArm.Pitch - tpc.pitchUpperClamp) / (tpc.pitchLowerClamp - tpc.pitchUpperClamp); } private void PlayPickUpAnimation() { if (PlayerAnimations.Instance) { PlayerAnimations.Instance.playerAnimator.PlayOneShot(PlayerAnimations.Instance.playerPickUpClip); PlayerAnimations.Instance.playerAnimator.OnClipFinished.RegisterAction((x) => { if (x.FinishedClip == PlayerAnimations.Instance.playerPickUpClip) { if (pc.isMoveKeyPress) PlayerAnimations.Instance.playerAnimator.Play(PlayerAnimations.Instance.playerCarryWalkClip); else PlayerAnimations.Instance.playerAnimator.Play(PlayerAnimations.Instance.playerCarryIdleClip); } }); PlayerAnimations.Instance.BagAnimator.PlayOneShot(PlayerAnimations.Instance.playerPickUpClip); PlayerAnimations.Instance.BagAnimator.OnClipFinished.RegisterAction((x) => { if (x.FinishedClip == PlayerAnimations.Instance.playerPickUpClip) { if (pc.isMoveKeyPress) PlayerAnimations.Instance.BagAnimator.Play(PlayerAnimations.Instance.playerCarryWalkClip); else PlayerAnimations.Instance.BagAnimator.Play(PlayerAnimations.Instance.playerCarryIdleClip); } }); PlayerAnimations.Instance.silhoPlayerAnimator.PlayOneShot(PlayerAnimations.Instance.playerPickUpClip); PlayerAnimations.Instance.silhoPlayerAnimator.OnClipFinished.RegisterAction((x) => { if (x.FinishedClip == PlayerAnimations.Instance.playerPickUpClip) { if (pc.isMoveKeyPress) PlayerAnimations.Instance.silhoPlayerAnimator.Play(PlayerAnimations.Instance.playerCarryWalkClip); else PlayerAnimations.Instance.silhoPlayerAnimator.Play(PlayerAnimations.Instance.playerCarryIdleClip); } }); PlayerAnimations.Instance.silhoBagAnimator.PlayOneShot(PlayerAnimations.Instance.playerPickUpClip); PlayerAnimations.Instance.silhoBagAnimator.OnClipFinished.RegisterAction((x) => { if (x.FinishedClip == PlayerAnimations.Instance.playerPickUpClip) { if (pc.isMoveKeyPress) PlayerAnimations.Instance.silhoBagAnimator.Play(PlayerAnimations.Instance.playerCarryWalkClip); else PlayerAnimations.Instance.silhoBagAnimator.Play(PlayerAnimations.Instance.playerCarryIdleClip); } }); } } private void PlayThrowAnimation() { if (PlayerAnimations.Instance) { PlayerAnimations.Instance.playerAnimator.PlayOneShot(PlayerAnimations.Instance.playerThrowClip); PlayerAnimations.Instance.playerAnimator.OnClipFinished.RegisterAction((x) => { if (x.FinishedClip == PlayerAnimations.Instance.playerThrowClip) { if (pc.isMoveKeyPress) PlayerAnimations.Instance.playerAnimator.Play(PlayerAnimations.Instance.playerWalkClip); else PlayerAnimations.Instance.playerAnimator.Play(PlayerAnimations.Instance.playerIdleClip); } }); PlayerAnimations.Instance.BagAnimator.PlayOneShot(PlayerAnimations.Instance.playerPickUpClip); PlayerAnimations.Instance.BagAnimator.OnClipFinished.RegisterAction((x) => { if (x.FinishedClip == PlayerAnimations.Instance.playerThrowClip) { if (pc.isMoveKeyPress) PlayerAnimations.Instance.BagAnimator.Play(PlayerAnimations.Instance.playerWalkClip); else PlayerAnimations.Instance.BagAnimator.Play(PlayerAnimations.Instance.playerIdleClip); } }); PlayerAnimations.Instance.silhoPlayerAnimator.PlayOneShot(PlayerAnimations.Instance.playerPickUpClip); PlayerAnimations.Instance.silhoPlayerAnimator.OnClipFinished.RegisterAction((x) => { if (x.FinishedClip == PlayerAnimations.Instance.playerThrowClip) { if (pc.isMoveKeyPress) PlayerAnimations.Instance.silhoPlayerAnimator.Play(PlayerAnimations.Instance.playerWalkClip); else PlayerAnimations.Instance.silhoPlayerAnimator.Play(PlayerAnimations.Instance.playerIdleClip); } }); PlayerAnimations.Instance.silhoBagAnimator.PlayOneShot(PlayerAnimations.Instance.playerPickUpClip); PlayerAnimations.Instance.silhoBagAnimator.OnClipFinished.RegisterAction((x) => { if (x.FinishedClip == PlayerAnimations.Instance.playerThrowClip) { if (pc.isMoveKeyPress) PlayerAnimations.Instance.silhoBagAnimator.Play(PlayerAnimations.Instance.playerWalkClip); else PlayerAnimations.Instance.silhoBagAnimator.Play(PlayerAnimations.Instance.playerIdleClip); } }); } } private void TweenFood() { if (!foodHoldReach) { pickUptimer += Time.DeltaTimeF; itemTransform.LocalPosition = Vector3.Lerp(itemTransform.LocalPosition, raccoonHoldLocation.GlobalPosition, pickUptimer / lerpPickUpDuration); } else itemTransform.LocalPosition = raccoonHoldLocation.GlobalPosition; if (pickUptimer >= lerpPickUpDuration) { foodHoldReach = true; pickUptimer = 0.0f; } } public void TweenAimCamArm(bool aim) { if (aim) { offSetCamTween = TweenManager.CreateTweenThreadVec3(tweenAimDuration, pc.camArm.TargetOffset, cameraArmOffSet, EASING_METHOD.EASE_IN_SINE); camArmTween = TweenManager.CreateTweenThread(tweenAimDuration, pc.camArm.ArmLength, aimingLength, EASING_METHOD.EASE_IN_SINE); FOVTween = TweenManager.CreateTweenThread(tweenAimDuration, pc.cam.FOV, Settings.cameraFOV + aimingFOV, EASING_METHOD.EASE_IN_SINE); } else { offSetCamTween = TweenManager.CreateTweenThreadVec3(tweenAimDuration, pc.camArm.TargetOffset, prevTargetOffSet, EASING_METHOD.EASE_IN_SINE); camArmTween = TweenManager.CreateTweenThread(tweenAimDuration, pc.camArm.ArmLength, tpc.armLength, EASING_METHOD.EASE_IN_SINE); FOVTween = TweenManager.CreateTweenThread(tweenAimDuration, pc.cam.FOV, Settings.cameraFOV , EASING_METHOD.EASE_IN_SINE); } camTweenUpdate = true; } }