public void PreGetIn(Collision other, Vector3 speedOnEdge, Global.Del0 callback = null, Transform sender = null) { r.isKinematic = true; pr.isKinematic = true; Physics.IgnoreCollision(b, other.collider, true); tarCol = other.collider; coled = true; tarRigid = other.rigidbody; r.transform.rotation = rotationBeforHit; if (inbedingCour != null) { StopCoroutine(inbedingCour); } inbedingCour = StartCoroutine(GetIn(speedOnEdge, callback, sender)); }
IEnumerator GetIn(Vector3 speedOnEdge, Global.Del0 callback, Transform sender) { //UnityEditor.EditorApplication.isPaused = true; // 在开始就行 插入逻辑之前 //先将碰撞体 旋转量设置到 碰撞前的状态 //并通过 ComputePenetration 来计算出 碰撞体 和目标碰撞体恰好接触的位置 // Vector3 speedOnEdge = Vector3.Project(velBeforeHit, transform.right); Vector3 outdir; float outdist; bool penetrated = Physics.ComputePenetration(b, transform.position, transform.rotation, tarCol, tarCol.transform.position, tarCol.transform.rotation, out outdir, out outdist); if (!penetrated) { OnJointBreak(0); yield break; } float cos = Mathf.Abs(Vector3.Dot(outdir.normalized, speedOnEdge.normalized)); r.transform.position = r.transform.position - speedOnEdge.normalized * (outdist / cos); inbedding = true; // 开始进行 插入逻辑 yield return(new WaitForFixedUpdate()); r.isKinematic = false; pr.isKinematic = false; r.useGravity = false; pr.useGravity = false; Vector3 startVel = Vector3.ClampMagnitude(speedOnEdge / 10, 2.5f); r.velocity = pr.velocity = startVel; // 需要保持之前的 rotation 因为 // 结果物理引擎的 作用之后 rotation 可能会发生变化 //r.transform.rotation = rotationBeforHit; Vector3 inPoint = r.position; float dist = Vector3.Distance(inPoint, r.position); for (int i = 1; i < 4 && dist <= width / 2 && penetrated; i++) { dist = Vector3.Distance(inPoint, r.position); r.velocity -= startVel / 4; pr.velocity -= startVel / 4; yield return(new WaitForFixedUpdate()); penetrated = Physics.ComputePenetration(b, transform.position, transform.rotation, tarCol, tarCol.transform.position, tarCol.transform.rotation, out outdir, out outdist); } r.velocity = Vector3.zero; pr.velocity = Vector3.zero; pr.angularVelocity = Vector3.zero; if (!penetrated) { if (callback != null) { callback(); } OnJointBreak(0); //手动break; yield break; } // 当 插入之后 HingeJoint hinge = gameObject.AddComponent <HingeJoint>(); if (tarRigid) { hinge.connectedBody = tarRigid; } hinge.axis = Vector3.up; hinge.useLimits = true; JointLimits jointLimits = new JointLimits(); jointLimits.min = -5f; jointLimits.max = 5f; hinge.limits = jointLimits; hinge.breakForce = 5000f * dist / width; r.drag = 0; // 设置 父物体 pr.constraints = ~(RigidbodyConstraints.FreezeRotationY); pr.mass = 1; pr.drag = 0.5f; coled = false; if (callback != null) { callback(); } // 触发事件 //MessageManager.Invoke("OnStabOver",sender); }