一起来玩U3D之基础物理引擎

一、人机交互Input类

人机交互的常用外部设备就是我们平时用的那些⿏标、键盘、⼿柄、遥杆、触屏、VR⼿柄、按键、VR 等等一系列。我们就是使用这些与计算机进行交互,下面我们看看U3D中常用 的一些方法来实现交互。

  • Input键盘输⼊⽅法
    GetKey ——按住时返回True
    GetKeyDown ——按下第⼀个帧返回True
    GetKeyUp ——松开第⼀帧返回True
    例如:
//这三个方法返回值都是bool类型,所以可以直接用来判断
if (Input.GetKeyDown(KeyCode.Space))
		{
			//如果为真,执行一个功能,比如空格一般对应跳跃
		}
  • Input⿏标输⼊⽅法(左键为0,右键为1,中键为2)
    mousePosition ——⿏标的屏幕坐标
    GetMouseButtonDown ——按下⿏标第⼀帧返回True
    GetMouseButtonUp ——松开⿏标第⼀帧返回true
    GetMouseButton ——按住⿏标返回True
    例如:
if (Input.GetMouseButtonDown(0))
		{
			//如果按下左键,就执行此处的代码
		}
  • Input虚拟轴/按键

打开U3D的设置⾯板 Edit->ProjectSetting->Input
在这里插入图片描述

  • 自上到下一次对应下面的条目:
    虚拟按键名称
    描述名称±
    对应按键±
    备⽤按键±
    抬起按键,值恢复为0的时间
    ⼩于此值,计为0(仅⽤于遥感)
    按下按键,值到达+1或-1的时间
    同时按下正负键值为0
    ±反转

  • 获取轴⽅法 GetAxis
    Horizontal 键盘⽔平轴
    Vertical 键盘竖直轴
    Mouse X ⿏标⽔平移动距离
    Mouse Y ⿏标垂直移动距离
    Mouse ScrollWheel 获取⿏标滚轮值

  • 获取虚拟键⽅法
    GetButton
    Fire
    Jump
    GetButtonDown
    GetButtonUp

例如:

	float hor = Input.GetAxis("HorizontalUI");

	float ver = Input.GetAxis("VerticalUI");

	//控制前后移动
	transform.Translate(Vector3.forward * ver * moveSpeed * Time.deltaTime);

	//控制左右转向
	transform.Rotate(Vector3.up * hor * turnSpeed * Time.deltaTime);

二、Prefab预设体(预制体)

  • 什么是预设体?
    预设是Unity中的一种特殊的资源。
    一般来说预设就是一个或者一系列组件的集合体,你可以在创建了预设以后,对预设进行实例化。
    可以理解成你把一个做好的游戏对象保存成了一个模具,你能够通过这个模具直接创建对象。
  • 怎么保存一个对象为预设体?
    在U3D中,可以通过直接将游戏对象拖入Project面板以创建一个预设体
    在这里插入图片描述
  • 怎么通过一个预设体实例化一个游戏对象?
    可以通过——Instantiate(预设体,位置 Vector3,旋转 Quaternion)——这个方法实现
  • 怎么销毁一个游戏对象?
    可以通过——Destroy方法销毁对象
    该方法有两个重载——⽴刻销毁 Destroy(gameObject)——延迟销毁 Destroy(gameObject,3f)
  • 例如:
//在transform.position位置创建一个旋转为transform.rotation的shellExplosionPrefab对象
//并在explosionTime时间后销毁
Destroy(Instantiate(shellExplosionPrefab, transform.position, transform.rotation), explosionTime);
  • 预设体的作⽤
    1、使⼀个游戏对象以单独⽂件的⽅式存在
    2、使⽤该预设体⽂件,即可随时创建出与该预设体完全⼀样的游戏对象到场景中

  • 预设体注意:
    给预设体拖拽属性对象时,只能拖拽⽂件,不能拖场景⾥的游戏对象

  • 点击场景中⽤预设体⽣成的对象可以进行下面的操作
    Select 选中属于的预设体⽂件
    Revert 还原成与预设体⽂件⼀致的对象
    Apply 将当前游戏对象的设置应⽤到预设体

三、碰撞器

  • 碰撞体组件的作⽤
    1、⽤⼀个包围盒(box、sphere、capsule)将⼀个模型包裹起来,该包围盒来描述碰撞范围
    2、配合刚体组件,实现物理碰撞效果
  • Collider组件
    碰撞盒编辑 Edit Collider
    是否设置为触发器
    添加物理材质
    碰撞体⼤⼩中⼼设置
  • Collider种类
    Box
    Sphere
    Capsule
    Mesh(能不⽤就别⽤,必须要⽤的话, 减少顶点和⾯)
    。。。。。。

刚体

