Files
JJBB/Assets/Project/Script/Scene/SceneLogic/ActiveScene.cs
2024-08-23 15:49:34 +08:00

701 lines
25 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/********************************************************************************
* 文件名: ActiveSceneManager.cs
* 全路径: \Script\Scene\ActiveSceneManager.cs
* 创建人: 李嘉
* 创建时间2013-10-29
*
* 功能说明:游戏当前激活场景,负责游戏的场景数据保存和提供常用方法
* 修改记录:
*********************************************************************************/
using Games.GlobeDefine;
using Games.LogicObj;
using GCGame.Table;
using Module.Log;
using UnityEngine;
using UnityEngine.AI;
namespace Games.Scene
{
public class Scene_Init_Data
{
public bool m_bIsValid; //该结构体是否合法,创建的时候不合法,必须手动赋值后再设置该项
public int m_nCurSceneSrvID; //场景服务器ID
private Scene_Init_Data()
{
m_bIsValid = false;
}
}
public class ActiveScene
{
public const float navSampleHeight = 5f;
public const float raycastHeight = 200f;
public const float sphereCastRadius = 3f;
public const float edgeSnapDist = 0.05f;
//public static Vector3 GetTrrainPositionByAndroid(Vector3 orgPosition)
//{
// Vector3 newPosition = orgPosition;
//
// return newPosition;
//}
public static readonly int terrainLayMask = LayerMask.GetMask("Default", "T4MLayer");
public static readonly int obstacleLayer = LayerMask.NameToLayer("Terrain");
private SkillCircleProjector _skillCircleProjector; //技能范围光圈
public DialogTipUIRoot DialogTipUIRoot;
private float m_ChangeTime = -1;
//////////////////////////////////////////////////////////////////////////
//地面特效部分
//////////////////////////////////////////////////////////////////////////
private GameObject m_MovingCircle; //地表移动特效
private float m_SceneTimeScaleStart = -1;
private GameObject m_SelectCircle; //怪物选中特效
private GameObject m_SelectCircleNPC; //NPC选中特效
//地形文件
public ActiveScene()
{
SelectObj = null;
//TerrainData = null;
}
/// <summary>
/// 场景主摄像机
/// </summary>
//public GameObject MainCamera { get; private set; }
public int CurSceneServerID { get; set; }
public GameObject UIRoot { get; set; }
public GameObject FellowDialogueRoot { set; get; }
public GameObject NameBoardRoot { set; get; }
public GameObject FakeObjRoot { get; set; }
public GameObject FakeObjTrans
{
get { return FakeObjRoot.transform.Find("TransformOff").gameObject; }
}
public GameObject[] SceneAudioSources { get; set; }
public GameObject Teleport { get; set; }
public GameObject TeleportCopyScene { get; set; }
public GameObject[] QingGongPointList { get; set; }
//名字版池子
// 注之前实现方式已经脱离名字版池的概念在移除相关代码前只有Player名字板受到这个东西影响其他类型都脱离了该系统。
//private GameObjectPool m_NameBoardPool = null;
//public GameObjectPool NameBoardPool
//{
// get { return m_NameBoardPool; }
// set { m_NameBoardPool = value; }
//}
public GameObject SelectObj { get; set; }
//设置移动特效状态和位置
public void ActiveMovingCircle(Vector3 pos)
{
if (null == m_MovingCircle) return;
if (!m_MovingCircle.activeSelf) m_MovingCircle.SetActive(true);
m_MovingCircle.transform.position = pos;
//DeactiveSelectCircle();
}
public void DeactiveMovingCircle()
{
if (null != m_MovingCircle) m_MovingCircle.SetActive(false);
}
//设置选择特效状态和位置
public void ActiveSelectCircle(GameObject obj)
{
//在开启显示服务器主角位置的情况下,选中特效作为位置显示使用,不参与选中逻辑
if (GameManager.gameManager.ShowMainPlayerServerTrace) return;
if (null == obj) return;
//激活
SelectObj = obj;
var camp = 1;
var targetObj = SelectObj.GetComponent<Obj_Character>();
if (targetObj != null)
if (Reputation.CanAttack(targetObj))
camp = 0;
SetCirCleColor(camp);
//float height = 0;
//if (GameManager.gameManager.ActiveScene.IsT4MScene())
//{
// height = GameManager.gameManager.ActiveScene.GetTerrainHeight(obj.transform.position);
//}
//else
//{
// height = UnityEngine.Terrain.activeTerrain.SampleHeight(obj.transform.position);
//}
////由于特效需要显示在最上层,所以判断点击点和地表哪个更高,取最高值
//if (height > obj.transform.position.y)
//{
// Vector3 pos = m_SelectCircle.transform.position;
// pos.y = height;
// m_SelectCircle.transform.position = pos;
//}
}
//设置选中框的颜色
public void SetCirCleColor(int camp)
{
if (SelectObj == null)
{
if (m_SelectCircle)
m_SelectCircle.SetActive(false);
if (m_SelectCircleNPC)
m_SelectCircleNPC.SetActive(false);
}
else
{
GameObject current;
GameObject other;
if (camp > 0)
{
current = m_SelectCircleNPC;
other = m_SelectCircle;
}
else
{
current = m_SelectCircle;
other = m_SelectCircleNPC;
}
if (current != null)
{
current.transform.position = SelectObj.transform.position;
current.SetActive(true);
}
if (other != null)
other.SetActive(false);
}
}
public void DeactiveSelectCircle()
{
//在开启显示服务器主角位置的情况下,选中特效作为位置显示使用,不参与选中逻辑
if (GameManager.gameManager.ShowMainPlayerServerTrace) return;
if (null != m_SelectCircle) m_SelectCircle.SetActive(false);
if (null != m_SelectCircleNPC) m_SelectCircleNPC.SetActive(false);
SelectObj = null;
}
private void UpdateSelectCircle()
{
//在开启显示服务器主角位置的情况下,选中特效作为位置显示使用,不参与选中逻辑
if (GameManager.gameManager.ShowMainPlayerServerTrace) return;
if (null != SelectObj)
{
var z = SceneLogic.CameraController != null && SceneLogic.CameraController.MainCamera != null
? -SceneLogic.CameraController.MainCamera.transform.forward
: Vector3.back;
z.y = 0f;
var rotation = z == Vector3.zero ? Quaternion.identity : Quaternion.LookRotation(z, Vector3.up);
if (m_SelectCircle != null)
{
m_SelectCircle.transform.position = SelectObj.transform.position;
m_SelectCircle.transform.rotation = rotation;
}
if (m_SelectCircleNPC != null)
{
m_SelectCircleNPC.transform.position = SelectObj.transform.position;
m_SelectCircleNPC.transform.rotation = rotation;
}
}
}
//主角服务器位置测试选项
public void ShowMainPlayerServerPosition(float fX, float fZ)
{
if (false == GameManager.gameManager.ShowMainPlayerServerTrace) return;
if (null != m_SelectCircle)
{
m_SelectCircle.SetActive(true);
SetCirCleColor(1);
var pos = new Vector3(fX, 0, fZ);
pos.y = Singleton<ObjManager>.GetInstance().MainPlayer.ObjTransform.position.y;
m_SelectCircle.transform.position = pos;
}
}
//public Vector2 SkillAttackPoint
//{
// get { return _skillAttackPoint; }
// set
// {
// _skillAttackPoint = value;
// LogModule.WarningLog("Set Skill Attack: " + _skillAttackPoint);
// }
//}
//
//private Vector2 _skillAttackPoint;
//
//public void SetSkillTargetPoint(Vector2 point)
//{
// LogModule.WarningLog("Set Skill Target Point: " + point);
// SkillAttackPoint = point;
//}
//
//public void AfterUseSkill()
//{
// SkillAttackPoint = Vector2.zero;
//}
public void UpdateSkillCirclePos(Vector2 vec, bool isEnterRelex)
{
if (_skillCircleProjector != null)
_skillCircleProjector.UpdatePos(vec, isEnterRelex);
}
public void ShowSkillCircleEffect(Tab_SkillEx skillEx, Vector2 vec)
{
if (skillEx != null)
{
if (_skillCircleProjector != null)
{
_skillCircleProjector.gameObject.SetActive(true);
_skillCircleProjector.InitSkillInfo(skillEx, vec);
}
}
else
{
HideSkillCircleEffect();
}
}
public void HideSkillCircleEffect()
{
if (_skillCircleProjector != null)
_skillCircleProjector.gameObject.SetActive(false);
}
public bool Init()
{
//m_UIRoot = GameObject.Find("UI Root");
//if (null == m_UIRoot)
//{
// LogModule.WarningLog("can not find uiroot in curscene");
//}
//else
//{
// if (null == m_UIRoot.GetComponent<UIManager>())
// {
// m_UIRoot.AddComponent<UIManager>();
// }
//}
var dialogUI = GameObject.Find("UI Root/WorldUIRoot/DialogueRoot");
if (dialogUI != null)
DialogTipUIRoot = dialogUI.GetComponent<DialogTipUIRoot>();
NameBoardRoot = GameObject.Find("UI Root/WorldUIRoot/NameBoardRoot");
if (DropBoardManager.Instacne == null)
ResourceManager.InstantiateResource("Prefab/HeadInfo/DropItemBoardRoot");
//初始化特效
if (null == m_MovingCircle)
{
m_MovingCircle = ResourceManager.InstantiateResource("Prefab/Effect/MovingCircle");
if (null != m_MovingCircle)
{
m_MovingCircle.transform.position = Vector3.zero;
m_MovingCircle.transform.rotation = Quaternion.Euler(Vector3.zero);
m_MovingCircle.SetActive(false);
m_MovingCircle.name = "MovingCircle";
Object.DontDestroyOnLoad(m_MovingCircle);
}
}
if (null == m_SelectCircle)
{
m_SelectCircle = ResourceManager.InstantiateResource("Prefab/Effect/SelectCircle");
if (null != m_SelectCircle)
{
m_SelectCircle.transform.position = Vector3.zero;
m_SelectCircle.transform.rotation = Quaternion.Euler(Vector3.zero);
m_SelectCircle.SetActive(false);
m_SelectCircle.name = "SelectCircle";
Object.DontDestroyOnLoad(m_SelectCircle);
}
}
if (null == m_SelectCircleNPC)
{
m_SelectCircleNPC = ResourceManager.InstantiateResource("Prefab/Effect/SelectCircleNPC");
if (null != m_SelectCircleNPC)
{
m_SelectCircleNPC.transform.position = Vector3.zero;
m_SelectCircleNPC.transform.rotation = Quaternion.Euler(Vector3.zero);
m_SelectCircleNPC.SetActive(false);
m_SelectCircleNPC.name = "m_SelectCircleNPC";
Object.DontDestroyOnLoad(m_SelectCircleNPC);
}
}
GameObject skillCircleProjectObj = null;
if (null == _skillCircleProjector)
skillCircleProjectObj =
ResourceManager.InstantiateResource("Prefab/Effect/SkillCircleEffect");
if (null == skillCircleProjectObj)
{
LogModule.ErrorLog("无法获得技能范围指示器!");
}
else
{
_skillCircleProjector = skillCircleProjectObj.GetComponent<SkillCircleProjector>();
skillCircleProjectObj.SetActive(false);
}
Teleport = GameObject.Find("Teleport");
if (Teleport != null)
{
//if (IsCopyScene())
//{
// m_Teleport.SetActive(false);
//}
}
TeleportCopyScene = GameObject.Find("TeleportCopyScene");
if (TeleportCopyScene)
{
//if (IsCopyScene())
//{
// m_TeleportCopyScene.SetActive(false);
//}
}
QingGongPointList = GameObject.FindGameObjectsWithTag("QingGongPoint");
// if (m_QingGongPoint != null)
// {
// if (IsCopyScene())
// {
// m_QingGongPoint.SetActive(false);
// }
// }
for (var i = 0; i < QingGongPointList.Length; ++i)
if (IsCopyScene() && QingGongPointList[i] != null)
QingGongPointList[i].SetActive(false);
//声音资源
SceneAudioSources = GameObject.FindGameObjectsWithTag("SceneSoundEffect");
for (var i = 0; i < SceneAudioSources.Length; ++i)
if (SceneAudioSources[i] != null && !PlayerPreferenceData.SystemSoundEffect)
SceneAudioSources[i].SetActive(false);
//初始化Terrain数据
//if (GameManager.gameManager != null) GameManager.gameManager.m_loadErrorNum = 0;
//SetTerrainData();
////初始化名字版池子
//if (null == m_NameBoardPool)
//{
// m_NameBoardPool = new GameObjectPool("HeadInfo", 128);
//}
//if (null != m_NameBoardPool)
//{
// m_NameBoardPool.ClearAllPool();
//}
//if (MainCamera == null)
// MainCamera = GameObject.Find("Main Camera");
return true;
}
/// <summary>
/// 设置TerrainData 数据
/// </summary>
// public void SetTerrainData()
// {
// if (GameManager.gameManager.RunningScene ==
// (int) GameDefine_Globe.SCENE_DEFINE.SCENE_LOGIN)
// return;
//
// if (null != TerrainData) TerrainData = null;
//
// var sceneClass = TableManager.GetSceneClassByID(GameManager.gameManager.RunningScene, 0);
// if (null != sceneClass)
// {
// //PC上Raw文件路径为Assets/MLDJ/Scene/TerrainRaw/+场景名称.raw
// //iPhone上文件路径为Application.dataPath/TerrainRaw/+场景名称.raw
// var streamingAssetPath = Utils.GetStreamingAssetPath();
// //if ("" == streamingAssetPath)
// //{
// // return false;
// //}
//
// var strTerrainRawFilePath = streamingAssetPath + "/TerrainRaw/" + sceneClass.ResName + ".raw";
//
//#if UNITY_ANDROID && !UNITY_EDITOR
// m_TerrainData = new TerrainManager(); // 可优化区
// //场景如果分32*32个块那么顶点应该是33*33
// if (false == m_TerrainData.InitTerrianData(strTerrainRawFilePath,
// sceneClass.TerrainHeightMapLength + 1,
// sceneClass.TerrainHeightMapWidth + 1,
// sceneClass.TerrainHeightMax,
// sceneClass.Length + 1,
// sceneClass.Width + 1))
// {
// LogModule.DebugLog("init Scene TerrainData Failed");
// }
//#else
//
// GameManager.gameManager.m_loadErrorNum++;
//
// if (GameManager.gameManager.m_loadErrorNum > GameManager.gameManager.m_MaxErrorNum) return;
//
// if (File.Exists(strTerrainRawFilePath))
// {
// TerrainData = new TerrainManager(); // 可优化区
// //场景如果分32*32个块那么顶点应该是33*33
// if (false == TerrainData.InitTerrianData(strTerrainRawFilePath,
// sceneClass.TerrainHeightMapLength + 1,
// sceneClass.TerrainHeightMapWidth + 1,
// sceneClass.TerrainHeightMax,
// sceneClass.Length + 1,
// sceneClass.Width + 1))
// {
// LogModule.DebugLog("init Scene TerrainData Failed");
//
// //资源加载失败时
// SetTerrainData();
// }
// }
// else
// {
// //文件不存在或路径不对时,重新申请资源
// SetTerrainData();
// }
//#endif
// }
// }
public void Update()
{
UpdateSelectCircle();
//UpdateMovingCircle();
UpdateSceneTimeScale();
}
public void RelaseActiveSceneData()
{
CurSceneServerID = GlobeVar.INVALID_ID;
UIRoot = null;
NameBoardRoot = null;
//TerrainData = null;
m_MovingCircle = null;
m_SelectCircle = null;
Teleport = null;
TeleportCopyScene = null;
QingGongPointList = null;
SceneAudioSources = null;
}
public void SceneTimeScale(int nTimeScaleType)
{
if (nTimeScaleType == 0)
{
Time.timeScale = 0.2f;
m_ChangeTime = 0.6f;
m_SceneTimeScaleStart = Time.fixedTime;
}
else if (nTimeScaleType == 1) //todo 临时实验代码
{
// Time.timeScale = 0.5f;
// m_ChangeTime = 0.1f;
// m_SceneTimeScaleStart = Time.fixedTime;
}
}
private void UpdateSceneTimeScale()
{
if (m_ChangeTime > 0)
if (Time.fixedTime - m_SceneTimeScaleStart >= m_ChangeTime)
{
m_SceneTimeScaleStart = -1;
m_ChangeTime = -1;
Time.timeScale = 1;
}
}
public bool IsCopyScene()
{
return IsCopyScene(GameManager.gameManager.RunningScene);
}
public bool IsCopyScene(int sceneId)
{
var tabSceneClass = TableManager.GetSceneClassByID(sceneId, 0);
return tabSceneClass != null && tabSceneClass.IsCopyScene();
}
public bool IsWildeScene()
{
var tabSceneClass = TableManager.GetSceneClassByID(GameManager.gameManager.RunningScene, 0);
if (tabSceneClass != null)
if (tabSceneClass.Type == (int) GameDefine_Globe.SCENE_TYPE.SCENETYPE_WILDCITY)
return true;
return false;
}
public void SetSceneSoundEffect(bool bIsActive)
{
for (var i = 0; i < SceneAudioSources.Length; ++i)
if (SceneAudioSources[i] != null)
SceneAudioSources[i].SetActive(bIsActive);
}
public static bool GetTerrainPosition(ref Vector3 origin)
{
var result = false;
if (GameManager.gameManager != null)
{
#if UNITY_EDITOR
// 为Log输出备份的原始位置
var originBackup = origin;
#endif
var raySource = origin;
raySource.y = raycastHeight;
// 试图使用射线位置校正高度
RaycastHit raycastHit;
if (Physics.Raycast(raySource, Vector3.down, out raycastHit, raycastHeight * 2f, terrainLayMask))
{
origin.y = raycastHit.point.y;
}
else // if (GameManager.gameManager.SceneLogic != null && GameManager.gameManager.SceneLogic.allowSphereCast)
{
#if UNITY_EDITOR
LogModule.WarningLog(string.Format("射线无法获得高度于位置{0},使用半径{1}球形射线修正高度。", originBackup,
sphereCastRadius));
#endif
// 注SamplePosition 30f超过SphereCast 3f的20倍因此使用SphereCast直接过滤。
if (Physics.SphereCast(raySource, sphereCastRadius, Vector3.down, out raycastHit,
raycastHeight * 2f, terrainLayMask))
{
origin.y = raycastHit.point.y;
}
else
{
#if UNITY_EDITOR
//LogModule.WarningLog(string.Format("球体射线无法找到地形碰撞体于位置{0},使用主角高度修正。", originBackup));
#endif
// 暂时使用MainPlayer来校正位置
var mainPlayer = ObjManager.Instance.MainPlayer;
if (mainPlayer)
origin.y = mainPlayer.Position.y;
}
}
// 对高度修正后的位置实现采样
NavMeshHit navMeshHit;
if (NavMesh.SamplePosition(origin, out navMeshHit, navSampleHeight,
NavMesh.AllAreas))
{
result = true;
origin = navMeshHit.position;
// 防止采样点是在边界上导致寻路机卡住
if (NavMesh.FindClosestEdge(origin, out navMeshHit, NavMesh.AllAreas)
&& (navMeshHit.position - origin).sqrMagnitude < edgeSnapDist.ToSquare())
origin = navMeshHit.position;
}
else
{
#if UNITY_EDITOR
//LogModule.ErrorLog(string.Format("地图NavMesh采样失败于位置{0}", originBackup));
#endif
}
}
return result;
}
/// <summary>
/// 将服务器推送的2d寻路目标转化为客户端3d位置
/// </summary>
/// <param name="origin">服务器位置</param>
/// <returns>客户端位置</returns>
public static Vector3 GetTerrainPosition(Vector3 origin)
{
GetTerrainPosition(ref origin);
return origin;
}
/// <summary>
/// 将射线转换为客户端3d位置
/// </summary>
public static Vector3? GetTerrainPosition(Ray ray)
{
Vector3? result = null;
RaycastHit hit;
if (Physics.Raycast(ray, out hit, float.PositiveInfinity, terrainLayMask))
{
NavMeshHit navMeshHit;
if (NavMesh.SamplePosition(hit.point, out navMeshHit, navSampleHeight, NavMesh.AllAreas))
result = navMeshHit.position;
}
return result;
}
public void ShowFakeObj()
{
FakeObjRoot.SetActive(true);
}
public void HideFakeObj()
{
FakeObjRoot.SetActive(false);
}
public void ClearUiBoard()
{
if (m_MovingCircle != null)
{
Object.Destroy(m_MovingCircle);
m_MovingCircle = null;
}
if (m_SelectCircle != null)
{
Object.Destroy(m_SelectCircle);
m_SelectCircle = null;
}
if (m_SelectCircleNPC != null)
{
Object.Destroy(m_SelectCircleNPC);
m_SelectCircleNPC = null;
}
if (_skillCircleProjector != null)
{
Object.Destroy(_skillCircleProjector.gameObject);
_skillCircleProjector = null;
}
if (DropBoardManager.Instacne != null)
DropBoardManager.Instacne.ClearDropName();
}
}
}