Unity 3d 刚体与碰撞体属性 固定、铰链、弹簧关节的使用 子弹的发射和销毁

本文主要是介绍Unity 3d 刚体与碰撞体属性 固定、铰链、弹簧关节的使用 子弹的发射和销毁,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

任务:子弹射击实例 
1. 定义物理射线; 
2. 实现从摄像机到鼠标目标位置射线发射子弹并碰撞目标对象的碰撞效果; 
3. 功能: 

利用子弹预制体生成子弹; 
利用 cube 生成一墙面;墙面 cube 对象带有刚体和碰撞体组件; 
利用 Random.range(float, float) 在随机的位置生成一个 cube 对象; 
对随机生成的 cube 对象添加 box collider 碰撞体组件; 
鼠标点击发射一带有刚体和碰撞体的子弹; 
子弹撞击 cube 墙面后带有物理碰撞效果; 
子弹跟随机生成的 cube 对象触发检测,触碰后销毁; 

使用技巧

vs不错!

添加刚体组件

才会具有动力学特征,才会动

重力

两个组件:刚体,碰撞体

添加了碰撞体,才会发生碰撞

四种情况

• 第一种情况:主模型有刚体和碰撞体,目标物体只有碰撞体,没有刚体
效果:主模型和目标物体碰撞,但是碰不动
• 第二种情况:主模型只有刚体,没有碰撞体,目标物体只有碰撞体,没有刚体
效果:主模型会直接掉落到地面以下
• 第三种情况:主模型有刚体和碰撞体,目标物体没有碰撞体和刚体
效果:主模型会直接穿透目标物体
• 第四种情况:主模型和目标物体都有刚体和碰撞体
效果:主模型与目标物体相撞,且可以直接将其撞倒

Is Kinematic / 作为触发器:

可以穿透,不会碰撞

添加物理材质

创建一个主要的cube

创建一个RigidbodyMovement.cs脚本,并将其绑定到此cube上

主要功能:键盘操控,鼠标拖动,碰撞检测

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class RigidbodyMovement : MonoBehaviour
{Rigidbody rbody;//公开到显示面板 publicpublic float speed = 30f;//速度预先定义在外部// Start is called before the first frame updatevoid Start(){rbody = GetComponent<Rigidbody>();//获取一个对象上面的刚体组件}// Update is called once per framevoid Update(){//获取虚拟轴,h、v定义在函数体内部float h = Input.GetAxis("Horizontal");//获取水平轴,即左右键返回的数据float v = Input.GetAxis("Vertical");//获取垂直轴,即上下键返回的数据rbody.MovePosition(rbody.position + transform.right * h * Time.deltaTime * speed);//刚体左右移动rbody.MovePosition(rbody.position + transform.forward * v * Time.deltaTime * speed);//刚体上下移动}private void OnMouseDrag(){//通过鼠标扯拽控制刚体移动transform.position += Vector3.right * speed * Time.deltaTime * Input.GetAxis("Mouse X");transform.position += Vector3.up * speed * Time.deltaTime * Input.GetAxis("Mouse Y");transform.position += Vector3.forward * speed * Time.deltaTime * Input.GetAxis("Mouse ScrollWheel");}private void OnCollisionEnter(Collision collision){//碰撞进入瞬间显示除地板外碰撞体名称if (collision.gameObject.name != "Plane"){print("the name of collision enrty:" + collision.gameObject.name);}}private void OnCollisionStay(Collision collision){//碰撞中显示除地板外碰撞体名称if (collision.gameObject.name != "Plane"){print("the name of collision stay:" + collision.gameObject.name);}}private void OnCollisionExit(Collision collision){//碰撞退出瞬间显示除地板外碰撞体名称if (collision.gameObject.name != "Plane"){print("the name of collision exit:" + collision.gameObject.name);}}private void OnTriggerEnter(Collider other){//如果另外一个碰撞体进入了触发器,则显示其名称print("triggerEnter:" + other.gameObject.name);}private void OnTriggerStay(Collider other){print("triggerStay:" + other.gameObject.name);}private void OnTriggerExit(Collider other){print("triggerExit:" + other.gameObject.name);}
}

MovePosition(三维向量) 改变位置

MoveRotation 让其旋转

效果如下

 

固定关节的用法

先创建一个空对象,再添加关节组件

关节要具有运动学特征才能被固定

所以要勾选 Is Kinematic

kinematic  
adj.运动的;运动学的;

这样红色方块无论是否受重力作用,都被固定在关节上了。

