Unity学习笔记 02 —— 更多API

Unity更多API

常用函数

线性插值Mathf.Lerp

用法Mathf.Lerp(float from, float to, float rate);

返回值 = from + (to - from) * rate

例如有代码

private float rate = 0.1f;
private float step = 0.1f;
void FixedUpdate() 
{
    if (rate <= 1) 
    {
        Debug.Log(Mathf.Lerp(1, 10, rate));
        rate += step;
    }
}

其输入形似:

1.9
2.8
3.7
4.6
5.5
6.4
7.3
8.20001
9.1

在实际使用中可以起缓动作用。另外,Vector3、Vector2等类也有相似类型的函数,如Vector3.Lerp(Vector3 from, Vector3 to, float rate);

更多Api

时间Time

Time.time 从游戏开始的时间,受时间缩放影响

Time.timeScale 时间缩放值

Time.unscaledTime 不受时间缩放影响的时间

Time.deltaTime 渲染一帧的时间,受硬件影响,每一次渲染都可能不同,受时间缩放影响

Time.unscaledTime 不受时间缩放影响

因为每次Update执行的时间间隔都可能不同,所以一般固定时长的操作在FixedUpdate中进行

Time.realtimeSinceStartup 项目从启动到现在的时间

预制件Prefab

可以在Assets中右键,选择Create目录中的Prefab选项创建空白的预制件,或者将Hierarchy中游戏对象直接拖动到Assets中可以根据游戏对象创建预制件。

通过使用预制件可以快速复用游戏对象,提升开发效率。

需要注意的是,修改单个预制件的实例不会影响其他实例,如果要修改所有实例可以通过以下两种方法:

  1. 从Assets中进入预制件修改界面,会同时修改所有用到预制件的地方。

  2. 修改实例,然后选择覆盖预制件

使用预制件截图

输入Input

Input.GetMouseButton 鼠标按住

Input.GetMouseButtonUp 鼠标按下瞬间

Input.GetMouseButtonDown 鼠标按下瞬间

Input.GetKeyDown 监听按下某一按键

应用示例:

    void Update()
    {
        if (Input.GetMouseButton(0))    // 按住鼠标左键
        {
            transform.Translate(0F, 0.1F, 0F);
        }
        if (Input.GetMouseButton(1))    // 按住鼠标右键
        {
            transform.Translate(0F, -0.1F, 0F);
        }
        if (Input.GetMouseButtonUp(0))  // 松开鼠标左键瞬间
        {
            transform.Translate(-0.1F, 0F, 0F);
        }
        if (Input.GetMouseButtonDown(1))    // 按下鼠标右键瞬间
        {
            transform.Translate(0.1F, 0F, 0F);
        }
        if (Input.GetKeyDown(KeyCode.Space))    // 按下空格键瞬间
        {
            transform.Rotate(0.5F, 0.5F, 0.5F, Space.World);
        }
    }

按住鼠标左键时:物体向上移动

按住鼠标右键时:物体向下移动

松开鼠标左键瞬间:物体向左移动

按下鼠标右键瞬间:物体向右移动

按下空格瞬间:物体轻微旋转(多按几次会比较明显)

视锥体

场景中的摄像机Camara中表示视野范围

在Unity中,摄像机的视野方位是一个锥台,其范围受以下因素影响

  1. 近裁剪平面 Clipping Planes -> Near 视锥体靠近摄像机的面,可以视为锥台的上表面

  2. 远裁剪平面 Clipping Planes -> Far 视锥体原理摄像机的面,可以视为锥台的下表面

  3. 视野距离 Field of View 两个面之间的距离,即锥台的高

虚拟轴

可以改动的按钮

可以在Edit -> Project Setting -> Input Manager -> Axes中管理

[[InputManagerAxesHorizontal截图]]

主要属性

Name: 虚拟轴名称

Negative Button: 负按键,此处为键盘左方向键

Positive Button: 正按键,此处为键盘右方向键

Alt Negative Button: 替代负按键,效果等同于负按键,此处为a键

Alt Positive Button: 替代正按键,效果等同于正按键,此处为b键

Gravity:从1恢复回0的速度,越大越快

Dead: 过度的精细度

Sensitivity: 从0到1的速度,越大越快

Invert: 翻转,勾选时交换负按键和正按键的作用

Type: 虚拟轴类型,此处为按键

Axis: 轴

Joy Num: 手柄编号

获取虚拟轴的函数

Input.GetAxis(虚拟轴名称)

正负按键同时按下时,返回0。按下Negative Button或Alt Negative Button时返回负值,按下Positive Button或Alt Positive Button时返回正值。

例如Input.GetAxis("Horizontal")

有顺序的按下时,返回先按下的。按下Negative Button或Alt Negative Button时返回负值,按下Positive Button或Alt Positive Button时返回正值。

Input.GetAxisRaw(虚拟轴名称)

只要都按下了,就返回0

例如Input.GetAxisRaw("Horizontal")

物理引擎

