我正在研究一个简单的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部分所在的代码。
有人可以引导我吗?
非常感谢。
答案 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;
}
}
}
}
}