Unity - OnTriggerEnter bullet ricochet

时间:2016-02-11 17:17:53

标签: c# unity3d

我在简单的弹道学方面遇到了一些问题。由于我是编码新手而且我在搜索时浪费了2天,所以我决定提问。我的bullet.cs脚本有问题,代码工作正常,除了弹跳部分。我使用OnTriggerEnter beacuse子弹将穿透不同的材料,但会在特定角度下反弹,所以我只使用对撞机作为触发器。我知道可以使用OnCollisionEnter来确定正常并使用Vector3.Reflect。但是如果没有将对撞机设置为触发器,则子弹将从永远不会穿透墙壁的方式反弹。只需要帮助底部的弹跳部分。

public Rigidbody rb;

private float vel;
private float kEnergy;

private bool AP = false;
private bool HP = false;
private bool ricochet = false;

// Use this for initialization
void Start () {

    vel = 738f;
    kEnergy = 2108f;
    //HP == false;
    Destroy (gameObject, 10);
    rb = GetComponent<Rigidbody> ();
    rb.velocity = transform.forward * vel;
    Quaternion bulletRotaion = transform.rotation;
    Debug.Log (bulletRotaion.eulerAngles);
}

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

    float curVelocity = rb.velocity.magnitude;
    if (curVelocity <= 0)
    {
        curVelocity = 0f;
    }
}

void OnTriggerEnter (Collider c)
{
    if (c.tag == "Wall") {

        Quaternion localOffset = transform.rotation;
        float impactAngleX = c.gameObject.GetComponent <MaterialDensity> ().angleX;
        float impactAngleY = c.gameObject.GetComponent <MaterialDensity> ().angleY;
        float impactAngleZ = c.gameObject.GetComponent <MaterialDensity> ().angleZ;
        float angleX = localOffset.eulerAngles.x;
        float angleY = localOffset.eulerAngles.y;
        float angleZ = localOffset.eulerAngles.z;
        float density = c.gameObject.GetComponent <MaterialDensity> ().materialDensity;
        float ricochetX = (angleX + impactAngleX);
        if (ricochetX > 360) 
        {
            ricochetX = (ricochetX - 360);
        }

        if (ricochetX < 0) 
        {
            ricochetX = (ricochetX + 360);
        }
        float ricochetY = (angleY + impactAngleY);
        if (ricochetY > 360) 
        {
            ricochetY = (ricochetY - 360);
        }

        if (ricochetY < 0) 
        {
            ricochetY = (ricochetY + 360);
        }
        float ricochetZ = (angleZ + impactAngleZ);
        if (ricochetZ > 360) 
        {
            ricochetZ = (ricochetZ - 360);
        }

        if (ricochetZ < 0) 
        {
            ricochetZ = (ricochetZ + 360);
        }

        if ((ricochetX > 60 && ricochetX < 300) || (ricochetY > 60 && ricochetY < 300) || (ricochetZ > 60 && ricochetZ < 300)) {
            ricochet = true;
            //Debug.Log (ricochet);
        } 

        if ((ricochetX < 60 && ricochetX > 300) || (ricochetY < 60 && ricochetY > 300) || (ricochetZ < 60 && ricochetZ > 300)) {
            ricochet = false;
            //Debug.Log (ricochet);
        }

        Debug.Log (ricochet);
        Debug.Log (ricochetX);
        Debug.Log (ricochetY);
        Debug.Log (ricochetZ);

        if (AP) 
        {
            density *= 0.9f;
        }
        if (HP) 
        {
            density *= 3f;
        }

        //float vel = gameObject.GetComponent<GunNew>().velocity;
        float curVelocity = rb.velocity.magnitude;
        float velocityMod = curVelocity / vel;
        float densityMod = density / velocityMod;
        float curEnergy = (kEnergy * velocityMod);
        float energyMod = (curEnergy * velocityMod);
        rb = GetComponent<Rigidbody> ();
        //Quaternion localOffset = transform.rotation;
        float randomX = Random.Range (0.03f, 0f);
        float randomY = Random.Range (0.03f, -0.03f);
        if (randomX == 0) 
        {
            randomX = 0.01f;
        }
        if (randomY == 0) 
        {
            randomY = 0.01f;
        }
        localOffset.x += randomX;
        localOffset.y += randomY;

        if (curVelocity > densityMod && !ricochet) {
            rb.rotation = localOffset;
            rb.velocity = transform.forward * ((curVelocity - (curVelocity * (randomX + randomY))) - densityMod);

            //Debug.Log (curVelocity);
            //Debug.Log (energyMod);
        } 

        if (curVelocity > densityMod && ricochet)
        {
            Vector3 objAngle = new Vector3 (impactAngleX, impactAngleY, impactAngleZ);
            Vector3 bulletAngle = rb.rotation.eulerAngles;
            Debug.Log (objAngle);
        }

        if (curVelocity <= densityMod)
        {
            //Debug.Log (curVelocity);
            //Debug.Log (energyMod);
            Destroy (gameObject);
        }
    }
}

第二个代码是来自墙的代码。

public float materialDensity = 100f;
public float angleX;
public float angleY;
public float angleZ;

//Quaternion localOffset = transform.rotation;

// Use this for initialization
public void Start () 
{
    GetComponent<Rigidbody> ();
    Quaternion localOffset = transform.rotation;
    float angleX = localOffset.eulerAngles.x;
    float angleY = localOffset.eulerAngles.y;
    float angleZ = localOffset.eulerAngles.z;
    //Debug.Log (localOffset.eulerAngles.x);
}

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

}

1 个答案:

答案 0 :(得分:0)

首先,我会在你的游戏中制作一层可以弹跳的东西,以及不会发生的事情。

然后,当您测试与子弹的碰撞时,您只能检查与弹跳层的碰撞。这将提高性能并使编码更简单。

从那里你可以依靠团结的物理学来做它自己的弹跳,或者如果你想自己计算它,你可以做一个光线投射并使用如上所述的光线投射法线

if(Physics.Raycast(shootRay,out shootHit,range,ricochetMask)){ ...