笔记14 灯光、预设体、3d物体的事件、碰撞体、刚体、炸箱子、触发器、物理材质、射线

灯光

基本项

在这里插入图片描述

烘焙

在这里插入图片描述

灯光的种类

在这里插入图片描述

Lighting窗口

在这里插入图片描述

预设体

了解预设体

在这里插入图片描述

利用代码操作预设体

实例化预设体Instantiate

在这里插入图片描述

    //预设体的类型也是GameObject,名字是CubePre。
    public GameObject CubePre;
    //注意这一步:在unity中,将预设体关联到脚本的变量上来。
    void Start () {
        /*法一:实例化到指定位置。
预设体,位置(中心),旋转(默认四元数。此处设为不转)。返回值是刚生成的物体。*/
        GameObject go = Instantiate(CubePre, transform.position, Quaternion.identity);
        //法二:不指定位置的实例化。
        Instantiate(CubePre);
    }

删除

位置:Start

删除物体
        /*删除物体。一般是在一帧完了之后删除。
 不能写在Update里,因为这个删除是有延迟的,和垃圾回收机制一样。*/
        Destroy(go);
3秒之后删除
        Destroy(go, 3f);   //3秒之后删除
立刻删除
       //立刻删除(强制删除)。可以写在Update里。费性能,少用。
        DestroyImmediate(go);   
删除组件
        //删除组件。例如删除AudioSource组件
        Destroy(GetComponent<AudioSource>());

3d物体的事件

注意:该物体需勾已选碰撞器这个组件;在Game窗口进行操作

鼠标移动进物体,在物体范围内,离开物体

 //鼠标移动进物体
    private void OnMouseEnter()
    {
        Debug.Log("Enter");
    }
    //鼠标在物体范围内
    private void OnMouseOver()
    {
        Debug.Log("Over");
    }
    //鼠标离开物体
    private void OnMouseExit()
    {
        Debug.Log("Exit");
    }

鼠标按下,抬起,按下并抬起

//鼠标按下
    private void OnMouseDown()
    {
        Debug.Log("Down");
    }
    //鼠标抬起。如果按下是在物体上,那么一出物体时,抬起是调用的
    private void OnMouseUp()
    {
        Debug.Log("Up");
    }
    //按下并抬起(上面两个方法的结合)。按下并抬起必须都在物体身上
    private void OnMouseUpAssButton()
    {
        Debug.Log("Butten")
    } 

按下持续调用

//按下持续调用(可用于拖拽,但拖拽更多是用射线)
    private void OnMouseDrag()
    {
        Debug.Log("Drag");
    } 

碰撞体、刚体

两个物体产生碰撞的条件:两个物体都要有碰撞体,且至少一个有刚体。
注意:运行时添加的组件,在运行结束后会消失。

Unity里

在这里插入图片描述

代码

产生碰撞的时候会调用OnCollisionEnter

    //产生碰撞的时候会调用。
    /*unity里面的碰撞器是Collider,但代码中Colision是一个类,它里面包含一些数据信息。
    里面可以找到碰撞器、游戏物体、刚体等。 */
    private void OnCollisionEnter(Collision collision)
    {
    
    } 

当碰撞结束的时候会调用OnCollisionExit

 //当碰撞结束的时候会调用
    private void OnCollisionExit(Collision collision)
    {
        Debug.Log("Exit");
    }

获得碰撞的物体的碰撞器,碰撞点,碰撞法线

    //产生碰撞的时候会调用。
    private void OnCollisionEnter(Collision collision)
    {
        //获得碰撞的物体的碰撞器
        Collider collider = collision.collider;
        Debug.Log("Enter" + collider.name);   //此时获得的是地面

        //碰撞点。它是个数组,因为物体不同,碰撞点的个数不同。
        Vector3 point = collision.contacts[0].point;
        //碰撞法线
        Vector3 normal = collision.contacts[0].normal;
    } 

移动物体

法一:无刚体时用。有刚体,速度特别快时,不能用(遇墙抖动)。
void Update () {
        //移动物体,法一:无刚体时用。有刚体,速度特别快时,不能用。向前每秒走十米   
        transform.Translate(transform.forward * 10 *Time.deltaTime);  
    } 
法二:给力Rbody.AddForce(利用刚体,只给一次力。所以速度是越来越慢的)
    //移动物体,法二、法三:利用刚体
    private Rigidbody Rbody;

	void Start () {
        //先得到物体身上的刚体组件
        Rbody = GetComponent<Rigidbody>();
        //法二:给力(给一次。所以速度是越来越慢的 )。方向(前方向量)* 力
        Rbody.AddForce(transform .forward * 300f);		
	}
