网站建设的功能模块,全国企业信息系统网官网,好的微商城平台,长兴县住房和城乡建设局 网站文章目录简介Variables实现Target PositionTarget RotationOthers简介
本文介绍如何实现用于Avatar角色的相机控制脚本#xff0c;支持第一人称、第三人称以及两种模式之间的切换#xff0c;工具已上传至SKFramework框架的Package Manager中#xff1a; Variables
Avatar支持第一人称、第三人称以及两种模式之间的切换工具已上传至SKFramework框架的Package Manager中 Variables
Avatar相机跟随的Avatar角色Control Mode控制模式 第一人称/第三人称Mode Change Key切换第一/第三人称模式的快捷键若不支持切换设为None即可 Forward Align With Avatar视角前方是否与Avatar对齐为flase时表示视角可以在水平方向旋转 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在视野中偏左或偏右 Obstacle Layer用于避障检测的Layer层级
如下例所示将场景中障碍物体的Layer设为Obstacle
避障检测时检测该层级 Ctrl Avatar Rot When FP Mode是否在第一人称模式下旋转视角时同步旋转Avatar角色的朝向 实现
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;//只取相机的RotYeuler.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角色运动完成后相机再进行跟随。