当我捡起和放下它们时,如何阻止它们穿过墙壁?

时间:2019-01-28 15:16:10

标签: unity3d

当我捡起一个物体时,我可以通过地图对其进行故障处理,使其脱离世界。当我捡起它并将物体放在地板的一半位置时,会发生这种情况。我收到的结果不是我期望的解决方案。同样,对撞机和刚体的设置正确。

public GameObject PressEtoInteractText;

public bool pickup, inrange;

public Collider Playercol;

public Vector3 guide;

private GameObject temp;

private Rigidbody rb;

void Update()
{
    if (Input.GetKeyDown(KeyCode.E) && inrange == true)
    {
        PressEtoInteractText.SetActive(false);
        pickup = true;
    }

    if (Input.GetMouseButtonDown(0) && pickup == true)
    {
        pickup = false;
        Playercol.isTrigger = true;
    }
    UpdatePickUpFollow();
}

void OnTriggerEnter(Collider other)
{
    if (other.gameObject.tag == "Interact")
    {
        PressEtoInteractText.SetActive(true);
        temp = other.gameObject;
        inrange = true;
    }

    if (other.gameObject.tag == "Interact" && temp.transform.position == guide)
    {
        return;
    }
}

void OnTriggerExit(Collider other)
{
    if (other.gameObject.name != "Interact")
    {
        PressEtoInteractText.SetActive(false);
        inrange = false;
    }
}

public void PickUp()
{
    rb = temp.GetComponent<Rigidbody>();
    rb.MovePosition(transform.position += guide);
    Playercol.isTrigger = false;
}

public void UpdatePickUpFollow()
{
    if (pickup == true)
    {
        PickUp();
    }
}

1 个答案:

答案 0 :(得分:0)

如果您使用tempCol.enabled = false;停用对象碰撞器,它将不记录任何碰撞,您可以整天将其推入或拉出墙壁。请确保将其从脚本中删除。

此外,使用MoveTowards可能会导致碰撞检测出现问题。以我的经验,最好使用AddForceMovePosition移动Rigidbody组件,而不是直接修改Transform。尝试Rigidbody.MovePosition(Vector3 position)。也许这对您更好。

这里是指向文档页面的链接。基本上就是您的确切用例:

Rigidbody.MoveTowards Unity Docs

(提示:请注意他们如何使用FixedUpdate而不是常规的Update。在使用刚体时,还应该始终这样做,因为它与物理更新同步。)

//编辑: 这是用更干净,更希望正确的方式对代码进行的一点实现。我没有未测试,可能是我错过了一些东西。以此为参考来构建您自己的工作解决方案。

    //set in inspector
public Transform guidePosition;
public GameObject pressEToInteractText;

private bool isObjectInRange;
private GameObject inRangeObject;
private bool isObjectPickedUp;
private Rigidbody pickedUpRigidBody;

/*  check if button is pressed. 
 *  If no object is in hand -> pick up; 
 *  if object is in hand -> drop;
 */ 
private void FixedUpdate()
{
    if (Input.GetKeyDown(KeyCode.E) && isObjectInRange && !isObjectPickedUp)
    {
        PickupObject();
    }

    if(Input.GetKeyDown(KeyCode.E) && isObjectPickedUp)
    {
        DropObject();
    }

    if (isObjectPickedUp)
    {
        PickedUpObjectFollow();
    }
}

//save references 
private void PickupObject()
{
    pickedUpRigidBody = inRangeObject.GetComponent<Rigidbody>();
    isObjectPickedUp = true;
}

//remove saved references
private void DropObject()
{
    isObjectPickedUp = false;
    pickedUpRigidBody = null;
}

//move position to guidePosition
private void PickedUpObjectFollow()
{
    pickedUpRigidBody.MovePosition(guidePosition.position);
}

private void OnTriggerEnter(Collider other)
{
    if (other.CompareTag("Interact") && !isObjectPickedUp)
    {
        pressEToInteractText.SetActive(true);
        isObjectInRange = true;
        inRangeObject = other.gameObject;
    }
}

private void OnTriggerExit(Collider other)
{
    if(other.CompareTag("Interact") && other.gameObject == inRangeObject)
    {
        pressEToInteractText.SetActive(false);
        isObjectInRange = false;
        inRangeObject = null;
    }
}