adjust
This commit is contained in:
+177
-171
File diff suppressed because it is too large
Load Diff
+118
-83
@@ -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,19 +27,129 @@ 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()
|
||||||
{
|
{
|
||||||
if (isGrounded)
|
if (isGrounded)
|
||||||
@@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
};
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f59c799d38bfd9a4faa671a30dec48ae
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
|
|
||||||
public class CECHostPlayer : MonoBehaviour
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 7cd2ee670dc30154685fd720c71d3712
|
|
||||||
@@ -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,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
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
-
|
|
||||||
|
|||||||
Reference in New Issue
Block a user