为什么会出现这种奇怪的抖动?

时间:2014-09-01 15:06:10

标签: c# unity3d position game-physics rigid-bodies

我有一个场景,玩家可以拾取和放下物体,以及移动和环顾四周。

所有玩家对象都是空游戏对象“MainCharacter”的孩子:

MainCharacter >
    Capsule (With RigidBody and PlayerMoveScript) >
        PlayerBase (empty - used for checking if grounded)
        MainCamera >
            Hands(With PickUpDrop script)

我拿起Lerps到我的手位置的物体,然而在我的胶囊碰撞任何墙壁之后有一个奇怪的抖动,我无法解决如何修复!!

继承人.exe:GameTest 继承数据文件夹:Data

以下是脚本:

选择和删除脚本:

public bool handsFull = false;

    public float distanceMax = 20f;

    public Transform handPosition;

    public LayerMask canPickUp;

    public GameObject taggedGameObject;

    public bool colliderTriggered;

    public bool bounds;

    public PickedUpObject pickedUpScript;

    public Rigidbody player;

    // Use this for initialization
    void Start () {

        print(FindClosestPickup().name);
        handPosition = transform;
        pickedUpScript = null;

    }

    // Update is called once per frame
    void Update () {


                if (Input.GetKeyDown (KeyCode.E) && !bounds) {
                        if (Physics.CheckSphere (handPosition.position, 2f, canPickUp)) {

                                if (handsFull) {
                                        Drop ();
                                }

                                if (!handsFull) {
                                        PickedUp ();
                                }

                handsFull = !handsFull;

                        }
                }

                if (handsFull) {
                        RotateMovePickedUpObject();
                }   


        }



    private void PickedUp(){

        //Closest object to top of list
        taggedGameObject = (GameObject)FindClosestPickup();

        taggedGameObject.collider.isTrigger = true;



        taggedGameObject.rigidbody.useGravity = false;
        taggedGameObject.rigidbody.isKinematic = true;

        pickedUpScript = taggedGameObject.GetComponent<PickedUpObject> ();

        Debug.Log ("Pick Up");


    }

    private void RotateMovePickedUpObject(){

        //Rotate

        if(Input.GetKeyDown(KeyCode.End)){
            taggedGameObject.transform.localRotation *= Quaternion.Euler(0, 0, 45);
        }
        if(Input.GetKeyDown(KeyCode.Delete)){
            taggedGameObject.transform.localRotation *= Quaternion.Euler(0, 45, 0);
        }
        if(Input.GetKeyDown(KeyCode.PageDown)){
            taggedGameObject.transform.localRotation *= Quaternion.Euler(0, -45, 0);
        }
        if(Input.GetKeyDown(KeyCode.Home)){
            taggedGameObject.transform.localRotation *= Quaternion.Euler(0, 0, -45);
        }
        if(Input.GetKeyDown(KeyCode.PageUp)){
            taggedGameObject.transform.localRotation *= Quaternion.Euler(-45, 0, 0);
        }
        if(Input.GetKeyDown(KeyCode.Insert)){
            taggedGameObject.transform.localRotation *= Quaternion.Euler(45, 0, 0);
        }

        taggedGameObject.transform.position = Vector3.Lerp(taggedGameObject.transform.position, handPosition.position, (1 - Mathf.Exp( -20 * Time.smoothDeltaTime )) * 10);

    }


    private void Drop(){

        taggedGameObject.collider.isTrigger = false;

        taggedGameObject.rigidbody.useGravity = true;
        taggedGameObject.rigidbody.isKinematic = false;

        taggedGameObject = null;

        Debug.Log ("Drop");

        pickedUpScript = null;

    }

    private GameObject FindClosestPickup() {

        //Find closest gameobject with tag
        GameObject[] gos;
        gos = GameObject.FindGameObjectsWithTag("pickup");
        GameObject closest = null;
        float distance = Mathf.Infinity;
        Vector3 position = transform.position;

        foreach (GameObject go in gos) {
            Vector3 diff = go.transform.position - position;
            float curDistance = diff.sqrMagnitude;
            if (curDistance < distance) {
                closest = go;
                distance = curDistance;
            }
        }

        return closest;
    }

}

拾取对象脚本:

public PickUpDrop pickUpScript;
    public GameObject thisOne;
    public Color thecolor;
    public bool inObject;

    // Use this for initialization
    void Start () {
        thisOne = this.gameObject;
    }

    // Update is called once per frame
    void Update () 
    {
        thecolor = thisOne.renderer.material.color;

    if (pickUpScript.taggedGameObject != thisOne)
        {
            gameObject.renderer.material.color = Color.gray;
        }

    if (pickUpScript.taggedGameObject == thisOne)
        {
            Color color = renderer.material.color;
            color.a = 0.5f;
            renderer.material.color = color;
        }
    }

    void OnTriggerEnter ()
    {
        if (thisOne == pickUpScript.taggedGameObject)
        {
            inObject = true;
            pickUpScript.bounds = true;
            gameObject.renderer.material.color = Color.red;

        }
    }

    void OnTriggerExit()
    {
        if(thisOne == pickUpScript.taggedGameObject)
        {
            inObject = false;
            pickUpScript.bounds = false;
            gameObject.renderer.material.color = Color.gray;        
        }
    }

}

1 个答案:

答案 0 :(得分:0)

taggedGameObject.transform.position = Vector3.Lerp(taggedGameObject.transform.position, handPosition.position, (1 - Mathf.Exp( -20 * Time.smoothDeltaTime )) * 10);

此线将持续将物体移向手的位置。如果您正在移动游戏对象上附着刚体,那么在物理计算期间作用于该对象的物理将与更新功能期间对象的手动移动冲突。

这取决于在解决方案发生此冲突时您希望发生什么。如果您只是希望“抖动”停止并且仍然能够将物体保持在其他物理对象上,那么使用它;

taggedGameObject.rigidbody.AddForce( ( taggedGameObject.transform.position - handPosition.position ) * force );

这将保持与刚体的所有互动。你必须调整你移动物体的力量,并且可能会禁用标记的游戏物体上的重力,而它们在玩家手中。但它应该有预期的效果。