426 lines
11 KiB
C#
426 lines
11 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;//救援按钮
|
||
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;
|
||
}*/
|
||
|
||
}
|