1.准备:配置Unity3d环境和用VS2019写C#脚本
首先,配置Unity3d环境推荐使用是UnityHub作为平台,然后在UnityHub里边下载Unity3D版本,笔者这里选用的的是2019.4.16f1c1版本,值得注意的是由于Unity给的人机认证邮件的图片源是google的,因此注册的时候是需要翻墙的,挂个梯子验证邮箱就可以了
然后,就是配置VS2019写C#脚本的环境,这里放一个人家博客
VS写C#脚本
此篇文章
以上环节都搞定了之后,就可以正式开始进入Unity3D的学习了。
2.预制体及其编辑(prefab)
概念:是预先制作好的物体(模板),将游戏对象事件制作好,作为资源备用。一般用于游戏对象的动态创建。
预制体的创建方法是:
在Hierarchy窗口选定当前场景的物体,然后拖入下面Project里面的Assets的目标文件夹中,这样就创建了一个预制体
预制体实例(prefab instance),根据prefab制作出来的实例,使用预制体,可以快速创建多个实例(相当于一个模板)
预制体资源,是可以单独编辑的:
①在Project窗口,双击*.prefab资源
②在Inspector窗口,点Open prefabs
③在Hierarchy窗口,找到预制体的实例,点右侧的小箭头
值得注意的是,就算实例已经被创建出来,而后面预制体再被改变了,那么已经被创建出来的实例也会被改变。
3.使用物理组件的注意事项
当使用物理引擎的时候,游戏对象的大小比刚体的质量更重要。如果你发现刚体的行为不是你所期望的,比如移动的太慢,漂浮,或者不能正确的进行碰撞,尝试一下修改你的模型的缩放值。Unity的默认单位是1 unit = 1 米,物理引擎的计算也是按照这个单位来的。比如,一个摩天大楼的倒塌与一个由积木搭成的玩具房子的倒塌是完全不一样的,所以,不同大小的对象在建模时都应该按照统一的比例。
对于一个人类角色模型来说,他应该有2米高。可以创建一个Box来作为参照物,默认的Box为1米,所以一个角色应该是Box的两倍高。
当然,你也可以通过修改导入模型的缩放来调整比例,如果你不能直接修改模型本身的话。在Project面板中选中模型,调整其Importer属性,注意不是变换里的缩放。
如果你的游戏需要你实例化具有不同缩放值的对象,你也可以调整变换里的缩放值,但是物理引擎来创建这个对象的时候会额外多做一点工作,这可能会引起一点性能问题。这个问题不会太严重,但性能显然会比上面两种方法低。同样要注意的是,non-uniform scales也会引起一些问题,如果这个对象具有父对象的话。基于以上原因,尽可能的在制作模型的时候就按照Unity的比例来建模。
4.物理组件之刚体
描述
刚体能让你的游戏对象被物理引擎所控制,它能通过受到推力和扭力来实现真实的物理表现效果。所有游戏对象必须包含刚体组件来实现重力、通过脚本施加力、或者与其他对象进行交互,这一切都通过NVIDIA的PhysX物理引擎来实现。
属性
Mass 质量,单位为Kg,建议不要让对象之间的质量差达到100倍以上
Drag 空气阻力,为0表示没有阻力,infinity表示立即停止移动
Angular Drag 扭力的阻力,数值意义同上
Use Gravity 是否受重力影响
Is Kinematic 是否为Kinematic刚体,如果启用该参数,则对象不会被物理所控制,只能通过直接设置位置、旋转和缩放来操作它,一般用来实现移动平台,或者带有HingeJoint的动画刚体
Interpolate 如果你的刚体运动时有抖动,尝试一下修改这个参数,None表示没有插值,Interpolate表示根据上一桢的位置来做平滑插值,Extrapolate表示根据预测的下一桢的位置来做平滑插值
Freeze Rotation 如果选中了该选项,那么刚体将不会因为外力或者扭力而发生旋转,你只能通过脚本的旋转函数来进行操作
Collision Detection 碰撞检测算法,用于防止刚体因快速移动而穿过其他对象
Constraints 刚体运动的约束,包括位置约束和旋转约束,勾选表示在该坐标上不允许进行此类操作
应用场景
总而言之,Unity3D中任何物体想要受到重力、外力的影响都必须包含一个刚体组件。
常用方法
(1)AddForce函数:对刚体施加一个指定方向的力,使其发生移动。
函数表示如下:
function AddForce(force: Vector3,mode: ForceMode=ForceMode.Force) : void
函数ForceMode有四种模式:Force、Impulse、Acceleration、VelocityChange
Force表示施加一个恒力, Impulse表示施加一个瞬间冲击力
Acceleration表示对物体施加加速度 VelocityChange 表示改变物体速度
(2)MovePosition函数:将刚体移动到position位置。
函数表示如下:
function MovePosition(position : Vector3) : void
3)MoveRoration函数:将刚体旋转相对应的角度。
5.物理组件之碰撞体
描述
碰撞体使得物体具有了"体积这一特性",当其他物体与之交互时,能够感知到这个物体的存在
常用的碰撞体
Box Collider:盒子碰撞体(骨骼),形状是立方体,用于包裹类似“立方体”的模型,例如门、盒子等
组件属性:
(1)Center:骨骼的中心点
(2)Size:骨骼的大小
Sphere Collider:球形碰撞体(骨骼),形状是球形,用于包裹类似“球形”的模型
组件属性:
Radius:骨骼的半径
Capsule Collider:胶囊碰撞体(骨骼),形状是胶囊
组件属性:
Radius:骨骼的半径
Height:骨骼沿某个方向放缩的高度
Direction:调整放缩高度的对应方向
Mesh Collider:网格碰撞体,万能碰撞体,可以用于包裹所有复杂的模型(可能需要自己配置该组件)
组件属性:
Mesh:根据指定的网格,生成碰撞体骨骼
6.应用方法:碰撞检测(Collision检测)
描述
Collision检测的实现是基于Collider这个组件来完成的,使用Collision检测需要用到下面三个重要的方法:OnCollisionEnter()在刚体与刚体接触时立即调用此方法、OnCollisionStay()在刚体与刚体碰撞中调用此方法、OnCollisionExit()在刚体与刚体碰撞结束时调用此方法。
触发条件
发生碰撞(Collision)的前提是:双方都有碰撞器,且至少一方有刚体。此时将产生物理碰撞(也就是不会穿模)
代码示例
子弹碰撞体检测,并且做出对应的扣血动作
private void OnCollisionEnter(Collision collision)
{
if (isFirstTime)
{
isFirstTime = false;
return;
}
//分好类后就按照类里的东西来操作
Debug.Log(robotType + "检测到了碰撞");
this.valNow = slider.value;//更新
//1.首先是进行该机器人的扣血操作
this.valNow -= damage;
//2.然后检测是不是死了
if (this.isDestory())
{
Destroy(robotNow);
Debug.Log(robotNow + "寄了");
Application.Quit();
}
//如果没死,那么就更新UI上的数据
healText.text = "血量:" + this.valNow + "/2000";
slider.value = this.valNow;
}
7.应用方法:触发检测(Trigger检测)
描述
使用Trigger检测需要勾选IsTrigger属性,并用到下面的三个重要方法:OnTriggerEnter():开始碰撞、OnTriggerStay():碰撞中 、 OnTriggerExit():结束碰撞。
触发条件
Trigger将造成非物理碰撞(将会产生穿模现象),发生接触(Trigger)的前提是:双方都有碰撞器,且至少一方有刚体,且至少一方勾选了IsTrigger属性。
代码示例
private void OnTriggerEnter(Collider other)
{
if (!(transform.tag.Equals("F1Buff"))) {
//筛选信号发出者
return;
}
if (!isTouch)//F1Buff区域的作用的是为PlayerRobot机器人增加200点血量,注意不要溢出
{
healText = GameObject.FindWithTag("PlayerRobotUI").transform.GetChild(0).GetChild(3).GetComponent<Text>();
slider = GameObject.FindWithTag("PlayerRobotUI").transform.GetChild(0).GetComponent<Slider>();
valNow = slider.value+200;
if (valNow >= 2000)
{
valNow = 2000;
}
slider.value = valNow;
isTouch = true;
healText.text= "血量:" + valNow + "/2000";
Debug.Log("PlayerRobot的血量恢复了两百");
}
//最终将触发flag调整为true;
}