_xiaofang/xiaofang/Assets/Script/Character/CharacterControl.cs
2024-10-23 20:48:23 +08:00

426 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;//救援按钮
private Button disbtn;//配电箱按钮
private Button connectgun;//连接水枪按钮
private Button connectfa;//连接水阀按钮
private Button openfa;//打开水阀按钮
private Image Timermusk;
private Text TimerText;
private int XfsStep=0;
public GameObject cha;
public GameObject xfs;
//private Animator animator;
//private AnimatorStateInfo stateInfo;
private void Awake()
{
Init();
}
// Start is called before the first frame update
void Start()
{
xfs = GameObject.Find("Canvas/xfs");
recubtn = GameObject.Find("Canvas/Recuse").GetComponent<Button>();
disbtn = GameObject.Find("Canvas/Distribution box").GetComponent<Button>();
connectgun = GameObject.Find("Canvas/xfs/ConnectGun").GetComponent<Button>();
connectfa = GameObject.Find("Canvas/xfs/ConnectFa").GetComponent<Button>();
openfa = GameObject.Find("Canvas/xfs/OpenFa").GetComponent<Button>();
Timermusk = GameObject.Find("Canvas/xfs/Timerbg/Timermusk").GetComponent<Image>();
TimerText = GameObject.Find("Canvas/xfs/Timerbg/Timermusk/Timernumer").GetComponent<Text>();
//animator = this.GetComponent<Animator>();
// stateInfo = animator.GetCurrentAnimatorStateInfo(0);
recubtn.gameObject.SetActive(false);
disbtn.gameObject.SetActive(false);
xfs.gameObject.SetActive(false);
recubtn.onClick.AddListener(Recuse);
disbtn.onClick.AddListener(disClick);
connectgun.onClick.AddListener(CgunClick);
connectfa.onClick.AddListener(CfaClick);
openfa.onClick.AddListener(OfaClick);
}
// 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>();
if (Characterain==null)
{
Debug.LogError("Characterain==null");
}
}
//移动走、奔跑键盘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");
}
void disClick()//配电箱操作
{
}
void CgunClick()//连接水枪操作
{
if (XfsStep == 0)
{
//执行操作动画
Debug.Log("连接水枪");
CoGunHide(0);
XfsStep++;
StartCoroutine(AnimTime(5));
Characterain.SetSkillAin(CharacterSkill.OperateSuccess);
}
else
{
//执行操作失败动画
Debug.Log("操作失败,重新开始");
XfsStep = 0;
CoGunHide(0);
Characterain.SetSkillAin(CharacterSkill.OperateFail);
}
}
void CfaClick()//连接水阀操作
{
if (XfsStep == 1)
{
//执行操作动画
Debug.Log("连接水阀");
CoGunHide(1);
XfsStep++;
connectfa.gameObject.SetActive(false);
Characterain.SetSkillAin(CharacterSkill.OperateSuccess);
}
else
{
//执行操作失败动画
XfsStep = 0;
CoGunHide(0);
Characterain.SetSkillAin(CharacterSkill.OperateFail);
}
}
void OfaClick()//打开水阀操作
{
if (XfsStep == 2)
{
//执行操作动画
Debug.Log("打开水阀");
CoGunHide(1);
XfsStep++;
Characterain.SetSkillAin(CharacterSkill.OperateSuccess);
}
else
{
//执行操作失败动画
XfsStep = 0;
CoGunHide(0);
Characterain.SetSkillAin(CharacterSkill.OperateFail);
}
}
IEnumerator AnimTime(float timer)
{
//Timermusk.fillAmount = (5 - 0.2f * Time.deltaTime) / 5;
//TimerText.text = "" + ((5 - 0.2f * Time.deltaTime) / 5).ToString("F2");
yield return new WaitForSeconds(1f);
}
IEnumerator Rescuereturn()//携程实现npc被救援成功后进行撤离
{
recubtn.gameObject.SetActive(false);
yield return new WaitForSeconds(2);
Characterain.SetSkillAin(CharacterSkill.NoSkill);
cha.GetComponent<RecuseNpc>().Setnpcstate();
}
void OperateClick()//帧事件函数,等动作执行完毕允许点击按钮
{
Characterain.SetSkillAin(CharacterSkill.NoSkill);
CoApper();
}
void CoGunHide(int Hide)//执行动作期间对按钮进行隐藏
{
switch (Hide)
{
case 0:
connectgun.gameObject.SetActive(false);
connectfa.gameObject.SetActive(false);
openfa.gameObject.SetActive(false);
break;
case 1:
openfa.gameObject.SetActive(false);
break;
}
}
void CoApper()//显示当前步骤应该出现的按钮
{
switch (XfsStep)
{
case 0:
connectgun.gameObject.SetActive(true);
connectfa.gameObject.SetActive(true);
openfa.gameObject.SetActive(true);
break;
case 1:
connectfa.gameObject.SetActive(true);
openfa.gameObject.SetActive(true);
break;
case 2:
openfa.gameObject.SetActive(true);
break;
}
}
public void Restore()//启用fire那边造成的脚本隐藏
{
this.enabled = true;
}
/* public NpcState Setnpcstate()
{
Debug.Log("Setnpcstate调用");
return NpcState.Healthy;
}*/
}