This commit is contained in:
VDH
2025-09-08 18:04:40 +07:00
parent e59fa3fe0c
commit f1ca00030d
8 changed files with 314 additions and 289 deletions
File diff suppressed because it is too large Load Diff
+118 -83
View File
@@ -1,12 +1,10 @@
using CSNetwork.Protocols; using CSNetwork.Protocols;
using CSNetwork.Protocols.RPCData; using CSNetwork.Protocols.RPCData;
using System.Data;
using System.Text; using System.Text;
using TMPro; using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.InputSystem; using UnityEngine.InputSystem;
using UnityEngine.UI; using UnityEngine.UI;
using UnityEngine.Windows;
public class CharacterCtrl : MonoBehaviour public class CharacterCtrl : MonoBehaviour
{ {
@@ -29,17 +27,127 @@ public class CharacterCtrl : MonoBehaviour
[SerializeField] bool isGrounded = false; [SerializeField] bool isGrounded = false;
bool isRun = false; bool isRun = false;
// ====== Ground cast config ======
[Header("Ground Cast")]
[Tooltip("Khoảng thêm ngoài skinWidth để SphereCast xuống (m ngắn)")]
[SerializeField] private float extraGroundDistance = 0.05f;
[Tooltip("Bớt bán kính một chút để tránh tự va vào capsule (epsilon)")]
[SerializeField] private float radiusEpsilon = 0.005f;
[Tooltip("Layer mặt đất")]
[SerializeField] private LayerMask groundMask;
[Tooltip("Layer mặt đất")]
[SerializeField] private float slopeToleranceDeg = 2f;
// cache tùy chọn (không bắt buộc)
float ccRadius, ccSkin;
RaycastHit lastGroundHit;
private void Awake() private void Awake()
{ {
moveState = new PlayerMoveState(this); moveState = new PlayerMoveState(this);
playerStateMachine = new PlayerStateMachine(); playerStateMachine = new PlayerStateMachine();
// Cache: không bắt buộc, nhưng gọn tay và ít gọi property lặp.
if (controller != null)
{
ccRadius = controller.radius;
ccSkin = controller.skinWidth;
}
} }
private void Start() private void Start()
{ {
playerStateMachine.InitState(moveState); playerStateMachine.InitState(moveState);
// btnJump.onClick.AddListener(HandleJump);
}
//btnJump.onClick.AddListener(HandleJump); private void Update()
{
// Nếu có thay đổi runtime, có thể lấy lại mỗi vài giây/Start nếu bạn thích:
// ccRadius = controller.radius; ccSkin = controller.skinWidth;
playerStateMachine.UpdateState();
}
public void HandleMovement()
{
// 1) Kiểm tra grounded bằng SphereCast ngắn dựa trên radius + skinWidth
isGrounded = GroundCheck(out lastGroundHit);
// 2) Input tạm thời: giữ nguyên như bạn
if (UnityEngine.Input.GetKeyDown(KeyCode.LeftShift)) SetStatusRun(true);
if (UnityEngine.Input.GetKeyUp(KeyCode.LeftShift)) SetStatusRun(false);
if (UnityEngine.Input.GetKeyDown(KeyCode.Space)) HandleJump();
// 3) Trọng lực / sticky
if (isGrounded && playerVelocity.y < 0f)
{
// Đè nhẹ để bám đất (tránh nhấp-nháy)
playerVelocity.y = -2f;
}
else
{
playerVelocity.y += gravityValue * Time.deltaTime;
}
// 4) Chuyển động phẳng
float x = joystick.Horizontal;
float z = joystick.Vertical;
Vector3 move = new Vector3(x, 0, z);
move = Vector3.ClampMagnitude(move, 1f);
if (move != Vector3.zero)
{
transform.forward = move;
if (isRun) SetAnimRun();
else SetAnimWalk();
}
else
{
SetAnimIdle();
}
Vector3 finalMove = (move * playerSpeed) + (playerVelocity.y * Vector3.up);
controller.Move(finalMove * Time.deltaTime);
}
private bool GroundCheck(out RaycastHit hit)
{
float radius = controller.radius;
float skin = controller.skinWidth;
float height = controller.height;
// Tâm capsule theo world
Vector3 cWorld = transform.TransformPoint(controller.center);
float hemi = Mathf.Max(0f, (height * 0.5f) - radius);
// Hai điểm top/bottom của capsule nhân vật (đang đứng)
Vector3 pTop = cWorld + Vector3.up * hemi;
Vector3 pBottom = cWorld - Vector3.up * hemi;
// Ta tạo một "đoạn capsule ngắn" gần đáy để sweep xuống
// Nhấc đoạn bắt đầu lên 1 chút để không bắt đầu trong trạng thái giao nhau
Vector3 startBottom = pBottom + Vector3.up * (skin + 0.01f);
Vector3 startTop = startBottom + Vector3.up * (radius * 2f - 0.02f); // chiều cao đoạn ngắn ~2*radius
float castRadius = Mathf.Max(0f, radius - radiusEpsilon);
float castDistance = skin + extraGroundDistance; // quãng sweep ngắn
bool hitSomething = Physics.CapsuleCast(
startTop, startBottom, castRadius,
Vector3.down, out hit, castDistance,
groundMask, QueryTriggerInteraction.Ignore
);
if (!hitSomething) return false;
// Lọc theo slope limit
float maxSlope = controller.slopeLimit + slopeToleranceDeg;
float slope = Vector3.Angle(hit.normal, Vector3.up);
if (slope > maxSlope) return false;
return true;
} }
private void HandleJump() private void HandleJump()
@@ -66,113 +174,40 @@ public class CharacterCtrl : MonoBehaviour
string roleName = "(Error decoding name)"; string roleName = "(Error decoding name)";
if (role.name != null && role.name.ByteArray != null) if (role.name != null && role.name.ByteArray != null)
{ {
// Be careful with encoding, assume UTF8 is correct roleName = Encoding.UTF8.GetString(role.name.ByteArray, 0, role.name.Length);
roleName = Encoding.UTF8.GetString(
role.name.ByteArray,
0,
role.name.Length
);
} }
Vector3 pos = new Vector3(role.posx, role.posy, role.posz); Vector3 pos = new Vector3(role.posx, role.posy, role.posz);
if(txtName != null) if (txtName != null) txtName.text = roleName;
{
txtName.text = roleName;
}
transform.position = pos; transform.position = pos;
Debug.LogError("Pos Character = " + pos); Debug.LogError("Pos Character = " + pos);
} }
private void Update()
{
playerStateMachine.UpdateState();
}
public void HandleMovement()
{
isGrounded = controller.isGrounded;
if (UnityEngine.Input.GetKeyDown(KeyCode.LeftShift))
{
SetStatusRun(true);
}
if (UnityEngine.Input.GetKeyUp(KeyCode.LeftShift))
{
SetStatusRun(false);
}
if (UnityEngine.Input.GetKeyDown(KeyCode.Space))
{
HandleJump();
}
if (isGrounded && playerVelocity.y < 0)
{
playerVelocity.y = 0f;
}
float x = joystick.Horizontal;
float z = joystick.Vertical;
Vector3 move = new Vector3(x, 0, z);
move = Vector3.ClampMagnitude(move, 1f);
if (move != Vector3.zero)
{
transform.forward = move;
if (isRun)
{
SetAnimRun();
}
else
{
SetAnimWalk();
}
}
else
{
SetAnimIdle();
}
playerVelocity.y += gravityValue * Time.deltaTime;
Vector3 finalMove = (move * playerSpeed) + (playerVelocity.y * Vector3.up);
controller.Move(finalMove * Time.deltaTime);
}
private void SetAnimIdle() private void SetAnimIdle()
{ {
if(stateAnim == StateAnim.Idle || !isGrounded) if (stateAnim == StateAnim.Idle || !isGrounded) return;
{
return;
}
stateAnim = StateAnim.Idle; stateAnim = StateAnim.Idle;
animator.SetTrigger("Idle"); animator.SetTrigger("Idle");
} }
private void SetAnimRun() private void SetAnimRun()
{ {
if (stateAnim == StateAnim.Run || !isGrounded) if (stateAnim == StateAnim.Run || !isGrounded) return;
{
return;
}
stateAnim = StateAnim.Run; stateAnim = StateAnim.Run;
animator.SetTrigger("Run"); animator.SetTrigger("Run");
} }
private void SetAnimWalk() private void SetAnimWalk()
{ {
if (stateAnim == StateAnim.Walk || !isGrounded) if (stateAnim == StateAnim.Walk || !isGrounded) return;
{
return;
}
stateAnim = StateAnim.Walk; stateAnim = StateAnim.Walk;
animator.SetTrigger("Walk"); animator.SetTrigger("Walk");
} }
private void SetAnimJump() private void SetAnimJump()
{ {
if (stateAnim == StateAnim.Jump) if (stateAnim == StateAnim.Jump) return;
{
return;
}
stateAnim = StateAnim.Jump; stateAnim = StateAnim.Jump;
// Tạm dùng Idle trigger như code cũ của bạn
animator.SetTrigger("Idle"); animator.SetTrigger("Idle");
} }
} }
+11
View File
@@ -0,0 +1,11 @@
using UnityEngine;
struct cmd_player_move
{
Vector3 vCurPos;
Vector3 vNextPos;
ushort use_time;
short sSpeed; // Move speed 8.8 fix-point
byte move_mode; // Walk run swim fly .... walk_back run_back
ushort stamp; // move command stamp
};
+2
View File
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: f59c799d38bfd9a4faa671a30dec48ae
-7
View File
@@ -1,7 +0,0 @@
using UnityEngine;
public class CECHostPlayer : MonoBehaviour
{
}
@@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 7cd2ee670dc30154685fd720c71d3712
+4
View File
@@ -3,6 +3,8 @@ using UnityEngine;
public class PlayerStateMachine public class PlayerStateMachine
{ {
PlayerState _state; PlayerState _state;
CharacterCtrl _characterCtrl;
public void InitState(PlayerState state) public void InitState(PlayerState state)
{ {
if (_state != null) if (_state != null)
@@ -32,4 +34,6 @@ public class PlayerStateMachine
{ {
_state.Update(); _state.Update();
} }
//TODO: tìm OnMsgHstCorrectPos bên C++
} }
+2 -26
View File
@@ -2,13 +2,13 @@
%TAG !u! tag:unity3d.com,2011: %TAG !u! tag:unity3d.com,2011:
--- !u!78 &1 --- !u!78 &1
TagManager: TagManager:
serializedVersion: 2 serializedVersion: 3
tags: [] tags: []
layers: layers:
- Default - Default
- TransparentFX - TransparentFX
- Ignore Raycast - Ignore Raycast
- - Player
- Water - Water
- UI - UI
- -
@@ -50,27 +50,3 @@ TagManager:
- Light Layer 5 - Light Layer 5
- Light Layer 6 - Light Layer 6
- Light Layer 7 - Light Layer 7
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-