unity如何相对于某个角度从另一个对象“反弹”一个对象?

时间:2019-08-12 19:38:00

标签: c# algorithm unity3d

我正在研究一个简单的3D游戏,其中一些球(固定的Z位置)沿着一条路径(使用重力和物理材料)掉落到一个小的扁平平台上,并从该平台“反弹”。玩家可以旋转该平台,所以我想根据平台的角度重新创建逼真的反弹方向。

我是编码新手,但到目前为止,我已经弄清楚了与平台碰撞时球的矢量与平台法线之间的关系,该法线应该是与表面垂直的线,并且可以是用于将球的矢量反射到另一个方向。

我已经使用OnCollisionEnter和if语句检测它是否是您要与之碰撞的平台,但是我不知道在何处指示表面的法线以及如何访问该表面。它应该是另一个对象中的公共类,还是可以从球类游戏对象中检测出来?

我尝试了该网站和其他网站上的一些示例,并且到目前为止:

public class OnCollision : MonoBehaviour
{

    public float speed = 25f;
    public Rigidbody rb;
    private Rigidbody rigid;

    private void Start()
    {
        rigid = transform.GetComponent<Rigidbody>();
    }
    private void OnCollisionEnter(Collision collision)
    {
        if (collision.transform.tag == "BouncePad") {
            rb.velocity = transform.up * speed;
        }

    }
}

现在它会垂直弹起,所以我猜我应该更改transform.up * speed部分所在的代码。

有人可以引导我吗?

非常感谢。

3 个答案:

答案 0 :(得分:2)

如果您已经在使用Physics material,请查看Bounciness属性。值为0表示没有反弹,值为1不会导致能量损失。反弹的角度将为您计算。确保将物理材质拖到每个对象上-球和墙的材质都会起作用。

答案 1 :(得分:0)

最后有人帮我解决了这个问题:

public class Bounce : MonoBehaviour
{
public Rigidbody rb;
public float str = 0.21f;
public float str2 = 0.15f;

// Start is called before the first frame update
private void Start()
{
    rb = GetComponent<Rigidbody>();
}

private void OnCollisionEnter(Collision col)
{
    if (col.gameObject.tag == "BouncePad")
    {
        rb.AddForce(rb.velocity * str, ForceMode.Impulse);
    }
    if (col.gameObject.tag == "BouncePad2")
    {
        rb.AddForce(rb.velocity * str2, ForceMode.Impulse);
    }
}

// Update is called once per frame
void Update()
{

}

}

答案 2 :(得分:0)

公共类BouncTest:MonoBehaviour {

[SerializeField] private float hight = 3;
[SerializeField] private int times = 5;
[SerializeField] private float speed = 8;

private Vector3 _startPos;
private bool _checkUP;
private int _countTimes;
private float _hightbuf;
[HideInInspector]
public bool _bounceEnd;

private void Awake()
{
    _startPos = transform.position;
}

public void TurnOnBounceEffect()
{
    _bounceEnd = true;
    _checkUP = false;
    _hightbuf = hight;
    _countTimes = 0;
}

private void FixedUpdate()
{
    BounceEffect();
}

private void BounceEffect()
{
    if (_bounceEnd)
    {
        if (!_checkUP)
        {
            if (transform.position.y <= (_startPos.y + _hightbuf))
                transform.position = Vector2.MoveTowards(transform.position, new Vector2(_startPos.x, transform.position.y) + (Vector2.up * _hightbuf), speed * Time.fixedDeltaTime);
            else
            {
                _checkUP = true;
            }
        }
        else if (times != _countTimes)
        {
            if (transform.position.y > _startPos.y)
                transform.position = Vector2.MoveTowards(transform.position, _startPos, speed * Time.fixedDeltaTime);
            else
            {
                _countTimes++;
                _checkUP = false;
                _hightbuf /= 2;
            }
        }
        else
        {
            transform.position = Vector2.MoveTowards(transform.position, _startPos, speed * Time.fixedDeltaTime);
            if (transform.position.y <= _startPos.y)
            {
                _bounceEnd = false;
            }
        }
    }
}

}