IEnumerator TongueGrab(SCR_TongueTarget target) { grabbedOnTarget = true; // Stop targeting currentTarget = null; ConfigurableJoint targetJoint = target.GetComponentInChildren <ConfigurableJoint>(); // Temporarily turn player towards target to set up correct joint anchor position Quaternion playerStartingRotation = transform.rotation; Quaternion targetRotation = Quaternion.LookRotation(new Vector3(target.transform.position.x, tongueTargetAnchor.position.y, target.transform.position.z) - tongueTargetAnchor.position); transform.rotation = targetRotation; targetJoint.transform.rotation = targetRotation; // Connect player to target joint targetJoint.connectedBody = rb; // Set player's rotation back to where it was transform.rotation = playerStartingRotation; // get distance to grabbed object (this is used to determine if player is pulling on it) float maxTargetDistance = Vector3.Distance(tongueTargetAnchor.position, targetJoint.transform.position); // Disable normal movement movement.overrideRotation = true; movement.overrideJump = true; float timeObjectPulled = 0; while (holdingTongueButton && !grabTerminated && movement.touchingGround && target != null) { // Turn player towards target targetRotation = Quaternion.LookRotation(new Vector3(target.transform.position.x, tongueTargetAnchor.position.y, target.transform.position.z) - tongueTargetAnchor.position); transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 20 * Time.deltaTime); targetJoint.transform.rotation = targetRotation; if (Vector3.Distance(tongueTargetAnchor.position, targetJoint.transform.position) <= maxTargetDistance + 0.2f) { // Behavior when not pulling on target (player is closer than when it was grabbed) // Allow free movement by updating joint's target distance targetJoint.targetPosition = new Vector3(0, 0, maxTargetDistance - Vector3.Distance(tongueTargetAnchor.position, targetJoint.transform.position)); // Tell target that it isn't being pulled target.isBeingPulled = false; timeObjectPulled = 0; } else { // Behavior when pulling on target (player is farther away than when it was grabbed) // restrict player from moving any farther away targetJoint.targetPosition = new Vector3(0, 0, 0); target.isBeingPulled = true; // If pulling should trigger an event on target, trigger it timeObjectPulled += Time.deltaTime; if (timeObjectPulled >= target.timeToPull && target.eventOnPull) { target.eventTriggered = true; } } tongueCollider.position = target.transform.position; yield return(null); } if (target != null) { // Break connection to joint targetJoint.connectedBody = null; target.isBeingPulled = false; } grabbedOnTarget = false; // Start retracting tongue StartCoroutine(TongueRetract(tongueCollider.transform.position, 1)); // If player was forced to release grab: if (grabTerminated) { // Jerk player backwards rb.AddRelativeForce(0, 0, -6, ForceMode.Impulse); movement.overrideNormalMovement = true; // Delay enabling normal movement yield return(new WaitForSeconds(0.5f)); } // Enable normal movement movement.overrideJump = false; movement.overrideRotation = false; movement.overrideNormalMovement = false; grabTerminated = false; }
/* * This region contains the various interactions that can be performed once tongue has hit a target. * The type of interaction performed is determined by checking the targetType of the target object. * * FUNCTIONS IN THIS REGION: * Tongue Swing * Tongue Eat * Tongue Grab * Terminate Grab */ IEnumerator TongueSwing(SCR_TongueTarget target) { // Stop targeting currentTarget = null; tongueState = TongueState.Attached; ConfigurableJoint targetJoint = target.GetComponentInChildren <ConfigurableJoint>(); Rigidbody targetJointRb = targetJoint.GetComponent <Rigidbody>(); // Turn player towards target Quaternion targetRotation = Quaternion.LookRotation(target.transform.position - tongueTargetAnchor.position); transform.rotation = targetRotation; targetJoint.transform.rotation = targetRotation; // Tell target that player is swinging on it target.isBeingSwung = true; // Connect player to target joint targetJoint.connectedBody = rb; // Set target distance while swinging (promote to variable later) targetJoint.targetPosition = new Vector3(0, 0, Vector3.Distance(tongueTargetAnchor.position, targetJoint.transform.position) - variables.swingDistance); // Set initial swing velocity. Change this in future to convert linear velocity to angular //rb.velocity = rb.velocity.normalized * 7; rb.velocity = new Vector3(rb.velocity.x, 0, rb.velocity.z); // Deactivate normal movement movement.overrideNormalMovement = true; movement.overrideJump = true; movement.overrideRotation = true; movement.canMidairJump = false; rb.constraints &= ~RigidbodyConstraints.FreezeRotationX; rb.constraints &= ~RigidbodyConstraints.FreezeRotationY; rb.constraints &= ~RigidbodyConstraints.FreezeRotationZ; float swingTime = 0; while ((holdingTongueButton || swingTime < 0.2f) && target != null) { swingTime += Time.deltaTime; // Add some forward rotation at the beginning of swing if (target.startWithVelocity && swingTime < 0.1f) { targetJointRb.AddRelativeTorque(-400 * Time.deltaTime, 0, 0, ForceMode.Impulse); } tongueCollider.position = target.transform.position; yield return(null); } if (target != null) { // Break connection to joint targetJoint.connectedBody = null; // Tell target that player stopped swinging on it target.isBeingSwung = false; } // Set velocity on swing end. Change this in future to convert linear velocity to angular //rb.velocity = rb.velocity.normalized * targetJointRb.angularVelocity.magnitude * 2; movement.externalVelocity.velocity = rb.velocity; if (movement.externalVelocity.velocity.y < 1) { movement.externalVelocity.velocity = new Vector3(movement.externalVelocity.velocity.x, 1, movement.externalVelocity.velocity.z); } // Re-activate normal movement movement.overrideNormalMovement = false; movement.overrideJump = false; movement.overrideRotation = false; rb.constraints = RigidbodyConstraints.FreezeRotation; // Refresh midair jump after swinging movement.canMidairJump = true; StartCoroutine(TongueRetract(tongueCollider.transform.position, 1)); }