法三:给速度Rbody.velocity(利用刚体)
    //移动物体,法二、法三:利用刚体
    private Rigidbody Rbody;

	void Start () {
        //先得到物体身上的刚体组件
        Rbody = GetComponent<Rigidbody>();
    }
    
    void Update () {
        /*移动物体,法三:给速度。velocity代表当前物体的速度。
        transform.forward我的前方,如果是会滚动的物体,那么它的前方是会发生改变,
        所以注意是否需要锁定滚动。*/
        Rbody.velocity = transform.forward * 10;
        
        //匀速移动。Vector3.forward世界的前方,方向不会变。
        Rbody.velocity = Vector3.forward * 10;
    } 

在这里插入图片描述

炸箱子

课程代码

    //产生碰撞的时候会调用。
    /*unity里面的碰撞器是Collider,但代码中Colision是一个类,它里面包含一些数据信息。
    里面可以找到碰撞器、游戏物体、刚体等。 */
    private void OnCollisionEnter(Collision collision)
    {
        //爆炸范围半径5m
        float r = 5;
        //Physics物理的类,它有很多方法,比如此处的OverlapSphere。
        //得到圆心为collision.contacts[0].point,半径为r的圆中间的所有碰撞体。
        Collider[] colliders = Physics.OverlapSphere(collision.contacts[0].point,r);
        //在unity里面把箱子的标签统一成Box
        //遍历碰撞体
        foreach(Collider collider in colliders)
        {
            //判断是不是可以被击飞的箱子
            if(collider.tag == "Box")
            {
                /*给箱子添加爆炸力。首先拿它的刚体GetComponent,
          然后给它一个爆炸力AddExplosionForce,参数:力(50),爆炸点(圆心),半径(r)*/
                collider.GetComponent<Rigidbody>().AddExplosionForce(500f, collision.contacts[0].point, r);
            }
        } 

复习自写代码

   //产生碰撞时调用
    void OnCollisionEnter(Collision collision)
    {
        //爆炸半径
        float radius = 5f;
        //爆炸点
        Vector3 point = collision.contacts[0].point;
        //拿到要炸的物体
        Collider[] colliders = Physics.OverlapSphere(point, radius);
        //遍历物体,找到要炸的
        for(int i = 0; i < colliders.Length; i++)
        {
            if (colliders[i].CompareTag("Box"))
            {
                //给爆炸力
                colliders[i].GetComponent<Rigidbody>().AddExplosionForce(500f, point, radius);
            }
        }
    }

触发器

在这里插入图片描述
下面的实例中,脚本在球上,让球穿过立方体,立方体的触发器应该打上勾。

进入触发区域调用

 //进入触发区域调用。other代表你(球)进入的那个物体(立方体)的触发器
    private void OnTriggerEnter(Collider other)
    {
        //打印触发器的名字,结果是立方体
        Debug.Log("Enter" + other.name); 
    }

离开触发区域调用

     //离开触发区域调用
    private void OnTriggerExit(Collider other)
    {
        Debug.Log("Exit");
    } 

物理材质

在这里插入图片描述

射线

画出射线

 void Start () {
        //射线。射线的起始点,射线向量。从003的点向下4米的射线。
        Ray ray = new Ray(Vector3.up * 3, Vector3.down * 4);
	}
	
	void Update () {
        //画出射线
        Debug.DrawRay(Vector3.up * 3, Vector3.down * 4);                    
	}

检测碰撞

法一:只显示第一个碰撞点

   void Start () {
        //射线。射线的起始点,射线向量。从003的点向下4米的射线。
        Ray ray = new Ray(Vector3.up * 3, Vector3.down * 4);
        //取得射线碰撞的物体。RaycastHit碰撞数据结构体。
        RaycastHit hit;   //声明一个碰撞数据结构体。 
        /*检测射线碰撞。out的意思就是,我们把hit传进去,
            它在内部可以给hit赋值,之后我们就可以把hit拿出来了。*/       
        bool res = Physics.Raycast(ray, out hit);
        if (res == true)
        {
             //鼠标点在地面上。打印碰撞点(只会打印第一个碰撞点)。
             //Debug.Log("鼠标点在:" + hit.point);
         }
	}
	
	void Update () {
        //画出射线
        Debug.DrawRay(Vector3.up * 3, Vector3.down * 4);
            }
        }
	}

