前言
添加程序摇摆和摆动是为任何FPS游戏添加一些细节的非常简单的方法。但是并不是所以的模型动画都会配有武器摆动动画效果,在本文中,将实现如何使用一些简单的代码实现武器摇摆和摆动效果,这比设置动画来尝试实现类似效果要容易得多
开始
新增SwayNBobScript代码
using UnityEngine; // 武器摆动脚本 public class SwayNBobScript : MonoBehaviour { [Header("Sway")] public float step = 0.01f; // 摆动步长 public float maxStepDistance = 0.06f; // 最大步长距离 Vector3 swayPos; // 摆动位置 [Header("Sway Rotation")] public float rotationStep = 4f; // 摆动旋转步长 public float maxRotationStep = 5f; // 最大旋转步长 Vector3 swayEulerRot; // 摆动旋转角度 public float smooth = 10f; // 平滑移动速度 float smoothRot = 12f; // 平滑旋转速度 [Header("Bobbing")] public float speedCurve; // 速度曲线参数 float curveSin { get => Mathf.Sin(speedCurve); } // 曲线正弦值 float curveCos { get => Mathf.Cos(speedCurve); } // 曲线余弦值 public Vector3 travelLimit = Vector3.one * 0.025f; // 移动限制 public Vector3 bobLimit = Vector3.one * 0.01f; // 摆动限制 Vector3 bobPosition; // 摆动位置偏移量 public float bobExaggeration; // 摆动夸张系数 [Header("Bob Rotation")] public Vector3 multiplier; // 摆动旋转系数 Vector3 bobEulerRotation; // 摆动旋转角度 void Update() { GetInput(); Sway(); SwayRotation(); BobOffset(); BobRotation(); CompositePositionRotation(); } Vector2 walkInput; // 行走输入 Vector2 lookInput; // 视角输入 // 获取输入 void GetInput() { walkInput.x = Input.GetAxis("Horizontal"); walkInput.y = Input.GetAxis("Vertical"); walkInput = walkInput.normalized; lookInput.x = Input.GetAxis("Mouse X"); lookInput.y = Input.GetAxis("Mouse Y"); } // 摆动 void Sway() { Vector3 invertLook = lookInput * -step; invertLook.x = Mathf.Clamp(invertLook.x, -maxStepDistance, maxStepDistance); invertLook.y = Mathf.Clamp(invertLook.y, -maxStepDistance, maxStepDistance); swayPos = invertLook; } // 摆动旋转 void SwayRotation() { Vector2 invertLook = lookInput * -rotationStep; invertLook.x = Mathf.Clamp(invertLook.x, -maxRotationStep, maxRotationStep); invertLook.y = Mathf.Clamp(invertLook.y, -maxRotationStep, maxRotationStep); swayEulerRot = new Vector3(invertLook.y, invertLook.x, invertLook.x); } // 合成位置和旋转部分 void CompositePositionRotation() { transform.localPosition = Vector3.Lerp(transform.localPosition, swayPos + bobPosition, Time.deltaTime * smooth); transform.localRotation = Quaternion.Slerp(transform.localRotation, Quaternion.Euler(swayEulerRot) * Quaternion.Euler(bobEulerRotation), Time.deltaTime * smoothRot); } // 摆动偏移 void BobOffset() { speedCurve += Time.deltaTime * (MovementScript.Instance.isGround ? (Input.GetAxis("Horizontal") + Input.GetAxis("Vertical")) * bobExaggeration : 1f) + 0.01f; bobPosition.x = (curveCos * bobLimit.x * (MovementScript.Instance.isGround ? 1 : 0)) - (walkInput.x * travelLimit.x); bobPosition.y = (curveSin * bobLimit.y) - (Input.GetAxis("Vertical") * travelLimit.y); bobPosition.z = -(walkInput.y * travelLimit.z); } // 摆动旋转 void BobRotation() { bobEulerRotation.x = (walkInput != Vector2.zero ? multiplier.x * (Mathf.Sin(2 * speedCurve)) : multiplier.x * (Mathf.Sin(2 * speedCurve) / 2)); bobEulerRotation.y = (walkInput != Vector2.zero ? multiplier.y * curveCos : 0); bobEulerRotation.z = (walkInput != Vector2.zero ? multiplier.z * curveCos * walkInput.x : 0); } }
代码挂载在武器父类上即可
正常情况下,我们还要实现武器在瞄准时,减低或者禁用武器摆动效果,可以选择在瞄准时启动和禁用SwayNBobScript脚本
public SwayNBobScript swayNBobScript; private void Update() { DetermineAim(); } //瞄准 void DetermineAim(){ swayNBobScript.enabled = true; if (Input.GetMouseButton(1)){ swayNBobScript.enabled = false; } }
效果