美女镇文
图片没找到,请重新加载
?两个对象,一个当前需要移动的物体,一个摄像机物体,摄像机物体放到移动物体子物体下,然后两个脚本分别挂在到对应物体上,组件对象见图:
角色移动脚本:?
using System.Collections.Generic;
using UnityEngine;
public class FirstPersonMovement : MonoBehaviour
{
public float moveSpeed = 5;
[Header("Running")]
public bool canRun = true;
[Tooltip("奔跑速度")]
public float runSpeed = 9;
[Header("奔跑按键")]
public KeyCode runningKey = KeyCode.LeftShift;
//检测是否离地高度
float groundCheck = 1f;
[Tooltip("跳跃高度")]
public float jumpStrength = 2;
//跳跃事件
public event System.Action Jumped;
/// <summary>
/// 重写移动速度,根据最后添加速度为移动速度
/// </summary>
public List<System.Func<float>> speedOverrides = new List<System.Func<float>>();
/// <summary>
/// 当再次接触地面调用当前事件
/// </summary>
public event System.Action Grounded;
public bool IsRunning { get; private set; }
//是否在地面
bool isGrounded = true;
Rigidbody playerRigidbody;
const float OriginOffset = .001f;
Vector3 RaycastOrigin => transform.position + Vector3.up * OriginOffset;
void Awake()
{
playerRigidbody = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
PlayerMove();
}
private void LateUpdate()
{
GroundCheck();
if (Input.GetButtonDown("Jump") && isGrounded)
{
Jump();
}
}
void PlayerMove()
{
IsRunning = canRun && Input.GetKey(runningKey);
// 判断是否奔跑更改玩家移动速度
float targetMovingSpeed = IsRunning ? runSpeed : moveSpeed;
if (speedOverrides.Count > 0)
{
targetMovingSpeed = speedOverrides[speedOverrides.Count - 1]();
}
//得到最终期望数据
Vector2 targetVelocity = new Vector2(Input.GetAxis("Horizontal") * targetMovingSpeed, Input.GetAxis("Vertical") * targetMovingSpeed);
//更新刚体速度
playerRigidbody.velocity = transform.rotation * new Vector3(targetVelocity.x, playerRigidbody.velocity.y, targetVelocity.y);
}
/// <summary>
/// 检测是否离地
/// </summary>
void GroundCheck()
{
CapsuleCollider capsuleCollider = GetComponent<CapsuleCollider>();
Ray ra = new Ray(RaycastOrigin, Vector3.down);
//从当前角色位置发射球形检测,方向向下,距离为groundCheck设置的值
bool isGroundedNow = Physics.SphereCast(ra, capsuleCollider.radius, groundCheck);
if (isGroundedNow && !isGrounded)
{
Grounded?.Invoke();
}
//更新是否离地
isGrounded = isGroundedNow;
}
void Jump()
{
playerRigidbody.AddForce(Vector3.up * 100 * jumpStrength);
Jumped?.Invoke();
}
}
摄像机旋转脚本:?
using UnityEngine;
public class FirstPersonLook : MonoBehaviour
{
[SerializeField]
[Tooltip("玩家对象")]
Transform character;
[Tooltip("鼠标移动灵敏度")]
public float sensitivity = 2;
[Tooltip("移动中平滑")]
public float smoothing = 1.5f;
Vector2 velocity;
Vector2 frameVelocity;
void Reset()
{
//从父对象中找到玩家对象初始化
character = GetComponentInParent<FirstPersonMovement>().transform;
}
void Start()
{
// 进入游戏时锁定鼠标
Cursor.lockState = CursorLockMode.Locked;
}
void Update()
{
MouseRotate();
}
void MouseRotate()
{
Vector2 mouseDelta = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
//根据灵敏度修改输入数据
Vector2 rawFrameVelocity = Vector2.Scale(mouseDelta, Vector2.one * sensitivity);
//在目标速度和当前速度之间进行线性插值,使旋转平滑
frameVelocity = Vector2.Lerp(frameVelocity, rawFrameVelocity, 1 / smoothing);
velocity += frameVelocity;
//对摄像机上下旋转角度进行限制,不超出(-60,60)度
velocity.y = Mathf.Clamp(velocity.y, -60, 60);
// 旋转摄像机的上下,旋转角色的左右
transform.localRotation = Quaternion.AngleAxis(-velocity.y, Vector3.right);
character.localRotation = Quaternion.AngleAxis(velocity.x, Vector3.up);
}
}
|