using System; using Thousandto.Plugins.Common.UniScene; using UnityEngine; using Thousandto.Core.Asset; using Thousandto.Cfg.Data; using Thousandto.Core.RootSystem; using Thousandto.Core.Base; using Thousandto.Code.Center; using Thousandto.Code.Global; using System.Collections.Generic; using Thousandto.Core.PostEffect; using Thousandto.Code.Logic.LocalPlayerBT; using FLogger = UnityEngine.Gonbest.MagicCube.FLogger; namespace Thousandto.Code.Logic { /// /// 游戏的逻辑场景类 /// public class GameScene : BaseScene { #region member private int _lineID = 0; private int _frontMapID = 0; //切换场景Type(切换场景原因) private int _transType = 0; //切换场景服务器下发参数 private int _transParam = 0; private FGameObjectVFX _cameraVfxID = null; //美术制作场景的根节点 private Transform _unitySceneRoot = null; private static Type grassRlationType = null; #endregion #region//属性 public int LineID { get { return _lineID; } set { _lineID = value; } } public int FrontMapID { get { return _frontMapID; } set { _frontMapID = value; } } //重写获取本地玩家的接口 new public LocalPlayer GetLocalPlayer() { if (base.GetLocalPlayer() != null) { return base.GetLocalPlayer() as LocalPlayer; } else { return null; } } public int TransType { get { return _transType; } set { _transType = value; } } public int TransParam { get { return _transParam; } set { _transParam = value; } } #endregion #region//构造函数 public GameScene() { } #endregion #region//继承基类 protected override bool OnCreate(bool isPlane, bool cameraBlend) { base.OnCreate(isPlane, cameraBlend); //清理模型计数的容器 FGameObjectModel.ClearModelTypeFGOContainer(); //载入雾效配置 LoadFogSettings(); //载入阴影设置 LoadShadowSettings(); //载入摄像机配置 LoadCameraSettings(cameraBlend); //载入草 LoadGrassScript(); //载入镜头特效 LoadCameraVfx(); //设置Shader的全局属性 SetShaderGlobal(); //处理摄像机的层切 SetCameraLayerCull(); //设置场景特效的等级 SetSceneEffectLevel(); return true; } protected override void OnDestroy() { //释放镜头特效 UnLoadCameraVfx(); //删除草 //UnLoadGrassScript(); grassRlationType = null; } #endregion #region loaders public T LoadEntity(EntityInfo baseInfo, ModelLODLevel userLod = ModelLODLevel.Default, MyAction postLoadCallback = null) where T : Entity, new() { bool ret = false; T obj = null; if (Entities.Contains(baseInfo.ID) == false) { var entity = new T(); try { if (entity.Initialize(baseInfo, this)) { if (Entities.Add(entity, (entity is LocalPlayer) == false)) { if (postLoadCallback != null) { try { postLoadCallback(entity); } catch (Exception e) { FLogger.DebugLogException(e); } } ret = true; } } } finally { if (ret == false && entity != null) { entity.Uninitialize(); entity = null; } } obj = entity; } else { obj = Entities.Find(baseInfo.ID) as T; } return obj; } public bool LoadNpc(NpcInitInfo baseInfo) { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { } ); } public bool LoadMonster(MonsterInitInfo baseInfo) { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { } ); } public bool LoadPet(PetInitInfo baseInfo) { if (baseInfo.MasterID == 0) { FLogger.DebugLogError("Load pet failed: host code is 0."); return false; } if(baseInfo.MasterID == GetLocalPlayerID()) { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { } ); } else { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { } ); } } public bool LoadAssistPet(AssistPetInitInfo baseInfo) { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { } ); } public bool LoadFlySword(FlySwordInitInfo baseInfo) { if (baseInfo.MasterID == 0) { FLogger.DebugLogError("Load fabao failed: host code is 0."); return false; } if (baseInfo.MasterID == GetLocalPlayerID()) { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { } ); } else { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { } ); } } public bool LoadMarryChild(MarryChildInitInfo baseInfo) { if (baseInfo.Owner == null) { FLogger.DebugLogError("Load marrychild failed: host code is 0."); return false; } return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { } ); } public bool LoadLocalPlayer(LocalPlayerInitInfo baseInfo) { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { LocalPlayerRoot.SetLocalPlayer(e as LocalPlayer); Entities.SetLocalPlayer(e); } ); } //重新载入主角 public bool ReloadLocalPlayer(Vector2? position) { if (LocalPlayerRoot.LocalPlayer != null) { LocalPlayerRoot.LocalPlayer.ChangeToScene(this, position); if (Entities.Add(LocalPlayerRoot.LocalPlayer, false)) { Entities.SetLocalPlayer(LocalPlayerRoot.LocalPlayer); } } return true; } public bool LoadRemotePlayer(RemotePlayerInitInfo baseInfo) { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { } ); } public bool LoadCollection(CollectionInitInfo baseInfo) { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { }); } public bool LoadLockTrajectoryObj(LockTrajectoryObjInitInfo baseInfo) { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { } ); } public bool LoadSimpleSkillObject(SimpleSkillObjectInitInfo baseInfo) { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { } ); } public bool LoadSkillObject(SkillObjectInitInfo baseInfo) { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { } ); } public bool LoadDropItem(DropItemInitInfo baseInfo) { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { } ); } public bool LoadDropGold(DropGoldInitInfo baseInfo) { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { } ); } public bool LoadGroundBuff(GroundBuffInitInfo baseInfo) { return null != LoadEntity( baseInfo, ModelLODLevel.Default, (e) => { }); } public bool LoadLuaCharacter(LuaCharInitInfo baseInfo) { bool ret = false; LuaCharacter obj = null; if (Entities.Contains(baseInfo.ID) == false) { var entity = new LuaCharacter(); //绑定lua脚本 GameCenter.LuaSystem.Adaptor.BindLuaCharacter(entity, baseInfo); try { if (entity.Initialize(baseInfo, this)) { if (Entities.Add(entity, true)) { ret = true; } } } finally { if (ret == false && entity != null) { entity.Uninitialize(); entity = null; } } obj = entity; } else { obj = Entities.Find(baseInfo.ID) as LuaCharacter; } return obj != null; } #endregion //设置摄像机的层切处理 public void SetCameraLayerCull() { //如果当前质量等级小于1,那么就表示是最低等级,可见距离也变为原来的0.8 //float scale = 1f; //if (GameCenter.GameSetting.GetSetting(GameSettingKeyCode.QualityLevel) < 1) //{ // scale = 0.8f; //} //float[] layerCullDis = new float[32]; //for (int i = 0; i < layerCullDis.Length; i++) layerCullDis[i] = Cfg.CamLayerCullDistance * scale; //layerCullDis[1] = 30f; //传送点 //layerCullDis[16] = 30f; //场景特效 //layerCullDis[8] = 2000; //SceneCamera.layerCullSpherical = true; //SceneCamera.layerCullDistances = layerCullDis; } //处理场景特效等级 public void SetSceneEffectLevel() { //场景中的特效 var effectGo = FindSceneRootChild("[vfx]"); if (effectGo != null) { effectGo.gameObject.SetActive(!GameCenter.GameSetting.IsEnabled(GameSettingKeyCode.TPVFXScene)); FGameObjectVFXRoot.ApplyVFXLevel(effectGo, GameCenter.GameSetting.GetSetting(GameSettingKeyCode.SceneVFXLevel)); } } //载入无效设置 protected void LoadFogSettings() { _haveFogSetting = false; var haveDay = false; if(!string.IsNullOrEmpty(Cfg.FogDayParam)) { var fogParams = Cfg.FogDayParam.Split(';'); if(fogParams.Length >= 3) { var colorParams = fogParams[0].Split('_'); if(colorParams.Length >= 3) { int r, g, b; float min, max; if(int.TryParse(colorParams[0], out r) && int.TryParse(colorParams[1], out g) && int.TryParse(colorParams[2], out b) && float.TryParse(fogParams[1], out min) && float.TryParse(fogParams[2], out max)) { _fogDayColor = new Color(r / 255f, g / 255f, b / 255f, 1f); _fogDayMinDis = min; _fogDayMaxDis = max; haveDay = true; } } } } var haveNight = false; if (!string.IsNullOrEmpty(Cfg.FogNightParam)) { var fogParams = Cfg.FogNightParam.Split(';'); if (fogParams.Length >= 3) { var colorParams = fogParams[0].Split('_'); if (colorParams.Length >= 3) { int r, g, b; float min, max; if (int.TryParse(colorParams[0], out r) && int.TryParse(colorParams[1], out g) && int.TryParse(colorParams[2], out b) && float.TryParse(fogParams[1], out min) && float.TryParse(fogParams[2], out max)) { _fogNightColor = new Color(r / 255f, g / 255f, b / 255f, 1f); _fogNightMinDis = min; _fogNightMaxDis = max; haveNight = true; } } } } _haveFogSetting = haveDay && haveNight; } //载入阴影设置 protected void LoadShadowSettings() { bool playerShadowEnable = false; ParseShadowParam(Cfg.ShadowParam, ref playerShadowEnable,ref _shadowLightDir, ref _shadowDayStrength, ref _shadowNightStrength); ParseShadowParam(Cfg.SceneShadowParam, ref _sceneShadowOpen,ref _sceneShadowLightDir, ref _sceneShadowDayStrength, ref _sceneShadowNightStrength); } private void ParseShadowParam(string cfgStr,ref bool enabled,ref Vector3 dir,ref float day,ref float night) { dir = Vector3.down; day = 0.7f; night = 0.3f; enabled = true; var param = cfgStr.Split(';'); if (param != null && param.Length >= 4) { int open = 0; int.TryParse(param[0], out open); enabled = open > 0; String[] dirParam = param[1].Split('_'); if (dirParam != null && dirParam.Length >= 3) { float x, y, z; if (float.TryParse(dirParam[0], out x) && float.TryParse(dirParam[1], out y) && float.TryParse(dirParam[2], out z)) { dir = new Vector3(x, y, z); } } float.TryParse(param[2], out day); float.TryParse(param[3], out night); } } protected void LoadCameraSettings(bool cameraBlend) { GameCenter.CameraControlUtil.LoadCameraSetting(Cfg, SceneCameraControl); ////需要时开启离屏特效,现在暂时不需要了 //UnityUtils.RequireComponent(CameraManager.CamerasRoot.gameObject); if (!CameraManager.ChangeCamera(DayCameraName, cameraBlend)) { CameraManager.ChangeCamera(CameraManager.NormalCameraName, cameraBlend); } var eveneId = GameCenter.GameSetting.IsEnabled(GameSettingKeyCode.EnablePostEffect) ? Global.LogicEventDefine.EID_EVENT_ENABLE_CAMERA_POSTEFFECT : Global.LogicEventDefine.EID_EVENT_DISABLE_CAMERA_POSTEFFECT; var cameraList = CameraManager.SceneCamList; for (int i = 0; i < cameraList.Count; ++i) { GameCenter.PushFixEvent(eveneId, cameraList[i].gameObject); } } public void LoadGrassScript() { SetGrassEnable(); } public static void SetGrassEnable() { if (grassRlationType == null) { var assemblys = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblys.Length; i++) { var assembly = assemblys[i]; grassRlationType = assembly.GetType("Thousandto.Launcher.ExternalLibs.GrassRelationScript"); if (grassRlationType != null) break; } } if (grassRlationType == null) return; System.Reflection.MethodInfo mInfo = grassRlationType.GetMethod("SetEnabled", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.InvokeMethod); //object reflect = Activator.CreateInstance(grassRlationType); bool isEnable = GameCenter.GameSetting.IsEnabled(GameSettingKeyCode.EnableGrass); mInfo.Invoke(null, new object[] { isEnable }); } public void UnLoadGrassScript() { var grassGo = FindSceneRootChild("grass"); if (grassGo != null) { //GrassAnimateScript.UnInstallScript(grassGo.transform); } } public void LoadCameraVfx() { UnLoadCameraVfx(); if (GameCenter.GameSetting.GetSetting(GameSettingKeyCode.EnableCameraVFX) > 0) { _cameraVfxID = new FGameObjectVFX(ModelTypeCode.OtherVFX, Cfg.CameraVfx, true); _cameraVfxID.SetParent(CameraManager.CamerasRoot, true); _cameraVfxID.SetLayer(LayerUtils.Terrain, true); FixCameraVfx(_cameraVfxID, SceneCamera); _cameraVfxID.Play(1); /* //需要时开启离屏特效,现在暂时不需要了 if (_cameraVfxID.AllRenderList != null) { CameraManager.CamerasRoot.SendMessage("OnCameraVfxChanged", _cameraVfxID.AllRenderList); } else { _cameraVfxID.OnLoadFinishedCallBack = delegate (FGameObjectBase x) { Debug.LogError("Invoke:OnCameraVfxChanged:" + (_cameraVfxID.AllRenderList == null ? "NULL" : _cameraVfxID.AllRenderList.Count.ToString())); CameraManager.CamerasRoot.SendMessage("OnCameraVfxChanged", _cameraVfxID.AllRenderList); }; } */ } } public override void Update(float deltaTime) { base.Update(deltaTime); } public void UnLoadCameraVfx() { if (_cameraVfxID != null) { _cameraVfxID.Destroy(); ////需要时开启离屏特效,现在暂时不需要了 //CameraManager.CamerasRoot.SendMessage("OnCameraVfxChanged", string.Empty, SendMessageOptions.DontRequireReceiver); } } //设置Shader的全局参数 protected void SetShaderGlobal() { //设置brdf的vfd纹理 //GameCenter.MaterialManager.SetGlobalTexture(ShaderPropertyNameDefine.CN_SPN_MAGICTEX, "tex_brdf_fvd_01", ImageTypeCode.Shader); //设置环境的cube //GameCenter.MaterialManager.SetGlobalTexture(ShaderPropertyNameDefine.CN_SPN_ENVCUBE, "tex_reflection_01", ImageTypeCode.Shader); //X光线纹理 //GameCenter.MaterialManager.SetGlobalTexture(ShaderPropertyNameDefine.CN_SPN_XRAYTEX, "tex_xray_sphere", ImageTypeCode.Shader); } //恢复Shader的全局参数 protected void ResetShaderGlobal() { //GameCenter.MaterialManager.ResetGlobalTexture(ShaderPropertyNameDefine.CN_SPN_MAGICTEX); //GameCenter.MaterialManager.ResetGlobalTexture(ShaderPropertyNameDefine.CN_SPN_ENVCUBE); //GameCenter.MaterialManager.ResetGlobalTexture(ShaderPropertyNameDefine.CN_SPN_XRAYTEX); } public void PlayObjectAnimation(String objectPath, String name) { Trigger_PlayAnimation(objectPath, name); } protected bool Trigger_PlayAnimation(String objectPath, String name) { for (; ; ) { var go = GameObject.Find(objectPath); if (go == null) { FLogger.DebugLogErrorFormat("Trigger_PlayAnimation: target '{0}' not found!", objectPath); break; } var anim = go.GetComponentInChildren(); if (anim == null) { var animator = go.GetComponentInChildren(); if (animator != null) { animator.Play(name); return true; } break; } var clip = anim.GetClip(name); if (clip == null) { FLogger.DebugLogErrorFormat("Trigger_PlayAnimation: animation not found: {0}", name); break; } return anim.Play(name, PlayMode.StopSameLayer); } return false; } protected override bool OnGameMessage(Message msg) { if(!GameCenter.LuaSystem.Adaptor.OnGameMessage(msg)) { return base.OnGameMessage(msg); } return false; } //换线 public void DoChangeLine(DeclareMapsetting cfg, int lineID, bool isRealChange) { LocalPlayer lp = GetLocalPlayer(); if (lp == null) return; lp.DoChangeLine(); if (isRealChange) { Msger.PostMessage(MessageId.SwitchLine); //换线之后停止挂机 GameCenter.LuaSystem.Adaptor.EndMandate(); } _lineID = lineID; //更新小地图名字 GameCenter.PushFixEvent(LogicEventDefine.EID_EVENT_PLYAER_ENTER_SCENE); } //进入位面 public void DoEnterPlaneCopy(int id, int fMapId, ref int activeMapId, string name, string levelName, string dayCameraName, string nightCameraName, int lineId, Vector2? position = null) { LocalPlayer lp = GetLocalPlayer(); if (lp == null) return; //离开老地图 GameCenter.LuaSystem.Adaptor.OnLeaveScene(true); //尝试加载一下地图配置文件,防止寻路点不对 GameCenter.PathFinderSystem.LoadSingleMapInfo(DeclareMapsetting.Get(id)); var cameraBlend = true; if(position != null && Vector2.SqrMagnitude(lp.Position2d - position.Value) > 100f) { //位移过大,不做摄像机混合 cameraBlend = false; } Load(id, name, levelName, dayCameraName, nightCameraName, true, cameraBlend); //LoadPlanCopyMapData(id, name, levelName, dayCameraName, nightCameraName); var cameraSwitchTime = 0f; if (Cfg.CamSwitchTime > 0) { cameraSwitchTime = Cfg.CamSwitchTime / 1000f; } else { var fCfg = DeclareMapsetting.Get(fMapId); if (fCfg != null && fCfg.CamSwitchTime > 0) { cameraSwitchTime = fCfg.CamSwitchTime / 1000f; } } //执行摄像机动画 var camOffsetY = CameraControlDefine.LockOffsetY; var targetDis = CameraControlDefine.CurMaxDis; if (lp.IsOnMount) { if (lp.Skin != null && lp.Skin.SkinPartIsValid(FSkinPartCode.Mount)) { //在坐骑上的时候使用坐骑高度 var cfg = DeclareHuaxingHorse.Get(lp.Skin.GetSkinPartCfgID(FSkinPartCode.Mount)); if (cfg != null) { camOffsetY = cfg.SceneCameraYAdd / 100f; CameraControlDefine.DisAddValue = cfg.SceneCameraDisadd / 100f; targetDis += CameraControlDefine.DisAddValue; CameraControlDefine.PitchAddValue = cfg.SceneCameraPitchadd; } } } SceneCameraControl.PlayAnim(CameraControlDefine.LockPitch, CameraControlDefine.LockYaw, targetDis, 0f, camOffsetY, CameraControlDefine.CurFov, cameraSwitchTime); FrontMapID = fMapId; LineID = lineId; GameCenter.LuaSystem.Adaptor.EndMandate(); lp.DoChangeLine(); //做一次角色清除 var allEntity = Entities.GetAll(); var removeList = new List(); for (int i = 0; i < allEntity.Count; ++i) { var entity = allEntity[i]; if (entity is Monster) { var m = entity as Monster; if (!m.IsDead()) { DeleteEntity(entity.ID); } } else if (entity.IsLocal() || entity is DropGold || entity is DropItem) { } else { DeleteEntity(entity.ID); } } //更新删除列表 UpdateDeleateList(); //设置当前活跃地图id activeMapId = id; //告诉服务器加载完成 NetHandler.SendMessage_ReqLoadFinish(); if (position != null) { lp.RayCastToGroundXOZ(new Vector2(position.Value.x, position.Value.y)); } //重新载入飞剑 lp.LoadFlySword(); //重新载入仙娃 lp.LoadMarryChild(); //进入新地图 GameCenter.LuaSystem.Adaptor.OnEnterScene(id, true); PlayerBT.crossBD.OnEnterScene(); var mCfg = DeclareMapsetting.Get(id); if (mCfg != null) { AudioPlayer.PlayMusic(mCfg.Music); } //刷新buff列表,删除切换场景清除的buff GameCenter.BuffSystem.OnChangeScene(); } #region//私有函数 //查找场景节点的子节点 private Transform FindSceneRootChild(string name) { var root = GetUnitySceneRoot(); if (root != null) { for (int i = 0; i < root.childCount; i++) { var child = root.GetChild(i); if (child.name.Trim() == name) { return child; } } } return null; } //获取美术制作的Unity场景 public Transform GetUnitySceneRoot() { if (_unitySceneRoot == null) { var root = UnityUtils.FindSceneRoot("SceneRoot"); if (root != null) { _unitySceneRoot = root.transform; } } return _unitySceneRoot; } #endregion #region//测试代码 public static void PreLoadSceneData(int id, String name, String levelName, String pathSuffix = null, String mapInfoSuffix = null) { GameCenter.GameSceneSystem.ReSetPreLoadScene(); GameScene scene = new GameScene(); scene.PreLoadData(id, name, levelName, pathSuffix, mapInfoSuffix); GameCenter.GameSceneSystem.SetPreLoadScene(scene); } #endregion } }