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使用ANTLR4对Lua脚本语法校验详解

《Java使用ANTLR4对Lua脚本语法校验详解》ANTLR是一个强大的解析器生成器,用于读取、处理、执行或翻译结构化文本或二进制文件,下面就跟随小编一起看看Java如何使用ANTLR4对Lua脚本... 目录什么是ANTLR?第一个例子ANTLR4 的工作流程Lua脚本语法校验准备一个Lua Gramm

Java Optional的使用技巧与最佳实践

《JavaOptional的使用技巧与最佳实践》在Java中,Optional是用于优雅处理null的容器类,其核心目标是显式提醒开发者处理空值场景,避免NullPointerExce... 目录一、Optional 的核心用途二、使用技巧与最佳实践三、常见误区与反模式四、替代方案与扩展五、总结在 Java

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Qt中QUndoView控件的具体使用

《Qt中QUndoView控件的具体使用》QUndoView是Qt框架中用于可视化显示QUndoStack内容的控件,本文主要介绍了Qt中QUndoView控件的具体使用,具有一定的参考价值,感兴趣的... 目录引言一、QUndoView 的用途二、工作原理三、 如何与 QUnDOStack 配合使用四、自

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

使用Python构建一个Hexo博客发布工具

《使用Python构建一个Hexo博客发布工具》虽然Hexo的命令行工具非常强大,但对于日常的博客撰写和发布过程,我总觉得缺少一个直观的图形界面来简化操作,下面我们就来看看如何使用Python构建一个... 目录引言Hexo博客系统简介设计需求技术选择代码实现主框架界面设计核心功能实现1. 发布文章2. 加

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

使用Python开发一个带EPUB转换功能的Markdown编辑器

《使用Python开发一个带EPUB转换功能的Markdown编辑器》Markdown因其简单易用和强大的格式支持,成为了写作者、开发者及内容创作者的首选格式,本文将通过Python开发一个Markd... 目录应用概览代码结构与核心组件1. 初始化与布局 (__init__)2. 工具栏 (setup_t

Python虚拟环境终极(含PyCharm的使用教程)

《Python虚拟环境终极(含PyCharm的使用教程)》:本文主要介绍Python虚拟环境终极(含PyCharm的使用教程),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录一、为什么需要虚拟环境?二、虚拟环境创建方式对比三、命令行创建虚拟环境(venv)3.1 基础命令3

Python Transformer 库安装配置及使用方法

《PythonTransformer库安装配置及使用方法》HuggingFaceTransformers是自然语言处理(NLP)领域最流行的开源库之一,支持基于Transformer架构的预训练模... 目录python 中的 Transformer 库及使用方法一、库的概述二、安装与配置三、基础使用:Pi