move and stop

This commit is contained in:
VDH
2025-09-13 17:48:04 +07:00
parent 3e3eb4b018
commit 36168112bf
10 changed files with 241 additions and 41 deletions
@@ -1,10 +1,13 @@
using System.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class Joystick : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
public event Action OnPointUp;
public float Horizontal { get { return (snapX) ? SnapFloat(input.x, AxisOptions.Horizontal) : input.x; } }
public float Vertical { get { return (snapY) ? SnapFloat(input.y, AxisOptions.Vertical) : input.y; } }
public Vector2 Direction { get { return new Vector2(Horizontal, Vertical); } }
@@ -133,6 +136,8 @@ public class Joystick : MonoBehaviour, IPointerDownHandler, IDragHandler, IPoint
{
input = Vector2.zero;
handle.anchoredPosition = Vector2.zero;
OnPointUp?.Invoke();
}
protected Vector2 ScreenPointToAnchoredPosition(Vector2 screenPosition)
Binary file not shown.
@@ -70,7 +70,17 @@ namespace BrewMonster.Network
Instance._gameSession.LoginAsync(username, password, onLoginComplete);
}
public void c2s_SendCmdStopMove(in Vector3 vDest, float fSpeed, int iMoveMode,
byte byDir, ushort wStamp, int iTime)
{
Debug.LogWarning("HoangDev : c2s_SendCmdStopMove");
Instance._gameSession.c2s_SendCmdStopMove(EC_Utility.ToNumerics( vDest),fSpeed,iMoveMode,byDir,wStamp,iTime);
}
public void c2s_CmdPlayerMove(in Vector3 vCurPos, in Vector3 vDest,
int iTime, float fSpeed, int iMoveMode, ushort wStamp)
{
Instance._gameSession.c2s_CmdPlayerMove(EC_Utility.ToNumerics(vCurPos),EC_Utility.ToNumerics( vDest),iTime,fSpeed,iMoveMode,wStamp);
}
protected override void Initialize()
{
BaseSecurity.Initizalize();
+27 -8
View File
@@ -13,6 +13,8 @@ using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Scene = UnityEngine.SceneManagement.Scene;
using System.Runtime.InteropServices;
using static UnityEngine.InputManagerEntry;
using Unity.VisualScripting;
public class CECHostPlayer : MonoBehaviour
{
@@ -24,8 +26,9 @@ public class CECHostPlayer : MonoBehaviour
[SerializeField] private Button btnRun;
[SerializeField] private Transform parentModel;
PlayerStateMachine playerStateMachine;
PlayerMoveState moveState;
PlayerStateMachine _playerStateMachine;
PlayerMoveState _moveState;
PlayerIdleState _idleState;
CECHostMove m_MoveCtrl;
float playerSpeed = 5.0f;
@@ -55,8 +58,9 @@ public class CECHostPlayer : MonoBehaviour
private void Awake()
{
moveState = new PlayerMoveState(this);
playerStateMachine = new PlayerStateMachine();
_moveState = new PlayerMoveState(this);
_idleState = new PlayerIdleState(this);
_playerStateMachine = new PlayerStateMachine();
m_MoveCtrl = new CECHostMove(this);
// Cache: không bắt buộc, nhưng gọn tay và ít gọi property lặp.
@@ -67,6 +71,7 @@ public class CECHostPlayer : MonoBehaviour
}
}
public void SetModelHostPlayer()
{
modle = NPCManager.Instance.GetModelPlayer();
@@ -78,19 +83,23 @@ public class CECHostPlayer : MonoBehaviour
}
private void Start()
{
playerStateMachine.InitState(moveState);
_playerStateMachine.InitState(_moveState);
// btnJump.onClick.AddListener(HandleJump);
}
private void Update()
{
m_MoveCtrl.Tick(Time.deltaTime);
Debug.Log($"(ulong)Time.deltaTime * 1000 {(ulong)(Time.deltaTime * 1000)}");
m_MoveCtrl.Tick((ulong)(Time.deltaTime * 1000));
// 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();
_playerStateMachine.UpdateState();
}
public void StopMovement()
{
m_MoveCtrl.SendStopMoveCmd(transform.position, 5f, (int)MoveMode.GP_MOVE_WALK);
}
public void HandleMovement()
{
// 1) Kiểm tra grounded bằng SphereCast ngắn dựa trên radius + skinWidth
@@ -127,6 +136,11 @@ public class CECHostPlayer : MonoBehaviour
m_MoveCtrl.SendMoveCmd(transform.position, controller.velocity, (int)MoveMode.GP_MOVE_RUN);
}
else
{
//_playerStateMachine.ChangeState(_idleState);
}
if (joystick)
{
}
@@ -134,6 +148,10 @@ public class CECHostPlayer : MonoBehaviour
Vector3 finalMove = (move * playerSpeed) + (playerVelocity.y * Vector3.up);
controller.Move(finalMove * Time.deltaTime);
}
private void JoystickRelease()
{
StopMovement();
}
private bool GroundCheck(out RaycastHit hit)
{
@@ -327,6 +345,7 @@ public class CECHostPlayer : MonoBehaviour
SetModelHostPlayer();
Debug.LogError("Pos Character = " + pos);
joystick = FindAnyObjectByType<Joystick>();
joystick.OnPointUp += JoystickRelease;
}
}
+37
View File
@@ -0,0 +1,37 @@
using System;
using UnityEngine;
public static class EC_Utility
{
public static byte glb_CompressDirH(float x, float z)
{
const float fInvInter = 256.0f / 360.0f;
if (Math.Abs(x) < 0.00001f)
{
if (z > 0.0f)
return 64;
else
return 192;
}
else
{
// atan2 trong C# trả về radian, cần đổi sang độ
float fDeg = (float)(Math.Atan2(z, x) * (180.0 / Math.PI));
// đảm bảo góc nằm trong [0, 360)
if (fDeg < 0)
fDeg += 360.0f;
return (byte)(fDeg * fInvInter);
}
}
public static System.Numerics.Vector3 ToNumerics(this UnityEngine.Vector3 v)
{
return new System.Numerics.Vector3(v.x, v.y, v.z);
}
public static float MagnitudeH(this Vector3 v)
{
return Mathf.Sqrt(v.x * v.x + v.z * v.z);
}
}
+2
View File
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 927789371b017f345a12f6d7adbc87ff
+131 -30
View File
@@ -8,47 +8,127 @@ using System.Text;
using UnityEngine;
using CSNetwork.Protocols;
using UnityEngine.LightTransport;
using CSNetwork;
public class CECHostMove
{
ushort m_wMoveStamp;
ushort m_wMoveStamp;
float m_fMoveTime;
CECHostPlayer m_pHost;
CECCounter m_CmdTimeCnt;
bool m_bStop;
const float MOVECMD_INTERVAL = .5f;
Vector3 m_vLastSevPos;
STOPMOVE m_DelayedStop;
ulong cmdstopdelayCounter = 500;
ulong cmdmovedelayCounter = 500;
ulong m_dwLastTime;
Vector3 m_vLastPos;
float m_fAverSpeedH;
public CECHostMove(CECHostPlayer pHost)
{
m_wMoveStamp = 0;
m_fMoveTime = 0.0f;
m_pHost = pHost;
m_bStop = true;
m_CmdTimeCnt = new CECCounter();
m_CmdTimeCnt.SetPeriod(MOVECMD_INTERVAL);
m_bStop = false;
}
public void Tick(float dwDeltaTime)
public void Tick(ulong dwDeltaTime)
{
m_CmdTimeCnt.IncCounter(dwDeltaTime);
cmdstopdelayCounter += dwDeltaTime;
cmdmovedelayCounter += dwDeltaTime;
if (cmdstopdelayCounter >= 500 && m_DelayedStop.bValid)
{
var m = m_DelayedStop;
// a_GetTime() -> Environment.TickCount (ms)
ulong dwCurrent = (ulong)Mathf.RoundToInt( Time.time * 1000);
// iTime: thời gian tích lũy (ms) + delta từ timestamp đến hiện tại
int iTime = (int)((m.fTime * 1000f)
+ ((dwCurrent > m.dwTimeStamp) ? (dwCurrent - m.dwTimeStamp) : 0));
// tính tốc độ trung bình (giây = iTime * 0.001f)
float fSpeed = l_CalcAverageSpeed(m_vLastSevPos, m.vPos, iTime * 0.001f, m.fSpeed);
int iMoveMode = m.iMoveMode;
// make a potential check with tuojigua
iMoveMode |= (int)MoveMode.GP_MOVE_DEAD;
UnityGameSession.Instance.c2s_SendCmdStopMove(
m.vPos, fSpeed, iMoveMode, m.byDir, m_wMoveStamp++, iTime
);
// Record this position
m_vLastSevPos = m.vPos;
Reset();
}
m_dwLastTime = Math.Max(m_dwLastTime, 1);
Vector3 vOffset = m_pHost.transform.position - m_vLastPos;
m_fAverSpeedH = EC_Utility.MagnitudeH(vOffset) * 1000.0f / m_dwLastTime;
m_vLastPos = m_pHost.transform.position;
m_dwLastTime = dwDeltaTime;
}
public void SendStopMoveCmd(in Vector3 vPos, float fSpeed, int iMoveMode)
{
Debug.LogWarning("HoangDev : SendStopMoveCmd");
iMoveMode |= (int)MoveMode.GP_MOVE_DEAD;
if (cmdstopdelayCounter == 500)
{
Vector3 vDir = m_pHost.transform.forward;
byte byDir = EC_Utility.glb_CompressDirH(vDir.x, vDir.z);
fSpeed = l_CalcAverageSpeed(m_vLastSevPos, vPos, m_fMoveTime, fSpeed);
int iTime = (int)(m_fMoveTime * 1000);
UnityGameSession.Instance.c2s_SendCmdStopMove(vPos, fSpeed, iMoveMode, byDir, m_wMoveStamp++, iTime);
m_vLastSevPos = vPos;
Reset();
}
else
{
Vector3 vDir = m_pHost.transform.forward;
byte byDir = EC_Utility.glb_CompressDirH(vDir.x, vDir.z);
if (!m_DelayedStop.bValid)
{
m_DelayedStop.dwTimeStamp = (ulong)Mathf.RoundToInt(Time.time * 1000);
m_DelayedStop.fTime = m_fMoveTime;
}
m_DelayedStop.bValid = true;
m_DelayedStop.byDir = byDir;
m_DelayedStop.vPos = vPos;
m_DelayedStop.iMoveMode = iMoveMode;
m_DelayedStop.fSpeed = fSpeed;
}
m_fMoveTime = 0.0f;
}
public void SendMoveCmd(in Vector3 vCurPos, in Vector3 vVel, int iMoveMode, bool bForceSend = false)
{
Vector3 vMoveDir = vVel;
float fSpeed = vMoveDir.magnitude;
SendMoveCmd(vCurPos, fSpeed, iMoveMode, bForceSend);
SendMoveCmd(vCurPos, fSpeed, iMoveMode, bForceSend);
}
void SendMoveCmd(in Vector3 vCurPos,
float fSpeed, int iMoveMode, bool bForceSend)
{
Debug.LogWarning($"cmdmovedelayCounter 1 = {cmdmovedelayCounter}");
if (m_bStop)
{
Debug.LogWarning($"cmdmovedelayCounter 2 = {(ulong)m_fMoveTime * 1000}");
// m_CmdTimeCnt.Reset();
m_CmdTimeCnt.SetCounter((m_fMoveTime * 1000));
cmdmovedelayCounter = (ulong)( m_fMoveTime * 1000);
m_bStop = false;
}
if (!bForceSend && !m_CmdTimeCnt.IsFull())
Debug.LogWarning($"cmdmovedelayCounter = {cmdmovedelayCounter}");
if (!bForceSend && cmdmovedelayCounter < 500)
return;
int iTime = (int)(m_fMoveTime * 1000);
@@ -58,42 +138,63 @@ public class CECHostMove
if (iTime == 0 || !bForceSend)
{
// if time is too little, wait again
m_CmdTimeCnt.SetCounter(iTime);
cmdmovedelayCounter = (ulong)(iTime);
return;
}
}
cmdmovedelayCounter = 0;
m_DelayedStop.bValid = false;
fSpeed = l_CalcAverageSpeed(m_vLastSevPos, vCurPos, m_fMoveTime, fSpeed);
m_fMoveTime = 0.0f;
m_CmdTimeCnt.Reset();
iMoveMode |= (int)MoveMode.GP_MOVE_DEAD;
// HoangTODO: vCurPos c# unity khác với vCurPos của bên c++ kia
c2s_CmdPlayerMove(vCurPos, vCurPos, iTime/* MOVECMD_INTERVAL */, fSpeed, iMoveMode, m_wMoveStamp++);
Debug.LogWarning("nityGameSession.Instance.c2s_CmdPlayerMove");
UnityGameSession.Instance.c2s_CmdPlayerMove(vCurPos, vCurPos, iTime/* MOVECMD_INTERVAL */, fSpeed, iMoveMode, m_wMoveStamp++);
m_vLastSevPos = vCurPos;
}
float l_CalcAverageSpeed(in Vector3 p1, in Vector3 p2, float fTime, float fDefSpeed)
{
if (Mathf.Approximately(fTime, 0f))
return fDefSpeed;
Vector3 d = p2 - p1;
float fSpeed = d.magnitude / fTime;
if (fTime < 0.05f || fSpeed > 50.0f)
{
// tương đương ASSERT(0) trong C++, ở đây có thể Debug.LogWarning
Debug.LogWarning("CalcAverageSpeed: invalid input, fallback to default speed.");
return fDefSpeed;
}
return fSpeed;
}
private void Reset()
{
cmdstopdelayCounter = 0;
m_bStop = true;
}
private void c2s_CmdPlayerMove(in Vector3 vCurPos, in Vector3 vDest,
int iTime, float fSpeed, int iMoveMode, ushort wStamp)
{
gamedatasend gamedatasend = new gamedatasend();
Debug.LogWarning("vCurPos " + vCurPos);
gamedatasend.Data = C2SCommandFactory.CreatePlayerMove(ToSysVec3(vCurPos), ToSysVec3(vDest), (ushort)iTime, fSpeed, (byte)iMoveMode, wStamp);
UnityGameSession.SendProtocol(gamedatasend);
Debug.LogWarning("HoangDev : SendProtocolSendProtocolSendProtocol");
m_DelayedStop.bValid = false;
}
public void GroundMove(float ftime)
{
m_fMoveTime += ftime;
}
public System.Numerics.Vector3 ToSysVec3(UnityEngine.Vector3 v)
=> new System.Numerics.Vector3(v.x, v.y, v.z);
struct STOPMOVE
{
public bool bValid; // Valid flag
public Vector3 vPos;
public float fSpeed;
public int iMoveMode;
public byte byDir;
public ulong dwTimeStamp;
public float fTime;
};
}
public struct CDR_INFO
{
@@ -127,4 +228,4 @@ public struct CDR_INFO
//the moving dist
public float fMoveDist;
};
};
@@ -0,0 +1,23 @@
using UnityEngine;
public class PlayerIdleState : PlayerState
{
public PlayerIdleState(CECHostPlayer characterCtrl) : base(characterCtrl)
{
}
public override void Enter()
{
}
public override void Exit()
{
}
public override void Update()
{
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 89482cfe1c5315b4d833133e919eac40
@@ -13,11 +13,12 @@ public class PlayerMoveState : PlayerState
public override void Exit()
{
_characterCtrl.StopMovement();
}
public override void Update()
{
_characterCtrl.HandleMovement();
}
}