Init
This commit is contained in:
8
Assets/Scripts/HotUpdate/Main/AutoChess.meta
Normal file
8
Assets/Scripts/HotUpdate/Main/AutoChess.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 615751979a29d8d42adbf3d007555fd0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
55
Assets/Scripts/HotUpdate/Main/GameStart.cs
Normal file
55
Assets/Scripts/HotUpdate/Main/GameStart.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using YooAsset;
|
||||
|
||||
public class GameStart : MonoBehaviour
|
||||
{
|
||||
SceneHandle sceneHandle;
|
||||
void Start()
|
||||
{
|
||||
StartCoroutine(LoadScene());
|
||||
//StartCoroutine(LoadNetWorkManager());
|
||||
StartCoroutine(LoadUIManager());
|
||||
}
|
||||
IEnumerator LoadScene()
|
||||
{
|
||||
sceneHandle = YooAssets.LoadSceneAsync("MirrorRoomOffline");
|
||||
//sceneHandle = YooAssets.LoadSceneAsync("Game");
|
||||
sceneHandle.Completed += (handle) =>
|
||||
{
|
||||
handle.ActivateScene();
|
||||
};
|
||||
yield return sceneHandle;
|
||||
}
|
||||
IEnumerator LoadUIManager()
|
||||
{
|
||||
AssetHandle _handle = YooAssets.LoadAssetAsync<GameObject>("UIManager");
|
||||
_handle.Completed += (handle) =>
|
||||
{
|
||||
GameObject go = Instantiate((GameObject)_handle.AssetObject);
|
||||
DontDestroyOnLoad(go);
|
||||
Debug.Log(_handle.AssetObject);
|
||||
};
|
||||
yield return _handle;
|
||||
}
|
||||
IEnumerator LoadNetWorkManager()
|
||||
{
|
||||
AssetHandle _handle = YooAssets.LoadAssetAsync<GameObject>("MyRoomManager");
|
||||
_handle.Completed += (handle) =>
|
||||
{
|
||||
GameObject go = Instantiate((GameObject)_handle.AssetObject);
|
||||
DontDestroyOnLoad(go);
|
||||
Debug.Log(_handle.AssetObject);
|
||||
};
|
||||
yield return _handle;
|
||||
}
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if(sceneHandle!=null && !sceneHandle.IsDone)
|
||||
{
|
||||
Debug.Log(sceneHandle.Progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/HotUpdate/Main/GameStart.cs.meta
Normal file
11
Assets/Scripts/HotUpdate/Main/GameStart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5db6d9ce76043f546b092e210f4512db
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
28
Assets/Scripts/HotUpdate/Main/Main.asmdef
Normal file
28
Assets/Scripts/HotUpdate/Main/Main.asmdef
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "Main",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:e34a5702dd353724aa315fb8011f08c3",
|
||||
"GUID:df380645f10b7bc4b97d4f5eb6303d95",
|
||||
"GUID:15fc0a57446b3144c949da3e2b9737a9",
|
||||
"GUID:6055be8ebefd69e48b49212b09b47b2f",
|
||||
"GUID:75469ad4d38634e559750d17036d5f7c",
|
||||
"GUID:4307f53044263cf4b835bd812fc161a4",
|
||||
"GUID:f22fac247a56d2d41b687bb0d900e54e",
|
||||
"GUID:c55575a9f1747c240822f4b7e0400716",
|
||||
"GUID:1ea6b676786131e4095182b742bb64ec",
|
||||
"GUID:8804cd4b3fef1e041ad4f6c94ec49e0c",
|
||||
"GUID:30817c1a0e6d646d99c048fc403f5979",
|
||||
"GUID:72872094b21c16e48b631b2224833d49",
|
||||
"GUID:3a5d3214f3d7fb845bf8991981763e58"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
7
Assets/Scripts/HotUpdate/Main/Main.asmdef.meta
Normal file
7
Assets/Scripts/HotUpdate/Main/Main.asmdef.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23bab669d3df73a4c9da776078d30ddc
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/HotUpdate/Main/MirrorRoomTest.meta
Normal file
8
Assets/Scripts/HotUpdate/Main/MirrorRoomTest.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ebf83dfbd6c23248aac2f42449a4cc9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,77 @@
|
||||
using Mirror;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public class MyRoomManager : NetworkRoomManager
|
||||
{
|
||||
|
||||
public static new MyRoomManager singleton => NetworkManager.singleton as MyRoomManager;
|
||||
public override void OnRoomClientSceneChanged()
|
||||
{
|
||||
base.OnRoomClientSceneChanged();
|
||||
if (networkSceneName == GameplayScene)
|
||||
{
|
||||
foreach (MyRoomPlayer player in roomSlots.ToList())
|
||||
{
|
||||
player.model.SetActive(false);
|
||||
}
|
||||
}
|
||||
else if (networkSceneName == RoomScene)
|
||||
{
|
||||
foreach (MyRoomPlayer player in roomSlots.ToList())
|
||||
{
|
||||
player.model.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void OnRoomStopClient()
|
||||
{
|
||||
base.OnRoomStopClient();
|
||||
}
|
||||
|
||||
public override void OnRoomStopServer()
|
||||
{
|
||||
base.OnRoomStopServer();
|
||||
}
|
||||
|
||||
/*
|
||||
This code below is to demonstrate how to do a Start button that only appears for the Host player
|
||||
showStartButton is a local bool that's needed because OnRoomServerPlayersReady is only fired when
|
||||
all players are ready, but if a player cancels their ready state there's no callback to set it back to false
|
||||
Therefore, allPlayersReady is used in combination with showStartButton to show/hide the Start button correctly.
|
||||
Setting showStartButton false when the button is pressed hides it in the game scene since NetworkRoomManager
|
||||
is set as DontDestroyOnLoad = true.
|
||||
*/
|
||||
|
||||
#if !UNITY_SERVER
|
||||
bool showStartButton;
|
||||
#endif
|
||||
|
||||
public override void OnRoomServerPlayersReady()
|
||||
{
|
||||
// calling the base method calls ServerChangeScene as soon as all players are in Ready state.
|
||||
if (Utils.IsHeadless())
|
||||
base.OnRoomServerPlayersReady();
|
||||
#if !UNITY_SERVER
|
||||
else
|
||||
showStartButton = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !UNITY_SERVER
|
||||
public override void OnGUI()
|
||||
{
|
||||
base.OnGUI();
|
||||
|
||||
if (allPlayersReady && showStartButton && GUI.Button(new Rect(150, 300, 120, 20), "START GAME"))
|
||||
{
|
||||
// set to false to hide it in the game scene
|
||||
showStartButton = false;
|
||||
|
||||
ServerChangeScene(GameplayScene);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8bf7a40ab294c80448b22b82ca91c15d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
57
Assets/Scripts/HotUpdate/Main/MirrorRoomTest/MyRoomPlayer.cs
Normal file
57
Assets/Scripts/HotUpdate/Main/MirrorRoomTest/MyRoomPlayer.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using Cinemachine;
|
||||
using Mirror;
|
||||
using UnityEngine;
|
||||
|
||||
public class MyRoomPlayer : NetworkRoomPlayer
|
||||
{
|
||||
public CinemachineVirtualCamera vCam;
|
||||
public GameObject model;
|
||||
public override void OnStartClient()
|
||||
{
|
||||
//Debug.Log($"OnStartClient {gameObject}");
|
||||
}
|
||||
|
||||
public override void OnClientEnterRoom()
|
||||
{
|
||||
//Debug.Log($"OnClientEnterRoom {SceneManager.GetActiveScene().path}");
|
||||
}
|
||||
[Command]
|
||||
public override void CmdChangeReadyState(bool readyState)
|
||||
{
|
||||
Debug.Log($"CmdChangeReadyState called (Host={isServer}, Local={isLocalPlayer})");
|
||||
SetReadyToBegin(readyState);
|
||||
MyRoomManager room = MyRoomManager.singleton as MyRoomManager;
|
||||
if (room != null)
|
||||
{
|
||||
room.ReadyStatusChanged();
|
||||
}
|
||||
//base.CmdChangeReadyState(readyState);
|
||||
}
|
||||
public override void OnClientExitRoom()
|
||||
{
|
||||
//Debug.Log($"OnClientExitRoom {SceneManager.GetActiveScene().path}");
|
||||
}
|
||||
|
||||
public override void IndexChanged(int oldIndex, int newIndex)
|
||||
{
|
||||
//Debug.Log($"IndexChanged {newIndex}");
|
||||
transform.position += new Vector3(2 * newIndex, 0, 0);
|
||||
}
|
||||
|
||||
public override void ReadyStateChanged(bool oldReadyState, bool newReadyState)
|
||||
{
|
||||
//Debug.Log($"ReadyStateChanged {newReadyState}");
|
||||
}
|
||||
public override void OnStartLocalPlayer()
|
||||
{
|
||||
base.OnStartLocalPlayer();
|
||||
vCam.Priority = 12;
|
||||
}
|
||||
|
||||
#if !UNITY_SERVER
|
||||
public override void OnGUI()
|
||||
{
|
||||
base.OnGUI();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84f3d79682e31e6478b25d85b6ff3f2a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/HotUpdate/Main/Player.meta
Normal file
8
Assets/Scripts/HotUpdate/Main/Player.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f22eca2a26fff8040b7a28bdddff92e0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
30
Assets/Scripts/HotUpdate/Main/Player/AttackController.cs
Normal file
30
Assets/Scripts/HotUpdate/Main/Player/AttackController.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class AttackController : MonoBehaviour
|
||||
{
|
||||
public GameObject Bullet;
|
||||
public GameObject Root;
|
||||
public float CD;
|
||||
public float Timer;
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
public void DoAttack()
|
||||
{
|
||||
GameObject go = Instantiate(Bullet);
|
||||
go.transform.position = Root.transform.position;
|
||||
go.transform.localScale = new Vector3(0.002f, 0.002f, 0.002f);
|
||||
go.transform.rotation = Root.transform.rotation;
|
||||
Timer = Time.time;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae8de499914d30e438bbef1a3b7d4c5b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
38
Assets/Scripts/HotUpdate/Main/Player/Bullet.cs
Normal file
38
Assets/Scripts/HotUpdate/Main/Player/Bullet.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using DestroyIt;
|
||||
using UnityEngine;
|
||||
|
||||
public class Bullet : MonoBehaviour
|
||||
{
|
||||
public float speed;
|
||||
public float damage;
|
||||
public Vector3 dir;
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
GetComponent<Rigidbody>().velocity = transform.forward * speed;
|
||||
dir = transform.forward;
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
private void OnCollisionEnter(Collision collision)
|
||||
{
|
||||
GetComponent<Rigidbody>().velocity = dir * speed;
|
||||
transform.forward = dir;
|
||||
if (collision.gameObject.GetComponent<Destructible>())
|
||||
{
|
||||
HitEffects hitEffects = collision.gameObject.GetComponentInParent<HitEffects>();
|
||||
if (hitEffects != null && hitEffects.effects.Count > 0)
|
||||
hitEffects.PlayEffect(HitBy.Bullet, transform.position, transform.forward);
|
||||
DestroyIt.Destructible destructible = collision.gameObject.GetComponent<DestroyIt.Destructible>();
|
||||
destructible.ApplyDamage(damage);
|
||||
if (destructible.CurrentHitPoints > 0)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/HotUpdate/Main/Player/Bullet.cs.meta
Normal file
11
Assets/Scripts/HotUpdate/Main/Player/Bullet.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34477b82ab45be24684e277ce61b0ecc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,262 @@
|
||||
using Cinemachine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using YooAsset;
|
||||
using Mirror;
|
||||
|
||||
public class NetWorkThirdCharacterController : NetworkBehaviour
|
||||
{
|
||||
#region ThirdCharacterController
|
||||
public float moveSpeed = 5f;
|
||||
public float turnSpeed = 10f;
|
||||
public float jumpSpeed = 8f;
|
||||
public float gravity = 20f;
|
||||
public float minCameraDistance = 2f;
|
||||
public float maxCameraDistance = 10f;
|
||||
public float cameraZoomSpeed = 0.1f;
|
||||
|
||||
public CharacterController controller;
|
||||
public Animator animator;
|
||||
public CinemachineVirtualCamera vCam;
|
||||
public Transform forwardReference;
|
||||
public Transform model;
|
||||
|
||||
private CinemachineFramingTransposer framingTransposer;
|
||||
private CinemachinePOV pov;
|
||||
private Vector3 moveDirection;
|
||||
private Vector3 verticalVelocity;
|
||||
private Vector2 moveInput;
|
||||
private bool isGrounded;
|
||||
private bool isCursorLocked = true;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
//if (!isLocalPlayer) return;
|
||||
framingTransposer = vCam.GetCinemachineComponent<CinemachineFramingTransposer>();
|
||||
pov = vCam.GetCinemachineComponent<CinemachinePOV>();
|
||||
UpdateCursorState();
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
ApplyGravity();
|
||||
Move();
|
||||
RotateModel();
|
||||
UpdateAnimator();
|
||||
}
|
||||
private void UpdateCursorState()
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
Cursor.lockState = isCursorLocked ? CursorLockMode.Locked : CursorLockMode.None;
|
||||
Cursor.visible = !isCursorLocked;
|
||||
if (pov == null) return;
|
||||
pov.m_HorizontalAxis.m_InputAxisName = isCursorLocked ? "Mouse X" : "";
|
||||
pov.m_VerticalAxis.m_InputAxisName = isCursorLocked ? "Mouse Y" : "";
|
||||
pov.m_HorizontalAxis.m_MaxSpeed = isCursorLocked ? 300 : 0;
|
||||
pov.m_VerticalAxis.m_MaxSpeed = isCursorLocked ? 300 : 0;
|
||||
}
|
||||
private void ApplyGravity()
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
isGrounded = controller.isGrounded;
|
||||
if (isGrounded && verticalVelocity.y < 0)
|
||||
{
|
||||
verticalVelocity.y = -2f;
|
||||
}
|
||||
else
|
||||
{
|
||||
verticalVelocity.y -= gravity * Time.deltaTime;
|
||||
}
|
||||
}
|
||||
private void Move()
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
forwardReference.rotation = Quaternion.AngleAxis(pov.m_HorizontalAxis.Value+transform.eulerAngles.y, Vector3.up);
|
||||
Vector3 horizontalMovement = forwardReference.TransformDirection(
|
||||
new Vector3(moveInput.x, 0, moveInput.y)) * moveSpeed;
|
||||
moveDirection = horizontalMovement + verticalVelocity;
|
||||
controller.Move(moveDirection * Time.deltaTime);
|
||||
}
|
||||
private void RotateModel()
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (moveInput == Vector2.zero) return;
|
||||
float targetAngle = Mathf.Atan2(moveInput.x, moveInput.y) * Mathf.Rad2Deg;
|
||||
Quaternion targetRotation = forwardReference.rotation * Quaternion.AngleAxis(targetAngle, Vector3.up);
|
||||
model.rotation = Quaternion.Slerp(model.rotation, targetRotation, turnSpeed * Time.deltaTime);
|
||||
}
|
||||
private void UpdateAnimator()
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (animator == null) return;
|
||||
animator.SetBool("Move", moveInput != Vector2.zero);
|
||||
}
|
||||
public void OnMove(InputAction.CallbackContext context)
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
moveInput = context.ReadValue<Vector2>();
|
||||
}
|
||||
public void OnJump(InputAction.CallbackContext context)
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (context.performed && isGrounded)
|
||||
{
|
||||
verticalVelocity.y = jumpSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnFire(InputAction.CallbackContext context)
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (context.performed)
|
||||
{
|
||||
animator.SetTrigger("Attack");
|
||||
}
|
||||
}
|
||||
public void OnEsc(InputAction.CallbackContext context)
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (context.performed)
|
||||
{
|
||||
isCursorLocked = !isCursorLocked;
|
||||
UpdateCursorState();
|
||||
if (isCursorLocked)
|
||||
{
|
||||
SettingsManager.Instance.CloseSettingWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
SettingsManager.Instance.OpenSettingWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void OnAlt(InputAction.CallbackContext context)
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (context.performed)
|
||||
{
|
||||
isCursorLocked = false;
|
||||
UpdateCursorState();
|
||||
}
|
||||
else if (context.canceled)
|
||||
{
|
||||
isCursorLocked = true;
|
||||
UpdateCursorState();
|
||||
}
|
||||
}
|
||||
public void OnZoom(InputAction.CallbackContext context)
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (framingTransposer == null) return;
|
||||
float scrollValue = context.ReadValue<float>();
|
||||
float newDistance = framingTransposer.m_CameraDistance + (scrollValue * cameraZoomSpeed * 0.01f);
|
||||
framingTransposer.m_CameraDistance = Mathf.Clamp(newDistance, minCameraDistance, maxCameraDistance);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Start & Stop Callbacks
|
||||
|
||||
/// <summary>
|
||||
/// This is invoked for NetworkBehaviour objects when they become active on the server.
|
||||
/// <para>This could be triggered by NetworkServer.Listen() for objects in the scene, or by NetworkServer.Spawn() for objects that are dynamically created.</para>
|
||||
/// <para>This will be called for objects on a "host" as well as for object on a dedicated server.</para>
|
||||
/// </summary>
|
||||
public override void OnStartServer()
|
||||
{
|
||||
Debug.Log("OnStartServer");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked on the server when the object is unspawned
|
||||
/// <para>Useful for saving object data in persistent storage</para>
|
||||
/// </summary>
|
||||
public override void OnStopServer() { }
|
||||
|
||||
/// <summary>
|
||||
/// Called on every NetworkBehaviour when it is activated on a client.
|
||||
/// <para>Objects on the host have this function called, as there is a local client on the host. The values of SyncVars on object are guaranteed to be initialized correctly with the latest state from the server when this function is called on the client.</para>
|
||||
/// </summary>
|
||||
public override void OnStartClient()
|
||||
{
|
||||
Debug.Log("OnStartClient");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is invoked on clients when the server has caused this object to be destroyed.
|
||||
/// <para>This can be used as a hook to invoke effects or do client specific cleanup.</para>
|
||||
/// </summary>
|
||||
public override void OnStopClient() { }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the local player object has been set up.
|
||||
/// <para>This happens after OnStartClient(), as it is triggered by an ownership message from the server. This is an appropriate place to activate components or functionality that should only be active for the local player, such as cameras and input.</para>
|
||||
/// </summary>
|
||||
public override void OnStartLocalPlayer()
|
||||
{
|
||||
Debug.Log("OnStartLocalPlayer");
|
||||
vCam.Priority = 15;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the local player object is being stopped.
|
||||
/// <para>This happens before OnStopClient(), as it may be triggered by an ownership message from the server, or because the player object is being destroyed. This is an appropriate place to deactivate components or functionality that should only be active for the local player, such as cameras and input.</para>
|
||||
/// </summary>
|
||||
public override void OnStopLocalPlayer() { }
|
||||
|
||||
/// <summary>
|
||||
/// This is invoked on behaviours that have authority, based on context and <see cref="NetworkIdentity.hasAuthority">NetworkIdentity.hasAuthority</see>.
|
||||
/// <para>This is called after <see cref="OnStartServer">OnStartServer</see> and before <see cref="OnStartClient">OnStartClient.</see></para>
|
||||
/// <para>When <see cref="NetworkIdentity.AssignClientAuthority">AssignClientAuthority</see> is called on the server, this will be called on the client that owns the object. When an object is spawned with <see cref="NetworkServer.Spawn">NetworkServer.Spawn</see> with a NetworkConnectionToClient parameter included, this will be called on the client that owns the object.</para>
|
||||
/// </summary>
|
||||
public override void OnStartAuthority() { }
|
||||
|
||||
/// <summary>
|
||||
/// This is invoked on behaviours when authority is removed.
|
||||
/// <para>When NetworkIdentity.RemoveClientAuthority is called on the server, this will be called on the client that owns the object.</para>
|
||||
/// </summary>
|
||||
public override void OnStopAuthority() { }
|
||||
|
||||
#endregion
|
||||
|
||||
public NetworkAnimator networkAnimator;
|
||||
|
||||
[SyncVar(hook = nameof(OnCurCharacterNameChange))]
|
||||
public string curCharacterName;
|
||||
public void OnCurCharacterNameChange(string _Old,string _New)
|
||||
{
|
||||
animator = null;
|
||||
model.GetChild(0).gameObject.SetActive(false);
|
||||
AssetHandle assetHandle = YooAssets.LoadAssetAsync(_New);
|
||||
assetHandle.Completed += (handle) =>
|
||||
{
|
||||
GameObject character = handle.InstantiateSync(model);
|
||||
animator = character.GetComponent<Animator>();
|
||||
networkAnimator.animator = animator;
|
||||
character.transform.SetAsFirstSibling();
|
||||
curCharacterName = _New;
|
||||
};
|
||||
}
|
||||
public void ChangeCharacter(InputAction.CallbackContext context)
|
||||
{
|
||||
if (context.performed && isLocalPlayer)
|
||||
{
|
||||
int bindingIndex = context.action.GetBindingIndexForControl(context.control);
|
||||
CmdChangeCharacter(test[bindingIndex]);
|
||||
}
|
||||
}
|
||||
[Command]
|
||||
public void CmdChangeCharacter(string name)
|
||||
{
|
||||
curCharacterName = name;
|
||||
}
|
||||
List<string> test = new List<string>()
|
||||
{
|
||||
"Aris",
|
||||
"Momoi",
|
||||
"Midori",
|
||||
"Yuzu",
|
||||
"CH0200"
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e922d666ae574ca41bf0d6be534cb0cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
190
Assets/Scripts/HotUpdate/Main/Player/ThirdCharacterController.cs
Normal file
190
Assets/Scripts/HotUpdate/Main/Player/ThirdCharacterController.cs
Normal file
@@ -0,0 +1,190 @@
|
||||
using Cinemachine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using YooAsset;
|
||||
|
||||
public class ThirdCharacterController : MonoBehaviour
|
||||
{
|
||||
public float moveSpeed = 5f;
|
||||
public float turnSpeed = 10f;
|
||||
public float jumpSpeed = 8f;
|
||||
public float gravity = 20f;
|
||||
public float minCameraDistance = 2f;
|
||||
public float maxCameraDistance = 10f;
|
||||
public float cameraZoomSpeed = 0.1f;
|
||||
|
||||
public CharacterController controller;
|
||||
public Animator animator;
|
||||
public CinemachineVirtualCamera vCam;
|
||||
public Transform forwardReference;
|
||||
public Transform model;
|
||||
|
||||
private CinemachineFramingTransposer framingTransposer;
|
||||
private CinemachinePOV pov;
|
||||
private Vector3 moveDirection;
|
||||
private Vector3 verticalVelocity;
|
||||
private Vector2 moveInput;
|
||||
private bool isGrounded;
|
||||
private bool isCursorLocked = true;
|
||||
public bool isLocalPlayer;
|
||||
string curCharacterName;
|
||||
|
||||
public Action<GameObject> changeCharacterComplete;
|
||||
void Awake()
|
||||
{
|
||||
//if (!isLocalPlayer) return;
|
||||
framingTransposer = vCam.GetCinemachineComponent<CinemachineFramingTransposer>();
|
||||
pov = vCam.GetCinemachineComponent<CinemachinePOV>();
|
||||
UpdateCursorState();
|
||||
ChangeCharacter("Aris");
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
ApplyGravity();
|
||||
Move();
|
||||
RotateModel();
|
||||
UpdateAnimator();
|
||||
}
|
||||
private void UpdateCursorState()
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
Cursor.lockState = isCursorLocked ? CursorLockMode.Locked : CursorLockMode.None;
|
||||
Cursor.visible = !isCursorLocked;
|
||||
if (pov == null) return;
|
||||
pov.m_HorizontalAxis.m_InputAxisName = isCursorLocked ? "Mouse X" : "";
|
||||
pov.m_VerticalAxis.m_InputAxisName = isCursorLocked ? "Mouse Y" : "";
|
||||
pov.m_HorizontalAxis.m_MaxSpeed = isCursorLocked ? 300 : 0;
|
||||
pov.m_VerticalAxis.m_MaxSpeed = isCursorLocked ? 300 : 0;
|
||||
}
|
||||
private void ApplyGravity()
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
isGrounded = controller.isGrounded;
|
||||
if (isGrounded && verticalVelocity.y < 0)
|
||||
{
|
||||
verticalVelocity.y = -2f;
|
||||
}
|
||||
else
|
||||
{
|
||||
verticalVelocity.y -= gravity * Time.deltaTime;
|
||||
}
|
||||
}
|
||||
private void Move()
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
forwardReference.rotation = Quaternion.AngleAxis(pov.m_HorizontalAxis.Value+transform.eulerAngles.y, Vector3.up);
|
||||
Vector3 horizontalMovement = forwardReference.TransformDirection(
|
||||
new Vector3(moveInput.x, 0, moveInput.y)) * moveSpeed;
|
||||
moveDirection = horizontalMovement + verticalVelocity;
|
||||
controller.Move(moveDirection * Time.deltaTime);
|
||||
}
|
||||
private void RotateModel()
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (moveInput == Vector2.zero) return;
|
||||
float targetAngle = Mathf.Atan2(moveInput.x, moveInput.y) * Mathf.Rad2Deg;
|
||||
Quaternion targetRotation = forwardReference.rotation * Quaternion.AngleAxis(targetAngle, Vector3.up);
|
||||
model.rotation = Quaternion.Slerp(model.rotation, targetRotation, turnSpeed * Time.deltaTime);
|
||||
}
|
||||
private void UpdateAnimator()
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (animator == null) return;
|
||||
animator.SetBool("Move", moveInput != Vector2.zero);
|
||||
}
|
||||
public void OnMove(InputAction.CallbackContext context)
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
moveInput = context.ReadValue<Vector2>();
|
||||
}
|
||||
public void OnJump(InputAction.CallbackContext context)
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (context.performed && isGrounded)
|
||||
{
|
||||
verticalVelocity.y = jumpSpeed;
|
||||
}
|
||||
}
|
||||
public void OnEsc(InputAction.CallbackContext context)
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (context.performed)
|
||||
{
|
||||
isCursorLocked = !isCursorLocked;
|
||||
UpdateCursorState();
|
||||
if (isCursorLocked)
|
||||
{
|
||||
SettingsManager.Instance.CloseSettingWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
SettingsManager.Instance.OpenSettingWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void OnFire(InputAction.CallbackContext context)
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (context.performed)
|
||||
{
|
||||
animator.SetTrigger("Attack");
|
||||
}
|
||||
}
|
||||
public void OnAlt(InputAction.CallbackContext context)
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (context.performed)
|
||||
{
|
||||
isCursorLocked = false;
|
||||
UpdateCursorState();
|
||||
}
|
||||
else if (context.canceled)
|
||||
{
|
||||
isCursorLocked = true;
|
||||
UpdateCursorState();
|
||||
}
|
||||
}
|
||||
public void OnZoom(InputAction.CallbackContext context)
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (framingTransposer == null) return;
|
||||
float scrollValue = context.ReadValue<float>();
|
||||
float newDistance = framingTransposer.m_CameraDistance + (scrollValue * cameraZoomSpeed * 0.01f);
|
||||
framingTransposer.m_CameraDistance = Mathf.Clamp(newDistance, minCameraDistance, maxCameraDistance);
|
||||
}
|
||||
public void OnChangeCharacter(InputAction.CallbackContext context)
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (context.performed)
|
||||
{
|
||||
int bindingIndex = context.action.GetBindingIndexForControl(context.control);
|
||||
ChangeCharacter(test[bindingIndex]);
|
||||
}
|
||||
}
|
||||
public void ChangeCharacter(string name)
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (curCharacterName == name) return;
|
||||
animator = null;
|
||||
model.GetChild(0).gameObject.SetActive(false);
|
||||
AssetHandle assetHandle = YooAssets.LoadAssetAsync(name);
|
||||
assetHandle.Completed += (handle) =>
|
||||
{
|
||||
GameObject character = handle.InstantiateSync(model);
|
||||
animator = character.GetComponent<Animator>();
|
||||
character.transform.SetAsFirstSibling();
|
||||
curCharacterName = name;
|
||||
changeCharacterComplete?.Invoke(character);
|
||||
};
|
||||
}
|
||||
List<string> test = new List<string>()
|
||||
{
|
||||
"Aris",
|
||||
"Momoi",
|
||||
"Midori",
|
||||
"Yuzu"
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f5ea1583657bf34da64f427793797f1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/HotUpdate/Main/SettingWindow.meta
Normal file
8
Assets/Scripts/HotUpdate/Main/SettingWindow.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1669278f047d12459ab7558d17707b0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
32
Assets/Scripts/HotUpdate/Main/SettingWindow/AudioPanel.cs
Normal file
32
Assets/Scripts/HotUpdate/Main/SettingWindow/AudioPanel.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Audio;
|
||||
|
||||
public class AudioPanel : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Slider masterVolumeSlider;
|
||||
[SerializeField] private AudioMixer audioMixer;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
masterVolumeSlider.value = SettingsManager.Instance.CurrentSettings.masterVolume;
|
||||
if (audioMixer == null) audioMixer = FindAnyObjectByType<AudioMixer>();
|
||||
}
|
||||
|
||||
public void OnMasterVolumeChanged(float value)
|
||||
{
|
||||
SettingsManager.Instance.CurrentSettings.masterVolume = value;
|
||||
SetVolume(value);
|
||||
}
|
||||
|
||||
public void ApplySettings()
|
||||
{
|
||||
SetVolume(SettingsManager.Instance.CurrentSettings.masterVolume);
|
||||
}
|
||||
|
||||
private void SetVolume(float volume)
|
||||
{
|
||||
if (audioMixer)
|
||||
audioMixer.SetFloat("MasterVolume", Mathf.Log10(Mathf.Max(volume, 0.0001f)) * 20);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 71d4a15b9c9ec1e4d91d6be9e66bd865
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
138
Assets/Scripts/HotUpdate/Main/SettingWindow/DisplayPanel.cs
Normal file
138
Assets/Scripts/HotUpdate/Main/SettingWindow/DisplayPanel.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using System.Collections;
|
||||
|
||||
public class DisplayPanel : MonoBehaviour
|
||||
{
|
||||
[Header("UI References")]
|
||||
[SerializeField] private TMP_Dropdown resolutionDropdown;
|
||||
[SerializeField] private Toggle fullscreenToggle;
|
||||
[SerializeField] private Toggle borderlessToggle;
|
||||
[SerializeField] private TMP_Dropdown displayDropdown;
|
||||
|
||||
private Resolution[] resolutions;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
InitializeResolutionDropdown();
|
||||
InitializeDisplayDropdown();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
StartCoroutine(InitializeDelayed());
|
||||
}
|
||||
IEnumerator InitializeDelayed()
|
||||
{
|
||||
yield return null;
|
||||
var settings = SettingsManager.Instance.CurrentSettings;
|
||||
|
||||
resolutionDropdown.SetValueWithoutNotify(settings.resolutionIndex);
|
||||
fullscreenToggle.SetIsOnWithoutNotify(settings.fullscreen);
|
||||
borderlessToggle.SetIsOnWithoutNotify(settings.borderless);
|
||||
displayDropdown.SetValueWithoutNotify(settings.displayIndex);
|
||||
|
||||
UpdateBorderlessToggleState();
|
||||
}
|
||||
|
||||
private void InitializeResolutionDropdown()
|
||||
{
|
||||
resolutions = Screen.resolutions;
|
||||
resolutionDropdown.ClearOptions();
|
||||
|
||||
var options = new List<string>();
|
||||
for (int i = 0; i < resolutions.Length; i++)
|
||||
{
|
||||
// ʹ<><CAB9>refreshRateRatio<69><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>refreshRate
|
||||
int refreshRate = Mathf.RoundToInt((float)resolutions[i].refreshRateRatio.value);
|
||||
options.Add($"{resolutions[i].width}x{resolutions[i].height} {refreshRate}Hz");
|
||||
}
|
||||
|
||||
resolutionDropdown.AddOptions(options);
|
||||
}
|
||||
|
||||
private void InitializeDisplayDropdown()
|
||||
{
|
||||
displayDropdown.ClearOptions();
|
||||
var options = new List<string>();
|
||||
|
||||
for (int i = 0; i < Display.displays.Length; i++)
|
||||
{
|
||||
options.Add($"Display {i + 1}");
|
||||
}
|
||||
|
||||
displayDropdown.AddOptions(options);
|
||||
}
|
||||
|
||||
public void OnResolutionChanged(int index)
|
||||
{
|
||||
SettingsManager.Instance.CurrentSettings.resolutionIndex = index;
|
||||
ApplySetResolution();
|
||||
}
|
||||
|
||||
public void OnFullscreenChanged(bool value)
|
||||
{
|
||||
SettingsManager.Instance.CurrentSettings.fullscreen = value;
|
||||
UpdateBorderlessToggleState();
|
||||
ApplySetResolution();
|
||||
}
|
||||
|
||||
public void OnBorderlessChanged(bool value)
|
||||
{
|
||||
SettingsManager.Instance.CurrentSettings.borderless = value;
|
||||
ApplySetResolution();
|
||||
}
|
||||
|
||||
public void OnDisplayChanged(int index)
|
||||
{
|
||||
SettingsManager.Instance.CurrentSettings.displayIndex = index;
|
||||
ApplySetDisplay();
|
||||
}
|
||||
|
||||
private void UpdateBorderlessToggleState()
|
||||
{
|
||||
borderlessToggle.interactable = fullscreenToggle.isOn;
|
||||
if (!fullscreenToggle.isOn)
|
||||
borderlessToggle.isOn = false;
|
||||
ApplySetResolution();
|
||||
}
|
||||
|
||||
public void ApplySettings()
|
||||
{
|
||||
ApplySetResolution();
|
||||
|
||||
ApplySetDisplay();
|
||||
}
|
||||
void ApplySetResolution()
|
||||
{
|
||||
if (resolutions == null) return;
|
||||
var settings = SettingsManager.Instance.CurrentSettings;
|
||||
Resolution res = resolutions[resolutions.Length];
|
||||
if (settings.resolutionIndex< resolutions.Length)
|
||||
{
|
||||
res = resolutions[settings.resolutionIndex];
|
||||
}
|
||||
|
||||
FullScreenMode mode = settings.borderless ?
|
||||
FullScreenMode.FullScreenWindow :
|
||||
(settings.fullscreen ? FullScreenMode.ExclusiveFullScreen : FullScreenMode.Windowed);
|
||||
|
||||
// ʹ<><CAB9>refreshRateRatio<69><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>refreshRate
|
||||
Screen.SetResolution(
|
||||
res.width,
|
||||
res.height,
|
||||
mode,
|
||||
res.refreshRateRatio
|
||||
);
|
||||
}
|
||||
void ApplySetDisplay()
|
||||
{
|
||||
var settings = SettingsManager.Instance.CurrentSettings;
|
||||
if (settings.displayIndex > 0 && settings.displayIndex < Display.displays.Length)
|
||||
{
|
||||
Display.displays[settings.displayIndex].Activate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b16c03c5d0a387641a3c978840f52037
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/Scripts/HotUpdate/Main/SettingWindow/GeneralPanel.cs
Normal file
18
Assets/Scripts/HotUpdate/Main/SettingWindow/GeneralPanel.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class GeneralPanel : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private TMP_InputField serverAddressInput;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
serverAddressInput.text = SettingsManager.Instance.CurrentSettings.serverAddress;
|
||||
}
|
||||
|
||||
public void OnServerAddressChanged(string value)
|
||||
{
|
||||
SettingsManager.Instance.CurrentSettings.serverAddress = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4949deb4d1315ae4790fc0068c036c04
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
176
Assets/Scripts/HotUpdate/Main/SettingWindow/GraphicsPanel.cs
Normal file
176
Assets/Scripts/HotUpdate/Main/SettingWindow/GraphicsPanel.cs
Normal file
@@ -0,0 +1,176 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
using TMPro;
|
||||
using System.Collections;
|
||||
|
||||
public class GraphicsPanel : MonoBehaviour
|
||||
{
|
||||
[Header("UI References")]
|
||||
[SerializeField] private TMP_Dropdown qualityDropdown;
|
||||
[SerializeField] private Toggle vsyncToggle;
|
||||
[SerializeField] private Slider shadowDistanceSlider;
|
||||
[SerializeField] private TMP_Dropdown antiAliasingDropdown;
|
||||
[SerializeField] private Toggle bloomToggle;
|
||||
[SerializeField] private Slider renderScaleSlider;
|
||||
|
||||
[Header("Graphics References")]
|
||||
[SerializeField] private VolumeProfile urpVolumeProfile;
|
||||
|
||||
[Header("Quality Presets")]
|
||||
[SerializeField]
|
||||
private QualityPreset[] qualityPresets = new QualityPreset[4]
|
||||
{
|
||||
new QualityPreset("Low", 0, false, 20f, 0, false, 0.8f),
|
||||
new QualityPreset("Medium", 1, false, 40f, 1, true, 1.0f),
|
||||
new QualityPreset("High", 2, true, 60f, 2, true, 1.2f),
|
||||
new QualityPreset("Ultra", 3, true, 100f, 2, true, 1.5f)
|
||||
};
|
||||
|
||||
[System.Serializable]
|
||||
public class QualityPreset
|
||||
{
|
||||
public string name;
|
||||
public int qualityLevel;
|
||||
public bool vsyncEnabled;
|
||||
public float shadowDistance;
|
||||
public int antiAliasing;
|
||||
public bool bloomEnabled;
|
||||
public float renderScale;
|
||||
|
||||
public QualityPreset(string name, int qualityLevel, bool vsyncEnabled, float shadowDistance,
|
||||
int antiAliasing, bool bloomEnabled, float renderScale)
|
||||
{
|
||||
this.name = name;
|
||||
this.qualityLevel = qualityLevel;
|
||||
this.vsyncEnabled = vsyncEnabled;
|
||||
this.shadowDistance = shadowDistance;
|
||||
this.antiAliasing = antiAliasing;
|
||||
this.bloomEnabled = bloomEnabled;
|
||||
this.renderScale = renderScale;
|
||||
}
|
||||
}
|
||||
|
||||
private UniversalRenderPipelineAsset _urpAsset;
|
||||
private Bloom _bloom;
|
||||
private void OnEnable()
|
||||
{
|
||||
StartCoroutine(InitializeDelayed());
|
||||
}
|
||||
|
||||
private IEnumerator InitializeDelayed()
|
||||
{
|
||||
yield return null; // <20>ȴ<EFBFBD>һ֡ȷ<D6A1><C8B7>URP<52><50>ʼ<EFBFBD><CABC>
|
||||
|
||||
// <20><>ȡURP Asset
|
||||
_urpAsset = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
|
||||
|
||||
if (_urpAsset == null)
|
||||
{
|
||||
Debug.LogError("<22><EFBFBD><DEB7><EFBFBD>ȡURP Asset<65><74><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>Ŀʹ<C4BF><CAB9>URP");
|
||||
yield break;
|
||||
}
|
||||
|
||||
// <20><>ȡBloomЧ<6D><D0A7>
|
||||
if (urpVolumeProfile != null && !urpVolumeProfile.TryGet(out _bloom))
|
||||
{
|
||||
Debug.LogWarning("Volume Profile<6C><65>δ<EFBFBD>ҵ<EFBFBD>BloomЧ<6D><D0A7>");
|
||||
}
|
||||
|
||||
// <20><>ʼ<EFBFBD><CABC>UI
|
||||
//InitializeQualityDropdown();
|
||||
var settings = SettingsManager.Instance.CurrentSettings;
|
||||
qualityDropdown.SetValueWithoutNotify(settings.qualityLevel);
|
||||
vsyncToggle.SetIsOnWithoutNotify(settings.vsyncEnabled);
|
||||
shadowDistanceSlider.SetValueWithoutNotify(settings.shadowDistance);
|
||||
antiAliasingDropdown.SetValueWithoutNotify(settings.antiAliasing);
|
||||
bloomToggle.SetIsOnWithoutNotify(settings.bloomEnabled);
|
||||
renderScaleSlider.SetValueWithoutNotify(settings.renderScale);
|
||||
ApplySettings();
|
||||
}
|
||||
|
||||
//private void InitializeQualityDropdown()
|
||||
//{
|
||||
// qualityDropdown.ClearOptions();
|
||||
// foreach (var preset in qualityPresets)
|
||||
// {
|
||||
// qualityDropdown.options.Add(new TMP_Dropdown.OptionData(preset.name));
|
||||
// }
|
||||
//}
|
||||
|
||||
public void OnQualityChanged(int index)
|
||||
{
|
||||
|
||||
SettingsManager.Instance.CurrentSettings.qualityLevel = index;
|
||||
var settings = SettingsManager.Instance.CurrentSettings;
|
||||
|
||||
if (index >= 0 && index < qualityPresets.Length)
|
||||
{
|
||||
var preset = qualityPresets[index];
|
||||
// Ӧ<><D3A6>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
vsyncToggle.SetIsOnWithoutNotify(preset.vsyncEnabled);
|
||||
shadowDistanceSlider.SetValueWithoutNotify(preset.shadowDistance);
|
||||
antiAliasingDropdown.SetValueWithoutNotify(preset.antiAliasing);
|
||||
bloomToggle.SetIsOnWithoutNotify(preset.bloomEnabled);
|
||||
renderScaleSlider.SetValueWithoutNotify(preset.renderScale);
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
OnVSyncChanged(settings.vsyncEnabled);
|
||||
OnShadowDistanceChanged(settings.shadowDistance);
|
||||
OnAntiAliasingChanged(settings.antiAliasing);
|
||||
OnBloomChanged(settings.bloomEnabled);
|
||||
OnRenderScaleChanged(settings.renderScale);
|
||||
}
|
||||
|
||||
public void OnVSyncChanged(bool value)
|
||||
{
|
||||
SettingsManager.Instance.CurrentSettings.vsyncEnabled = value;
|
||||
QualitySettings.vSyncCount = value ? 1 : 0;
|
||||
}
|
||||
|
||||
public void OnShadowDistanceChanged(float value)
|
||||
{
|
||||
SettingsManager.Instance.CurrentSettings.shadowDistance = value;
|
||||
if (_urpAsset != null)
|
||||
_urpAsset.shadowDistance = value;
|
||||
}
|
||||
|
||||
public void OnAntiAliasingChanged(int index)
|
||||
{
|
||||
SettingsManager.Instance.CurrentSettings.antiAliasing = index;
|
||||
if (_urpAsset != null)
|
||||
_urpAsset.msaaSampleCount = (int)Mathf.Pow(2, index);
|
||||
}
|
||||
|
||||
public void OnBloomChanged(bool value)
|
||||
{
|
||||
SettingsManager.Instance.CurrentSettings.bloomEnabled = value;
|
||||
if (_bloom != null)
|
||||
_bloom.active = value;
|
||||
}
|
||||
|
||||
public void OnRenderScaleChanged(float value)
|
||||
{
|
||||
SettingsManager.Instance.CurrentSettings.renderScale = value;
|
||||
if (_urpAsset != null)
|
||||
_urpAsset.renderScale = value;
|
||||
}
|
||||
|
||||
public void ApplySettings()
|
||||
{
|
||||
if (_urpAsset == null) return;
|
||||
|
||||
var settings = SettingsManager.Instance.CurrentSettings;
|
||||
if (settings.qualityLevel != 4)
|
||||
QualitySettings.SetQualityLevel(settings.qualityLevel);
|
||||
QualitySettings.vSyncCount = settings.vsyncEnabled ? 1 : 0;
|
||||
|
||||
_urpAsset.shadowDistance = settings.shadowDistance;
|
||||
_urpAsset.msaaSampleCount = (int)Mathf.Pow(2, settings.antiAliasing);
|
||||
_urpAsset.renderScale = settings.renderScale;
|
||||
|
||||
if (_bloom != null) _bloom.active = settings.bloomEnabled;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a15301d059dcf34ea494f21cef46548
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,94 @@
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
using YooAsset;
|
||||
using System;
|
||||
|
||||
public class SettingsManager : MonoBehaviour
|
||||
{
|
||||
public static SettingsManager Instance { get; private set; }
|
||||
|
||||
private GameSettings _currentSettings;
|
||||
private SettingsWindow settingsWindow;
|
||||
public GameSettings CurrentSettings => _currentSettings;
|
||||
private string settingsPath;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
|
||||
settingsPath = Path.Combine(Application.persistentDataPath, "settings.json");
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
public void LoadSettings()
|
||||
{
|
||||
if (File.Exists(settingsPath))
|
||||
{
|
||||
string json = File.ReadAllText(settingsPath);
|
||||
_currentSettings = JsonUtility.FromJson<GameSettings>(json);
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetToDefaultSettings();
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveSettings()
|
||||
{
|
||||
string json = JsonUtility.ToJson(_currentSettings, true);
|
||||
File.WriteAllText(settingsPath, json);
|
||||
}
|
||||
public void ResetToDefaultSettings()
|
||||
{
|
||||
_currentSettings = new GameSettings();
|
||||
SaveSettings();
|
||||
}
|
||||
public void OpenSettingWindow()
|
||||
{
|
||||
if (settingsWindow != null)
|
||||
{
|
||||
settingsWindow.gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
YooAssets.LoadAssetAsync<GameObject>("SettingsWindow").Completed += (handle) =>
|
||||
{
|
||||
settingsWindow = GameObject.Instantiate((GameObject)handle.AssetObject, GameManager.Inst.MainUICanvas.transform).GetComponent<SettingsWindow>();
|
||||
};
|
||||
}
|
||||
}
|
||||
public void CloseSettingWindow()
|
||||
{
|
||||
if (settingsWindow != null)
|
||||
{
|
||||
settingsWindow.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class GameSettings
|
||||
{
|
||||
public string serverAddress = "http://127.0.0.1:8080";
|
||||
|
||||
public float masterVolume = 0.75f;
|
||||
|
||||
public int qualityLevel = 2;
|
||||
public bool vsyncEnabled = true;
|
||||
public float shadowDistance = 50f;
|
||||
public int antiAliasing = 2;
|
||||
public bool bloomEnabled = true;
|
||||
public float renderScale = 1.0f;
|
||||
|
||||
public int resolutionIndex = 0;
|
||||
public bool fullscreen = true;
|
||||
public bool borderless = false;
|
||||
public int displayIndex = 0;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d1ed5819e87e0f4ebbdf4dad51fcb7a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,90 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class SettingsWindow : MonoBehaviour
|
||||
{
|
||||
[Header("Panels")]
|
||||
public GameObject generalPanel;
|
||||
public GameObject audioPanel;
|
||||
public GameObject graphicsPanel;
|
||||
public GameObject displayPanel;
|
||||
|
||||
[Header("Tab Buttons")]
|
||||
public Button generalTab;
|
||||
public Button audioTab;
|
||||
public Button graphicsTab;
|
||||
public Button displayTab;
|
||||
|
||||
[Header("Action Buttons")]
|
||||
public Button applyButton;
|
||||
public Button cancelButton;
|
||||
public Button defaultsButton;
|
||||
public Button quitButton;
|
||||
|
||||
private GameObject currentPanel;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ǩҳ<C7A9><D2B3>ť
|
||||
generalTab.onClick.AddListener(() => SwitchPanel(generalPanel));
|
||||
audioTab.onClick.AddListener(() => SwitchPanel(audioPanel));
|
||||
graphicsTab.onClick.AddListener(() => SwitchPanel(graphicsPanel));
|
||||
displayTab.onClick.AddListener(() => SwitchPanel(displayPanel));
|
||||
|
||||
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ť
|
||||
applyButton.onClick.AddListener(ApplyAllSettings);
|
||||
cancelButton.onClick.AddListener(CloseWindow);
|
||||
defaultsButton.onClick.AddListener(ResetToDefaults);
|
||||
quitButton.onClick.AddListener(() => { Application.Quit(); });
|
||||
|
||||
// Ĭ<>ϴ<CFB4>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
SwitchPanel(generalPanel);
|
||||
}
|
||||
|
||||
private void SwitchPanel(GameObject newPanel)
|
||||
{
|
||||
if (currentPanel != null)
|
||||
currentPanel.SetActive(false);
|
||||
|
||||
newPanel.SetActive(true);
|
||||
currentPanel = newPanel;
|
||||
UpdateTabButtons();
|
||||
}
|
||||
|
||||
private void UpdateTabButtons()
|
||||
{
|
||||
generalTab.interactable = currentPanel != generalPanel;
|
||||
audioTab.interactable = currentPanel != audioPanel;
|
||||
graphicsTab.interactable = currentPanel != graphicsPanel;
|
||||
displayTab.interactable = currentPanel != displayPanel;
|
||||
}
|
||||
|
||||
public void ApplyAllSettings()
|
||||
{
|
||||
// Ӧ<><D3A6><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD>ã<EFBFBD><C3A3><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>ִ<EFBFBD>У<EFBFBD>
|
||||
displayPanel.GetComponent<DisplayPanel>().ApplySettings();
|
||||
|
||||
// Ӧ<><D3A6>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
graphicsPanel.GetComponent<GraphicsPanel>().ApplySettings();
|
||||
|
||||
// Ӧ<><D3A6><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>
|
||||
audioPanel.GetComponent<AudioPanel>().ApplySettings();
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
SettingsManager.Instance.SaveSettings();
|
||||
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
public void CloseWindow()
|
||||
{
|
||||
// <20><><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD>
|
||||
SettingsManager.Instance.LoadSettings();
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
public void ResetToDefaults()
|
||||
{
|
||||
SettingsManager.Instance.ResetToDefaultSettings();
|
||||
SwitchPanel(currentPanel); // ˢ<>µ<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d6ce7fe9c8bcb144bfed87170589a6e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
7
Assets/Scripts/HotUpdate/Main/Test.cs
Normal file
7
Assets/Scripts/HotUpdate/Main/Test.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class Test : MonoBehaviour
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
11
Assets/Scripts/HotUpdate/Main/Test.cs.meta
Normal file
11
Assets/Scripts/HotUpdate/Main/Test.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5cc3b18a638faa5499da9f527721a48d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user