效果

HingeJoint 铰链关节

先创建一个空对象,再添加铰链关节组件

添加铰链关节组件会自动添加刚体组件

设定铰链关节的绑定对象:绿色方块  //这里不要绑错,不然没有反应

铰链关节属性设置

关闭重力作用(不影响cube的摆动),打开动力学属性(固定铰链,保持静止)

绿色方块属性设置

打开重力作用(摆动的动力来源),关闭动力学属性(这样不会静止) //为什么?不能理解。

绑定在空对象上的cube,这个transform属性的位置是相对位置。

先把相对位置设为(0,0,0),此时cube不会摆动。

改变z值,随便改一个,比如1,cube开始摆动。

效果

弹簧关节

先创建一个空对象,再添加弹簧关节组件

绑定球体至弹簧上

效果

 

点击以发射子弹

创建一个子弹(刚体)

把它做成预制体:

先创建一个Prefab文件夹,再把子弹拖进去,就变蓝了

创建BulletFire.cs脚本

using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using UnityEngine;public class BulletFire : MonoBehaviour
{Ray ray;//定义射线public Rigidbody bullet_rigidbody;//定义子弹刚体RaycastHit raycastHit;//射线碰撞检测// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){if(Input.GetMouseButtonDown(0)){ray = Camera.main.ScreenPointToRay(Input.mousePosition);//生成一条射线if (Physics.Raycast(ray, out raycastHit))//射线检测:如果和其他物体碰撞,就发射子弹{Rigidbody bullet = Instantiate<Rigidbody>(bullet_rigidbody);//定义子弹刚体,然后克隆一个子弹//此处不用bullet.position,而是bullet.transform.position,两者有区别bullet.transform.position = Camera.main.transform.position;//子弹初始位置设为摄像机的位置bullet.AddForce((raycastHit.point - bullet.transform.position)*3f,ForceMode.Impulse);//AddForce函数:给刚体施加一个力,然后发射出去。注意括号。//Destroy(raycastHit.collider.gameObject);//销毁点击对象}}}
}

把该脚本绑定到摄像机上,并在属性中指定子弹的预制体

效果(指哪打哪)

 

子弹的销毁(防止浪费内存资源)

创建一个DestroyBullet.cs脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DestoryBullet : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}private void OnCollisionEnter(Collision collision){if(collision.gameObject.tag!="bullet"){return;}Destroy(collision.gameObject);}private void OnTriggerStay(Collider other){if (other.gameObject.tag != "bullet")return;if (other.attachedRigidbody)other.attachedRigidbody.AddForce(Vector3.up * 20f);}
}

通过碰撞检测+标签的方式实现

给子弹添加标签

如果与墙碰撞的东西是子弹,就销毁子弹。

把脚本绑定到墙上,记得把墙固定住

注意:墙不能设置为触发器,否则无法碰撞,也就无法销毁子弹

效果

子弹碰墙后被销毁

 

子弹穿过cube加速

(代码包含在上面)

cube设置为

透明材质(暂时不会)

效果

子弹明显加速

 

随机生成Cube(按A键控制生成),子弹若与其碰撞,将被销毁

创建cube预制体,设定为可被撞开(运动学on)

若用代码创建cube,则难以调整其运动学属性

GameObject cloneCube = Instantiate(cubeObj, new Vector3(0, 3, 0), Quaternion.identity);
GameObject cubeObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
cubeObj.GetComponent<Renderer>().material.color = Color.cyan;

创建RandomCube.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class RandomCube : MonoBehaviour
{public Rigidbody cubeObj;//public GameObject cubeObject;// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){if (Input.GetKey(KeyCode.A)){Rigidbody cloneCube=Instantiate<Rigidbody>(cubeObj);float x = Random.Range(-5.0f, 5.0f);float y = Random.Range(1f, 5.0f);float z = Random.Range(-5.0f, 5.0f);cubeObj.transform.position = new Vector3(x, y, z);cubeObj.tag = "RandomCube";cubeObj.name = "RandomCube";}}
}

把RandomCube.cs挂到平面上

实现销毁子弹的效果,就把DestroyBullet.cs挂到RandomCube预制体上

效果

按A随机生成RandomCube,子弹撞击后,子弹销毁,RandomCube在撞击下运动

一张合照

 

 

 

 

这篇关于Unity 3d 刚体与碰撞体属性 固定、铰链、弹簧关节的使用 子弹的发射和销毁的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/267118

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他