312 lines
14 KiB
C#
312 lines
14 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.Networking;
|
|
using UnityEngine.Rendering;
|
|
using UnityEngine.Rendering.Universal;
|
|
using UnityEngine.UI;
|
|
|
|
|
|
namespace XGame
|
|
{
|
|
class Game : MonoBehaviour
|
|
{
|
|
static public Game Instance;
|
|
static public AssetBundle m_shaderBundleLoader;
|
|
static public XWebSocket m_WebSocket = null;
|
|
private static readonly Dictionary<string, Shader> s_RuntimeShaders = new Dictionary<string, Shader>();
|
|
|
|
private static readonly Color RuntimeAmbientSky = new Color(0.82f, 0.88f, 0.95f, 1f);
|
|
private static readonly Color RuntimeAmbientEquator = new Color(0.62f, 0.68f, 0.76f, 1f);
|
|
private static readonly Color RuntimeAmbientGround = new Color(0.34f, 0.32f, 0.28f, 1f);
|
|
private static readonly Color RuntimeSunColor = new Color(1f, 0.95686275f, 0.8392157f, 1f);
|
|
private const float RuntimeAmbientIntensity = 1.65f;
|
|
private const float RuntimeSunIntensity = 2.2f;
|
|
private const string RuntimeSunName = "RuntimeDirectionalLight";
|
|
private static readonly int RuntimeAmbientEnabledId = Shader.PropertyToID("_XRuntimeAmbientEnabled");
|
|
private static readonly int RuntimeAmbientSkyId = Shader.PropertyToID("_XRuntimeAmbientSky");
|
|
private static readonly int RuntimeAmbientEquatorId = Shader.PropertyToID("_XRuntimeAmbientEquator");
|
|
private static readonly int RuntimeAmbientGroundId = Shader.PropertyToID("_XRuntimeAmbientGround");
|
|
|
|
|
|
private void Awake()
|
|
{
|
|
|
|
//加载(添加)一个loading场景作为永久使用,(Test)
|
|
//XResLoader.AddScene("res/scene/loading/loading", (UnityEngine.GameObject[] objs) => {
|
|
// if (objs == null || objs[0] == null)
|
|
// {
|
|
// //Debug.Log("Loading Scene Load Failed!");
|
|
// }
|
|
// else
|
|
// {
|
|
// //Test
|
|
// foreach (var obj in objs)
|
|
// {
|
|
// (obj as UnityEngine.GameObject).SetActive(false);
|
|
// }
|
|
// }
|
|
// //添加场景后续可以通过场景名操作
|
|
// //XResLoader.AddScene("res/scene/s001/scene001", (UnityEngine.GameObject[] objs) =>
|
|
// //{
|
|
// // if (objs == null || objs[0] == null)
|
|
// // {
|
|
// // //Debug.Log("Loading Scene Load Failed!");
|
|
// // }
|
|
// // else
|
|
// // {
|
|
|
|
// // }
|
|
// //});
|
|
//});
|
|
}
|
|
public IEnumerator Init()
|
|
{
|
|
/*string url;
|
|
//test Dynamic RenderPipeline (ok)
|
|
XResLoader.LoadRes("res/RenderAsset/XRendePipline1.asset", typeof(RenderPipelineAsset), objs =>
|
|
{
|
|
if (objs == null || objs[0] == null)
|
|
{
|
|
Debug.Log($"res/RenderAsset/XRendePipline1.asset");
|
|
}
|
|
else
|
|
{
|
|
//GameObject obj = GameObject.Instantiate(objs[0], gameObject.transform) as GameObject;
|
|
RenderPipelineAsset rpasset = objs[0] as RenderPipelineAsset;
|
|
UniversalRenderPipelineAsset urpAsset = rpasset as UniversalRenderPipelineAsset;
|
|
QualitySettings.renderPipeline = rpasset;
|
|
GraphicsSettings.renderPipelineAsset = rpasset;
|
|
Debug.Log($"res/RenderAsset/XRendePipline1.asset : {rpasset.name} msaa : {urpAsset.msaaSampleCount}");
|
|
}
|
|
}, null);//*/
|
|
#if !UNITY_WEBGL
|
|
string sUpdatePath = Application.persistentDataPath;
|
|
#else
|
|
string sUpdatePath = Application.streamingAssetsPath;
|
|
#endif
|
|
// 加载 shader 变体集合(ShaderVariantCollection)并 WarmUp。
|
|
// 真机从 AssetBundle 加载的预设(如 Main)所用 shader,其光照变体在构建时可能被剔除,
|
|
// 导致平行光等不起效。把变体打进 game_shader.unity3d 并在此 WarmUp,可避免被剔除/运行时卡顿。
|
|
// 变体集合通过菜单 Tools/Shader 生成到 Assets/Game/Shader/Game.shadervariants(活跃流程会打进 game_shader.unity3d)。
|
|
DateTime swStart = DateTime.Now;
|
|
m_shaderBundleLoader = null;
|
|
s_RuntimeShaders.Clear();
|
|
Debug.Log($"###shader bundle md5 XWorld={XResLoader.GetFileMd5("XWorld", "game_shader.unity3d")}");
|
|
yield return XResLoader.coLoadAB("game_shader.unity3d", (ab) =>
|
|
{
|
|
m_shaderBundleLoader = ab;
|
|
if (ab == null) return;
|
|
Shader[] shaders = ab.LoadAllAssets<Shader>();
|
|
foreach (Shader shader in shaders)
|
|
{
|
|
if (shader == null)
|
|
{
|
|
continue;
|
|
}
|
|
s_RuntimeShaders[shader.name] = shader;
|
|
}
|
|
Shader xTexShader = GetRuntimeShader("Test/XTex");
|
|
Debug.Log($"###load Shader Count = {shaders.Length}, Test/XTex={(xTexShader != null ? xTexShader.name : "null")} supported={(xTexShader != null && xTexShader.isSupported)}");
|
|
ShaderVariantCollection[] svcs = ab.LoadAllAssets<ShaderVariantCollection>();
|
|
Debug.Log($"###load SVC Count = {svcs.Length}");
|
|
int i = 0;
|
|
foreach (var svc in svcs)
|
|
{
|
|
Debug.Log($"WarmUp{++i} : {svc.name} (variants={svc.variantCount})");
|
|
svc.WarmUp();
|
|
}
|
|
Debug.Log($"Shader WarmUp Finish! {(DateTime.Now - swStart).TotalMilliseconds} ms");
|
|
});
|
|
/*
|
|
// coLoadAB 在包缺失时不会回调 action,这里兜底提示(非致命,跳过 WarmUp 即可)
|
|
if (m_shaderBundleLoader == null)
|
|
Debug.LogWarning("未找到 shader 变体包 game_shader.unity3d,已跳过 WarmUp。" +
|
|
"若真机光照异常,请先用菜单 Tools/Shader 生成变体集合到 Assets/Game/Shader,并重打更新包发布。");
|
|
|
|
// 重建基于天空盒的环境光探针(SH)。场景环境光为 Skybox 模式且未烘焙时,
|
|
// 构建里不会自动生成该探针(编辑器会自动算,所以编辑器看着正常),真机会丢失基础环境光、整体偏暗。
|
|
// 调一次 DynamicGI.UpdateEnvironment() 即可在运行时从当前天空盒重新生成,恢复环境光。
|
|
ApplyRuntimeLighting("init");
|
|
*/
|
|
if (m_shaderBundleLoader == null)
|
|
Debug.LogWarning("Shader bundle game_shader.unity3d was not found; skipped WarmUp.");
|
|
ApplyRuntimeLighting("init");
|
|
StartCoroutine(CoReapplyRuntimeLighting());
|
|
|
|
/*/test 加载些东西 此场景可以
|
|
yield return XResLoader.coLoadRes("Assets/Arts/ScenePrefab/s001.prefab", typeof(GameObject), obj =>
|
|
{
|
|
if (obj == null )
|
|
{
|
|
Debug.Log($"Load Assets/Arts/ScenePrefab/s001 Failed");
|
|
}
|
|
else
|
|
{
|
|
GameObject objInst = GameObject.Instantiate(obj, gameObject.transform) as GameObject;
|
|
}
|
|
});
|
|
//
|
|
GameObject obj = GameObject.Find("Scene_21010100_Stone_005");
|
|
if (obj != null)
|
|
{
|
|
Debug.Log("Scene_21010100_Stone_005 ok");
|
|
}//*/
|
|
//Assets\Arts\Role\CharaterPrefab
|
|
//yield return XResLoader.coLoadRes("Assets/Arts/Role/CharaterPrefab/11501100_l.prefab", typeof(GameObject), obj =>
|
|
//{
|
|
// if (obj == null)
|
|
// {
|
|
// Debug.Log($"Load Assets/Arts/Role/CharaterPrefab/11501100_l Failed");
|
|
// }
|
|
// else
|
|
// {
|
|
// GameObject objInst = GameObject.Instantiate(obj, gameObject.transform) as GameObject;
|
|
// }
|
|
//});
|
|
/*/test net
|
|
string addr = "wss://192.168.10.186:4009";//"wss://app.xworld.link:16888";//"wss://app.xworld.link:16887";//"ws://192.168.10.186:2009";// "ws://127.0.0.1:16888";// 192.168.51.105
|
|
int port = 0;
|
|
lsocket.connect(addr, port, (GYWebSocket sock, string err) =>
|
|
{//连接结果
|
|
m_WebSocket = sock;
|
|
if (sock == null)
|
|
{
|
|
Debug.LogError($"connect {addr} Failed!");
|
|
}
|
|
else
|
|
{
|
|
//发送信息
|
|
byte[] byteArray;
|
|
//string abc = "123_test_msg_string";
|
|
//byteArray = System.Text.Encoding.ASCII.GetBytes(abc);
|
|
byteArray = new byte[] { 0x00 ,0x0B, 0x30, 0x15, 0x03, 0x16, 0x01, 0x51, 0x06, 0x02, 0x07, 0x01, 0x02 };
|
|
m_WebSocket.send(byteArray, (int nData, string str) =>
|
|
{
|
|
Debug.Log($"Send {nData} Bytes ");
|
|
}, ref err );
|
|
}
|
|
});//*/
|
|
yield break;
|
|
}
|
|
|
|
public static Shader GetRuntimeShader(string shaderName)
|
|
{
|
|
if (string.IsNullOrEmpty(shaderName))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
Shader shader;
|
|
s_RuntimeShaders.TryGetValue(shaderName, out shader);
|
|
return shader;
|
|
}
|
|
|
|
private static IEnumerator CoReapplyRuntimeLighting()
|
|
{
|
|
yield return null;
|
|
ApplyRuntimeLighting("next-frame");
|
|
yield return new WaitForEndOfFrame();
|
|
ApplyRuntimeLighting("end-of-frame");
|
|
yield return new WaitForSeconds(0.5f);
|
|
ApplyRuntimeLighting("delay-0.5");
|
|
yield return new WaitForSeconds(1.5f);
|
|
ApplyRuntimeLighting("delay-2.0");
|
|
}
|
|
|
|
private static void ApplyRuntimeLighting(string reason)
|
|
{
|
|
RenderSettings.ambientMode = AmbientMode.Trilight;
|
|
RenderSettings.ambientSkyColor = RuntimeAmbientSky;
|
|
RenderSettings.ambientEquatorColor = RuntimeAmbientEquator;
|
|
RenderSettings.ambientGroundColor = RuntimeAmbientGround;
|
|
RenderSettings.ambientIntensity = RuntimeAmbientIntensity;
|
|
RenderSettings.reflectionIntensity = Mathf.Max(RenderSettings.reflectionIntensity, 0.8f);
|
|
Shader.SetGlobalFloat(RuntimeAmbientEnabledId, 1f);
|
|
Shader.SetGlobalColor(RuntimeAmbientSkyId, RuntimeAmbientSky * RuntimeAmbientIntensity);
|
|
Shader.SetGlobalColor(RuntimeAmbientEquatorId, RuntimeAmbientEquator * RuntimeAmbientIntensity);
|
|
Shader.SetGlobalColor(RuntimeAmbientGroundId, RuntimeAmbientGround * RuntimeAmbientIntensity);
|
|
|
|
// The runtime ambient probe is authored here. DynamicGI.UpdateEnvironment can
|
|
// rebuild it from the skybox later on some platforms and overwrite these values.
|
|
RenderSettings.ambientProbe = BuildRuntimeAmbientProbe();
|
|
SphericalHarmonicsL2 probe = RenderSettings.ambientProbe;
|
|
|
|
Light sun = EnsureRuntimeDirectionalLight();
|
|
Debug.Log($"[Game] Runtime lighting applied({reason}). ambientMode={RenderSettings.ambientMode}, " +
|
|
$"intensity={RenderSettings.ambientIntensity}, sky={RenderSettings.ambientSkyColor}, " +
|
|
$"sun={(sun != null ? sun.name : "null")} enabled={(sun != null && sun.enabled)} " +
|
|
$"sunIntensity={(sun != null ? sun.intensity : 0f)} skybox={(RenderSettings.skybox != null ? RenderSettings.skybox.name : "null")} " +
|
|
$"probeL00=({probe[0, 0]:F3},{probe[1, 0]:F3},{probe[2, 0]:F3})");
|
|
}
|
|
|
|
private static SphericalHarmonicsL2 BuildRuntimeAmbientProbe()
|
|
{
|
|
SphericalHarmonicsL2 probe = new SphericalHarmonicsL2();
|
|
probe.AddAmbientLight(RuntimeAmbientEquator * RuntimeAmbientIntensity);
|
|
probe.AddDirectionalLight(new Vector3(0.15f, 1f, 0.25f).normalized, RuntimeAmbientSky, 0.85f);
|
|
probe.AddDirectionalLight(new Vector3(-0.25f, -1f, -0.1f).normalized, RuntimeAmbientGround, 0.28f);
|
|
return probe;
|
|
}
|
|
|
|
private static Light EnsureRuntimeDirectionalLight()
|
|
{
|
|
Light sun = RenderSettings.sun;
|
|
if (!IsDirectionalLight(sun))
|
|
{
|
|
GameObject sunObj = GameObject.Find("DirectionalLight") ?? GameObject.Find(RuntimeSunName);
|
|
sun = sunObj != null ? sunObj.GetComponent<Light>() : null;
|
|
}
|
|
|
|
if (!IsDirectionalLight(sun))
|
|
{
|
|
foreach (Light light in FindObjectsOfType<Light>())
|
|
{
|
|
if (IsDirectionalLight(light))
|
|
{
|
|
sun = light;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sun == null)
|
|
{
|
|
GameObject sunObj = new GameObject(RuntimeSunName);
|
|
sun = sunObj.AddComponent<Light>();
|
|
}
|
|
|
|
sun.gameObject.SetActive(true);
|
|
sun.enabled = true;
|
|
sun.type = LightType.Directional;
|
|
sun.color = RuntimeSunColor;
|
|
sun.intensity = Mathf.Max(sun.intensity, RuntimeSunIntensity);
|
|
sun.shadows = LightShadows.None;
|
|
sun.transform.rotation = Quaternion.Euler(50f, -30f, 0f);
|
|
RenderSettings.sun = sun;
|
|
return sun;
|
|
}
|
|
|
|
private static bool IsDirectionalLight(Light light)
|
|
{
|
|
return light != null && light.type == LightType.Directional;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
//获得消息
|
|
if (Input.GetKey(KeyCode.H))
|
|
{
|
|
Camera camera = UnityEngine.Camera.main;
|
|
var forward = camera.transform.forward;
|
|
Debug.Log($"H Key Up {forward.x},{forward.y},{forward.z}");
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|