unity3d 如何限制与多个对象碰撞

lstz6jyr  于 2023-03-03  发布在  其他
关注(0)|答案(2)|浏览(197)

我有一个机械师。有一个玩家和一个敌人。他们每个人都能吸引立方体。所以当他们都接触立方体时,立方体会同时飞向敌人和玩家,我需要它飞向第一个接触它的人。这就是我现在拥有的

[SerializeField] private Transform _cube;
[SerializeField] private Transform _playerParent;
[SerializeField] private Transform _enemyParent;
private Transform _carPlayer, _carEnemy;
private Rigidbody _rigidbody;

private void Start()
    {
        _rigidbody = GetComponent<Rigidbody>();
    }

public void OnTriggerEnter(Collider collider)
{
    if (collider.gameObject.tag == "Player")
    {
        _carPlayer = collider.transform;
    }

    if (collider.gameObject.tag == "Enemy")
    {
        _carEnemy = collider.transform;
    }
}

private void FixedUpdate()
{
    if (_carPlayer)
    {
        PlayerTakeCube();
    }

    if (_carEnemyFirst)
    {
        EnemyFirstTakeCube();
    }
}

private void PlayerTakeCube()
{
    _cube.transform.position = Vector3.MoveTowards(transform.position, 
    _playerParent.position, 0.02f);
    _cube.transform.rotation = _playerParent.transform.rotation;
    _rigidbody.isKinematic = true;
    _cube.transform.SetParent(_playerParent);
}

private void EnemyFirstTakeCube()
{
    _cube.transform.position = Vector3.MoveTowards(transform.position, 
    _enemyParent.position, 0.02f);
    _cube.transform.rotation = _enemyParent.transform.rotation;
    _rigidbody.isKinematic = true;
    _cube.transform.SetParent(_enemyParent);
}
wfsdck30

wfsdck301#

在OnTriggerEnter中,检查是否已分配carPlayer或carEnemy,如果已分配,则不执行其余操作:
我还建议加上以下几行:将“刚体.isKinematic = true”和“立方体.变换.SetParent(...)”添加到OnTriggerEnter方法中,因为您不需要每次调用FixedUpdate();

public void OnTriggerEnter(Collider collider)
{
    if(_carPlayer || _carEnemy) return; //Check if someone already took control
    if (collider.gameObject.tag == "Player")
    {
        _carPlayer = collider.transform;
        _rigidbody.isKinematic = true;
        _cube.transform.SetParent(_playerParent);
    }
    
    if (collider.gameObject.tag == "Enemy")
    {
        _carEnemy = collider.transform;
        _rigidbody.isKinematic = true;
        _cube.transform.SetParent(_enemyParent);
    }
}

只有当您不希望多维数据集相互窃取时,上面的示例才有效。
如果可以的话,我会建议创建一个1秒的短计时器,在此期间,立方体在有人触摸后无法控制:

public void OnTriggerEnter(Collider collider)
{
    if(timer < 1) return;
    if (collider.gameObject.tag == "Player")
    {
        _carPlayer = collider.transform;
        _rigidbody.isKinematic = true;
        _cube.transform.SetParent(_playerParent);
        timer = 0;
    }

    if (collider.gameObject.tag == "Enemy")
    {
        _carEnemy = collider.transform;
        _rigidbody.isKinematic = true;
        _cube.transform.SetParent(_enemyParent);
        timer = 0;
    }
}

private void FixedUpdate()
{
    if(timer < 1)
        timer += Time.fixedDeltaTime
    ...
}
brc7rcf0

brc7rcf02#

我会把它统一起来,简单地用一个组件,比如。

public class Car : MonoBehaviour
{
    public Transform CubeParent;
}

在你们两辆汽车。
然后你可以简单地

private Car currentTarget;

public void OnTriggerEnter(Collider collider)
{
    // Someone else was here before already 
    if(currentTarget) return;

    // Otherwise is this even a car at all?
    if(collider.TryGetComponent<Car>(out var car))
    {
        // If so get the parent object we should move to
        currentTarget = car;
        // make this kinematic
        _rigidbody.isKinematic = true;         
    }
}

private void FixedUpdate()
{
    // Only if _cube and currentTarget are both set
    if(_cube && currentTarget)
    {
        // Move the cube towards the target
        _cube.transform.position = Vector3.MoveTowards(_cube.transform.position, currentTarget.CubeParent.position, 0.02f);
        _cube.transform.rotation = currentTarget.CubeParent.rotation;

        // If it reaches the position
        if(_cube.transform.position == currentTarget.CubeParent.position)
        {
            // parent it and forget the cube and target as no longer needed
            _cube.transform.SetParent(currentTarget.CubeParent);
            _cube = null;
            currentTarget = null;
        }
    }
}

相关问题