Unity Avatar Camera Controller 第一、第三人称相机控制


简介

本文介绍如何实现用于Avatar角色的相机控制脚本,支持第一人称、第三人称以及两种模式之间的切换,工具已上传至SKFramework框架的Package Manager中:

SKFramework PackageManager

Avatar Camera Controller

Variables

  • Avatar:相机跟随的Avatar角色;
  • Control Mode:控制模式 第一人称/第三人称;
  • Mode Change Key:切换第一/第三人称模式的快捷键,若不支持切换设为None即可;

切换视角

  • Forward Align With Avatar:视角前方是否与Avatar对齐,为flase时表示视角可以在水平方向旋转;

Forward Align With Avatar 为 false

  • Horizontal Sensitivity:水平方向旋转的灵敏度;
  • Vertical Sensitivity:垂直方向旋转的灵敏度;
  • Rot Y Min Limit:垂直方向上旋转最小值限制;
  • Rot Y Max Limit:垂直方向上旋转最大值限制;
  • Rotation Lerp Time:插值到目标旋转值所需的时间;
  • Height:相机与Avatar角色的高度差;
  • Distance:相机与Avatar角色的默认距离;
  • Min Distance Limit:相机距人物最小距离限制;
  • Max Distance Limit:相机距人物最大距离限制;
  • fpmDistance:第一人称模式所用的固定距离(第一人称时距离固定);
  • scollSensitivity:鼠标滚轮的灵敏度(第三人称时可滚动距离);

滚动距离

  • Invert Scroll Direction:反转鼠标滚轮滚动的反向;
  • Horizontal Offset:与Avatar在水平方向上的偏移值(仅在Forward Align With Avatar为true时开启使用,可以让Avatar在视野中偏左或偏右);

Horizontal Offset

  • Obstacle Layer:用于避障检测的Layer层级

如下例所示,将场景中障碍物体的Layer设为Obstacle
Obstacle Layer

避障检测时检测该层级:

避障检测

Ctrl Avatar Rot When FP Mode:是否在第一人称模式下旋转视角时,同步旋转Avatar角色的朝向;

Ctrl Avatar Rot When FP Mode

实现

Target Position

影响相机坐标的元素包括Avatar与相机的距离(Distance)、Avatar与相机的高度差(Height)、目标旋转值、水平方向上的偏移量(Horizontal Offset)及避障检测的影响。

  • Avatar与相机的距离:第三人称模式下通过鼠标滚轮控制,并通过最大最小值进行钳制,第一人称模式下使用固定值,代码如下:
//鼠标滚轮滚动改变距离
distance -= Input.GetAxis("Mouse ScrollWheel") * Time.deltaTime * 100f * scollSensitivity * (invertScrollDirection ? -1f : 1f);
//距离钳制
distance = Mathf.Clamp(distance, minDistanceLimit, maxDistanceLimit);
//插值方式计算距离
targetDistance = controlMode == ControlMode.ThirdPersonControl
    ? Mathf.Lerp(targetDistance, distance, Time.deltaTime * scollSensitivity)
    : fpmDistance;
  • 调用避障检测之前,目标坐标值等于Avatar角色的坐标加上Height高度,加上Distance距离,并乘上目标旋转值,代码如下:
//目标坐标值
Vector3 targetPosition = targetRotation * Vector3.forward * -targetDistance + avatar.position + Vector3.up * height;
  • 避障检测,通过SphereCast球形物理检测,检测碰撞点并向前移动:
//避障检测
private Vector3 ObstacleAvoidance(Vector3 current, Vector3 target, float radius, float maxDistance)
{
    Ray ray = new Ray(target, current - target);
    if (Physics.SphereCast(ray, radius, out RaycastHit hit, maxDistance, obstacleLayer))
    {
        return ray.GetPoint(hit.distance - radius * 2f);
    }
    return current;
}
  • 最终加上水平方向上偏移量的影响:
//避障
targetPosition = ObstacleAvoidance(targetPosition, avatar.position + Vector3.up * height, .1f, distance);
transform.position = targetPosition + Vector3.left * horizontalOffset;

Target Rotation

  • 获取水平及垂直方向上的输入值,让旋转x、y值自增/自减,并通过最大最小值限制垂直方向上的取值范围:
//检测鼠标右键按下
if (Input.GetMouseButton(1))
{
    horizontal = forwardAlignWithAvatar ? 0f : Input.GetAxis("Mouse X") * Time.deltaTime * 100f * horizontalSensitivity;
    vertical = Input.GetAxis("Mouse Y") * Time.deltaTime * 100f * verticalSensitivity;

    rotX += horizontal;
    rotY -= vertical;
    //钳制旋转y值角度
    rotY = Mathf.Clamp(rotY, rotYMinLimit, rotYMaxLimit);
}
  • 加入插值运算,实现平滑旋转:
//目标旋转值
Quaternion targetRotation = Quaternion.Euler(rotY, rotX, 0f);
//旋转值插值率
float rotationLerpPct = 1f - Mathf.Exp(Mathf.Log(1f - .99f) / rotationLerpTime * Time.deltaTime);
//插值方式计算旋转值
targetRotation = Quaternion.Lerp(transform.rotation, targetRotation, rotationLerpPct);
  • 第一人称模式时,相机视角旋转的同时控制Avatar角色的旋转:
transform.rotation = targetRotation;

//第一人称控制模式 相机视角旋转的同时控制Avatar角色的旋转
if (controlMode == ControlMode.FirstPersonControl && ctrlAvatarRotWhenFPMode)
{
    Vector3 euler = Vector3.zero;
    //只取相机的RotY
    euler.y = targetRotation.eulerAngles.y;
    avatar.rotation = Quaternion.Euler(euler);
}

Others

  • 切换控制模式:
if (Input.GetKeyDown(modeChangeKey))
{
    controlMode = controlMode == ControlMode.FirstPersonControl
        ? ControlMode.ThirdPersonControl
        : ControlMode.FirstPersonControl;
}
  • 相机控制代码需写在MonoBehaviour生命周期函数LateUpdate中,确保Avatar角色运动完成后,相机再进行跟随。
Unity相机控制是指在Unity游戏引擎中,对游戏场景中的摄像机进行控制和设置的功能。相机控制可以通过编写C#脚本来实现。 在Unity中,通过C#编写脚本可以实现对相机的位置、旋转和缩放等属性的控制。可以使用Transform组件的方法来实现这些控制,例如使用Translate方法来移动相机的位置,使用Rotate方法来旋转相机的角度,使用Scale方法来缩放相机的大小。 除了基本的位置、旋转和缩放控制Unity还提供了其他功能丰富的相机控制选项。例如,可以设置相机的投影方式,可以使用透视投影或正交投影来呈现不同的视觉效果。可以设置相机的裁剪面,通过设置近裁剪面和远裁剪面的距离,控制场景中的可见范围。 Unity还提供了一些相机运动效果的预设,例如平滑跟随目标物体、旋转围绕目标物体、观察目标物体等。通过调用相应的函数或方法,可以实现这些相机运动效果。 除了基本的相机控制Unity还支持对多个相机进行设置和管理。可以通过设置相机的渲染顺序,实现多个相机在场景中的渲染效果。还可以通过在场景中放置不同的视角相机,实现多角度观察场景。 总结来说,通过使用C#脚本编写代码,可以实现在Unity中对相机的位置、旋转、缩放等属性进行控制,还可以实现一些相机运动效果和多相机管理等功能。这样可以为游戏场景创造出更多丰富和独特的视觉效果。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CoderZ1010

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值