using System.Collections; using System.Threading.Tasks; using BrewMonster; using BrewMonster.Managers; using BrewMonster.Scripts; using CSNetwork.GPDataType; using CSNetwork.Protocols; using PerfectWorld.Scripts; using UnityEngine; /////////////////////////////////////////////////////////////////////////// // // Class CECObject // /////////////////////////////////////////////////////////////////////////// public partial class CECObject : MonoBehaviour { protected static int ALPHA_HASH = Shader.PropertyToID("_Alpha"); protected Quaternion targetRotation; protected Quaternion startRotation; // Store starting rotation for Slerp protected Vector3 g_vAxisY = Vector3.up; protected Transform _objectTransform; protected Vector3 objectPosition; public Vector3 ObjectPosition { get => objectPosition; } // Class ID public static class Class_ID { public const int OCID_OBJECT = 0, OCID_PLAYER = 1, OCID_HOSTPLAYER = 2, OCID_ELSEPLAYER = 3, OCID_LOGINPLAYER = 4, OCID_NPC = 5, OCID_MONSTER = 6, OCID_SERVER = 7, OCID_MATTER = 8, OCID_PET = 9, OCID_CLONED_PLAYER = 10, // ¸´ÖƽÇɫģÐÍ OCID_HOST_NAVIGATER = 11, // ´¿¿Í»§¶ËplayerÀà,ÓÃÓÚÇ¿ÖÆÒÆ¶¯ OCID_NPCCLONED_MASTER = 12; // NPC ¸´ÖƵĽÇɫģÐÍ } // Render flag public static class Render_flag { public const int RD_NORMAL = 0, RD_REFRACT = 1, RD_REFLECT = 2; } // Move environment public static class Move_environment { public const int MOVEENV_GROUND = 0, // Move on ground MOVEENV_WATER = 1, MOVEENV_AIR = 2; } // Constructor and Destructor public CECObject() { m_iCID = Class_ID.OCID_OBJECT; m_bAdjustOrient = false; m_bVisible = true; m_bBornInSight = false; m_dwBornStamp = 0; m_bUseGroundNormal = false; m_vecGroundNormal = new A3DVECTOR3(0.0f, 1.0f, 0.0f); m_vecGroundNormalSet = new A3DVECTOR3(0.0f, 1.0f, 0.0f); m_bSelectable = true; } public virtual void SetUpCECObject() { m_dwBornStamp = 0; m_bBornInSight = false; //m_bSelectable = false; m_iCID = (int)Class_ID.OCID_OBJECT; } public void SetSelectable(bool bSelectable) { m_bSelectable = bSelectable; } // Tick routine public virtual bool Tick(uint dwDeltaTime) { if (m_bAdjustOrient) AdjustOrientation(dwDeltaTime); m_vecGroundNormal = Normalize(m_vecGroundNormal * 0.85f + m_vecGroundNormalSet * 0.15f); return true; } // Set absolute forward and up direction public virtual void SetDirAndUp(Vector3 vDir, Vector3 vUp) { //if (m_bUseGroundNormal) //{ // A3DVECTOR3 vecRight = Normalize(CrossProduct(g_vAxisY, vDir)); // A3DVECTOR3 vecNormal = m_vecGroundNormal - DotProduct(m_vecGroundNormal, vecRight) * vecRight; // A3DVECTOR3 vecNewDir = Normalize(CrossProduct(vecRight, vecNormal)); // A3DCoordinate::SetDirAndUp(vecNewDir, vecNormal); //} //else // A3DCoordinate::SetDirAndUp(vDir, vUp); // Stop orientation adjusting if (vDir != Vector3.zero) { Quaternion lookRot = Quaternion.LookRotation(vDir, vUp); transform.rotation = lookRot; } m_bAdjustOrient = false; } // Set destination orientation of model public virtual void SetDirAndUp(A3DVECTOR3 vDir, A3DVECTOR3 vUp){ SetDirAndUp(EC_Utility.ToVector3(vDir), EC_Utility.ToVector3(vUp)); } public void SetDestDirAndUp(A3DVECTOR3 vDir, Vector3 vUp, float dwTime) { m_bAdjustOrient = true; m_dwOrientTime = dwTime; m_dwOrientTimeCnt = 0; startRotation = transform.rotation; // Store current rotation as start targetRotation = Quaternion.LookRotation(EC_Utility.ToVector3(vDir), Vector3.up); } // Calculate distance between this object and specified position public float CalcDist(A3DVECTOR3 vPos, bool b3D) { A3DVECTOR3 vDelta = GetPos() - vPos; return b3D ? vDelta.Magnitude() : vDelta.MagnitudeH(); } private A3DVECTOR3 Normalize(A3DVECTOR3 v) { float mag = v.Magnitude(); if (mag < 1e-12 && mag > -1e-12) return new A3DVECTOR3(0.0f); else return v / mag; } /// /// Get the position of the object.
/// Consider NOT use the transform position if you get the data from outside of the MainThread. ///
/// If true, use the transform position, otherwise use the object position for slighly better performance. /// public A3DVECTOR3 GetPos(bool useTransform = true) { return EC_Utility.ToA3DVECTOR3(useTransform ? _objectTransform.position : objectPosition); } public Vector3 GetPosVector3(bool useTransform = true) { return useTransform ? _objectTransform.position : objectPosition; } // Turn around object and face to specified object public virtual void TurnFaceTo(int idTarget, float timeturn) { // Face to target Vector3 vTarget = new Vector3(); CECObject pObject = EC_ManMessageMono.Instance.GetObject(idTarget, 0); if (!pObject) return; if (GPDataTypeHelper.ISNPCID(idTarget)) { CECNPC pNPC = (CECNPC)pObject; vTarget = pNPC.transform.position; } else if (GPDataTypeHelper.ISPLAYERID(idTarget)) { CECPlayer pPlayer = (CECPlayer)pObject; vTarget = pPlayer.transform.position; } /* else { CECMatter* pMatter = g_pGame->GetGameRun()->GetWorld()->GetMatterMan()->GetMatter(idTarget); if (pMatter && pMatter->IsMonsterSpiritMine()) vTarget = pMatter->GetPos(); else return; }*/ // Every some time we check whether player still face to // it's attack target. Vector3 vDir = vTarget - transform.position; vDir.y = 0.0f; if (vDir.sqrMagnitude < 1e-6f) { vDir = transform.forward; } else { vDir.Normalize(); } SetDestDirAndUp(EC_Utility.ToA3DVECTOR3(vDir), g_vAxisY, timeturn); } protected virtual void Update() { if (_objectTransform == null) { _objectTransform = transform; } objectPosition = _objectTransform.position; if (m_bAdjustOrient) AdjustOrientation(Time.deltaTime); } // Set / Get visible flag public void SetVisible(bool bVisible) { m_bVisible = bVisible; } public bool GetVisible() { return m_bVisible; } // Get object class ID public int GetClassID() { return m_iCID; } public bool IsPlayer() { return m_iCID == Class_ID.OCID_HOSTPLAYER || m_iCID == Class_ID.OCID_ELSEPLAYER || m_iCID == Class_ID.OCID_LOGINPLAYER; } public bool IsHostPlayer() { return m_iCID == Class_ID.OCID_HOSTPLAYER; } public bool IsElsePlayer() { return m_iCID == Class_ID.OCID_ELSEPLAYER; } public bool IsLoginPlayer() { return m_iCID == Class_ID.OCID_LOGINPLAYER; } public bool IsNPC() { return m_iCID == Class_ID.OCID_MONSTER || m_iCID == Class_ID.OCID_SERVER; } public bool IsMonsterNPC() { return m_iCID == Class_ID.OCID_MONSTER; } public bool IsServerNPC() { return m_iCID == Class_ID.OCID_SERVER; } public bool IsMatter() { return m_iCID == Class_ID.OCID_MATTER; } public bool IsSelectable() { return m_bSelectable; } // Set / Get object born stamp public uint GetBornStamp() { return m_dwBornStamp; } public void SetBornStamp(uint dwStamp) { m_dwBornStamp = dwStamp; } // Set / Get born in sight flag public bool GetBornInSight() { return m_bBornInSight; } public void SetBornInSight(bool bFlag) { m_bBornInSight = bFlag; } // Get object id public static int GetObjectID(CECObject pObject) { if (!pObject) return 0; if (pObject.IsPlayer()) return ((CECPlayer)pObject).GetCharacterID(); else if (pObject.IsNPC()) return ((CECNPC)pObject).GetNPCID(); else if (pObject.IsMatter()) return ((CECMatter)pObject).GetMatterID(); else return 0; } protected int m_iCID; // Class ID protected bool m_bAdjustOrient; // Is adjusting orientation //protected A3DQUATERNION m_quOrientStart; // Orientation start //protected A3DQUATERNION m_quOrientEnd; // Orientation end protected float m_dwOrientTime; // Orientation adjusting time counter protected float m_dwOrientTimeCnt; // Orientation adjusting time counter protected bool m_bBornInSight; // Born in my sight protected uint m_dwBornStamp; // Born time stamp protected bool m_bVisible; // Render flag protected bool m_bUseGroundNormal; // flag indicates whether we use a ground normal as up protected A3DVECTOR3 m_vecGroundNormal; // current ground normal protected A3DVECTOR3 m_vecGroundNormalSet; // ground normal set protected bool m_bSelectable; // whether the object can be selected public A3DVECTOR3 GetGroundNormal() { return m_vecGroundNormal; } public bool GetUseGroundNormal() { return m_bUseGroundNormal; } public void SetUseGroundNormal(bool bFlag) { //if (m_bUseGroundNormal == bFlag) // return; if(m_bUseGroundNormal == bFlag) return; m_bUseGroundNormal = bFlag; //if (m_bUseGroundNormal) //{ // // now reset dir and up to make the object show correct pose // SetDirAndUp(GetDir(), GetUp()); //} //else //{ // // now reset dir and up to make the player show correct pose // A3DVECTOR3 vLeft = CrossProduct(GetDir(), g_vAxisY); // A3DVECTOR3 vDir = Normalize(CrossProduct(g_vAxisY, vLeft)); // SetDirAndUp(vDir, g_vAxisY); //} if(m_bUseGroundNormal) { SetDirAndUp(transform.forward, transform.up); } else { Vector3 vLeft = Vector3.Cross(transform.forward, g_vAxisY); Vector3 vDir = Vector3.Cross(g_vAxisY, vLeft); SetDirAndUp(vDir, g_vAxisY); } } public void SetGroundNormal(A3DVECTOR3 vecNormal) { m_vecGroundNormalSet = vecNormal; } protected void AdjustOrientation(float dwDeltaTime) { m_dwOrientTimeCnt += dwDeltaTime; // Adjust model's orientation if (m_dwOrientTimeCnt >= m_dwOrientTime) { // Set final rotation to target (not Vector3.forward) transform.rotation = targetRotation; m_bAdjustOrient = false; } else { // Interpolate from START to TARGET rotation based on time progress float f = m_dwOrientTimeCnt / m_dwOrientTime; transform.rotation = Quaternion.Slerp(startRotation, targetRotation, f); m_bAdjustOrient = true; } } protected void FadeOut() { StartCoroutine(FadeOutCoroutine()); } private IEnumerator FadeOutCoroutine() { var collider = GetComponent(); if (collider != null) { collider.enabled = false; } var skinnedMeshRenderer = GetComponentInChildren(); if (skinnedMeshRenderer == null) yield break; var material = skinnedMeshRenderer.sharedMaterial; var newMaterial = new Material(material); skinnedMeshRenderer.sharedMaterial = newMaterial; // use for to fade out alpha for (float alpha = 1f; alpha >= 0f; alpha -= 0.01f) { newMaterial.SetFloat(ALPHA_HASH, alpha); yield return null; } } }