2014-09-01 2 views
0

У меня есть сцена, в которой игрок может поднимать и опускать объекты, а также перемещаться и оглядываться.Почему возникает это странное дрожание?

Все объекты игрок дети пустой объект игры «MainCharacter»:

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

Объект Я поднимаю Lerps в мое положение руки, однако после того, как моя капсула сталкивается с какими-либо стенами есть странное дрожание, которое Я не могу понять, как это исправить!

Heres Исполняемый: GameTest Heres папка данных: 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;   
     } 
    } 

} 
+0

Я не отлаживал ваш код, но я заметил, что у вас есть метод GameObject FindClosestPickup() '. Если несколько объектов одинаково закрыты, возвращаемый методом метод может быть нестабильным из-за [ошибок с плавающей запятой] (http://floating-point-gui.de/errors/comparison/). Нестабильность может привести к flip-flopping, поскольку метод возвращает другой объект для каждого обновления игры. Может ли это быть здесь? – dbc

+0

Я сомневаюсь, что это причина, мои объекты находятся далеко друг от друга, а дрожание все еще происходит только с одним объектом, но спасибо за будущее предупреждение! – user3902259

ответ

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

Это будет поддерживать все взаимодействия с жестким корпусом. Вам нужно будет настроить силу, с которой вы перемещаете объект, и, возможно, отключите гравитацию на помеченном игровом объекте, пока он находится в руках игроков. Но он должен иметь желаемый эффект.

+0

Привет! Спасибо за помощь, скрипт по большей части работает! (мне пришлось отменить вычисление до (handPosition.position -taggedGameObject.transform.position)) Я временно решил проблему с пружинным соединением, однако это исправление позволило мне решить проблему гораздо более эффективно ! Еще раз спасибо! – user3902259

Смежные вопросы