刚体组件RigidBody

添加刚体组件:选中游戏对象 -> 打开Inspector -> 页面底部选择Add Component -> Phisics -> RigifBody即可添加刚体组件

刚体组件属性截图

主要属性

Mass 物体质量

Drag 物体移动时收到的空气阻力

Angular Drag 物体转动时收到的空气阻力

Use Gravity 使用重力,勾选时物体受重力影响

Is Kinematic 勾选时物体不在受物理引擎控制

Interpolate 插值,用于缓解刚体运动时的抖动,包括以下三个取值

1. None

2. Interpolate 内插值,根据上一帧变化来平滑本帧变化

3. Extrapolate 外插值,预估下一帧变化来平滑本帧变化

Collision Detection 碰撞检测,取值如下

1. Discrete 离散碰撞检测,适用于普通碰撞

2. Continuous 连续碰撞检测

3. Continuous Dynamic 连续动态碰撞检测,适用于告诉物体

可以设置碰撞检测频率,频率越大性能要求越高

Constraints 运动约束

`Freeze Position` 冻结对应坐标轴的移动

`Freeze Rotation` 冻结对应坐标轴的旋转
发生碰撞的条件
  1. 接触的物体具有碰撞器

  2. 主动运动的物体具有刚体

碰撞器Collider

碰撞器是物体碰撞的必要条件,面数越少的碰撞器的系统开销更小,正方体碰撞器的开销最小。

游戏对象默认碰撞器为Mesh Collider,它的有点是和Mesh相同,比较逼真,缺点是系统开销很大。

碰撞的三阶段及钩子函数

OnCollisionEnter(Collision collOther) 进入碰撞的瞬间(碰撞的第一帧)

OnCollisionStay(Collision collOther) 碰撞后每一帧都执行

OnCollisionExit(Collision collOther) 停止碰撞的瞬间(碰撞的最后一帧)

示例

    void OnCollisionEnter(Collision collOther) {
        Debug.Log(collOther.gameObject.name);
    }

上述代码代码会在碰撞瞬间,打印出发生碰撞的另一个游戏对象的名字。在本示例项目中输出如下(一个Capsule碰撞另一Capsule,然后和地面Land碰撞):

碰撞测试输出

内容应用 —— 移动相机

脚本文件CameraControll.cs

using UnityEngine;
public class CameraControll : MonoBehaviour
{
    [SerializeField]
    private float rotataionSpeed = 1F;    // 转动速度
    [SerializeField]
    private float translationSpeed = 1F;  // 移动速度

    void FixedUpdate()
    {
        // 旋转相机
        CameraRotationControll();
        // 移动相机    
        CameraPositionControll();
    }

    void CameraRotationControll() {
        // 旋转相机
        float x = Input.GetAxis("Mouse X"); // 获取鼠标X轴移动的虚拟轴
        float y = Input.GetAxis("Mouse Y"); // 获取鼠标Y轴移动的虚拟轴

        if ( Input.GetMouseButton(2) && (x != 0 || y != 0))   // 用户按下鼠标中间并移动鼠标
        {   // 计算摄像机转动

            // 围绕X轴转动实现视野的上下转动
            // 因为鼠标向上移动时欧拉角为负数,但是我们需要向正方向运动,所以加负号翻转方向
            // 上下转动时应当围绕自身X轴转动
            transform.Rotate(- y * rotataionSpeed, 0F, 0F, Space.Self);

            // 围绕Y轴转动实现视野的左右转动
            // 左右转动时应当围绕世界Y轴转动,否则将影响到Z轴的值(而Z轴的值不应该被修改)
            transform.Rotate(0F, x * rotataionSpeed, 0F, Space.World);
        }
    }

    void CameraPositionControll() {
        float horizontal = Input.GetAxis("Horizontal"); // 左右
        float vertical = Input.GetAxis("Vertical"); // 前后
        if (horizontal != 0)
        {
            // 在X轴上移动
            transform.Translate(horizontal * translationSpeed, 0F, 0F);
        }
        if (vertical != 0)
        {
            // 在Y轴上移动
            transform.Translate(0F, 0F, vertical * translationSpeed);
        }

    }
}

上面的代码实现了以下的功能:

  1. 按下鼠标中键并移动鼠标时,转动摄像头

  2. 按下WASD或上下左右箭头时,移动摄像头

算法流程

摄像机转动
Created with Raphaël 2.3.0 开始 鼠标X轴移动数据 鼠标Y轴移动数据 按住鼠标中键? 鼠标在X轴移动? 转动摄像头 结束 鼠标在Y轴移动? yes no yes no yes no
摄像机移动
Created with Raphaël 2.3.0 开始 键盘水平输入数据 键盘垂直输入数据 键盘在X轴有数据? 沿X轴移动摄像头 键盘在Y轴有数据? 沿Y轴移动摄像头 结束 yes no yes no

存在的问题

  1. 摄像头的转动和移动不平滑

  2. 移动的交互可以改进

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值