protected override void Awake() { base.Awake(); // set to active by default IsActive = true; // grab triggers List <Collider> tmpTriggers = new List <Collider>(); List <Collider> tmpColliders = new List <Collider>(); Collider[] colliders = GetComponents <Collider>(); for (int i = 0; i < colliders.Length; i++) { if (colliders[i].isTrigger) { tmpTriggers.Add(colliders[i]); } else { tmpColliders.Add(colliders[i]); } } this.colliders = tmpColliders.ToArray(); this.impalePoints = tmpTriggers.ToArray(); // init impale state as none colliderMap = new List <Collider>(); impaleState = ImpaleState.None; isColliderTrigger = false; lastVelocity = Vector3.zero; calculatedAngle = Mathf.Cos(Mathf.Deg2Rad * angleOfImpalement); }
// reset and set active. protected void Reset() { // reset state info IsActive = true; impaleState = ImpaleState.None; rigidbody.isKinematic = true; currentLerpTime = 0; // set last velocity back lastVelocity = transform.right * currSpeed; rigidbody.velocity = lastVelocity; currSpeed = 0; }
// reset and set active. public void Reset() { //if (impaleState != ImpaleState.Impaling) //{ // reset state info IsActive = true; impaleState = ImpaleState.None; parentRigidBody.isKinematic = true; currentLerpTime = 0; // set last velocity back lastVelocity = parentModel.right * currSpeed; parentRigidBody.velocity = lastVelocity; currSpeed = 0; //} }
// Properties /// <summary> /// Get or set the distance you want this object to sink into after contact. /// </summary> //public float ImpaleDistance { get; set; } void Awake() { IsActive = true; // WAS TRUE! collider = GetComponent <Collider>(); // set trigger collider.isTrigger = true; // set kinematic //rigidbody.isKinematic = true; // dont use gravity //rigidbody.useGravity = false; // Error check to see if parent is null if ((parentModel = transform.parent) == null) { Debug.LogError("ERROR: No required parent set for " + name); } // Get parent rigidbody and error if its not there. if ((parentRigidBody = parentModel.GetComponent <Rigidbody>()) == null) { Debug.LogError("ERROR: " + transform.parent.name + " doesnt have a rigidbody!"); } // init collider stack colliderStack = new Stack <Collider>(); colliderQueue = new Queue <Collider>(); // ignore collision with parent //Physics.IgnoreCollision(GetComponent<Collider>(), parentModel.GetComponent<Collider>()); // Default to no impale state impaleState = ImpaleState.None; // set layer to 9 gameObject.layer = 9; }
void FixedUpdate() { // react based on state switch (impaleState) { case ImpaleState.None: // store last velocity lastVelocity = rigidbody.velocity; //Debug.Log(lastVelocity); break; case ImpaleState.Impaling: // thanks to: https://chicounity3d.wordpress.com/2014/05/23/how-to-lerp-like-a-pro/ //increment timer once per frame currentLerpTime += Time.fixedDeltaTime; if (currentLerpTime > lerpTime) { currentLerpTime = lerpTime; } // below float value is dependent on the density of the penetrating object. currSpeed = Mathf.Lerp(lastVelocity.magnitude, 0, (currentLerpTime / lerpTime) * collidedMass); /*if (transform.parent == null) * { * GetComponent<Renderer>().material.SetColor("_Color", Color.black); * name = "F**K"; * Debug.Break(); * } * else*/ //transform.parent.InverseTransformDirection( if (transform.parent != null) { transform.localPosition += (transform.parent.InverseTransformDirection(transform.right) * currSpeed) * Time.fixedDeltaTime; } // go until embedded if (currSpeed <= .05f) { // reset velocities rigidbody.velocity = Vector3.zero; lastVelocity = Vector3.zero; // reset lerp currentLerpTime = 0; // call after impale event AfterImpale(LastCollision); // set to embedded impaleState = ImpaleState.Embedded; // Turn off triggers ToggleTriggers(false); // ignore collision w/ CURRENTLY collided for (int z = 0; z < colliderMap.Count; z++) { for (int i = 0; i < colliders.Length; i++) { Physics.IgnoreCollision(colliderMap[z], colliders[i]); } } } break; case ImpaleState.Embedded: break; } }
void OnTriggerEnter(Collider collider) { if (IsActive || ImpaleState == ImpaleState.Impaling) { // if velocity is negative direction of forward, return // if speed is too little to impale, return. if (!PointOfCollisionCheck(collider)) { return; } if (!colliderMap.Contains(collider)) { /* * if (collider.GetComponent<BodyPart>() != null) * { * UnityEditor.Selection.activeGameObject = gameObject; * UnityEditor.SceneView.lastActiveSceneView.FrameSelected(true); * Debug.Break(); * } */ // set parent //Debug.Log("IN: " + collider.name); transform.parent = collider.transform; // stop checking for OnCollisionEnter IsActive = false; // go kinematic and stop detecting collision rigidbody.isKinematic = true; // set impale state to currently impaling impaleState = ImpaleState.Impaling; // see if collided object has a rigibody attachement. Rigidbody collidedRigidbody; if ((collidedRigidbody = collider.GetComponent <Rigidbody>()) != null) { collidedMass = collidedRigidbody.mass; } else { collidedMass = 50f; } if (!isColliderTrigger) { ToggleTriggers(true); } // call on impale event //Debug.DrawLine(transform.position, transform.position + lastVelocity, Color.red); //Debug.DrawLine(transform.position, transform.right * 5, Color.blue); //Debug.DrawLine(transform.position, collider.transform.position - transform.position, Color.green); OnImpale(collider); //Debug.Break(); } colliderMap.Add(collider); } }
// after traveling for speicifed distance from contact point // stop /* * void OnCollisionEnter(Collision collision) * { * * if (IsActive && * collision.collider.GetComponent<ImpalePoint>() == null && * collision.collider.GetComponent<Spear>() == null) * { * // TO-DO: slow speed? dont let it attach!! * // if velocity is negative direction of forward, return * // if speed is too little to impale, return. * //if (Vector3.Dot(projection, parentModel.right) < 0 || * // (projection = Vector3.Project(parentRigidBody.velocity, parentModel.TransformDirection(parentModel.right))).sqrMagnitude < 10) * * if (Vector3.Dot(lastVelocity, parentModel.right) < minVelocity) * { * return; * } * Debug.Log(parentModel.name + " collided with " + collision.collider.name); * * // ignore collision w/ collided * Physics.IgnoreCollision(collision.collider, GetComponent<Collider>()); * Physics.IgnoreCollision(collision.collider, parentModel.GetComponent<Collider>()); * * // set parent * parentModel.parent = collision.transform; * * // stop checking for OnCollisionEnter * IsActive = false; * //Debug.Log(transform.parent.name + " is active: " + IsActive); * // go kinematic and stop detecting collision * rigidbody.isKinematic = true; * parentRigidBody.isKinematic = true; * * //rigidbody.detectCollisions = false; * //parentRigidBody.detectCollisions = false; * * // set impale state to currently impaling * impaleState = ImpaleState.Impaling; * * // set final collision * finalCollision = collision; * * // see if collided object has a rigibody attachement. * Rigidbody collidedRigidbody; * if ((collidedRigidbody = finalCollision.collider.GetComponent<Rigidbody>()) != null) * collidedMass = collidedRigidbody.mass; * else * collidedMass = 50f; * * // call on impale event * if (OnImpale != null) * OnImpale(finalCollision); * } * }*/ void OnTriggerEnter(Collider collider) { Debug.Log("CALLED"); if (IsActive || ImpaleState == ImpaleState.Impaling) { // TO-DO: slow speed? dont let it attach!! // if velocity is negative direction of forward, return // if speed is too little to impale, return. //if (Vector3.Dot(projection, parentModel.right) < 0 || // (projection = Vector3.Project(parentRigidBody.velocity, parentModel.TransformDirection(parentModel.right))).sqrMagnitude < 10) if (Vector3.Dot(lastVelocity, parentModel.right) < minVelocity) { return; } /* * Collider[] parentColliders = parentModel.GetComponents<Collider>(); * if (finalCollision != null) * { * Collider[] finalColliders = finalCollision.GetComponents<Collider>(); * for (int i = 0; i < parentColliders.Length; i++) * if (!parentColliders[i].isTrigger) * for(int z = 0; z < finalColliders.Length; z++) * Physics.IgnoreCollision(finalColliders[i], parentColliders[i], false); * } */ // ignore collision w/ collided //Physics.IgnoreCollision(collider, GetComponent<Collider>()); Collider[] parentColliders = parentModel.GetComponents <Collider>(); for (int i = 0; i < parentColliders.Length; i++) { if (!parentColliders[i].isTrigger) { //colliderStack.Push(collider); colliderQueue.Enqueue(collider); Physics.IgnoreCollision(collider, parentColliders[i]); } } // set parent parentModel.parent = collider.transform; // stop checking for OnCollisionEnter IsActive = false; //Debug.Log(transform.parent.name + " is active: " + IsActive); // go kinematic and stop detecting collision //rigidbody.isKinematic = true; parentRigidBody.isKinematic = true; //rigidbody.detectCollisions = false; //parentRigidBody.detectCollisions = false; // set impale state to currently impaling impaleState = ImpaleState.Impaling; // set final collision //finalCollision = collider; // see if collided object has a rigibody attachement. Rigidbody collidedRigidbody; if ((collidedRigidbody = LastCollision.GetComponent <Rigidbody>()) != null) { collidedMass = collidedRigidbody.mass; } else { collidedMass = 50f; } // call on impale event if (OnImpale != null) { OnImpale(LastCollision); } } }
void FixedUpdate() { // react based on state switch (impaleState) { case ImpaleState.None: lastVelocity = parentRigidBody.velocity; //projection = Vector3.Project(parentRigidBody.velocity, parentModel.TransformDirection(parentModel.right)); //Debug.Log(Vector3.Dot(parentRigidBody.velocity, parentModel.right)); //Debug.Log(Vector2.Dot(projection.normalized, Vector3.forward)); //Debug.DrawLine(parentModel.position, parentModel.position + projection, Color.black); //Debug.DrawLine(parentModel.position, parentModel.position + parentModel.right * 10, Color.red); break; case ImpaleState.Impaling: // thanks to: https://chicounity3d.wordpress.com/2014/05/23/how-to-lerp-like-a-pro/ //increment timer once per frame currentLerpTime += Time.fixedDeltaTime; if (currentLerpTime > lerpTime) { currentLerpTime = lerpTime; } // below float value is dependent on the density of the penetrating object. currSpeed = Mathf.Lerp(lastVelocity.magnitude, 0, (currentLerpTime / lerpTime) * collidedMass); // newPosition = lerp(contactpoint, contactpoint + (lastVelocity.forward * desiredDistance), currentLerpTime / lerpTime // if position = endPoint // end action. //parentRigidBody.MovePosition(Vector3.zero); //parentRigidBody.mov //parentRigidBody.position += (parentRigidBody.transform.right * currSpeed) * Time.fixedDeltaTime; // below works //parentModel.localPosition += (parentRigidBody.transform.right * currSpeed) * Time.fixedDeltaTime; parentModel.localPosition += (parentModel.parent.InverseTransformDirection(parentModel.right) * currSpeed) * Time.fixedDeltaTime; //Debug.Log(currSpeed + " : " + parentRigidBody.position); // go until embedded if (currSpeed <= .05f) { // reset velocities parentRigidBody.velocity = Vector3.zero; lastVelocity = Vector3.zero; // reset lerp currentLerpTime = 0; // run backwards into enemies at full speed to kill them! //parentRigidBody.detectCollisions = true; // call after impale event if (AfterImpale != null) { AfterImpale(LastCollision); } // set to embedded //Debug.Log(transform.parent.name + " is impaled."); impaleState = ImpaleState.Embedded; } break; case ImpaleState.Embedded: break; } }