Beispiel #1
0
    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));
    }
Beispiel #2
0
    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);
    }