move and stop
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 927789371b017f345a12f6d7adbc87ff
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user