法二:RaycastHit[]碰撞点的集合

  void Start () {
        //射线。射线的起始点,射线向量。从003的点向下4米的射线。
        Ray ray = new Ray(Vector3.up * 3, Vector3.down * 4);
        //取得射线碰撞的物体。RaycastHit碰撞数据结构体。
        RaycastHit hit;   //声明一个碰撞数据结构体。
        
        //法二:检测射线碰撞
        RaycastHit[] hits = Physics.RaycastAll(ray);
	}
	
	void Update () {
        //画出射线
        Debug.DrawRay(Vector3.up * 3, Vector3.down * 4);
            }
        }
	}

鼠标点在地面上

	   void Update () {
        if(Input.GetMouseButtonDown(0))
        {
            //取得射线。Camera.main主摄像机。屏幕坐标的位置
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            //取得射线碰撞的物体。RaycastHit碰撞数据结构体。
            RaycastHit hit;   //声明一个碰撞数据结构体。
            /*检测射线碰撞。
 意思就是,我们把hit传进去,它在内部可以给hit赋值,之后我们就可以把hit拿出来了。*/
            bool res = Physics.Raycast(ray, out hit);
            if (res == true)
            {
                //鼠标点在地面上。打印碰撞点(只会打印第一个碰撞点)。
                Debug.Log("鼠标点在:" + hit.point);
            }
        }
	}

物体向鼠标点击的位置移动

 public class ReyTest : MonoBehaviour {
    //目标点traget
    private Vector3 target;
	 
	void Start () {
        //首先,目标点位置就是自身位置
        target = transform.position;   
	}
	
	// Update is called once per frame
	void Update () {
        if(Input.GetMouseButtonDown(0))
        {
            //取得射线。Camera.main主摄像机。屏幕坐标的位置
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            //取得射线碰撞的物体。RaycastHit碰撞数据结构体。
            RaycastHit hit;   //声明一个碰撞数据结构体。
            /*检测射线碰撞。out的意思就是,我们把hit传进去,
            它在内部可以给hit赋值,之后我们就可以把hit拿出来了。*/
            bool res = Physics.Raycast(ray, out hit, 500f,1<<LayerMask.NameToLayer("Ground"));
            if (res == true)
            {
                //鼠标点在地面上。打印碰撞点(只会打印第一个碰撞点)。
                //Debug.Log("鼠标点在:" + hit.point);
               
                //之后,将鼠标点击的位置赋值给目标点
                target = hit.point;
                //如果希望Y轴不变,则等于它自身的Y值
                target.y = transform.position.y;
            }
            //判断一下目标位置和我的位置之间的距离,如果大于0.3就向目标距离前进
            if(Vector3.Distance(target,transform.position)> 0.3f)
            {
                //得到向量。(目标位置-我的位置),然后转换成单位向量,这样便于计算速度。
                Vector3 dir = (target - transform.position).normalized;
                //转向这个向量。Quaternion四元数
                transform.rotation = Quaternion.LookRotation(dir);
                //前进
                transform.Translate(Vector3.forward * 2 * Time.deltaTime);
            }
        }
	}
}

特别说明

法一:(ray, out hit)两个参数(会出现墙后位置不能到达的问题)
            //法一:(ray, out hit)两个参数。会出现墙后位置不能到达的问题。
//检测射线碰撞。out的意思就是,我们把hit传进去,它在内部可以给hit赋值,之后我们就可以把hit拿出来了。
            bool res = Physics.Raycast(ray, out hit);
法二:四个参数(指定与哪一层进行检测,解决墙后位置不能到达的问题)

参数3:射线长度是500米。参数4:第几层(层Ground在第8层)。
第四个参数:
1、左移运算符<<
2、导致两种写法:比如此处都是要检测地面。
3、第四个参数还影响着:如果不想和谁检测。
即将第四个参数用小括号括起来,前面加波浪线。例如:~(1<<8)

写法一:1<<8 查看地面是哪一层,把层数写在这里,此处为8.
            /*左移运算符<<。LayerMask:1<<层数,就代表和这层进行射线检测。
            如果是两层,则加|隔开,例如:1<<8 | 1<<9*/
            //法一:1<<8   查看地面是哪一层,把层数写在这里,此处为8. 
            bool res = Physics.Raycast(ray, out hit, 500f,1<<8);
写法二:1<<LayerMask.NameToLayer(“Ground”) 直接写要检测的物体的名字,此处为地面
    //法二:1<<LayerMask.NameToLayer("Ground") 直接写要检测的物体的名字,此处为地面
            bool res = Physics.Raycast(ray, out hit, 500f,1<<LayerMask.NameToLayer("Ground"));

在这里插入图片描述

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值