240 lines
6.6 KiB
C#
240 lines
6.6 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
public class CharacterControl : MonoBehaviour
|
||
{
|
||
// 当前移动速度
|
||
private float currentSpeed = 0f;
|
||
private float speedSmoothVelocity = 0f; // 用于存储速度平滑过渡的参考值
|
||
|
||
//移动的速度
|
||
public float moveSpeed=1f;
|
||
//主摄像机,用于确定移动的方向
|
||
public Camera mainCamera;
|
||
private Vector3 moveDirection = Vector3.zero;
|
||
|
||
//角色rigidbody
|
||
private Rigidbody body;
|
||
//弹跳力
|
||
public float JumpAbility = 1f;
|
||
//跳后的移动速度
|
||
public float JumpMoveSpeed = 1f;
|
||
//角色动画控制器
|
||
private CharacterAin Characterain;
|
||
|
||
//接收输入
|
||
float vertical;
|
||
float horizontal;
|
||
//垂直和水平输入值计算出一个方向向量
|
||
Vector3 dir;
|
||
|
||
//判断是否在移动
|
||
private bool IsMoving = false;
|
||
|
||
|
||
|
||
// 定义相机 FOV 相关变量
|
||
public float normalFOV = 60f; // 正常行走时的FOV
|
||
public float sprintFOV = 120f; // 奔跑时的FOV
|
||
public float fovChangeSpeed = 2f; // FOV改变的速
|
||
|
||
|
||
//跑步切换的时间
|
||
private float MoveTime = 0f;
|
||
//走路的时间
|
||
public float walkTime;
|
||
//跑的时间
|
||
public float runTime;
|
||
//跑步时平滑切换fov
|
||
private float targetFOV;
|
||
|
||
private Button recubtn;
|
||
|
||
public GameObject cha;
|
||
// Start is called before the first frame update
|
||
void Start()
|
||
{
|
||
recubtn = GameObject.Find("Canvas/Recuse").GetComponent<Button>();
|
||
recubtn.gameObject.SetActive(false);
|
||
recubtn.onClick.AddListener(Recuse);
|
||
Init();
|
||
}
|
||
|
||
// Update is called once per frame
|
||
void Update()
|
||
{
|
||
// Jump();
|
||
//JumpMove();
|
||
}
|
||
|
||
private void FixedUpdate()
|
||
{
|
||
Move();
|
||
Face();
|
||
}
|
||
|
||
|
||
//初始化
|
||
void Init()
|
||
{
|
||
body = transform.GetComponent<Rigidbody>();
|
||
if (body==null)
|
||
{
|
||
body = gameObject.AddComponent<Rigidbody>();
|
||
}
|
||
Characterain = transform.GetComponent<CharacterAin>();
|
||
}
|
||
|
||
//移动,走、奔跑,键盘or手柄控制
|
||
void Move()
|
||
{
|
||
|
||
//不在地面不能移动或者在跳跃不能移动
|
||
//如果不加Characterain.characterState==CharacterState.jump,可能会导致跳跃后落到地面的瞬间,瞬间转为移动状态,动画会异常,无法恢复站立
|
||
//解决方案二,在charaterAin中将检测恢复函数写到update里。(现写在fixedupdate)
|
||
if (!Characterain.IsOnGround()|| Characterain.characterState==CharacterState.jump)
|
||
{
|
||
return;
|
||
}
|
||
|
||
//获取输入
|
||
vertical = Input.GetAxis("Vertical");
|
||
horizontal = Input.GetAxis("Horizontal");
|
||
|
||
|
||
// 使用摄像头的方向来计算角色的移动方向
|
||
Vector3 forward = mainCamera.transform.forward; // 摄像头前方
|
||
Vector3 right = mainCamera.transform.right; // 摄像头右方
|
||
|
||
// 将 Y 轴的方向设为 0,避免角色朝上下移动
|
||
forward.y = 0f;
|
||
right.y = 0f;
|
||
|
||
// 归一化方向向量
|
||
forward.Normalize();
|
||
right.Normalize();
|
||
|
||
// 计算移动方向
|
||
dir = forward * vertical + right * horizontal;
|
||
//dir = transform.forward * vertical +transform.right * horizontal;
|
||
|
||
//死区
|
||
//移动,暂时只要向前移动的动画
|
||
if (Mathf.Abs(vertical) > 0.01f || Mathf.Abs(horizontal) > 0.01f)
|
||
{
|
||
if (MoveTime< (walkTime + runTime+0.1f))
|
||
{
|
||
MoveTime += Time.deltaTime;
|
||
}
|
||
|
||
|
||
MoveState();
|
||
|
||
if (!IsMoving)
|
||
{
|
||
IsMoving = true;
|
||
}
|
||
}
|
||
else if(Characterain.GetCharacterState()!= CharacterState.jump)
|
||
{
|
||
Characterain.SetPlayerState(CharacterState.idle);
|
||
IsMoving = false;
|
||
MoveTime = 0f;
|
||
}
|
||
}
|
||
|
||
//移动状态
|
||
void MoveState()
|
||
{
|
||
if (MoveTime < walkTime) // 慢走
|
||
{
|
||
Characterain.SetPlayerState(CharacterState.SlowWalk);
|
||
body.MovePosition(transform.position + dir * Time.deltaTime * moveSpeed * 1f);
|
||
targetFOV = normalFOV; // 设置目标FOV为正常值
|
||
}
|
||
else if (MoveTime < (walkTime+runTime)) // 普通行走
|
||
{
|
||
Characterain.SetPlayerState(CharacterState.walk);
|
||
body.MovePosition(transform.position + dir * Time.deltaTime * moveSpeed * 1.5f);
|
||
targetFOV = normalFOV + 30f; // 设置目标FOV为增加值
|
||
}
|
||
else // 奔跑
|
||
{
|
||
Characterain.SetPlayerState(CharacterState.run);
|
||
body.MovePosition(transform.position + dir * Time.deltaTime * moveSpeed * 2f);
|
||
targetFOV = sprintFOV; // 设置目标FOV为奔跑值
|
||
}
|
||
|
||
// 使用插值平滑调整相机的FOV
|
||
mainCamera.fieldOfView = Mathf.Lerp(mainCamera.fieldOfView, targetFOV, fovChangeSpeed * Time.deltaTime);
|
||
}
|
||
|
||
|
||
|
||
//面向
|
||
void Face()
|
||
{
|
||
|
||
// 计算输入方向
|
||
Vector3 moveInput = new Vector3(horizontal, 0f, vertical).normalized;
|
||
|
||
if (moveInput.magnitude > 0.1f) // 如果有输入
|
||
{
|
||
// 将输入方向与摄像机方向结合,计算出角色应该面向的世界方向
|
||
Vector3 targetDirection = mainCamera.transform.forward * vertical + mainCamera.transform.right * horizontal;
|
||
targetDirection.y = 0f; // 忽略Y轴的旋转,只关注水平旋转
|
||
targetDirection.Normalize();
|
||
|
||
// 计算目标旋转角度
|
||
Quaternion targetRotation = Quaternion.LookRotation(targetDirection);
|
||
|
||
// 使用Slerp平滑地旋转到目标角度,rotationSpeed控制转身的快慢
|
||
float rotationSpeed = 10f; // 旋转速度可调
|
||
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
|
||
}
|
||
}
|
||
|
||
//jump已经不需要了
|
||
//跳
|
||
//void Jump()
|
||
//{
|
||
// if (Input.GetKey(KeyCode.Space) && Characterain.GetCharacterState() != CharacterState.jump)
|
||
// {
|
||
// body.AddForce(Vector3.up * JumpAbility * 2F, ForceMode.Impulse);
|
||
// Characterain.SetPlayerState(CharacterState.jump);
|
||
// }
|
||
//}
|
||
|
||
//跳后的移动
|
||
//void JumpMove()
|
||
//{
|
||
// if (IsMoving && !Characterain.IsOnGround())
|
||
// {
|
||
// Vector3 airMoveForce = dir.normalized * JumpMoveSpeed * 0.5f;
|
||
// body.AddForce(airMoveForce, ForceMode.Force);
|
||
// }
|
||
//}
|
||
|
||
void Recuse()
|
||
{
|
||
Characterain.SetSkillAin(CharacterSkill.Rescue);
|
||
StartCoroutine("Rescuereturn");
|
||
}
|
||
|
||
IEnumerator Rescuereturn()
|
||
{
|
||
yield return new WaitForSeconds(2);
|
||
Characterain.SetSkillAin(CharacterSkill.NoSkill);
|
||
cha.GetComponent<RecuseNpc>().Setnpcstate();
|
||
|
||
}
|
||
|
||
/* public NpcState Setnpcstate()
|
||
{
|
||
Debug.Log("Setnpcstate调用");
|
||
return NpcState.Healthy;
|
||
}*/
|
||
|
||
}
|