刚体是可以用来完成逼真物理效果的物理组件,包括重⼒、阻⼒、作⽤⼒与反作⽤⼒。

  • RigidBody属性
    质量:在同⼀场景中,两个刚体的质量不要差超过100倍
    阻⼒
    ⻆阻⼒
    是否使⽤重⼒
    是否开启动⼒学(保留物理效果但⽆论发⽣怎样的碰撞,都不会发⽣位置和旋转的改变)
    插值运算:内插值、外插值
    碰撞检测:间隔检测 离散、连续检测 增加检测到碰撞的概率、间隔连续交替
    约束:位置约束、⻆度约束
    在这里插入图片描述

注意:对物体的操作要么使用Transform组件,要么使用RigidBody组件,不要混合使用

  • 常⽤属性
    velocity 速度(⽮量)
    angularVelocity
    drag
    angularDrag
    useGravity
    isKinematic
    freezeRotation
    collisionDetectionMode
  • 常⽤⽅法
    AddForce(Vector3) 添加⼀个⼒
    AddExplosionForce 添加爆炸⼒——参数列表(爆炸⼒⼤⼩Float,爆炸点Vector3,爆炸半径Float)
    注意:执⾏了添加爆炸⼒的⽅法,才会产⽣爆炸,不执⾏⽅法,即便距离爆炸点很近,也不会有任何的爆炸效果
    AddForceAtPosition 在⼀个点上施加⼀个⼒
    AddRelativeForce 添加相对⼒
    AddRelativeTorque 添加相对⼒矩

碰撞检测

  • 碰撞产⽣的条件
    两物体都有Collider、⾄少有⼀个带有RigidBody、两物体保持相对运动
  • 回调⽅法
    OnCollisionEnter(Collision other) ——碰撞开始⼀瞬间时调⽤⼀次
    OnCollisionStay(Collision other)—— 碰撞过程中相对运动时持续调⽤,每帧⼀次
    OnCollisionExit(Collision other) ——碰撞分离⼀瞬间时调⽤
  • 回调⽅法参数 Collision(包含以下信息)
    (1)collider 当前物体所碰撞到的游戏对象(游戏对象的碰撞体组件)
    (2)contacts[] 所有碰撞点的信息:normal、point(碰撞点的坐标) Vector3、…

触发事件

  • 触发事件产⽣的条件
    两物体都有碰撞体
    ⾄少有⼀个带有刚体
    两碰撞体⾄少有⼀个是触发器
  • 设置触发器 将碰撞体组件中的isTrigger属性勾选
  • 回调函数
    OnTriggerEnter(Collider other) 进⼊触发器的时候调⽤⼀次
    OnTriggerStay(Collider other) 处于某个触发器之中的时候持续调⽤,每帧⼀次
    OnTriggerExit(Collider other) 退出触发器的时候调⽤⼀次

碰撞和触发异曲同工,所以只给出一个触发的例子。

  • 例如:

//当该触发器被触发时,如果是玩家触发的,将调用该玩家的Tank组件中的Invincible()方法,
//并销毁这个触发器,否则不做任何操作
void OnTriggerEnter(Collider player)
	{
		if (player.tag.Equals("Player"))
		{
			player.GetComponent<Tank>().Invincible();

			Destroy(gameObject);
		}
		else
		{
			return;
		}

	}

物理射线(⽤于检测碰撞体)

  • 射线类Ray
    射线组成部分:起点(origin)、⽅向(direction )
    获取⿏标屏幕射线 ——ScreenPointToRay ——将屏幕上的⼀个点转换成射线
  • 发射射线
    Raycast 发射物理射线,返回⼀个碰撞检测对象RaycastHit
    RaycastAll 发射物理射线,返回所有碰撞检测对象RaycastHit
    RaycastHit对象中包含——collider 碰撞物体的Collider组件、point 碰撞点坐标
  • 例如:
			//实例一个射线
			Ray ray = new Ray(transform.position + Vector3.up, transform.forward);
			//用来保存射线碰撞对象的信息
			RaycastHit hitInfo;
			
			//射线检测碰撞
			if (Physics.Raycast(ray, out hitInfo))
			{
				//如果射线碰到了碰撞器就执行以下代码
				GameObject obj = hitInfo.collider.gameObject;
				
				if (obj != null && obj.tag.StartsWith("Player"))
				{
					Debug.DrawLine(ray.origin, hitInfo.point);
					if (time > CDTime)
					{
						tankWeapon.Shoot();
						time = 0f;
					}
				}
			}

有疑问的可以私信博主。
点个关注,给个赞呗!
下面的链接是用以上只是做的一个坦克大战单机游戏的脚本实现,有兴趣的可以看一看。
https://blog.csdn.net/maybe_ice/article/details/104738968

发布了35 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/maybe_ice/article/details/104758312