void OnCollisionEnter2D(Collision2D collision) { foreach (ContactPoint2D contact in collision.contacts) Debug.DrawRay (contact.point, contact.normal, Color.white); foreach (ContactPoint2D contact in collision.contacts) { if (collision.gameObject.GetComponent<Spring>() != null) { //must initiate from here to avoid some race condition collision.gameObject.GetComponent<Spring>().SpringCollide(gameObject); return; } if (collision.gameObject.GetComponent<Treadmill>() != null) return; if (collision.gameObject.GetComponent<Death>() != null) return; if (collision.gameObject.GetComponent<BounceAbsorption>() != null) absorptionFactor = collision.gameObject.GetComponent<BounceAbsorption>().absorptionFactor; else absorptionFactor = 0f; //more hacky code to get spiderball with moving platform working if (spiderball && (collision.collider.GetComponent<MovingPlatform>() != null || (collision.collider.transform.childCount > 0 && collision.collider.transform.GetChild(0).GetComponent<MovingPlatform>() != null))) { spiderOnMovingPlatform = true; platformParent = collision.collider.transform; } if (Mathf.Abs(Vector2.Angle(-Physics2D.gravity, contact.normal)) < groundedThresholdAngle) grounded = true; //Determine if ball should deform float velocityToCheck = boostThresholdVelocity; if(wasGrounded) velocityToCheck += groundedThresholdBonus; if(Mathf.Abs(Vector2.Angle(contact.normal,-Physics2D.gravity)) <= boostThresholdAngle && Mathf.Abs (Vector2.Dot (collision.relativeVelocity,contact.normal)) > velocityToCheck && dState == DeformationState.Normal) { dState = DeformationState.Deforming; Vector2 collisionNormal = contact.normal; Vector2 originalVelocity = -prevVelocity; float originalAngularVelocity = prevAngularVelocity; this.rigidbody2D.isKinematic = true;//Disable normal physics scaleObject = new GameObject("ScaleObject");//Create a gameObject to scale the ball along an axis Quaternion rot = Quaternion.LookRotation(collisionNormal);//Rotate the gameObject so that z+ is towards the collision normal scaleObject.transform.rotation = rot; scaleObject.transform.position = contact.point;//Center the scaleObject at the contact point so that the ball scales from one end //Debug.Log ("deforming"); //deforming onto a moving platform logic - in this case, the scale object should be child of platform //if (collision.gameObject.GetComponent<MovingPlatform>() != null) // scaleObject.transform.parent = collision.gameObject.transform; if ((onMovingPlatform && Vector2.Angle(contact.normal, -Physics2D.gravity) <= 5f) || spiderOnMovingPlatform) //odd angles cause screwiness { //Debug.Log ("reparenting scale object"); scaleObject.transform.parent = platformParent; } else if (collision.gameObject.transform.childCount > 0 && collision.gameObject.transform.GetChild(0).GetComponent<MovingPlatform>() != null && Vector2.Angle(contact.normal, -Physics2D.gravity) <= 2f) //super-hard-coding { //this is cheating a bit - relying on a straight collision with a horizontal platform //we probably won't have any exeptional cases in the game, though, so it should be fine..(?) scaleObject.transform.parent = collision.gameObject.transform; } //Parent the ball to the scaleObject transform.parent.parent = scaleObject.transform; originalScale = scaleObject.transform.localScale; deformTimer = 0.0f; originalMagnitude = originalVelocity.magnitude; //Calculate the reflection of originalVelocity about the collision normal to get the ball's new velocity vector Vector2 reflection = (2 * Vector2.Dot(originalVelocity,collisionNormal) * collisionNormal - originalVelocity); //Create a normalized vector representing the difference between the reflection and the original velocity //Vector2 bounceModifier = new Vector2(originalVelocity.x-reflection.x, -originalVelocity.y-reflection.y); //bounceModifier.Normalize(); //Set the rigidbody velocity to the reflection vector and modify it to make the collision inelastic //outVelocity = reflection + bounceModifier/bounciness; outVelocity = reflection * bounciness * (1f-absorptionFactor); //Decrease/Reverse the angular velocity based on whether the ball changed direction on the x axis float angleMod = 0.5f*Mathf.Sign(-originalVelocity.x)*Mathf.Sign (outVelocity.x); outAngularVelocity = originalAngularVelocity*angleMod; //Set the scaleChange based on collision force deformScaleChange = Mathf.Clamp(Mathf.Abs (Vector2.Dot (collision.relativeVelocity,contact.normal))*deformScaleFactor,0.2f, 0.8f); deformTime = Mathf.Clamp(Mathf.Abs (Vector2.Dot (collision.relativeVelocity, contact.normal)) * deformTimeFactor, 0.02f, 0.08f); return; } //else if (collision.gameObject.GetComponent<MovingPlatform>() != null) // transform.parent.parent = collision.gameObject.transform; //if we aren't deforming, just do normal parenting //else if (onMovingPlatform) // transform.parent.parent = platformParent; //if we aren't deforming, just do normal parenting } hasContact = true; }
public void ForceUndoDeformation() { if (dState == DeformationState.Deforming || dState == DeformationState.Reforming) { this.transform.parent.parent = null; GameObject.Destroy (scaleObject); this.transform.parent.localScale = Vector3.one; this.rigidbody2D.isKinematic = false; } dState = DeformationState.Normal; }
/* private void recordButtonDelay() { timeSinceJump += Time.fixedDeltaTime; timeSinceLeft += Time.fixedDeltaTime; timeSinceRight += Time.fixedDeltaTime; if(Input.GetButtonDown("Jump")) timeSinceJump = 0; if(Input.GetButtonDown("Left")) timeSinceLeft = 0; if(Input.GetButtonDown("Right")) timeSinceRight = 0; } */ void FixedUpdate() { if (grounded) wasGrounded = true; float h = Input.GetAxis ("Horizontal"); //locks the player if (playerLock == true) { h = 0; jumpTimer = 0; } if(dState == DeformationState.Normal) { ListenForJump (); if(h != 0) { //recordButtonDelay(); //translational movement if (!spiderball && !balloonActive) { Vector2 relativeRight = new Vector2(-Physics2D.gravity.y, Physics2D.gravity.x).normalized; if(Mathf.Sign(h) != Mathf.Sign (this.rigidbody2D.velocity.x)) { this.rigidbody2D.AddForce(relativeRight * h * moveForce * translationStoppingMultiplier); } else if (Mathf.Abs(this.rigidbody2D.velocity.x) < maxPlayerGeneratedSpeed) { this.rigidbody2D.AddForce(relativeRight * h * moveForce); } } //rotational movement if (Mathf.Sign (h) == Mathf.Sign (rigidbody2D.angularVelocity) && !hasContact) { this.rigidbody2D.AddTorque(-h * moveTorque * rotationStoppingMultiplier); } else if(Mathf.Abs (this.rigidbody2D.angularVelocity) < maxAngularVelocity && !hasContact) { this.rigidbody2D.AddTorque(-h * moveTorque); } } } else if(dState == DeformationState.Deforming) {// Scale ball down along z axis of scale object at deformSpeed until it's scale has changed more than the intended change //recordButtonDelay(); checkJumpBoosted(); if(deformTimer < deformTime) { deformTimer += Time.deltaTime; float compressScale = deformScaleChange * Mathf.Clamp (deformTimer / deformTime, 0.0f, 1.0f); //scaleObject.transform.localScale = new Vector3(scaleObject.transform.localScale.x, // scaleObject.transform.localScale.y, // 1.0f - compressScale); scaleObject.transform.localScale = new Vector3(originalScale.x, originalScale.y, originalScale.z * (1.0f - compressScale)); }else{ dState = DeformationState.Reforming; deformTimer = 0.0f; //baseScale = scaleObject.transform.localScale.z; baseScale = scaleObject.transform.localScale; } } else if(dState == DeformationState.Reforming) {//Scale ball up along z axis of scale object at deformSpeed until it's scale has changed more than the intended change //recordButtonDelay(); checkJumpBoosted(); if(deformTimer < deformTime) { deformTimer += Time.deltaTime; float compressScale = deformScaleChange * Mathf.Clamp (deformTimer / deformTime, 0.0f, 1.0f); //scaleObject.transform.localScale = new Vector3(scaleObject.transform.localScale.x, // scaleObject.transform.localScale.y, // baseScale + compressScale); scaleObject.transform.localScale = baseScale + new Vector3(0f, 0f, originalScale.z * compressScale); }else{ //Unparent from scaleObject and destroy scaleObject this.transform.parent.parent = null; GameObject.Destroy (scaleObject); this.transform.parent.localScale = Vector3.one; this.rigidbody2D.isKinematic = false;//Re-enabled rigidbody physics jumpLastTime = Time.timeSinceLevelLoad; if(jumpBoosted) { jumpBoosted = false; //timeSinceJump = boostForgiveness; //timeSinceLeft = boostForgiveness; //timeSinceRight = boostForgiveness; //Debug.Log ("Boosted bounce"); outVelocity = outVelocity.normalized * originalMagnitude * boostedBounciness * (1f-absorptionFactor); if(outVelocity.magnitude < (jumpForce/this.rigidbody2D.mass)*Time.fixedDeltaTime) { //Debug.Log("Back to original height"); outVelocity.Normalize(); outVelocity*=(jumpForce/this.rigidbody2D.mass)*Time.fixedDeltaTime; } } if(jumpDepressed) { jumpDepressed = false; outVelocity = outVelocity.normalized*originalMagnitude*depressedBounciness * (1f-absorptionFactor); } if (GetComponent<Spiderball>().enabled) { outVelocity = Vector2.zero; //super sticky! } this.rigidbody2D.angularVelocity = outAngularVelocity; this.rigidbody2D.velocity = outVelocity; dState = DeformationState.Reformed; GetComponent<PlayerSoundManager>().PlaySound("Bounce"); } } else if(dState == DeformationState.Reformed) {//Allow an extra tick before the ball is allowed to deform again dState = DeformationState.Normal; } if (!spiderball && spiderOnMovingPlatform) { spiderOnMovingPlatform = false; } if ((onMovingPlatform || spiderOnMovingPlatform) && transform.parent.parent == null) transform.parent.parent = platformParent; else if (!onMovingPlatform && !spiderOnMovingPlatform && platformParent != null) { transform.parent.parent = null; platformParent = null; } grounded = false; jumpTimer += Time.fixedDeltaTime; prevVelocity = this.rigidbody2D.velocity; prevAngularVelocity = this.rigidbody2D.angularVelocity; //Debug.Log (rigidbody2D.velocity.y); }