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

本文关键字:抖动 为什么 | 更新日期: 2023-09-27 18:20:17

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

所有玩家对象都是空游戏对象"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;        
        }
    }
}

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

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 );

这将保持与刚体的所有交互。你必须调整移动物体的力,也许在玩家手中禁用标记游戏物体的重力。但它应该具有预期的效果。