Merge pull request 'Merge logic show and move elseplayer.' (#6) from feature/elseplayer into develop

Reviewed-on: https://git.brew.monster/anhld/perfect-world-unity/pulls/6
This commit is contained in:
tungdv
2025-09-13 09:49:42 +00:00
10 changed files with 715 additions and 84 deletions
Binary file not shown.
@@ -586,11 +586,11 @@ namespace ModelRenderer.Scripts.GameData
add_id_data(ID_SPACE.ID_SPACE_ESSENCE, item.id, item);
}
foreach (var item in unionscroll_essence_array)
{
add_id_index(ID_SPACE.ID_SPACE_ESSENCE, item.id, DATA_TYPE.DT_UNIONSCROLL_ESSENCE);
add_id_data(ID_SPACE.ID_SPACE_ESSENCE, item.id, item);
}
//foreach (var item in unionscroll_essence_array)
//{
// add_id_index(ID_SPACE.ID_SPACE_ESSENCE, item.id, DATA_TYPE.DT_UNIONSCROLL_ESSENCE);
// add_id_data(ID_SPACE.ID_SPACE_ESSENCE, item.id, item);
//}
}
public void SaveDataToTextFile()
@@ -2,8 +2,11 @@
using BrewMonster.Network;
using CSNetwork;
using CSNetwork.GPDataType;
using CSNetwork.Protocols.RPCData;
using PerfectWorld.Scripts.Player;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using TMPro;
using UnityEngine;
@@ -16,6 +19,9 @@ namespace PerfectWorld.Scripts.Managers
[Serializable]
public class EC_ManPlayer : IMsgHandler
{
Dictionary<int, int> m_UkPlayerTab = new Dictionary<int, int>();
Dictionary<int, EC_ElsePlayer> m_PlayerTab = new Dictionary<int, EC_ElsePlayer>();
private readonly object m_csPlayerTab = new object();
public int HandlerId => (int)MANAGER_INDEX.MAN_PLAYER;
public bool ProcessMessage(ECMSG Msg)
{
@@ -39,6 +45,11 @@ namespace PerfectWorld.Scripts.Managers
OnMsgPlayerMove(Msg);
break;
}
case int value when value == EC_MsgDef.MSG_PM_PLAYERSTOPMOVE:
{
OnMsgPlayerStopMove(Msg);
break;
}
}
}
else
@@ -60,7 +71,8 @@ namespace PerfectWorld.Scripts.Managers
byteArray[i] = data[i];
}
int cid = BitConverter.ToInt32(byteArray);
switch (Convert.ToInt32(Msg.dwParam2))
int commandID = Convert.ToInt32(Msg.dwParam2);
switch (commandID)
{
case CommandID.PLAYER_INFO_1:
case CommandID.PLAYER_ENTER_WORLD:
@@ -68,6 +80,9 @@ namespace PerfectWorld.Scripts.Managers
{
if (cid != iHostID)
{
info_player_1 info_Player_1 = GPDataTypeHelper.FromBytes<info_player_1>((byte[])Msg.dwParam1);
RoleInfo roleInfo = (RoleInfo)Msg.dwParam4;
ElsePlayerEnter(info_Player_1, commandID, roleInfo);
GameController.Instance.Log("ElsePlayer has join");
}
break;
@@ -90,7 +105,7 @@ namespace PerfectWorld.Scripts.Managers
EC_ElsePlayer pPlayer = SeekOutElsePlayer(pCmd.id);
if (pPlayer)
{
//pPlayer->MoveTo(*pCmd);
pPlayer.MoveTo(pCmd);
}
}
}
@@ -109,78 +124,161 @@ namespace PerfectWorld.Scripts.Managers
GameController.Instance.InitCharacter(info);
};
string nameScene = "NPCRender";
/* UnityGameSession.Instance.LoadScene(nameScene, LoadSceneMode.Single, (value) =>
UnityGameSession.Instance.LoadScene(nameScene, LoadSceneMode.Single, (value) =>
{
isDoneNPCRender = value;
actLoadChar?.Invoke();
});
nameScene = "WorldRender";
UnityGameSession.Instance.LoadScene(nameScene, LoadSceneMode.Additive, (value) =>
{
isDoneWorldRender = value;
actLoadChar?.Invoke();
});*/
UnityGameSession.Instance.LoadScene("HoangTest", LoadSceneMode.Single, (value) =>
{
isDoneWorldRender = value;
actLoadChar?.Invoke();
});
//UnityGameSession.Instance.LoadScene("HoangTest", LoadSceneMode.Single, (value) =>
//{
// isDoneWorldRender = value;
// actLoadChar?.Invoke();
//});
return true;
}
public EC_ElsePlayer ElsePlayerEnter()
public EC_ElsePlayer ElsePlayerEnter(info_player_1 info, int iCmd, RoleInfo roleInfo)
{
return null;
// If this player's id is in unknown table, remove it because this player
// won't be unknown anymore
if (m_UkPlayerTab.TryGetValue(info.cid, out int value))
{
if (value != 0) // Pair.second != 0
{
m_UkPlayerTab.Remove(info.cid);
}
}
int iAppearFlag = (iCmd == (int)CommandID.PLAYER_ENTER_WORLD) ?
(int)PlayerAppearFlag.APPEAR_ENTERWORLD : (int)PlayerAppearFlag.APPEAR_RUNINTOVIEW;
// Has player been in active player table ?
EC_ElsePlayer pPlayer = GetElsePlayer(info.cid);
if (pPlayer)
{
// This player has existed in player table, call special initial function
// TODO: fix after pPlayer init
pPlayer.Init(roleInfo, info);
return pPlayer;
}
// Create a new player
if (!(pPlayer = CreateElsePlayer(roleInfo, info, iAppearFlag)))
{
return null;
}
lock (m_csPlayerTab)
{
if (m_PlayerTab.ContainsKey(info.cid))
{
m_PlayerTab[info.cid] = pPlayer;
}
else
{
m_PlayerTab.Add(info.cid ,pPlayer);
}
}
return pPlayer;
}
private EC_ElsePlayer CreateElsePlayer(RoleInfo roleInfo, info_player_1 info, int iAppearFlag)
{
var ob = GameController.Instance.InitCharacter(info);
EC_ElsePlayer elsePlayer = ob.AddComponent<EC_ElsePlayer>();
elsePlayer.GetComponent<CECHostPlayer>().enabled = false;
//init
elsePlayer.Init(roleInfo, info);
return elsePlayer;
}
public EC_ElsePlayer GetElsePlayer(int cid, long dwBornStamp = 0)
{
lock (m_csPlayerTab)
{
if (!m_PlayerTab.TryGetValue(cid, out var player))
return null;
if (dwBornStamp != 0)
{
//TO DO: fix after GetBornStamp() is create in code
//if (player.GetBornStamp() != dwBornStamp)
return null;
}
return player;
}
}
private EC_ElsePlayer SeekOutElsePlayer(int cid)
{
return null;
}
private cmd_object_move ConvertToStruct(byte[] bytes)
{
if (bytes.Length < Marshal.SizeOf<cmd_object_move>())
if (!m_PlayerTab.TryGetValue(cid, out var player))
{
return default;
// Couldn't find this else player, put it into unknown player table
m_UkPlayerTab[cid] = cid;
return null;
}
cmd_object_move result = new cmd_object_move();
int preLenghtData = 0;
int lenghtDataType = Marshal.SizeOf<int>();
byte[] arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData);
result.id = BitConverter.ToInt32(arrByteData);
preLenghtData += lenghtDataType;
lenghtDataType = Marshal.SizeOf<float>();
arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData);
result.dest_X = BitConverter.ToSingle(arrByteData);
preLenghtData += lenghtDataType;
lenghtDataType = Marshal.SizeOf<float>();
arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData);
result.dest_Y = BitConverter.ToSingle(arrByteData);
preLenghtData += lenghtDataType;
lenghtDataType = Marshal.SizeOf<float>();
arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData);
result.dest_Z = BitConverter.ToSingle(arrByteData);
preLenghtData += lenghtDataType;
lenghtDataType = Marshal.SizeOf<ushort>();
arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData);
result.use_time = BitConverter.ToUInt16(arrByteData);
preLenghtData += lenghtDataType;
lenghtDataType = Marshal.SizeOf<short>();
arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData);
result.sSpeed = BitConverter.ToInt16(arrByteData);
preLenghtData += lenghtDataType;
result.move_mode = bytes[preLenghtData + 1];
return result;
return player;
}
public bool OnMsgPlayerStopMove(ECMSG Msg)
{
cmd_object_stop_move pCmd = GPDataTypeHelper.FromBytes<cmd_object_stop_move>((byte[])Msg.dwParam1);
EC_ElsePlayer pPlayer = SeekOutElsePlayer(pCmd.id);
if (pPlayer)
pPlayer.StopMoveTo(pCmd);
return true;
}
//private cmd_object_move ConvertToStruct(byte[] bytes)
//{
// if (bytes.Length < Marshal.SizeOf<cmd_object_move>())
// {
// return default;
// }
// cmd_object_move result = new cmd_object_move();
// int preLenghtData = 0;
// int lenghtDataType = Marshal.SizeOf<int>();
// byte[] arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData);
// result.id = BitConverter.ToInt32(arrByteData);
// preLenghtData += lenghtDataType;
// lenghtDataType = Marshal.SizeOf<float>();
// arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData);
// result.dest_X = BitConverter.ToSingle(arrByteData);
// preLenghtData += lenghtDataType;
// lenghtDataType = Marshal.SizeOf<float>();
// arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData);
// result.dest_Y = BitConverter.ToSingle(arrByteData);
// preLenghtData += lenghtDataType;
// lenghtDataType = Marshal.SizeOf<float>();
// arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData);
// result.dest_Z = BitConverter.ToSingle(arrByteData);
// preLenghtData += lenghtDataType;
// lenghtDataType = Marshal.SizeOf<ushort>();
// arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData);
// result.use_time = BitConverter.ToUInt16(arrByteData);
// preLenghtData += lenghtDataType;
// lenghtDataType = Marshal.SizeOf<short>();
// arrByteData = GetBytes(bytes, lenghtDataType, preLenghtData);
// result.sSpeed = BitConverter.ToInt16(arrByteData);
// preLenghtData += lenghtDataType;
// result.move_mode = bytes[preLenghtData + 1];
// return result;
//}
private byte[] GetBytes(byte[] bytes, int length, int index)
{
byte[] arrByteData = new byte[length];
@@ -1,27 +1,30 @@
using UnityEngine;
public class NPCManager : MonoBehaviour
namespace PerfectWorld.Scripts.Managers
{
private static NPCManager instance;
[SerializeField] private GameObject modelPlayerCharacter;
public static NPCManager Instance
public class NPCManager : MonoBehaviour
{
get
private static NPCManager instance;
[SerializeField] private GameObject modelPlayerCharacter;
public static NPCManager Instance
{
if (instance == null)
get
{
instance = FindAnyObjectByType<NPCManager>();
}
return instance;
}
}
if (instance == null)
{
instance = FindAnyObjectByType<NPCManager>();
}
return instance;
}
}
public GameObject GetModelPlayer()
{
var player = Instantiate(modelPlayerCharacter);
player.SetActive(true);
return player;
public GameObject GetModelPlayer()
{
var player = Instantiate(modelPlayerCharacter);
player.SetActive(true);
return player;
}
}
}
@@ -8,9 +8,26 @@ namespace BrewMonster
[Serializable]
public class EC_ManMessageMono : MonoBehaviour
{
public EC_ManPlayer EC_ManPlayer;
private static EC_ManMessageMono instance;
public static EC_ManMessageMono Instance
{
get
{
if(instance == null)
{
instance = FindAnyObjectByType<EC_ManMessageMono>();
}
return instance;
}
}
public EC_ManPlayer EC_ManPlayer;
public EC_ManPlayer GetECManPlayer { get => EC_ManPlayer;}
private void Awake()
{
instance = this;
//TODO: Remove later
EC_ManPlayer = new EC_ManPlayer();
EC_ManMessage.RegisterHandler(EC_ManPlayer);
@@ -1,16 +1,502 @@
using BrewMonster;
using CSNetwork;
using CSNetwork.GPDataType;
using CSNetwork.Protocols.RPCData;
using System;
using UnityEngine;
public class EC_ElsePlayer : MonoBehaviour
namespace PerfectWorld.Scripts.Player
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
public class EC_ElsePlayer : MonoBehaviour
{
A3DVECTOR3 m_vMoveDir; // Player's velocity
A3DVECTOR3 m_vServerPos; // Player's real position on server
A3DVECTOR3 m_vStopDir; // The direction when player stop moving
// 是否是依附者 = Is it a dependent/attacher?
bool m_bHangerOn;
// 依附者或被依附者id = The ID of the attacher (dependent) or the attached target.
int m_iBuddyId;
bool m_bStopMove; // Stop move flag
public const float MAX_LAGDIST = 10.0f; // Maximum lag distance
A3DVECTOR3 g_vAxisY = new A3DVECTOR3(0.0f, 1.0f, 0.0f);
long m_dwLastMoveTime = 0; // Last move command arrived time
float m_fMoveSpeed; // Move speed
OtherPlayer_Move_Info m_cdr = new OtherPlayer_Move_Info();
// 和服务器提供的 aabb,无法影响朝向 = The AABB provided by the server cannot affect the facing/orientation
A3DAABB m_aabbServer = new A3DAABB();
A3DAABB m_aabb = new A3DAABB(); // Player's aabb£¬ÓÃÓÚÏÔʾµÄaabb£¬ÊÜËõ·ÅÓ°Ïì
string m_strName; // Player name
int m_iProfession; // Profession
int m_iGender; // Gender
float m_fScaleBySkill = 1f;
MOVECONST m_MoveConst; // Const used when moving control
public MOVECONST[] aMoveConsts = new MOVECONST[PROFESSION.NUM_PROFESSION * GENDER.NUM_GENDER]
{
// ÎäÏÀ
// fStepHei fMinAirHei fMinWaterHei fShoreDepth fWaterSurf
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
// ·¨Ê¦
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
// Î×ʦ
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
// Ñý¾«
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
// ÑýÊÞ
new MOVECONST(0.8f, 1.6f, 0.3f, 1.8f, 0.7f),
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
// ´Ì¿Í
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
// Óðâ
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
// ÓðÁé
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
// ½£Áé
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
// ÷ÈÁé
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
// Ò¹Ó°
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
// ÔÂÏÉ
new MOVECONST(0.8f, 1.6f, 0.3f, 1.6f, 0.6f),
new MOVECONST(0.8f, 1.6f, 0.3f, 1.5f, 0.55f),
};
public A3DVECTOR3[] aExts = new A3DVECTOR3[PROFESSION.NUM_PROFESSION * GENDER.NUM_GENDER]
{
new A3DVECTOR3(0.4f, 0.9f, 0.4f), // ÎäÏÀ
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // ·¨Ê¦
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // Î×ʦ
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // Ñý¾«
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
new A3DVECTOR3(0.5f, 1.05f, 0.5f), // ÑýÊÞ
new A3DVECTOR3(0.3f, 0.9f, 0.3f),
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // ´Ì¿Í
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // Óðâ
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // ÓðÁé
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // ½£Áé
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // ÷ÈÁé
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // Ò¹Ó°
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
new A3DVECTOR3(0.3f, 0.9f, 0.3f), // ÔÂÏÉ
new A3DVECTOR3(0.3f, 0.85f, 0.3f),
};
public void Init(RoleInfo roleInfo, info_player_1 Info)
{
m_iProfession = roleInfo.occupation;
m_iGender = roleInfo.gender;
CalcPlayerAABB();
SetServerPos(Info.pos);
SetPos(Info.pos);
m_cdr.fStepHeight = m_MoveConst.fStepHei;
m_cdr.vExts = m_aabbServer.Extents;
m_cdr.vVelocity.Clear();
A3DVECTOR3 vPos = GetPos();
m_aabb.Center = vPos + new A3DVECTOR3(0.0f, m_aabb.Extents.y, 0.0f);
m_aabb.CompleteMinsMaxs();
m_aabbServer.Center = vPos + new A3DVECTOR3(0.0f, m_aabbServer.Extents.y, 0.0f);
m_aabbServer.CompleteMinsMaxs();
}
void CalcPlayerAABB()
{
int iIndex = m_iProfession * GENDER.NUM_GENDER + m_iGender;
m_aabb.Extents = aExts[iIndex] * m_fScaleBySkill;
m_aabbServer.Extents = aExts[iIndex];
m_MoveConst = aMoveConsts[iIndex];
}
public void MoveTo(cmd_object_move Cmd)
{
if (Cmd.use_time == 0)
return;
SetServerPos(Cmd.dest);
m_vMoveDir = Cmd.dest - GetPos();
float fDist = m_vMoveDir.Normalize();
m_bStopMove = false;
// If destination position is too far to us, forcely pull player
// to that position.
if (fDist >= MAX_LAGDIST)
{
SetPos(Cmd.dest);
//m_pEPWorkMan->FinishWork(CECEPWork::WORK_MOVE);
return;
}
long dwTimeNow = Environment.TickCount;
long dwDeltaTime = (dwTimeNow > m_dwLastMoveTime) ? (dwTimeNow - m_dwLastMoveTime) : 0;
m_dwLastMoveTime = dwTimeNow;
if (dwDeltaTime < 500)
dwDeltaTime = 500;
if (dwDeltaTime > 1000)
dwDeltaTime = 1000;
float fSpeed = (Cmd.sSpeed) / 256f; // short / 256 <=> FIX8TOFLOAT(short)
m_fMoveSpeed = fDist / (dwDeltaTime * 0.001f);
Mathf.Clamp(m_fMoveSpeed, 0.0f, fSpeed * 1.2f);
}
public bool MovingTo(float dwDeltaTime)
{
bool bRet = false;
A3DVECTOR3 vPos, vCurPos = GetPos();
float fDeltaTime = dwDeltaTime;
if (m_bStopMove)
{
A3DVECTOR3 vDir = m_vServerPos - vCurPos;
float fDist = vDir.Normalize();
vPos = MoveStep(vDir, m_fMoveSpeed, fDeltaTime);
float fMoveDelta = A3d_Magnitude(vPos - vCurPos);
if (Math.Abs(fMoveDelta - 0f) <= float.Epsilon || fMoveDelta >= fDist) //!fMoveDelta <=> (Math.Abs(fMoveDelta - 0f) <= float.Epsilon) Compare with 0
{
SetPos(m_vServerPos);
bRet = true;
}
else
{
SetPos(vPos);
}
}
else // Just move on
{
// If we have move so far from destination and still don't
// receive new 'move' or 'stop move' command, it's better to
// stop moving and goto last destination at once
float fDist = A3d_Magnitude(m_vServerPos - vCurPos);
if (fDist >= MAX_LAGDIST)
{
SetPos(m_vServerPos);
return true;
}
A3DVECTOR3 vDir = m_vMoveDir;
vDir.Normalize();
vPos = MoveStep(vDir, m_fMoveSpeed, fDeltaTime);
SetPos(vPos);
}
return bRet;
}
public void StopMoveTo(cmd_object_stop_move Cmd)
{
m_vMoveDir = Cmd.dest - GetPos();
m_bStopMove = true;
m_fMoveSpeed = (Cmd.sSpeed) / 256f;
m_vStopDir = glb_DecompressDirH(Cmd.dir);
SetServerPos(Cmd.dest);
float fDist = m_vMoveDir.Normalize();
if (fDist >= MAX_LAGDIST || m_fMoveSpeed < 0.01f)
{
m_bStopMove = false;
SetPos(Cmd.dest);
return;
}
int iMoveMode = Cmd.move_mode;
m_cdr.bTraceGround = true;
}
// Decompress horizontal direction
A3DVECTOR3 glb_DecompressDirH(byte byDir)
{
float fInter = 360.0f / 256.0f;
float fRad = Mathf.Deg2Rad * (byDir * fInter);
A3DVECTOR3 v;
v.x = (float)Math.Cos(fRad);
v.z = (float)Math.Sin(fRad);
v.y = 0.0f;
return v;
}
private A3DVECTOR3 MoveStep(A3DVECTOR3 vDir, float fSpeed, float fTime)
{
A3DVECTOR3 vRealDir = vDir;
// OnAirMove only accept positive speed value
if (fSpeed < 0.0f)
{
vRealDir = -vDir;
fSpeed = -fSpeed;
}
m_cdr.vCenter = m_aabbServer.Center;
//Debug.LogError("m_aabbServer.Center = " + m_aabbServer.Center.x + "," + m_aabbServer.Center.y + ","+ m_aabbServer.Center.z);
m_cdr.vVelocity = vRealDir * fSpeed;
//Debug.LogError("vVelocity = " + m_cdr.vVelocity.x + "," + m_cdr.vVelocity.y + "," + m_cdr.vVelocity.z);
m_cdr.t = fTime;
m_cdr.bTestTrnOnly = false;
//OtherPlayerMove(m_cdr);
A3DVECTOR3 vDelta = m_cdr.t * m_cdr.vVelocity;
m_cdr.vCenter += vDelta;
m_cdr.vecGroundNormal = g_vAxisY;
//if (m_cdr.bTraceGround)
// SetGroundNormal(m_cdr.vecGroundNormal);
//else
// SetGroundNormal(g_vAxisY);
return m_cdr.vCenter - g_vAxisY * m_cdr.vExts.y;
}
void OtherPlayerMove(OtherPlayer_Move_Info OPMoveInfo)
{
A3DVECTOR3 vDelta = OPMoveInfo.t * OPMoveInfo.vVelocity;
OPMoveInfo.vCenter += vDelta;
OPMoveInfo.vecGroundNormal = g_vAxisY;
A3DVECTOR3 vGroundPos, vNormal;
// Now, we directly interpolate the pos, and we don't use bTraceGround
//if (OPMoveInfo.bTestTrnOnly)
//{
// GetTerrainInfo(OPMoveInfo.vCenter, vGroundPos, vNormal);
// vGroundPos.y += OPMoveInfo.vExts.y;
// if (OPMoveInfo.vCenter.y < vGroundPos.y + 0.1f)
// OPMoveInfo.vecGroundNormal = vNormal;
// // verify not below the terrain
// if (OPMoveInfo.vCenter.y < vGroundPos.y)
// OPMoveInfo.vCenter.y = vGroundPos.y;
//}
//else
//{
// if (VertRayTrace(OPMoveInfo.vCenter, vGroundPos, vNormal, 3.0f))
// {
// OPMoveInfo.vecGroundNormal = vNormal;
// vGroundPos.y += OPMoveInfo.vExts.y;
// // verify not below the ground
// if (OPMoveInfo.vCenter.y < vGroundPos.y)
// OPMoveInfo.vCenter.y = vGroundPos.y;
// }
//}
}
private float A3d_Magnitude(A3DVECTOR3 v)
{
return Mathf.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}
// Set server position
public void SetServerPos(A3DVECTOR3 vPos)
{
m_vServerPos = vPos;
// If this player is a mule, change it's rider's server pos too.
if (m_iBuddyId != 0 && !m_bHangerOn)
{
var pPlayer = EC_ManMessageMono.Instance.GetECManPlayer.GetElsePlayer(m_iBuddyId);
if (pPlayer)
pPlayer.SetServerPos(vPos);
}
}
private void Update()
{
MovingTo(Time.deltaTime);
}
private void SetPos(A3DVECTOR3 vPos)
{
Vector3 vector = new Vector3();
vector.x = vPos.x;
vector.y = vPos.y;
vector.z = vPos.z;
transform.position = vector;
m_aabb.Center = vPos + new A3DVECTOR3(0.0f, m_aabb.Extents.y, 0.0f);
m_aabb.CompleteMinsMaxs();
m_aabbServer.Center = vPos + new A3DVECTOR3(0.0f, m_aabbServer.Extents.y, 0.0f);
m_aabbServer.CompleteMinsMaxs();
}
private A3DVECTOR3 GetPos()
{
A3DVECTOR3 result = new A3DVECTOR3();
result.x = transform.position.x;
result.y = transform.position.y;
result.z = transform.position.z;
return result;
}
}
// Update is called once per frame
void Update()
// Player appear flag
public enum PlayerAppearFlag
{
APPEAR_DISAPPEAR = -1, // Player disappear
APPEAR_ENTERWORLD = 0, // Player join world
APPEAR_RUNINTOVIEW, // Player run into view
APPEAR_GHOST, // Player is in ghost state, in player list but not active
};
public struct OtherPlayer_Move_Info
{
// Bounding sphere of avator
public A3DVECTOR3 vCenter;
public A3DVECTOR3 vExts;
public float fStepHeight;
// Velocity
public A3DVECTOR3 vVelocity;
// time span ( sec )
public float t;
public bool bTraceGround; // Whether trace the ground
public bool bTestTrnOnly; // Trace terrain only
public A3DVECTOR3 vecGroundNormal; // if bTraceGround is true, this will contain the ground normal when returned
}
public class A3DAABB
{
public A3DVECTOR3 Center;
public A3DVECTOR3 Extents;
public A3DVECTOR3 Mins;
public A3DVECTOR3 Maxs;
public A3DAABB() { }
public A3DAABB(A3DAABB aabb)
{
Center = aabb.Center;
Extents = aabb.Extents;
Mins = aabb.Mins;
Maxs = aabb.Maxs;
}
public A3DAABB(A3DVECTOR3 mins, A3DVECTOR3 maxs)
{
Mins = mins;
Maxs = maxs;
Center = (mins + maxs) * 0.5f;
Extents = maxs - Center;
}
// Reset AABB về trạng thái rỗng
public void Clear()
{
Mins = new A3DVECTOR3(999999f, 999999f, 999999f);
Maxs = new A3DVECTOR3(-999999f, -999999f, -999999f);
Center = new A3DVECTOR3(0f, 0f, 0f);
Extents = new A3DVECTOR3(0f, 0f, 0f);
}
// Thêm 1 điểm vào AABB
public void AddVertex(A3DVECTOR3 v)
{
if (v.x < Mins.x) Mins.x = v.x;
if (v.y < Mins.y) Mins.y = v.y;
if (v.z < Mins.z) Mins.z = v.z;
if (v.x > Maxs.x) Maxs.x = v.x;
if (v.y > Maxs.y) Maxs.y = v.y;
if (v.z > Maxs.z) Maxs.z = v.z;
CompleteCenterExts();
}
// Hợp nhất 2 AABB
public void Merge(A3DAABB subAABB)
{
if (subAABB.Mins.x < Mins.x) Mins.x = subAABB.Mins.x;
if (subAABB.Mins.y < Mins.y) Mins.y = subAABB.Mins.y;
if (subAABB.Mins.z < Mins.z) Mins.z = subAABB.Mins.z;
if (subAABB.Maxs.x > Maxs.x) Maxs.x = subAABB.Maxs.x;
if (subAABB.Maxs.y > Maxs.y) Maxs.y = subAABB.Maxs.y;
if (subAABB.Maxs.z > Maxs.z) Maxs.z = subAABB.Maxs.z;
CompleteCenterExts();
}
// Cập nhật Mins, Maxs từ Center + Extents
public void CompleteMinsMaxs()
{
Mins = Center - Extents;
Maxs = Center + Extents;
}
// Cập nhật Center + Extents từ Mins, Maxs
public void CompleteCenterExts()
{
Center = (Mins + Maxs) * 0.5f;
Extents = Maxs - Center;
}
// Kiểm tra điểm có nằm trong AABB không
public bool IsPointIn(A3DVECTOR3 v)
{
return !(v.x > Maxs.x || v.x < Mins.x ||
v.y > Maxs.y || v.y < Mins.y ||
v.z > Maxs.z || v.z < Mins.z);
}
// Kiểm tra 1 AABB khác có nằm trong AABB này không
public bool IsAABBIn(A3DAABB aabb)
{
return (aabb.Mins.x >= Mins.x && aabb.Maxs.x <= Maxs.x &&
aabb.Mins.y >= Mins.y && aabb.Maxs.y <= Maxs.y &&
aabb.Mins.z >= Mins.z && aabb.Maxs.z <= Maxs.z);
}
// Xây AABB từ một tập vertices
public void Build(A3DVECTOR3[] vertices)
{
Clear();
foreach (var v in vertices)
AddVertex(v);
}
// Lấy các vertices (8 điểm) của AABB
public A3DVECTOR3[] GetVertices()
{
A3DVECTOR3[] verts = new A3DVECTOR3[8];
verts[0] = new A3DVECTOR3(Mins.x, Mins.y, Mins.z);
verts[1] = new A3DVECTOR3(Maxs.x, Mins.y, Mins.z);
verts[2] = new A3DVECTOR3(Maxs.x, Maxs.y, Mins.z);
verts[3] = new A3DVECTOR3(Mins.x, Maxs.y, Mins.z);
verts[4] = new A3DVECTOR3(Mins.x, Mins.y, Maxs.z);
verts[5] = new A3DVECTOR3(Maxs.x, Mins.y, Maxs.z);
verts[6] = new A3DVECTOR3(Maxs.x, Maxs.y, Maxs.z);
verts[7] = new A3DVECTOR3(Mins.x, Maxs.y, Maxs.z);
return verts;
}
}
}
+1 -1
View File
@@ -107,7 +107,7 @@ MonoBehaviour:
joystick: {fileID: 0}
btnJump: {fileID: 0}
btnRun: {fileID: 0}
parentModel: {fileID: 0}
parentModel: {fileID: 78581589932911603}
extraGroundDistance: 0.05
radiusEpsilon: 0.005
groundMask:
+15 -1
View File
@@ -8,12 +8,12 @@ using System;
using System.IO;
using System.Text;
using TMPro;
using UnityEditor.SearchService;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Scene = UnityEngine.SceneManagement.Scene;
using PerfectWorld.Scripts.Managers;
public class CECHostPlayer : MonoBehaviour
{
@@ -224,6 +224,20 @@ public class CECHostPlayer : MonoBehaviour
Debug.LogError("Pos Character = " + pos);
joystick = FindAnyObjectByType<Joystick>();
}
public void InitCharacter(info_player_1 role)
{
string roleName = "(Error decoding name)";
//if (role.name != null && role.name.ByteArray != null)
//{
// roleName = Encoding.UTF8.GetString(role.name.ByteArray, 0, role.name.Length);
//}
Vector3 pos = new Vector3(role.pos.x, role.pos.y, role.pos.z);
if (txtName != null) txtName.text = roleName;
transform.position = pos;
SetModelHostPlayer();
Debug.LogError("Pos Character = " + pos);
}
}
public enum StateAnim
+1
View File
@@ -1,5 +1,6 @@
using BrewMonster.UI;
using CSNetwork.Protocols.RPCData;
using PerfectWorld.Scripts.Managers;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
+12
View File
@@ -62,4 +62,16 @@ public class GameController : MonoBehaviour
//posGround.y -= 2f;
//ground.transform.position = posGround;
}
public GameObject InitCharacter(info_player_1 info)
{
if (characterPrefab == null)
{
Debug.LogError("null prefab");
return null;
}
CECHostPlayer character = Instantiate(characterPrefab, transform);
character.InitCharacter(info);
return character.gameObject;
}
}