【问题标题】:Unity HingeJoint have weird behavior in autogeneration problem with rotation?Unity HingeJoint 在旋转的自动生成问题中有奇怪的行为?
【发布时间】:2021-04-22 18:14:41
【问题描述】:

我是一个初学者,我在空中有一个立方体,上面附有元素,没有像节点一样旋转,我有几个立方体用于模拟带有提示关节的绳索。我在一个立方体上单击右键并从方向玩家到节点产生绳索,并将最后一个元素绳索与玩家连接,这很好。当玩家没有速度并阻止刚体元素的旋转时。但有时如果我被跳跃并尝试在移动元素中生成绳索,绳索会出现奇怪的旋转,有时会出现立方体旋转块。我怎么能使用旋转绳,或者我不知道,有什么建议吗?谢谢。

PS:对不起我的英语不好。

private void CheckMouseActivity()
{
        float x = Input.mousePosition.x;
        float y = Input.mousePosition.y;
        float z = Input.mousePosition.z;

        Vector3 point = new Vector3(x, y, z);

        if (Input.GetMouseButton(1) && !m_ropeIsActive)
        {
            m_aiming = true;

            Ray ray = Camera.main.ScreenPointToRay(point);
            GenerateRope(ray);
        }

        if (Input.GetButton("Jump") && m_ropeIsActive)
        {
            for (int i = 0; i < rope.Count; i++)
            {
                DestroyImmediate(rope[i]);
                //rope[i].active = false;
            }

            playerRb.AddForce(new Vector3(6f, 6f), ForceMode.Impulse); 
            m_ropeIsActive = false;
            m_hooked = false;
        }
        
        // check bounds in playing area
}

void GenerateRope(Ray ray)
{
        layerMask = ~layerMask;

        if (Physics.Raycast(ray, out RaycastHit hit, 10f, layerMask))
        {
            if (hit.transform.CompareTag("node") && !m_ropeIsActive)
            {
                activeHook = hit.transform.gameObject;
                m_CanMove = false;
                Vector3 hitPos = hit.transform.position;
                Transform hook = hit.transform.GetChild(0);
                Vector3 hookInverseNormal = hook.up * -1f;

                Rigidbody previosRb = hit.transform.GetChild(0).GetComponent<Rigidbody>();//hook

                Vector3 distanceFromNode = transform.position - hit.point;
                int distance = (int)distanceFromNode.magnitude;

                BoxCollider link = linkPrefub.GetComponent<BoxCollider>();
                int length = (int)((distance - 1f) / sizeCell); 
                float ropeLength = sizeCell * 10f;

                if (length < minLength) 
                {
                    length = minLength;
                }
                //else if (length > ropeLength)
                //{
                //    length = (int)ropeLength * 2;
                //}

                for (int i = 1; i < length - 1; i++) 
                {
                    var t = sizeCell * i; //позиция под новый куб
                    Vector3 dirToPlayer = transform.position - hit.transform.position;
                    Vector3 newPos = dirToPlayer.normalized * t;
                    GameObject toInstantiate = Instantiate(linkPrefub, hit.transform.position + new 
Vector3(newPos.x, -t, default), Quaternion.identity, hit.transform);
                    rope.Add(toInstantiate);
                    HingeJoint joint = toInstantiate.GetComponent<HingeJoint>();

                    if (i == 1)
                    {
                        joint.autoConfigureConnectedAnchor = true;
                    }
                    else
                    {
                        joint.autoConfigureConnectedAnchor = false;
                        joint.connectedAnchor = new Vector3(0f, -0.4f);
                    }

                    joint.enableCollision = false;
                    joint.connectedBody = previosRb;

                    previosRb = toInstantiate.GetComponent<Rigidbody>();
                }

                m_ropeIsActive = true;
                m_hooked = true;
                m_CanMove = true;
            }
        }
        else
        {
            // what to do if not did hit
        }
}

