using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.IO; using UnityEngine; using Thousandto.Core.Base; using MsgTime = System.Single; using Thousandto.Core.RootSystem; using Thousandto.Core.Framework; using Thousandto.Core.Asset; using Thousandto.Cfg.Data; using Thousandto.Core.Support; using Thousandto.Plugins.PathGrid; using PathEditor.Proxy.Plugin; using SceneEditor.Proxy.Plugin; using FLogger = UnityEngine.Gonbest.MagicCube.FLogger; #pragma warning disable 0219 #pragma warning disable 0168 #pragma warning disable 0162 namespace Thousandto.Plugins.Common.UniScene { /// /// 基础场景 /// public partial class BaseScene : IScene { #region constants --常量定义 public const string CameraBounderRootName = "[CameraBounder]"; public const string SpawnPointRootName = "[SpawnPoint]"; public const string MonsterStubRootName = "[MonsterStub]"; public const string WayPointRootName = "[WayPoint]"; public const string DynamicBlockerRootName = "[DynamicBlocker]"; public const string TriggerRootName = "[Trigger]"; public const string CollectionRootName = "[Collection]"; public const string CameraRootName = "[SceneCameraRoot]"; public const string CameraName = "[SceneCamera]"; private const string SceneRootName = "[SceneRoot]"; private const string SceneObjectsName = "[SceneObjects]"; #endregion #region members --成员变量 protected Transform _root = null; protected Transform _sceneObjectsRoot = null; protected Transform _wayPointRoot = null; protected Transform _dynamicBlockerRoot = null; protected Transform _triggerRoot = null; protected Messenger _msger = Messenger.SharedInstance; private CameraManager _cameraManager = null; private EntityContainer _entityContainer = null; private PathGridSystem _navigator = null; private int _id = -1; private DeclareMapsetting _cfg = null; private string _name = string.Empty; private string _levelName = string.Empty; private string _pathFileName = string.Empty; private string _mapInfoFileName = string.Empty; private string _dayCameraName = string.Empty; private string _nightCameraName = string.Empty; private SceneParams _scenesParams = null; private float _minMountFlyHeight = 0f; private float _maxMountFlyHeight = 0f; protected Vector3 _shadowLightDir = Vector3.down; protected float _shadowDayStrength = 0.7f; protected float _shadowNightStrength = 0.3f; protected bool _sceneShadowOpen = false; protected Vector3 _sceneShadowLightDir = Vector3.down; protected float _sceneShadowDayStrength = 0.7f; protected float _sceneShadowNightStrength = 0.3f; protected bool _haveFogSetting = false; protected Color _fogDayColor = Color.white; protected float _fogDayMinDis = 20f; protected float _fogDayMaxDis = 200f; protected Color _fogNightColor = Color.white; protected float _fogNightMinDis = 20f; protected float _fogNightMaxDis = 200f; //删除列表,在每次update的时候进行删除 protected List _deleteEnityList = new List(256); #endregion #region accessor -- 属性信息 public int MapId { get { return _id; } } public DeclareMapsetting Cfg { get { return _cfg; } } // NOTE: the name of map is not unique!!! public string Name { get { return _name; } } public string LevelName { get { return _levelName; } } public Transform SceneObjectsRoot { get { return _sceneObjectsRoot; } } public Messenger Msger { get { return _msger; } } public string DayCameraName { get { return _dayCameraName; } } public string NightCameraName { get { return _nightCameraName; } } public Camera SceneCamera { get { return _cameraManager != null ? _cameraManager.CurCamera : null; } } public CameraControl SceneCameraControl { get { return _cameraManager != null ? _cameraManager.SceneCameraControl : null; } } public CameraManager CameraManager { get { return _cameraManager; } } public EntityContainer Entities { get { return _entityContainer; } } public PathGridSystem navigator { get { return _navigator; } } public Transform DynamicBlockerRoot { get { return _dynamicBlockerRoot; } } public Transform TriggerRoot { get { return _triggerRoot; } } public float MinMountFlyHeight { get { return _minMountFlyHeight; } } public float MaxMountFlyHeight { get { return _maxMountFlyHeight; } } public Vector3 ShadowLightDir { get { return _shadowLightDir; } } public float ShadowDayStrength { get { return _shadowDayStrength; } } public float ShadowNightStrength { get { return _shadowNightStrength; } } public bool SceneShadowOpen { get { return _sceneShadowOpen; } } public Vector3 SceneShadowLightDir { get { return _sceneShadowLightDir; } } public float SceneShadowDayStrength { get { return _sceneShadowDayStrength; } } public float SceneShadowNightStrength { get { return _sceneShadowNightStrength; } } //public bool HaveFogSetting //{ // get // { // return _haveFogSetting; // } //} public Color FogDayColor { get { return _fogDayColor; } } public float FogDayMinDis { get { return _fogDayMinDis; } } public float FogDayMaxDis { get { return _fogDayMaxDis; } } public Color FogNightColor { get { return _fogNightColor; } } public float FogNightMinDis { get { return _fogNightMinDis; } } public float FogNightMaxDis { get { return _fogNightMaxDis; } } #endregion #region ctor --构造函数 public BaseScene() { var root = new GameObject(SceneRootName); _root = root.transform; _root.parent = AppRoot.Transform; _entityContainer = new EntityContainer(); } #endregion #region//场景的心跳方法 public void UpdateDeleateList() { if (_deleteEnityList.Count > 0) { for (int i = 0; i < _deleteEnityList.Count; ++i) { Entities.Remove(_deleteEnityList[i]); } _deleteEnityList.Clear(); } } public virtual void Update(float deltaTime) { //更新删除列表 UpdateDeleateList(); _msger.Tick(deltaTime); _entityContainer.Update(deltaTime); } #endregion #region//删除角色 public void DeleteEntity(ulong code) { _deleteEnityList.Add(code); } #endregion #region//LocalPlayer 对自己角色的操作 //获取玩家 public Entity GetLocalPlayer() { if (_entityContainer != null) { return _entityContainer.LocalPlayer; } else { return null; } } //获取玩家ID public ulong GetLocalPlayerID() { if (_entityContainer != null) { return _entityContainer.LocalPlayerID; } else { return 0; } } #endregion #region//对Entity的一些查询操作 public T Find(UInt64 code) where T : Entity { Entity retval = null; if (_entityContainer != null) { retval = _entityContainer.Find(code); } return retval as T; } public Entity FindEntity(UInt64 code) { Entity retval = null; if (_entityContainer != null) { retval = _entityContainer.Find(code); } return retval; } public List FindAll() where T : Entity { return Entities.FindAll(); } public int GetCount() where T : Entity { return Entities.GetCount(); } public int GetCount(MyFunc func) { return Entities.GetCount(func); } public List FindAll(MyFunc predicate) { return _entityContainer.FindAll(predicate); } #endregion #region//消息的一些处理 protected virtual bool OnGameMessage(Message msg) { if (msg.ToId != 0) { var e = Entities.Find(msg.ToId); if (e != null) { if (e.HandleGameMessage(msg)) { return true; } } FLogger.DebugLogFormat("Message: {0} not handle, target[{1}] not found!", msg.MsgId.ToString(), msg.ToId); return false; } return true; } private bool HandleGameMessage(BaseMessage msg) { return OnGameMessage(msg as Message); } #endregion #region //设置场景根GameObject有效 public void EnableSceneObjects(bool enable = true) { if (_sceneObjectsRoot != null) { _sceneObjectsRoot.gameObject.SetActive(enable); } } #endregion #region Load & UnLoad -- 场景的加载和卸载操作 protected virtual bool OnCreate(bool isPlane, bool cameraBlend) { return true; } protected virtual bool OnReCreate() { return true; } protected virtual void OnDestroy() { } private void LoadSceneParams() { _cfg = DeclareMapsetting.Get(_id); LoadSceneParams(_cfg); //var planes = setting.GetBitPlanes(); //if (planes != null) //{ // for (int j = 0; j < planes.Count; ++j) // { // var s = DeclareMapsetting.Get(planes[j].id); // LoadSceneParams(s); // } //} } private void LoadSceneParams(DeclareMapsetting setting) { if (setting == null) { return; } var levelName = setting.LevelName; var originName = setting.Name; _minMountFlyHeight = setting.FlyMinHeight; _maxMountFlyHeight = setting.FlyMaxHeight; _scenesParams = new SceneParams(); _scenesParams.m_id = setting.MapId; // load path gird data; //PathGirdData girdData = Navigator.LoadPathGridData(setting.MapGrid); //_scenesParams.m_pathGirdData = girdData; PathGridSystem.instance.LoadPathGridData(setting.MapGrid); _scenesParams.m_pathGirdData = PathGridSystem.instance.PathGridData; // load scene objects; //string mapName = FileUtils.MapInfoDirPath + "/" + setting.MapInfo.Replace(MapInfoConstDefine.FileExtName, MapInfoConstDefine.XmlExtName); string mapName = setting.MapInfo.Replace("_MapInfo.bytes", ""); GameObject go = MapInfoDataReader.LoadScene(mapName); _scenesParams.m_sceneObjectName = go.name; _scenesParams.m_sceneObjects = go; _scenesParams.m_sceneObjects.name = go.name + "_" + setting.MapId.ToString(); _scenesParams.m_sceneObjects.SetActive(false); _scenesParams.m_sceneObjects.transform.parent = _root; } public PathEditor.Proxy.Plugin.PathGirdData GetSceneGirdData() { if (_scenesParams == null) return null; return _scenesParams.m_pathGirdData; } public MapInfoBody GetMapBody() { if (_scenesParams == null) return null; return _scenesParams.m_mapBody; } public GameObject GetSceneObjects() { if (_scenesParams == null) return null; GameObject retval = null; if (_scenesParams.m_sceneObjects != null) { _scenesParams.m_sceneObjectName = _scenesParams.m_sceneObjects.name; _scenesParams.m_sceneObjects.name = SceneObjectsName; } retval = _scenesParams.m_sceneObjects; retval.SetActive(true); return retval; } private void CacheSubRoots() { _wayPointRoot = _sceneObjectsRoot.Find(WayPointRootName); _dynamicBlockerRoot = _sceneObjectsRoot.Find(DynamicBlockerRootName); _triggerRoot = _sceneObjectsRoot.Find(TriggerRootName); } //测试代码 public bool PreLoadData(int id, String name, String levelName, String pathSuffix = null, String mapInfoSuffix = null) { try { _id = id; _name = name; _levelName = levelName; _pathFileName = levelName; _mapInfoFileName = levelName; LoadSceneParams(); string pathDatakey = String.Format("{0}_{1}", levelName, pathSuffix); if (!String.IsNullOrEmpty(pathSuffix)) { _pathFileName += "_" + pathSuffix; } if (!String.IsNullOrEmpty(mapInfoSuffix)) { _mapInfoFileName += "_" + mapInfoSuffix; } _navigator = PathGridSystem.instance; _navigator.Initialize(this); _msger.ClearMsgPool(); _msger.RegisterCallback(HandleGameMessage); GameObject go = GetSceneObjects(); if (go != null) { _sceneObjectsRoot = go.transform; _sceneObjectsRoot.parent = _root; } PathLandSystem lanNav = _navigator as PathLandSystem; lanNav.LoadWayPointData(this); _entityContainer.Initialize(_root, _navigator.Get2DSize()); CacheSubRoots(); return true; } catch (Exception ex) { FLogger.LogException(ex); FLogger.LogTime(ex.Message); return false; } } // name: name by GD // levelName: unity level name // level suffix, could be null public bool Load(int id, string name, string levelName, string dayCameraName, string nightCameraName, bool isPlane, bool cameraBlend) { try { _id = id; _name = name; _levelName = levelName; _pathFileName = levelName; _mapInfoFileName = levelName; _dayCameraName = dayCameraName; _nightCameraName = nightCameraName; LoadSceneParams(); _navigator = PathGridSystem.instance; _navigator.Initialize(this); _msger.ClearMsgPool(); _msger.RegisterCallback(HandleGameMessage); GameObject go = GetSceneObjects(); if (go != null) { _sceneObjectsRoot = go.transform; _sceneObjectsRoot.parent = _root; SceneObject[] allSceneObjects = go.GetComponentsInChildren(); for (int i = 0; i < allSceneObjects.Length; ++i) { allSceneObjects[i].Initlaize(this); } } PathLandSystem lanNav = _navigator as PathLandSystem; lanNav.LoadWayPointData(this); _entityContainer.Initialize(_root, _navigator.Get2DSize()); CacheSubRoots(); if (_cameraManager == null) { _cameraManager = new CameraManager(); _cameraManager.Initialize(); } OnCreate(isPlane, cameraBlend); return true; } catch (Exception ex) { FLogger.LogException(ex); FLogger.LogTime(ex.Message); return false; } } public void Unload() { if (String.IsNullOrEmpty(_name)) { return; } OnDestroy(); Message exitSceneMsg = new Message(); exitSceneMsg.MsgId = MessageId.ExitScene; Entities.ForEach( (key, value) => { exitSceneMsg.ToId = key; value.HandleGameMessage(exitSceneMsg); } ); if (_scenesParams.m_sceneObjects != null) { _scenesParams.m_sceneObjects.SetActive(false); _scenesParams.m_sceneObjects.transform.parent = null; UnityEngine.Object.Destroy(_scenesParams.m_sceneObjects); } _msger.UnregisterCallback(HandleGameMessage); _wayPointRoot = null; _dynamicBlockerRoot = null; _triggerRoot = null; if (_entityContainer != null) { _entityContainer.Uninitialize(); _entityContainer = null; } // [SceneObjects] if (_sceneObjectsRoot != null) { GameObject.Destroy(_sceneObjectsRoot.gameObject); _sceneObjectsRoot = null; } // [SceneRoot] if (_root != null) { GameObject.Destroy(_root.gameObject); _root = null; } // [SceneCameraRoot] don't destroy, re-use it if (_navigator != null) { _navigator.Uninitialize(); _navigator = null; } _cameraManager.Uninitialize(); _cameraManager = null; _id = -1; _name = String.Empty; _levelName = String.Empty; _pathFileName = String.Empty; _mapInfoFileName = String.Empty; } #endregion #region //查找 寻路点 //查找线路点 public WayPointNode FindWayPointByName(String name) { if (_wayPointRoot != null) { WayPointPlanData pd = _wayPointRoot.GetComponent(); if (pd != null && pd.m_pointInfo != null) { for (int i = 0; i < pd.m_pointInfo.Length; ++i) if (pd.m_pointInfo[i].name == name) return pd.m_pointInfo[i]; } } return null; } //查找线路点 public WayPointNode FindWayPointById(int id) { if (_wayPointRoot != null) { WayPointPlanData pd = _wayPointRoot.GetComponent(); if (pd != null && pd.m_pointInfo != null) { for (int i = 0; i < pd.m_pointInfo.Length; ++i) if (pd.m_pointInfo[i].index == id) return pd.m_pointInfo[i]; } } return null; } //获取最近的线路点 public WayPointNode GetNearestWayPoint(ref Vector3 pos) { if (_wayPointRoot != null) { WayPointPlanData pd = _wayPointRoot.GetComponent(); if (pd != null) { Vector2 tempPos = Vector2.zero; tempPos.x = pos.x; tempPos.y = pos.z; int index = pd.GetNearestIndexBypos(ref tempPos); if (index != -1) return pd.m_pointInfo[index]; } } return null; } #endregion #region//静态函数 //获取地形位置 public Vector3 GetTerrainPosition(float x, float z) { float height = 0; GetHeightOnTerrain(x, z, out height); return new Vector3(x, height, z); } //获取地形高度 public bool GetHeightOnTerrain(float aX, float aZ, out float aHeight) { if (_scenesParams != null && _scenesParams.m_pathGirdData != null) { aHeight = _scenesParams.m_pathGirdData.GetHeight(aX, aZ); return true; } aHeight = 0; return false; } //获取地形高度 public float GetHeightOnTerrain(float aX, float aZ) { if (_scenesParams != null && _scenesParams.m_pathGirdData != null) { return _scenesParams.m_pathGirdData.GetHeight(aX, aZ); } return 0f; } //获取地形位置 public static Vector3 GetTerrainPositionByRay(float x, float z) { float height = 0; GetHeightOnTerrainByRay(x, z, out height); return new Vector3(x, height, z); } //获取地形高度 public static bool GetHeightOnTerrainByRay(float aX, float aZ, out float aHeight) { Ray ray = new Ray(); ray.origin = new Vector3(aX, 200.0f, aZ); ray.direction = Vector3.down; RaycastHit hit; LayerMask layerMask = LayerUtils.TerrainPath_Mask; Physics.Raycast(ray, out hit, 1000.0f, layerMask); if (hit.collider != null) { aHeight = hit.point.y + 0.1f; return true; } aHeight = 0; return false; } /// /// 修正摄像机特效以适应不同大小的屏幕 /// /// /// public static void FixCameraVfx(FGameObjectVFX vfx, Camera cam) { if (cam != null && vfx != null) { //这里以制作16:9为标准,来对特效z值进行调整 var z = Math.Min(0, (cam.aspect * 9 - 16) * (-0.02f)); vfx.SetLocalPosition(new Vector3(0, 0, z)); } } #endregion } }