0

プレイヤーがオブジェクトを拾ったり落としたり、移動したり見回したりできるシーンがあります。

すべてのプレーヤー オブジェクトは、空のゲーム オブジェクト「MainCharacter」の子です。

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

オブジェクトを Lerp で手の位置に持ち上げましたが、カプセルが壁に衝突した後、奇妙なジッタリングが発生し、修正方法がわかりません!!

.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;
    }

}

Picked Up Objects スクリプト:

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

}
4

1 に答える 1

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

これにより、リジッドボディとのすべての相互作用が維持されます。オブジェクトを動かす力を微調整する必要があり、おそらく、タグ付けされたゲーム オブジェクトがプレイヤーの手にある間は重力を無効にする必要があります。しかし、それは望ましい効果をもたらすはずです。

于 2014-09-02T02:52:53.273 に答える