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

相关文章

如何使用C#串口通讯实现数据的发送和接收

《如何使用C#串口通讯实现数据的发送和接收》本文详细介绍了如何使用C#实现基于串口通讯的数据发送和接收,通过SerialPort类,我们可以轻松实现串口通讯,并结合事件机制实现数据的传递和处理,感兴趣... 目录1. 概述2. 关键技术点2.1 SerialPort类2.2 异步接收数据2.3 数据解析2.

详解如何使用Python提取视频文件中的音频

《详解如何使用Python提取视频文件中的音频》在多媒体处理中,有时我们需要从视频文件中提取音频,本文为大家整理了几种使用Python编程语言提取视频文件中的音频的方法,大家可以根据需要进行选择... 目录引言代码部分方法扩展引言在多媒体处理中,有时我们需要从视频文件中提取音频,以便进一步处理或分析。本文

使用Dify访问mysql数据库详细代码示例

《使用Dify访问mysql数据库详细代码示例》:本文主要介绍使用Dify访问mysql数据库的相关资料,并详细讲解了如何在本地搭建数据库访问服务,使用ngrok暴露到公网,并创建知识库、数据库访... 1、在本地搭建数据库访问的服务,并使用ngrok暴露到公网。#sql_tools.pyfrom

使用mvn deploy命令上传jar包的实现

《使用mvndeploy命令上传jar包的实现》本文介绍了使用mvndeploy:deploy-file命令将本地仓库中的JAR包重新发布到Maven私服,文中通过示例代码介绍的非常详细,对大家的学... 目录一、背景二、环境三、配置nexus上传账号四、执行deploy命令上传包1. 首先需要把本地仓中要

Spring Cloud之注册中心Nacos的使用详解

《SpringCloud之注册中心Nacos的使用详解》本文介绍SpringCloudAlibaba中的Nacos组件,对比了Nacos与Eureka的区别,展示了如何在项目中引入SpringClo... 目录Naacos服务注册/服务发现引⼊Spring Cloud Alibaba依赖引入Naco编程s依

Java springBoot初步使用websocket的代码示例

《JavaspringBoot初步使用websocket的代码示例》:本文主要介绍JavaspringBoot初步使用websocket的相关资料,WebSocket是一种实现实时双向通信的协... 目录一、什么是websocket二、依赖坐标地址1.springBoot父级依赖2.springBoot依赖

Java使用Mail构建邮件功能的完整指南

《Java使用Mail构建邮件功能的完整指南》JavaMailAPI是一个功能强大的工具,它可以帮助开发者轻松实现邮件的发送与接收功能,本文将介绍如何使用JavaMail发送和接收邮件,希望对大家有所... 目录1、简述2、主要特点3、发送样例3.1 发送纯文本邮件3.2 发送 html 邮件3.3 发送带

使用DeepSeek搭建个人知识库(在笔记本电脑上)

《使用DeepSeek搭建个人知识库(在笔记本电脑上)》本文介绍了如何在笔记本电脑上使用DeepSeek和开源工具搭建个人知识库,通过安装DeepSeek和RAGFlow,并使用CherryStudi... 目录部署环境软件清单安装DeepSeek安装Cherry Studio安装RAGFlow设置知识库总

Python FastAPI入门安装使用

《PythonFastAPI入门安装使用》FastAPI是一个现代、快速的PythonWeb框架,用于构建API,它基于Python3.6+的类型提示特性,使得代码更加简洁且易于绶护,这篇文章主要介... 目录第一节:FastAPI入门一、FastAPI框架介绍什么是ASGI服务(WSGI)二、FastAP

Spring-AOP-ProceedingJoinPoint的使用详解

《Spring-AOP-ProceedingJoinPoint的使用详解》:本文主要介绍Spring-AOP-ProceedingJoinPoint的使用方式,具有很好的参考价值,希望对大家有所帮... 目录ProceedingJoinPoijsnt简介获取环绕通知方法的相关信息1.proceed()2.g