330 lines
11 KiB
C#
330 lines
11 KiB
C#
using System.Collections;
|
|
using System.Threading.Tasks;
|
|
using BrewMonster;
|
|
using BrewMonster.Managers;
|
|
using CSNetwork.GPDataType;
|
|
using CSNetwork.Protocols;
|
|
using PerfectWorld.Scripts;
|
|
using UnityEngine;
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Class CECObject
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
public 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;
|
|
// 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 bool Tick(float 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 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;
|
|
}
|
|
|
|
public A3DVECTOR3 GetPos()
|
|
{
|
|
return new A3DVECTOR3(transform.position.x, transform.position.y, transform.position.z);
|
|
}
|
|
public Vector3 GetPosVector3()
|
|
{
|
|
return transform.position;
|
|
}
|
|
|
|
// 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 (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;
|
|
|
|
//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);
|
|
//}
|
|
}
|
|
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<Collider>();
|
|
if (collider != null)
|
|
{
|
|
collider.enabled = false;
|
|
}
|
|
var skinnedMeshRenderer = GetComponentInChildren<SkinnedMeshRenderer>();
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|