void FixedUpdate()
{
    if (m_ropeIsActive)
    {
            if (m_hooked && activeHook)
            {
                //TODO крутить нод хука чтобы выглядило красиво
            }

            if (rope.Count != 0)
            {
                Rigidbody lastElementRope = rope[rope.Count - 1].GetComponent<Rigidbody>();

                if (lastElementRope)
                {
                    HingeJoint joint = GetComponent<HingeJoint>();
                    //joint.autoConfigureConnectedAnchor = false;
                    //joint.connectedBody = lastElementRope;
                    //joint.anchor = Vector2.zero;
                    //joint.connectedAnchor = new Vector2(0f, -0.4f);
                }
            }
        }
}

可以把来自github的代码和项目放在一起。

我在这里进行了实验,试图实现服从,但我确信这是错误的方向,我只是不知道如何使用旋转,我很困惑

                        if (i == 1)
                        {
                            joint.autoConfigureConnectedAnchor = true;
                        }
                        else
                        {
                            joint.autoConfigureConnectedAnchor = false;
                            joint.connectedAnchor = new Vector3(0f, -0.4f);
                        }

GitHub https://github.com/Heges/first-2d-platformer/tree/main/2D-platformer

【问题讨论】:

    标签: c# unity3d unity-editor


    【解决方案1】:

    我不确定,但是

     void GenerateRope(Ray ray)
    {
        layerMask = ~layerMask;
        if (Physics.Raycast(ray, out RaycastHit hit, 10f, layerMask))
        {
            Vector3 direction =  transform.position - hit.transform.position;
    
            if (direction.magnitude <= sizeOfRope)
            {
                if (hit.transform.CompareTag("node") && !m_ropeIsActive)
                {
                    activeHook = hit.transform.gameObject;
                    m_CanMove = false;
                    Transform hook = hit.transform.GetChild(0);
                    Vector3 hookInverseNormal = hook.up * -1f;
    
                    float dot = Vector3.Dot(hookInverseNormal, ray.direction.normalized);
                    Debug.Log(dot);
                    Quaternion rotation = hit.transform.rotation;
    
                    Rigidbody previosRb = hit.transform.GetChild(0).GetComponent<Rigidbody>();//hook
    
                    Vector3 distanceFromNode = transform.position - hit.point;
                    int distance = (int)distanceFromNode.magnitude;
    
                    BoxCollider link = linkPrefub.GetComponent<BoxCollider>();//(int)link.size.magnitude / 2;
                    int length = (int)((distance - 1f) / sizeCell); //size of cell rope -1f размер игрока
                    float ropeLength = sizeCell * sizeOfRope;
                    if (length < minLength)
                    {
                        length = minLength;
                    }
                    //else if (length > ropeLength) // и слишком длинных
                    //{
                    //    length = (int)ropeLength * 2;
                    //}
                    for (int i = 1; i < length - 1; i++)
                    {
                        var t = sizeCell * i; //позиция под новый куб
                        Vector3 dirToPlayer = transform.position - hit.transform.position;//направление до игрока,
                        Vector3 newPos = dirToPlayer.normalized * t;
                        GameObject toInstantiate = Instantiate(linkPrefub, hit.transform.position + new Vector3(newPos.x, -t, default), Quaternion.identity, hit.transform);
                        rope.Add(toInstantiate);
                        HingeJoint joint = toInstantiate.GetComponent<HingeJoint>();
                        joint.anchor = Vector2.up;
                        joint.connectedAnchor = new Vector2(0f, -0.4f);
                        joint.connectedBody = previosRb;
                        previosRb = toInstantiate.GetComponent<Rigidbody>();
                    }
                    m_ropeIsActive = true;
                    m_hooked = true;
                }
            }
            else
            {
                //what to do if not did hit
            }
        }
    

    它仍然不能很好地工作,但是我的问题已经解决了。 限制了可以召唤绳索的距离,事实证明,当自动生成绳索的某些部分时,Hint Joint 默认为其值,例如 AutoAnchor。在创建过程中禁用它们,似乎一切正常

    HingeJoint joint = toInstantiate.GetComponent<HingeJoint>();
                        joint.anchor = Vector2.up;
                        joint.connectedAnchor = new Vector2(0f, -0.4f);
                        joint.connectedBody = previosRb;
                        previosRb = toInstantiate.GetComponent<Rigidbody>();
    

    【讨论】:

      猜你喜欢
      • 2012-09-13
      • 1970-01-01
      • 1970-01-01
      • 2022-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-23
      相关资源
      最近更新 更多