关于动态添加与布料发生碰撞的物体

在unity中使用布料的时候,我们知道,设置与布料发生碰撞的物体有两种方式,一种是直接在属性中设置与不料发生碰撞的单个球形碰撞体,或者添加两个球形碰撞体再连接成一个胶囊体,如下图
在这里插入图片描述
在这里插入图片描述
然后在今天做项目的时候,由于提前不知道要求那个碰撞体可以与布料发生碰撞,所以需要动态的添加与布料发生碰撞的物体。
项目场景如下:

点击发射按钮,炮弹发射,点击上下移动按钮炮筒上下移动,因此需要动态监测炮弹是否与布料发生碰撞,如果发生碰撞,则需要有一系列的事件发生

代码如下
屏幕自适应、炮弹的发射、碰撞物体的添加与移除

 using UnityEngine;
using System.Collections;
public class SampleListener : MonoBehaviour {
    public GameObject ballPre;
    public Transform targetPos;
    public Cloth cloth;
    private int icount;
    public GameObject FireFlare;
    void Start () {
        InitUI();               //屏幕自适应
    }
    public void Fire() {
        Rigidbody ballRi = ((GameObject)(Instantiate(ballPre, targetPos.position, targetPos.rotation))).GetComponent<Rigidbody>();  //实例化炮弹
        ballRi.AddForce((targetPos.position - transform.position) * 500);               //向炮弹施加一个力
        addCollider(ref cloth, ballRi.gameObject.GetComponent<SphereCollider>());       //将自身添加到布料碰撞列表
        BallListener.destoryGameobject.Add((GameObject)Instantiate(FireFlare, targetPos.position, targetPos.rotation));
    }
    public void Update() {
        if (BallListener.destoryGameobject.Count != 0) {                            //检测待销毁对象列表是否为空
            icount++;                                                               //计数器自加
            if (icount > 60) {
                GameObject.Destroy((GameObject)BallListener.destoryGameobject[0]);  //销毁列表头对象
                BallListener.destoryGameobject.RemoveAt(0);                         //移除列表中的对象
                icount = 0;                                                         //重置计数器
            }
        }
    }
    public void Rota(int i) {                                                       //炮管旋转回调方法
        transform.Rotate(Vector3.forward, i * 5);
    }
    private void addCollider(ref Cloth c, SphereCollider sc) {
        ClothSphereColliderPair[] cscp = new ClothSphereColliderPair[c.sphereColliders.Length + 1]; //重新声明碰撞器数组
        for (int i = 0; i < c.sphereColliders.Length; i++) {
            cscp[i] = c.sphereColliders[i];                             //初始化碰撞器数组
        }
        cscp[cscp.Length - 1] = new ClothSphereColliderPair(sc);        //添加碰撞器
        BallListener.clothColliders.Add(cscp[cscp.Length - 1]);         //储存碰撞器至列表
        c.sphereColliders = cscp;                                       //设置碰撞列表
    }
    private void InitUI() {                                             //UI按钮屏幕自适应方法
        Vector2 editScreen = new Vector2(1381, 638);
        Transform canvas = GameObject.Find("Canvas").transform;         //在Canvas下的对象将进行位置和大小的调整
        Vector2 scaleExchange = new Vector2(Screen.width / editScreen.x, Screen.height / editScreen.y);
        for (int i = 0; i < canvas.childCount; i++) {
            RectTransform canvasChildRT = canvas.GetChild(i).GetComponent<RectTransform>();
            canvasChildRT.position = new Vector3(scaleExchange.x * canvasChildRT.position.x,    //调整其位置
                                                 scaleExchange.y * canvasChildRT.position.y, 0);
            canvasChildRT.sizeDelta = new Vector3(scaleExchange.x * canvasChildRT.sizeDelta.x,    //调整其大小
                                                   scaleExchange.y * canvasChildRT.sizeDelta.y, 0);
        }
    }
}

碰撞之后的自我销毁、在碰撞列表中对象的移除

using UnityEngine;
using System.Collections;
public class BallListener : MonoBehaviour {
    public static ArrayList clothColliders = new ArrayList();   //列表中储存了能与布料发生碰撞的对象
    public static ArrayList destoryGameobject = new ArrayList();
    public GameObject Emi;
    Cloth cloth;                                                //指定的布料对象
    void Start () {
        cloth = GameObject.Find("Cloth").GetComponent<Cloth>(); //初始化布料对象
    }
    void OnTriggerEnter(Collider target) {                  //碰撞检测
        removeCollider();                               //移除碰撞列表中的对象
        Quaternion q = new Quaternion();
        q.eulerAngles = new Vector3(270, 0, 0);
        GameObject fire = (GameObject)Instantiate(Emi, new Vector3(transform.position.x, transform.position.y+5, transform.position.z-3), q);
        if (!target.gameObject.name.Equals("Cloth")) {   //与布料对象发生碰撞
            destoryGameobject.Add(fire);
        }
        Destroy(gameObject);                            //进行自我销毁
    }
    void removeCollider() {
        clothColliders.Remove(new ClothSphereColliderPair(GetComponent<SphereCollider>())); //在碰撞列表中移除自身
        ClothSphereColliderPair[] cscp = new ClothSphereColliderPair[clothColliders.Count]; //重新声明碰撞列表
        for (int i = 0; i < cscp.Length; i++) {
            cscp[i] = (ClothSphereColliderPair)clothColliders[i];               //初始化碰撞列表
        }
        cloth.sphereColliders = cscp;                                           //设置碰撞列表
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值