Files
BlueArchiveMiniGame/Assets/Scripts/HotUpdate/Main/Player/ThirdCharacterController.cs

194 lines
6.3 KiB
C#
Raw Normal View History

2025-09-17 18:56:28 +08:00
using Cinemachine;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using YooAsset;
public class ThirdCharacterController : MonoBehaviour
{
public float moveSpeed = 5f;
public float turnSpeed = 10f;
public float jumpSpeed = 8f;
public float gravity = 20f;
public float minCameraDistance = 2f;
public float maxCameraDistance = 10f;
public float cameraZoomSpeed = 0.1f;
public CharacterController controller;
public Animator animator;
public CinemachineVirtualCamera vCam;
public Transform forwardReference;
public Transform model;
private CinemachineFramingTransposer framingTransposer;
private CinemachinePOV pov;
private Vector3 moveDirection;
private Vector3 verticalVelocity;
private Vector2 moveInput;
private bool isGrounded;
private bool isCursorLocked = true;
public bool isLocalPlayer;
string curCharacterName;
public Action<GameObject> changeCharacterComplete;
void Awake()
{
//if (!isLocalPlayer) return;
framingTransposer = vCam.GetCinemachineComponent<CinemachineFramingTransposer>();
pov = vCam.GetCinemachineComponent<CinemachinePOV>();
UpdateCursorState();
ChangeCharacter("Aris");
}
void Update()
{
if (!isLocalPlayer) return;
ApplyGravity();
Move();
RotateModel();
UpdateAnimator();
}
2025-10-09 11:54:18 +08:00
public void UpdateCursorState(bool value)
{
if (!isLocalPlayer) return;
isCursorLocked = value;
UpdateCursorState();
}
2025-09-17 18:56:28 +08:00
private void UpdateCursorState()
{
if (!isLocalPlayer) return;
Cursor.lockState = isCursorLocked ? CursorLockMode.Locked : CursorLockMode.None;
Cursor.visible = !isCursorLocked;
if (pov == null) return;
pov.m_HorizontalAxis.m_InputAxisName = isCursorLocked ? "Mouse X" : "";
pov.m_VerticalAxis.m_InputAxisName = isCursorLocked ? "Mouse Y" : "";
pov.m_HorizontalAxis.m_MaxSpeed = isCursorLocked ? 300 : 0;
pov.m_VerticalAxis.m_MaxSpeed = isCursorLocked ? 300 : 0;
}
private void ApplyGravity()
{
if (!isLocalPlayer) return;
isGrounded = controller.isGrounded;
if (isGrounded && verticalVelocity.y < 0)
{
verticalVelocity.y = -2f;
}
else
{
verticalVelocity.y -= gravity * Time.deltaTime;
}
}
private void Move()
{
if (!isLocalPlayer) return;
forwardReference.rotation = Quaternion.AngleAxis(pov.m_HorizontalAxis.Value+transform.eulerAngles.y, Vector3.up);
Vector3 horizontalMovement = forwardReference.TransformDirection(
new Vector3(moveInput.x, 0, moveInput.y)) * moveSpeed;
moveDirection = horizontalMovement + verticalVelocity;
controller.Move(moveDirection * Time.deltaTime);
}
private void RotateModel()
{
if (!isLocalPlayer) return;
if (moveInput == Vector2.zero) return;
float targetAngle = Mathf.Atan2(moveInput.x, moveInput.y) * Mathf.Rad2Deg;
Quaternion targetRotation = forwardReference.rotation * Quaternion.AngleAxis(targetAngle, Vector3.up);
model.rotation = Quaternion.Slerp(model.rotation, targetRotation, turnSpeed * Time.deltaTime);
}
private void UpdateAnimator()
{
if (!isLocalPlayer) return;
if (animator == null) return;
animator.SetBool("Move", moveInput != Vector2.zero);
}
public void OnMove(InputAction.CallbackContext context)
{
if (!isLocalPlayer) return;
moveInput = context.ReadValue<Vector2>();
}
public void OnJump(InputAction.CallbackContext context)
{
if (!isLocalPlayer) return;
if (context.performed && isGrounded)
{
verticalVelocity.y = jumpSpeed;
}
}
public void OnEsc(InputAction.CallbackContext context)
{
if (!isLocalPlayer) return;
if (context.performed)
{
2025-10-09 07:51:05 +08:00
if (UIManager.Inst.CheckShow(nameof(SettingsWindow)))
2025-09-29 11:03:26 +08:00
{
2025-10-09 07:51:05 +08:00
UIManager.Inst.HideWindow(nameof(SettingsWindow));
2025-09-29 11:03:26 +08:00
}
else
{
2025-10-09 07:51:05 +08:00
UIManager.Inst.ShowWindow<SettingsWindow>(nameof(SettingsWindow));
2025-09-29 11:03:26 +08:00
}
2025-09-17 18:56:28 +08:00
}
}
public void OnFire(InputAction.CallbackContext context)
{
if (!isLocalPlayer) return;
if (context.performed)
{
animator.SetTrigger("Attack");
}
}
public void OnAlt(InputAction.CallbackContext context)
{
if (!isLocalPlayer) return;
if (context.performed)
{
isCursorLocked = false;
UpdateCursorState();
}
else if (context.canceled)
{
isCursorLocked = true;
UpdateCursorState();
}
}
public void OnZoom(InputAction.CallbackContext context)
{
if (!isLocalPlayer) return;
if (framingTransposer == null) return;
float scrollValue = context.ReadValue<float>();
float newDistance = framingTransposer.m_CameraDistance + (scrollValue * cameraZoomSpeed * 0.01f);
framingTransposer.m_CameraDistance = Mathf.Clamp(newDistance, minCameraDistance, maxCameraDistance);
}
public void OnChangeCharacter(InputAction.CallbackContext context)
{
if (!isLocalPlayer) return;
if (context.performed)
{
int bindingIndex = context.action.GetBindingIndexForControl(context.control);
ChangeCharacter(test[bindingIndex]);
}
}
public void ChangeCharacter(string name)
{
if (!isLocalPlayer) return;
if (curCharacterName == name) return;
animator = null;
model.GetChild(0).gameObject.SetActive(false);
AssetHandle assetHandle = YooAssets.LoadAssetAsync(name);
assetHandle.Completed += (handle) =>
{
GameObject character = handle.InstantiateSync(model);
animator = character.GetComponent<Animator>();
character.transform.SetAsFirstSibling();
curCharacterName = name;
changeCharacterComplete?.Invoke(character);
};
}
List<string> test = new List<string>()
{
"Aris",
"Momoi",
"Midori",
"Yuzu"
};
}