首次提交
This commit is contained in:
3
Assets/Scripts/Common.meta
Normal file
3
Assets/Scripts/Common.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: caf75b28905c41ab8e414e696c3423f9
|
||||
timeCreated: 1756363998
|
||||
3
Assets/Scripts/Common/Assets.meta
Normal file
3
Assets/Scripts/Common/Assets.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a18bd4a09c14040b9ea1de796d645f1
|
||||
timeCreated: 1743783137
|
||||
12
Assets/Scripts/Common/Assets/BaitAsset.cs
Normal file
12
Assets/Scripts/Common/Assets/BaitAsset.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
/// <summary>
|
||||
/// 鱼饵
|
||||
/// </summary>
|
||||
public class BaitAsset : PreviewableAsset
|
||||
{
|
||||
public Transform hook;
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Assets/BaitAsset.cs.meta
Normal file
3
Assets/Scripts/Common/Assets/BaitAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 524c26f472e74fa1ad167db68e562324
|
||||
timeCreated: 1743824319
|
||||
28
Assets/Scripts/Common/Assets/BobberAsset.cs
Normal file
28
Assets/Scripts/Common/Assets/BobberAsset.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
/// <summary>
|
||||
/// 浮漂资产
|
||||
/// </summary>
|
||||
public class BobberAsset : PreviewableAsset
|
||||
{
|
||||
public Transform body;
|
||||
public Transform stick;
|
||||
|
||||
/// <summary>
|
||||
/// 顶部连接点
|
||||
/// </summary>
|
||||
public Transform topConnector;
|
||||
|
||||
/// <summary>
|
||||
/// 底部连接点
|
||||
/// </summary>
|
||||
public Transform bottomConnector;
|
||||
|
||||
/// <summary>
|
||||
/// 水线
|
||||
/// </summary>
|
||||
public Transform waterline;
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Assets/BobberAsset.cs.meta
Normal file
3
Assets/Scripts/Common/Assets/BobberAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e885da772834bb289c2368be2f6eb5b
|
||||
timeCreated: 1743824616
|
||||
14
Assets/Scripts/Common/Assets/FishAsset.cs
Normal file
14
Assets/Scripts/Common/Assets/FishAsset.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class FishAsset : PreviewableAsset
|
||||
{
|
||||
public Transform root;
|
||||
|
||||
/// <summary>
|
||||
/// 弯曲节点
|
||||
/// </summary>
|
||||
public Transform[] spines;
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Assets/FishAsset.cs.meta
Normal file
3
Assets/Scripts/Common/Assets/FishAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c12ba26d0bd74238ab26aee49ef6fd5d
|
||||
timeCreated: 1743824172
|
||||
18
Assets/Scripts/Common/Assets/FishGroupAsset.cs
Normal file
18
Assets/Scripts/Common/Assets/FishGroupAsset.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class FishGroupAsset : MonoBehaviour
|
||||
{
|
||||
// "previewRotationEnabled": 0,
|
||||
// "previewRotation": {
|
||||
// "x": 0.0,
|
||||
// "y": 0.0,
|
||||
// "z": 0.0
|
||||
// },
|
||||
// "previewFitVertical": 1,
|
||||
// "smallFishName": "ostrea_ed_o",
|
||||
// "mediumFishName": "ostrea_ed_o",
|
||||
// "largeFishName": "ostrea_ed_o"
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Assets/FishGroupAsset.cs.meta
Normal file
3
Assets/Scripts/Common/Assets/FishGroupAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e9e67584f094dcbba9e61f37a55a5b4
|
||||
timeCreated: 1743824179
|
||||
12
Assets/Scripts/Common/Assets/HookAsset.cs
Normal file
12
Assets/Scripts/Common/Assets/HookAsset.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class HookAsset : PreviewableAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 鱼饵挂点
|
||||
/// </summary>
|
||||
public Transform baitConnector;
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Assets/HookAsset.cs.meta
Normal file
3
Assets/Scripts/Common/Assets/HookAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6eea50c041f42d5bd95d9e56c3a9c6f
|
||||
timeCreated: 1743824134
|
||||
8
Assets/Scripts/Common/Assets/LineAsset.cs
Normal file
8
Assets/Scripts/Common/Assets/LineAsset.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class LineAsset : PreviewableAsset
|
||||
{
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Assets/LineAsset.cs.meta
Normal file
3
Assets/Scripts/Common/Assets/LineAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8059c6be171e47edb0390fa091285100
|
||||
timeCreated: 1743824214
|
||||
20
Assets/Scripts/Common/Assets/LureAsset.cs
Normal file
20
Assets/Scripts/Common/Assets/LureAsset.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class LureAsset : PreviewableAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 鱼钩挂点
|
||||
/// </summary>
|
||||
public Transform[] hookPoints;
|
||||
|
||||
[Tooltip("maksymalny kąt odchylenia przynetu przy sciaganiu, rotacja w osi Y")]
|
||||
public float rotateVeloMaxAngle = 10f;
|
||||
|
||||
[Tooltip("predkosc odchylenia przynetu przy sciaganiu, rotacja w osi Y")]
|
||||
public float rotateVeloMaxSpeed = 3f;
|
||||
|
||||
public Vector3 rotationInFishJaw = Vector3.zero;
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Assets/LureAsset.cs.meta
Normal file
3
Assets/Scripts/Common/Assets/LureAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 897c0165284148879a9d158ea8010a15
|
||||
timeCreated: 1743824269
|
||||
52
Assets/Scripts/Common/Assets/PlayerModelAsset.cs
Normal file
52
Assets/Scripts/Common/Assets/PlayerModelAsset.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using KINEMATION.MagicBlend.Runtime;
|
||||
using RootMotion.FinalIK;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class PlayerModelAsset : MonoBehaviour
|
||||
{
|
||||
public Animator Animator { get; private set; }
|
||||
public PlayerIK IK { get; private set; }
|
||||
public PlayerAnimator PlayerAnimator { get; private set; }
|
||||
public MagicBlending MagicBlending { get; private set; }
|
||||
|
||||
public Transform NeckTransform;
|
||||
public LookAtIK LookIk;
|
||||
|
||||
public PlayerArm LeftArm;
|
||||
public PlayerArm RightArm;
|
||||
|
||||
|
||||
public Transform RodRoot
|
||||
{
|
||||
get
|
||||
{
|
||||
if (RightArm == null)
|
||||
{
|
||||
return transform;
|
||||
}
|
||||
|
||||
return RightArm.RodContainer;
|
||||
}
|
||||
}
|
||||
// public Transform RodRoot;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
LookIk = GetComponent<LookAtIK>();
|
||||
Animator = GetComponent<Animator>();
|
||||
Animator.keepAnimatorStateOnDisable = true;
|
||||
MagicBlending = GetComponent<MagicBlending>();
|
||||
IK = GetComponent<PlayerIK>();
|
||||
PlayerAnimator = GetComponent<PlayerAnimator>();
|
||||
}
|
||||
|
||||
public void SetPlayer(FPlayer player)
|
||||
{
|
||||
LookIk.solver.target = player.FppLook;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Assets/PlayerModelAsset.cs.meta
Normal file
3
Assets/Scripts/Common/Assets/PlayerModelAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 553e656eacf648afb33751a88352d216
|
||||
timeCreated: 1757836335
|
||||
13
Assets/Scripts/Common/Assets/PreviewableAsset.cs
Normal file
13
Assets/Scripts/Common/Assets/PreviewableAsset.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
/// <summary>
|
||||
/// 可以3D预览的资产
|
||||
/// </summary>
|
||||
public class PreviewableAsset : MonoBehaviour
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Assets/PreviewableAsset.cs.meta
Normal file
3
Assets/Scripts/Common/Assets/PreviewableAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a000ba87cd97499eb23feecf39521ecb
|
||||
timeCreated: 1750736840
|
||||
8
Assets/Scripts/Common/Assets/PropAsset.cs
Normal file
8
Assets/Scripts/Common/Assets/PropAsset.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class PropAsset : PreviewableAsset
|
||||
{
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Assets/PropAsset.cs.meta
Normal file
3
Assets/Scripts/Common/Assets/PropAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea4d172189e248949431bb24b98369cb
|
||||
timeCreated: 1743824159
|
||||
113
Assets/Scripts/Common/Assets/ReelAsset.cs
Normal file
113
Assets/Scripts/Common/Assets/ReelAsset.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
/// <summary>
|
||||
/// 线轴资产配置
|
||||
/// </summary>
|
||||
public class ReelAsset : PreviewableAsset
|
||||
{
|
||||
// "previewRotationEnabled": 1,
|
||||
// "previewRotation": {
|
||||
// "x": 20.0,
|
||||
// "y": -130.0,
|
||||
// "z": 190.0
|
||||
// },
|
||||
// "reelType": 3,
|
||||
// "reelSize": 11,
|
||||
// "minLineMeshScale": 0.93,
|
||||
// "maxLineMeshScale": 2.0,
|
||||
// "scaleX": 0,
|
||||
// "scaleY": 1,
|
||||
// "scaleZ": 1,
|
||||
// "rollHandleAnimation": {
|
||||
// "m_FileID": 0,
|
||||
// "m_PathID": 5949981527590265242
|
||||
// },
|
||||
// "rollUkladchikAnimation": {
|
||||
// "m_FileID": 0,
|
||||
// "m_PathID": 8960665928823962917
|
||||
// },
|
||||
// "rollShpulyaAnimation": {
|
||||
// "m_FileID": 0,
|
||||
// "m_PathID": -8671758223453786131
|
||||
// },
|
||||
// "frictionAnimation": {
|
||||
// "m_FileID": 0,
|
||||
// "m_PathID": 0
|
||||
// },
|
||||
// "openAnimation": {
|
||||
// "m_FileID": 0,
|
||||
// "m_PathID": -2998254598457423134
|
||||
// },
|
||||
// "closeAnimation": {
|
||||
// "m_FileID": 0,
|
||||
// "m_PathID": -56605426968450186
|
||||
// },
|
||||
// "startEngineAnimation": {
|
||||
// "m_FileID": 0,
|
||||
// "m_PathID": 0
|
||||
// },
|
||||
// "stopEngineAnimation": {
|
||||
// "m_FileID": 0,
|
||||
// "m_PathID": 0
|
||||
// },
|
||||
// "handleAnimationLoopCycles": 6,
|
||||
// "ikLocatorFixEnabled": 0,
|
||||
// "ikLocatorFixRotation": {
|
||||
// "x": 0.0,
|
||||
// "y": 0.0,
|
||||
// "z": 0.0
|
||||
// },
|
||||
// "shiftRod": 0.0,
|
||||
// "materialWithSerial": {
|
||||
// "m_FileID": 0,
|
||||
// "m_PathID": 0
|
||||
// }
|
||||
|
||||
public enum Type
|
||||
{
|
||||
Normal = 0,
|
||||
Casting = 1
|
||||
}
|
||||
|
||||
public Type type;
|
||||
|
||||
/// <summary>
|
||||
/// 动画组件
|
||||
/// </summary>
|
||||
public Animator animator;
|
||||
|
||||
/// <summary>
|
||||
/// 根连接处
|
||||
/// </summary>
|
||||
public Transform rootConnector;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Transform rootCompensator;
|
||||
|
||||
/// <summary>
|
||||
/// 线连接处
|
||||
/// </summary>
|
||||
public Transform lineConnector;
|
||||
|
||||
/// <summary>
|
||||
/// 线相交处
|
||||
/// </summary>
|
||||
public Transform lineIntersect;
|
||||
|
||||
public Transform lineIntersectHelper;
|
||||
|
||||
/// <summary>
|
||||
/// ik抓握挂点
|
||||
/// </summary>
|
||||
public Transform handle;
|
||||
|
||||
/// <summary>
|
||||
/// 手柄真实结束点
|
||||
/// </summary>
|
||||
public Transform handleEnd;
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Assets/ReelAsset.cs.meta
Normal file
3
Assets/Scripts/Common/Assets/ReelAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8898b66b55404fd3be13b7dcdcfda463
|
||||
timeCreated: 1743785540
|
||||
77
Assets/Scripts/Common/Assets/RodAsset.cs
Normal file
77
Assets/Scripts/Common/Assets/RodAsset.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using RootMotion.FinalIK;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
/// <summary>
|
||||
/// 鱼竿资产配置
|
||||
/// </summary>
|
||||
public class RodAsset : PreviewableAsset
|
||||
{
|
||||
/// <summary>
|
||||
/// 根节点
|
||||
/// </summary>
|
||||
public Transform root;
|
||||
|
||||
public Transform gripEnd;
|
||||
|
||||
/// <summary>
|
||||
/// 左手连接点
|
||||
/// </summary>
|
||||
public Transform LeftHandConnector;
|
||||
|
||||
/// <summary>
|
||||
/// 右手连接点
|
||||
/// </summary>
|
||||
public Transform RightHandConnector;
|
||||
|
||||
/// <summary>
|
||||
/// 线轴连接点
|
||||
/// </summary>
|
||||
public Transform ReelConnector;
|
||||
|
||||
/// <summary>
|
||||
/// 弯曲节点
|
||||
/// </summary>
|
||||
public Transform[] joints;
|
||||
|
||||
/// <summary>
|
||||
/// 圈挂点
|
||||
/// </summary>
|
||||
public Transform[] rings;
|
||||
|
||||
/// <summary>
|
||||
/// rings 画线
|
||||
/// </summary>
|
||||
public LineRenderer lineRenderer;
|
||||
|
||||
/// <summary>
|
||||
/// 鱼线连接点
|
||||
/// </summary>
|
||||
public Transform lineConnector;
|
||||
|
||||
public CCDIK CCDIK;
|
||||
|
||||
|
||||
public Rigidbody LineConnectorRigidbody;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
CCDIK = GetComponent<CCDIK>();
|
||||
CCDIK.enabled = false;
|
||||
if (!lineConnector && joints.Length > 0)
|
||||
{
|
||||
lineConnector = joints[^1];
|
||||
// LineConnectorRigidbody = lineConnector.gameObject.AddComponent<Rigidbody>();
|
||||
// LineConnectorRigidbody.isKinematic = true;
|
||||
// LineConnectorRigidbody.useGravity = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Assets/RodAsset.cs.meta
Normal file
3
Assets/Scripts/Common/Assets/RodAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45b047324a3349b9aea42f50cbd1ba71
|
||||
timeCreated: 1743783252
|
||||
29
Assets/Scripts/Common/Assets/RodRingAsset.cs
Normal file
29
Assets/Scripts/Common/Assets/RodRingAsset.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
/// <summary>
|
||||
/// 鱼竿导环资产配置
|
||||
/// </summary>
|
||||
public class RodRingAsset : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// 导环节点
|
||||
/// </summary>
|
||||
public RodRingNode[] rings;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class RodRingNode
|
||||
{
|
||||
/// <summary>
|
||||
/// 导环点位
|
||||
/// </summary>
|
||||
public Transform ring;
|
||||
|
||||
/// <summary>
|
||||
/// 线挂点
|
||||
/// </summary>
|
||||
public Transform point;
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Assets/RodRingAsset.cs.meta
Normal file
3
Assets/Scripts/Common/Assets/RodRingAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cdfd33eb69534a1e87cd523df4bfb430
|
||||
timeCreated: 1743781816
|
||||
8
Assets/Scripts/Common/Assets/SpinnerLureAsset.cs
Normal file
8
Assets/Scripts/Common/Assets/SpinnerLureAsset.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class SpinnerLureAsset : PreviewableAsset
|
||||
{
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Assets/SpinnerLureAsset.cs.meta
Normal file
3
Assets/Scripts/Common/Assets/SpinnerLureAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed88dcaac7774ce79b04d90a3fa50533
|
||||
timeCreated: 1745487261
|
||||
3
Assets/Scripts/Common/Blur.meta
Normal file
3
Assets/Scripts/Common/Blur.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bedf4887d50d409fb132fee064bc8b37
|
||||
timeCreated: 1770108259
|
||||
25
Assets/Scripts/Common/Blur/TestBlur.cs
Normal file
25
Assets/Scripts/Common/Blur/TestBlur.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace NBF.Blur
|
||||
{
|
||||
public class TestBlur : MonoBehaviour
|
||||
{
|
||||
public RawImage raw;
|
||||
|
||||
public void Test()
|
||||
{
|
||||
Shader.SetGlobalInt("_UIBlurRefresh", 1);
|
||||
|
||||
// var blur = URPRendererFeatureUtil.GetRendererFeature<UIBlurDualKawaseFeature>();
|
||||
// blur?.RefreshOnce();
|
||||
}
|
||||
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
if (!raw) return;
|
||||
raw.texture = Shader.GetGlobalTexture("_UIBlurTexture");
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Blur/TestBlur.cs.meta
Normal file
3
Assets/Scripts/Common/Blur/TestBlur.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d6c5972785cf41e997b1bd6164a04e00
|
||||
timeCreated: 1770108402
|
||||
93
Assets/Scripts/Common/Blur/UIBlur.cs
Normal file
93
Assets/Scripts/Common/Blur/UIBlur.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using FairyGUI;
|
||||
using NBF;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class UIBlur : MonoBehaviour
|
||||
{
|
||||
[Header("Quality")] public RenderTexture blurRT;
|
||||
[Range(1, 6)] public int iterations = 2; // 模糊迭代次数
|
||||
[Range(0.5f, 4f)] public float blurSize = 1.2f;
|
||||
|
||||
[Header("Shader")] public Shader blurShader;
|
||||
|
||||
Material _mat;
|
||||
|
||||
RenderTexture _capturedRT;
|
||||
public static UIBlur Instance { get; private set; }
|
||||
|
||||
void Awake()
|
||||
{
|
||||
blurRT = new RenderTexture((int)(Screen.width * 0.5f), (int)(Screen.height * 0.5f), 0,
|
||||
RenderTextureFormat.ARGB32);
|
||||
_mat = new Material(blurShader);
|
||||
DontDestroyOnLoad(gameObject);
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
public void CaptureAndBlurOnce()
|
||||
{
|
||||
if (blurRT == null) return;
|
||||
var captureCamera = Camera.main;
|
||||
if (captureCamera == null) return;
|
||||
|
||||
|
||||
int w = blurRT.width;
|
||||
int h = blurRT.width;
|
||||
|
||||
ReleaseRTs();
|
||||
|
||||
var oldEnabled = StageCamera.main.enabled;
|
||||
|
||||
StageCamera.main.enabled = false;
|
||||
|
||||
_capturedRT = new RenderTexture(w, h, 0, RenderTextureFormat.ARGB32);
|
||||
_capturedRT.Create();
|
||||
|
||||
// 1) 抓摄像机画面到RT(不做ReadPixels)
|
||||
var prevTarget = captureCamera.targetTexture;
|
||||
captureCamera.targetTexture = _capturedRT;
|
||||
captureCamera.Render();
|
||||
captureCamera.targetTexture = prevTarget;
|
||||
StageCamera.main.enabled = oldEnabled;
|
||||
// 2) 模糊:ping-pong
|
||||
var rt1 = RenderTexture.GetTemporary(w, h, 0, RenderTextureFormat.ARGB32);
|
||||
var rt2 = RenderTexture.GetTemporary(w, h, 0, RenderTextureFormat.ARGB32);
|
||||
|
||||
Graphics.Blit(_capturedRT, rt1);
|
||||
|
||||
_mat.SetFloat("_BlurSize", blurSize);
|
||||
|
||||
for (int i = 0; i < iterations; i++)
|
||||
{
|
||||
// 横向
|
||||
_mat.SetVector("_Direction", new Vector2(1, 0));
|
||||
Graphics.Blit(rt1, rt2, _mat);
|
||||
|
||||
// 纵向
|
||||
_mat.SetVector("_Direction", new Vector2(0, 1));
|
||||
Graphics.Blit(rt2, rt1, _mat);
|
||||
}
|
||||
|
||||
Graphics.Blit(rt1, blurRT);
|
||||
|
||||
RenderTexture.ReleaseTemporary(rt1);
|
||||
RenderTexture.ReleaseTemporary(rt2);
|
||||
}
|
||||
|
||||
void ReleaseRTs()
|
||||
{
|
||||
if (_capturedRT != null)
|
||||
{
|
||||
_capturedRT.Release();
|
||||
Destroy(_capturedRT);
|
||||
_capturedRT = null;
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
ReleaseRTs();
|
||||
if (_mat) Destroy(_mat);
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Blur/UIBlur.cs.meta
Normal file
3
Assets/Scripts/Common/Blur/UIBlur.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a0a734b63534f5e8f244a76a4a8f48d
|
||||
timeCreated: 1770122480
|
||||
179
Assets/Scripts/Common/Blur/UIBlurDualKawaseFeature.cs
Normal file
179
Assets/Scripts/Common/Blur/UIBlurDualKawaseFeature.cs
Normal file
@@ -0,0 +1,179 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
using UnityEngine.Rendering.RenderGraphModule;
|
||||
using UnityEngine.Rendering.RenderGraphModule.Util;
|
||||
|
||||
public class UIBlurDualKawaseFeature : ScriptableRendererFeature
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Settings
|
||||
{
|
||||
public RenderPassEvent passEvent = RenderPassEvent.AfterRenderingTransparents;
|
||||
|
||||
[Range(0.25f, 1f)] public float downscale = 0.5f; // 0.5(中高端) / 0.25(低端更稳)
|
||||
[Range(1, 6)] public int blurPasses = 4; // 3~4 移动端常用
|
||||
[Range(0.5f, 4f)] public float offset = 1.0f; // 糊的“扩散感”
|
||||
|
||||
public bool updateEveryFrame = false; // 推荐 false,只在需要时刷新
|
||||
public string refreshFlagName = "_UIBlurRefresh"; // UI 触发用
|
||||
public string globalTextureName = "_UIBlurTexture";
|
||||
|
||||
public Shader blurShader; // Hidden/URP/DualKawaseBlur
|
||||
}
|
||||
|
||||
public Settings settings = new Settings();
|
||||
|
||||
class Pass : ScriptableRenderPass
|
||||
{
|
||||
readonly Settings s;
|
||||
readonly Material mat;
|
||||
|
||||
// 持久 RT:让 UI 能跨帧拿到(需要 ImportTexture):contentReference[oaicite:2]{index=2}
|
||||
RTHandle persistentOutput;
|
||||
|
||||
static readonly int SourceTexId = Shader.PropertyToID("_SourceTex");
|
||||
static readonly int OffsetId = Shader.PropertyToID("_Offset");
|
||||
|
||||
public Pass(Settings settings, Material material)
|
||||
{
|
||||
s = settings;
|
||||
mat = material;
|
||||
}
|
||||
|
||||
public RTHandle OutputRT => persistentOutput;
|
||||
|
||||
public void EnsureOutput(ref RenderTextureDescriptor desc, int w, int h)
|
||||
{
|
||||
desc.width = w;
|
||||
desc.height = h;
|
||||
desc.depthBufferBits = 0;
|
||||
desc.msaaSamples = 1;
|
||||
desc.useMipMap = false;
|
||||
desc.autoGenerateMips = false;
|
||||
|
||||
RenderingUtils.ReAllocateIfNeeded(
|
||||
ref persistentOutput,
|
||||
desc,
|
||||
FilterMode.Bilinear,
|
||||
TextureWrapMode.Clamp,
|
||||
name: s.globalTextureName
|
||||
);
|
||||
}
|
||||
|
||||
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
|
||||
{
|
||||
// 资源/相机数据(官方示例也是这么取 activeColorTexture):contentReference[oaicite:3]{index=3}
|
||||
var resourceData = frameData.Get<UniversalResourceData>();
|
||||
var cameraData = frameData.Get<UniversalCameraData>();
|
||||
|
||||
// 避免从 backbuffer blit(官方示例也这么做):contentReference[oaicite:4]{index=4}
|
||||
if (resourceData.isActiveTargetBackBuffer)
|
||||
return;
|
||||
|
||||
// 刷新策略:不每帧更新时,只有收到 UI 请求才做一轮
|
||||
if (!s.updateEveryFrame)
|
||||
{
|
||||
if (Shader.GetGlobalInt(s.refreshFlagName) == 0)
|
||||
return;
|
||||
|
||||
Shader.SetGlobalInt(s.refreshFlagName, 0);
|
||||
}
|
||||
|
||||
// 基础描述符(跟相机一致)
|
||||
var desc = cameraData.cameraTargetDescriptor;
|
||||
desc.depthBufferBits = 0;
|
||||
desc.msaaSamples = 1;
|
||||
|
||||
int baseW = Mathf.Max(16, Mathf.RoundToInt(desc.width * s.downscale));
|
||||
int baseH = Mathf.Max(16, Mathf.RoundToInt(desc.height * s.downscale));
|
||||
|
||||
EnsureOutput(ref desc, baseW, baseH);
|
||||
|
||||
// 把持久 RTHandle 导入 RenderGraph(跨帧可用):contentReference[oaicite:5]{index=5}
|
||||
TextureHandle outTex = renderGraph.ImportTexture(persistentOutput);
|
||||
|
||||
// 生成金字塔:0层(base), 1层(/2), 2层(/4)...
|
||||
int n = Mathf.Clamp(s.blurPasses, 1, 8);
|
||||
TextureHandle[] pyr = new TextureHandle[n];
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
int w = Mathf.Max(8, baseW >> i);
|
||||
int h = Mathf.Max(8, baseH >> i);
|
||||
|
||||
var d = desc;
|
||||
d.width = w;
|
||||
d.height = h;
|
||||
pyr[i] = UniversalRenderer.CreateRenderGraphTexture(renderGraph, d, $"_UIBlurPyr{i}", false);
|
||||
}
|
||||
|
||||
mat.SetFloat(OffsetId, s.offset);
|
||||
|
||||
// source:相机颜色
|
||||
TextureHandle src = resourceData.activeColorTexture;
|
||||
|
||||
// Downsample chain (pass 0)
|
||||
{
|
||||
var p = new RenderGraphUtils.BlitMaterialParameters(src, pyr[0], mat, 0);
|
||||
renderGraph.AddBlitPass(p, "UIBlur DualKawase Down 0");
|
||||
}
|
||||
for (int i = 1; i < n; i++)
|
||||
{
|
||||
var p = new RenderGraphUtils.BlitMaterialParameters(pyr[i - 1], pyr[i], mat, 0);
|
||||
renderGraph.AddBlitPass(p, $"UIBlur DualKawase Down {i}");
|
||||
}
|
||||
|
||||
// Upsample chain (pass 1)
|
||||
for (int i = n - 1; i > 0; i--)
|
||||
{
|
||||
var p = new RenderGraphUtils.BlitMaterialParameters(pyr[i], pyr[i - 1], mat, 1);
|
||||
renderGraph.AddBlitPass(p, $"UIBlur DualKawase Up {i}");
|
||||
}
|
||||
|
||||
// 最终写到持久输出 RT
|
||||
{
|
||||
var p = new RenderGraphUtils.BlitMaterialParameters(pyr[0], outTex, mat, 1);
|
||||
renderGraph.AddBlitPass(p, "UIBlur DualKawase Final");
|
||||
}
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
persistentOutput?.Release();
|
||||
persistentOutput = null;
|
||||
}
|
||||
}
|
||||
|
||||
Material _mat;
|
||||
Pass _pass;
|
||||
|
||||
public override void Create()
|
||||
{
|
||||
if (settings.blurShader == null)
|
||||
settings.blurShader = Shader.Find("Hidden/URP/DualKawaseBlur");
|
||||
|
||||
if (settings.blurShader != null)
|
||||
_mat = CoreUtils.CreateEngineMaterial(settings.blurShader);
|
||||
|
||||
_pass = new Pass(settings, _mat) { renderPassEvent = settings.passEvent };
|
||||
}
|
||||
|
||||
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
|
||||
{
|
||||
if (_mat == null) return;
|
||||
if (renderingData.cameraData.cameraType != CameraType.Game) return;
|
||||
|
||||
// 这里提前把全局纹理指向持久 RT(即使本帧不刷新,也能用旧结果)
|
||||
if (_pass.OutputRT != null)
|
||||
Shader.SetGlobalTexture(settings.globalTextureName, _pass.OutputRT);
|
||||
|
||||
renderer.EnqueuePass(_pass);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_pass?.Cleanup();
|
||||
CoreUtils.Destroy(_mat);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d992ccf80d34101a9e62b066d753dc3
|
||||
timeCreated: 1770108262
|
||||
3
Assets/Scripts/Common/Common.meta
Normal file
3
Assets/Scripts/Common/Common.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c8426c4b03da403284afe458076b9c10
|
||||
timeCreated: 1742387508
|
||||
3
Assets/Scripts/Common/Common/Attrobites.meta
Normal file
3
Assets/Scripts/Common/Common/Attrobites.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7cb50811095d496fad57afd7535d0f73
|
||||
timeCreated: 1748180763
|
||||
66
Assets/Scripts/Common/Common/Attrobites/AttributeHelper.cs
Normal file
66
Assets/Scripts/Common/Common/Attrobites/AttributeHelper.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public static class AttributeHelper
|
||||
{
|
||||
// 获取特定嵌套类中带有InputIconAttribute的常量字段
|
||||
public static Dictionary<string, List<FieldInfo>> GetNestedClassInputIconFields()
|
||||
{
|
||||
var result = new Dictionary<string, List<FieldInfo>>();
|
||||
|
||||
// 获取InputDef类型
|
||||
Type inputDefType = typeof(NBF.InputDef);
|
||||
|
||||
// 检查UI类
|
||||
Type uiType = inputDefType.GetNestedType("UI");
|
||||
if (uiType != null)
|
||||
{
|
||||
var uiFields = GetInputIconFieldsFromType(uiType);
|
||||
if (uiFields.Count > 0)
|
||||
{
|
||||
result.Add("UI", uiFields);
|
||||
}
|
||||
}
|
||||
|
||||
// 检查Player类
|
||||
Type playerType = inputDefType.GetNestedType("Player");
|
||||
if (playerType != null)
|
||||
{
|
||||
var playerFields = GetInputIconFieldsFromType(playerType);
|
||||
if (playerFields.Count > 0)
|
||||
{
|
||||
result.Add("Player", playerFields);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 从特定类型获取带有InputIconAttribute的常量字段
|
||||
private static List<FieldInfo> GetInputIconFieldsFromType(Type type)
|
||||
{
|
||||
List<FieldInfo> result = new List<FieldInfo>();
|
||||
|
||||
// 只获取公共常量字段
|
||||
FieldInfo[] fields = type.GetFields(
|
||||
BindingFlags.Public |
|
||||
BindingFlags.Static |
|
||||
BindingFlags.FlattenHierarchy);
|
||||
|
||||
foreach (FieldInfo field in fields)
|
||||
{
|
||||
// 检查是否是常量且带有InputIconAttribute
|
||||
if (field.IsLiteral && !field.IsInitOnly &&
|
||||
Attribute.IsDefined(field, typeof(InputIconAttribute)))
|
||||
{
|
||||
result.Add(field);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa024ae7ea104f809ace6beff59c12d8
|
||||
timeCreated: 1748188551
|
||||
92
Assets/Scripts/Common/Common/Attrobites/Attributes.cs
Normal file
92
Assets/Scripts/Common/Common/Attrobites/Attributes.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public abstract class BaseAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class UIBindAttribute : BaseAttribute
|
||||
{
|
||||
public int Id;
|
||||
|
||||
public UIBindAttribute(int id)
|
||||
{
|
||||
this.Id = id;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class UIExtensionAutoBindAttribute : BaseAttribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class InputIconAttribute : BaseAttribute
|
||||
{
|
||||
public string KeyBoardIcon;
|
||||
public string ControllerIcon;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="keyBoardIcon">键盘图标</param>
|
||||
/// <param name="controllerIcon">控制器图标</param>
|
||||
public InputIconAttribute(string keyBoardIcon, string controllerIcon)
|
||||
{
|
||||
KeyBoardIcon = keyBoardIcon;
|
||||
ControllerIcon = controllerIcon;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Class, AllowMultiple = true)]
|
||||
public class TitleAttribute : BaseAttribute
|
||||
{
|
||||
public string Title;
|
||||
|
||||
public TitleAttribute(string title)
|
||||
{
|
||||
Title = title;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Class, AllowMultiple = true)]
|
||||
public class DescriptionAttribute : BaseAttribute
|
||||
{
|
||||
public string Description;
|
||||
|
||||
public DescriptionAttribute(string description)
|
||||
{
|
||||
Description = description;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Class, AllowMultiple = true)]
|
||||
public class SortAttribute : BaseAttribute
|
||||
{
|
||||
public int Sort;
|
||||
|
||||
public SortAttribute(int sort)
|
||||
{
|
||||
Sort = sort;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class InputInvokeAttribute : BaseAttribute
|
||||
{
|
||||
public string Name;
|
||||
public string Key;
|
||||
public UIInputButtonShowMode Mode;
|
||||
|
||||
public InputInvokeAttribute(string name, UIInputButtonShowMode mode = UIInputButtonShowMode.None,
|
||||
string key = "")
|
||||
{
|
||||
Name = name;
|
||||
Key = key;
|
||||
Mode = mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 647174a4726c4c4c92193aa7dcd3ddad
|
||||
timeCreated: 1748509835
|
||||
83
Assets/Scripts/Common/Common/BaseCamera.cs
Normal file
83
Assets/Scripts/Common/Common/BaseCamera.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using FairyGUI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class BaseCamera : MonoBehaviour
|
||||
{
|
||||
public static Camera Main { get; private set; }
|
||||
|
||||
public static UniversalAdditionalCameraData MainCameraData { get; private set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
#if CINEMACHINE_URP
|
||||
int i = 0;
|
||||
#endif
|
||||
Init();
|
||||
DontDestroyOnLoad(gameObject);
|
||||
DepthOfField dof = ScriptableObject.CreateInstance<DepthOfField>();
|
||||
dof.aperture.value = 0;
|
||||
dof.focalLength.value = 0;
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
Main = GetComponent<Camera>();
|
||||
MainCameraData = Main.GetUniversalAdditionalCameraData();
|
||||
}
|
||||
|
||||
|
||||
private static void FixUICamera()
|
||||
{
|
||||
if (StageCamera.main == null) return;
|
||||
var stageCameraData = StageCamera.main.GetUniversalAdditionalCameraData();
|
||||
if (stageCameraData != null)
|
||||
{
|
||||
if (MainCameraData.cameraStack.Contains(StageCamera.main)) // 防止重复添加
|
||||
{
|
||||
RemoveStack(StageCamera.main);
|
||||
}
|
||||
|
||||
AddStack(StageCamera.main);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetOverlay(Camera camera, UniversalAdditionalCameraData stageCameraData = null)
|
||||
{
|
||||
if (stageCameraData == null)
|
||||
{
|
||||
stageCameraData = camera.GetUniversalAdditionalCameraData();
|
||||
}
|
||||
|
||||
if (stageCameraData != null)
|
||||
{
|
||||
stageCameraData.renderType = CameraRenderType.Overlay;
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddStack(Camera overlayCamera)
|
||||
{
|
||||
if (!MainCameraData.cameraStack.Contains(overlayCamera)) // 防止重复添加
|
||||
{
|
||||
SetOverlay(overlayCamera);
|
||||
MainCameraData.cameraStack.Add(overlayCamera);
|
||||
}
|
||||
|
||||
if (overlayCamera != StageCamera.main)
|
||||
{
|
||||
FixUICamera();
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveStack(Camera overlayCamera)
|
||||
{
|
||||
if (MainCameraData.cameraStack.Contains(overlayCamera))
|
||||
{
|
||||
MainCameraData.cameraStack.Remove(overlayCamera);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Common/BaseCamera.cs.meta
Normal file
3
Assets/Scripts/Common/Common/BaseCamera.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c40f26e5da0a454b93cd5d1e94157699
|
||||
timeCreated: 1742635242
|
||||
3
Assets/Scripts/Common/Common/Enum.meta
Normal file
3
Assets/Scripts/Common/Common/Enum.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef884391e7a4450a9cfc633e1c7a8785
|
||||
timeCreated: 1742999159
|
||||
75
Assets/Scripts/Common/Common/Enum/FishSpecies.cs
Normal file
75
Assets/Scripts/Common/Common/Enum/FishSpecies.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
namespace NBF
|
||||
{
|
||||
public enum FishSpecies
|
||||
{
|
||||
BlackBullhead = 0,
|
||||
Perch = 1,
|
||||
SalmonSockeye = 2,
|
||||
TroutRainbow = 3,
|
||||
BassSmallmouth = 4,
|
||||
PerchYellow = 5,
|
||||
Asp = 6,
|
||||
CommonBarbel = 7,
|
||||
CommonBream = 8,
|
||||
BreamSilver = 9,
|
||||
Burbot = 10,
|
||||
CarpCommon = 11,
|
||||
CarpMirror = 12,
|
||||
CarpSezan = 13,
|
||||
CarpGrass = 14,
|
||||
CarpSilver = 15,
|
||||
CarpCrucian = 16,
|
||||
CarpPrussian = 17,
|
||||
CatfishChannel = 18,
|
||||
CatfishFlathead = 19,
|
||||
CatfishRedtail = 20,
|
||||
CatfishWels = 21,
|
||||
Chub = 22,
|
||||
EuropeanGrayling = 23,
|
||||
Ide = 24,
|
||||
PickerelChain = 25,
|
||||
PickerelGrass = 26,
|
||||
PickerelRedfin = 27,
|
||||
PikeAmur = 28,
|
||||
PikeNorthern = 29,
|
||||
PikeSoutherm = 30,
|
||||
PikeMuskellunge = 31,
|
||||
Roach = 32,
|
||||
Tench = 33,
|
||||
Zander = 34,
|
||||
BassLargemouth = 35,
|
||||
Bluegill = 36,
|
||||
Pumpkinseed = 37,
|
||||
AtlanticSalmon = 38,
|
||||
CommonBleak = 39,
|
||||
Huchen = 40,
|
||||
BrookTrout = 41,
|
||||
BrownTrout = 42,
|
||||
EuropeanBass = 43,
|
||||
AtlanticCod = 44,
|
||||
CrocodileNeedlefish = 45,
|
||||
EuropeanEel = 46,
|
||||
EuropeanFlounder = 47,
|
||||
Garfish = 48,
|
||||
EuropeanSeaSturgeon = 49,
|
||||
SeaTrout = 50,
|
||||
Beluga = 51,
|
||||
BaikalBlackGrayling = 52,
|
||||
ChumSalmon = 53,
|
||||
CohoSalmon = 54,
|
||||
PinkSalmon = 55,
|
||||
BarracudaGreat = 56,
|
||||
BarracudaYellowtail = 57,
|
||||
GrouperGiant = 58,
|
||||
GrouperMalabar = 59,
|
||||
LionfishRed = 60,
|
||||
MahiMahi = 61,
|
||||
SharkBlacktipReef = 62,
|
||||
SharkTiger = 63,
|
||||
SnapperGrey = 64,
|
||||
TreadfishIndian = 65,
|
||||
TrevallyGiant = 66,
|
||||
TunaYellowfin = 67,
|
||||
ZombieBass = 68
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Common/Enum/FishSpecies.cs.meta
Normal file
3
Assets/Scripts/Common/Common/Enum/FishSpecies.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da1c9ef59c57429083f79d8c2a1bec86
|
||||
timeCreated: 1742999162
|
||||
22
Assets/Scripts/Common/Common/Enum/MapUnitState.cs
Normal file
22
Assets/Scripts/Common/Common/Enum/MapUnitState.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace NBF
|
||||
{
|
||||
public enum MapUnitState
|
||||
{
|
||||
idle = 0,
|
||||
move = 1,
|
||||
prepare = 2,
|
||||
casting = 3,
|
||||
fishing = 4,
|
||||
baitFlies = 5,
|
||||
fight = 6,
|
||||
fishView = 7,
|
||||
collectFish = 8,
|
||||
throwFish = 9,
|
||||
vehicle = 10,
|
||||
swiming = 11,
|
||||
flyModeDebug = 12,
|
||||
vehicleFishing = 13,
|
||||
preciseCastIdle = 14,
|
||||
preciseCastThrow = 15
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Common/Enum/MapUnitState.cs.meta
Normal file
3
Assets/Scripts/Common/Common/Enum/MapUnitState.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a25ab9f9b4140c7bd3e463da484301e
|
||||
timeCreated: 1765284104
|
||||
3
Assets/Scripts/Common/Common/Input.meta
Normal file
3
Assets/Scripts/Common/Common/Input.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1977fd60c4b24f33bc4143aaed9fba8a
|
||||
timeCreated: 1755792367
|
||||
10
Assets/Scripts/Common/Common/Input/InteractiveObject.cs
Normal file
10
Assets/Scripts/Common/Common/Input/InteractiveObject.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class InteractiveObject : MonoBehaviour
|
||||
{
|
||||
[Header("交互类型")] public UIDef.InteractiveType Type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa29ad8321da4a29a6fb475e9e97f87e
|
||||
timeCreated: 1747577976
|
||||
2773
Assets/Scripts/Common/Common/Input/PlayerInputControl.cs
Normal file
2773
Assets/Scripts/Common/Common/Input/PlayerInputControl.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cdaa795bad2ccc34faab0c9036785b02
|
||||
249
Assets/Scripts/Common/Common/Outline.cs
Normal file
249
Assets/Scripts/Common/Common/Outline.cs
Normal file
@@ -0,0 +1,249 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
[DisallowMultipleComponent]
|
||||
public class Outline : MonoBehaviour
|
||||
{
|
||||
public enum Mode
|
||||
{
|
||||
OutlineAll = 0,
|
||||
OutlineVisible = 1,
|
||||
OutlineHidden = 2,
|
||||
OutlineAndSilhouette = 3,
|
||||
SilhouetteOnly = 4
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
private class ListVector3
|
||||
{
|
||||
public List<Vector3> data;
|
||||
}
|
||||
|
||||
private static HashSet<Mesh> registeredMeshes = new HashSet<Mesh>();
|
||||
|
||||
[SerializeField] private Mode outlineMode;
|
||||
|
||||
[SerializeField] private Color outlineColor = Color.white;
|
||||
|
||||
[SerializeField] [Range(0f, 10f)] private float outlineWidth = 2f;
|
||||
|
||||
[Header("Optional")]
|
||||
[SerializeField]
|
||||
[Tooltip(
|
||||
"Precompute enabled: Per-vertex calculations are performed in the editor and serialized with the object. Precompute disabled: Per-vertex calculations are performed at runtime in Awake(). This may cause a pause for large meshes.")]
|
||||
private bool precomputeOutline;
|
||||
|
||||
[SerializeField] [HideInInspector] private List<Mesh> bakeKeys = new List<Mesh>();
|
||||
|
||||
[SerializeField] [HideInInspector] private List<ListVector3> bakeValues = new List<ListVector3>();
|
||||
|
||||
private Renderer[] renderers;
|
||||
|
||||
private Material outlineMaskMaterial;
|
||||
|
||||
private Material outlineFillMaterial;
|
||||
|
||||
private bool needsUpdate;
|
||||
|
||||
public Mode OutlineMode
|
||||
{
|
||||
get { return outlineMode; }
|
||||
set
|
||||
{
|
||||
outlineMode = value;
|
||||
needsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
public Color OutlineColor
|
||||
{
|
||||
get { return outlineColor; }
|
||||
set
|
||||
{
|
||||
outlineColor = value;
|
||||
needsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
public float OutlineWidth
|
||||
{
|
||||
get { return outlineWidth; }
|
||||
set
|
||||
{
|
||||
outlineWidth = value;
|
||||
needsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
renderers = GetComponentsInChildren<Renderer>();
|
||||
outlineMaskMaterial = Instantiate(Resources.Load<Material>("Materials/OutlineMask"));
|
||||
outlineFillMaterial = Instantiate(Resources.Load<Material>("Materials/OutlineFill"));
|
||||
outlineMaskMaterial.name = "OutlineMask (Instance)";
|
||||
outlineFillMaterial.name = "OutlineFill (Instance)";
|
||||
LoadSmoothNormals();
|
||||
needsUpdate = true;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
Renderer[] array = renderers;
|
||||
foreach (Renderer obj in array)
|
||||
{
|
||||
List<Material> list = Enumerable.ToList(obj.sharedMaterials);
|
||||
list.Add(outlineMaskMaterial);
|
||||
list.Add(outlineFillMaterial);
|
||||
obj.materials = list.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
needsUpdate = true;
|
||||
if ((!precomputeOutline && bakeKeys.Count != 0) || bakeKeys.Count != bakeValues.Count)
|
||||
{
|
||||
bakeKeys.Clear();
|
||||
bakeValues.Clear();
|
||||
}
|
||||
|
||||
if (precomputeOutline && bakeKeys.Count == 0)
|
||||
{
|
||||
Bake();
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (needsUpdate)
|
||||
{
|
||||
needsUpdate = false;
|
||||
UpdateMaterialProperties();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
Renderer[] array = renderers;
|
||||
foreach (Renderer obj in array)
|
||||
{
|
||||
List<Material> list = Enumerable.ToList(obj.sharedMaterials);
|
||||
list.Remove(outlineMaskMaterial);
|
||||
list.Remove(outlineFillMaterial);
|
||||
obj.materials = list.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
Destroy(outlineMaskMaterial);
|
||||
Destroy(outlineFillMaterial);
|
||||
}
|
||||
|
||||
private void Bake()
|
||||
{
|
||||
HashSet<Mesh> hashSet = new HashSet<Mesh>();
|
||||
MeshFilter[] componentsInChildren = GetComponentsInChildren<MeshFilter>();
|
||||
foreach (MeshFilter meshFilter in componentsInChildren)
|
||||
{
|
||||
if (hashSet.Add(meshFilter.sharedMesh))
|
||||
{
|
||||
List<Vector3> data = SmoothNormals(meshFilter.sharedMesh);
|
||||
bakeKeys.Add(meshFilter.sharedMesh);
|
||||
bakeValues.Add(new ListVector3
|
||||
{
|
||||
data = data
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadSmoothNormals()
|
||||
{
|
||||
MeshFilter[] componentsInChildren = GetComponentsInChildren<MeshFilter>();
|
||||
foreach (MeshFilter meshFilter in componentsInChildren)
|
||||
{
|
||||
if (registeredMeshes.Add(meshFilter.sharedMesh))
|
||||
{
|
||||
int num = bakeKeys.IndexOf(meshFilter.sharedMesh);
|
||||
List<Vector3> uvs = ((num >= 0) ? bakeValues[num].data : SmoothNormals(meshFilter.sharedMesh));
|
||||
meshFilter.sharedMesh.SetUVs(3, uvs);
|
||||
}
|
||||
}
|
||||
|
||||
SkinnedMeshRenderer[] componentsInChildren2 = GetComponentsInChildren<SkinnedMeshRenderer>();
|
||||
foreach (SkinnedMeshRenderer skinnedMeshRenderer in componentsInChildren2)
|
||||
{
|
||||
if (registeredMeshes.Add(skinnedMeshRenderer.sharedMesh))
|
||||
{
|
||||
skinnedMeshRenderer.sharedMesh.uv4 = new Vector2[skinnedMeshRenderer.sharedMesh.vertexCount];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Vector3> SmoothNormals(Mesh mesh)
|
||||
{
|
||||
IEnumerable<IGrouping<Vector3, KeyValuePair<Vector3, int>>> enumerable =
|
||||
Enumerable.GroupBy(
|
||||
Enumerable.Select(mesh.vertices,
|
||||
(Vector3 vertex, int index) => new KeyValuePair<Vector3, int>(vertex, index)),
|
||||
(KeyValuePair<Vector3, int> pair) => pair.Key);
|
||||
List<Vector3> list = new List<Vector3>(mesh.normals);
|
||||
foreach (IGrouping<Vector3, KeyValuePair<Vector3, int>> item in enumerable)
|
||||
{
|
||||
if (Enumerable.Count(item) == 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector3 zero = Vector3.zero;
|
||||
foreach (KeyValuePair<Vector3, int> item2 in item)
|
||||
{
|
||||
zero += mesh.normals[item2.Value];
|
||||
}
|
||||
|
||||
zero.Normalize();
|
||||
foreach (KeyValuePair<Vector3, int> item3 in item)
|
||||
{
|
||||
list[item3.Value] = zero;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private void UpdateMaterialProperties()
|
||||
{
|
||||
outlineFillMaterial.SetColor("_OutlineColor", outlineColor);
|
||||
switch (outlineMode)
|
||||
{
|
||||
case Mode.OutlineAll:
|
||||
outlineMaskMaterial.SetFloat("_ZTest", 8f);
|
||||
outlineFillMaterial.SetFloat("_ZTest", 8f);
|
||||
outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
|
||||
break;
|
||||
case Mode.OutlineVisible:
|
||||
outlineMaskMaterial.SetFloat("_ZTest", 8f);
|
||||
outlineFillMaterial.SetFloat("_ZTest", 4f);
|
||||
outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
|
||||
break;
|
||||
case Mode.OutlineHidden:
|
||||
outlineMaskMaterial.SetFloat("_ZTest", 8f);
|
||||
outlineFillMaterial.SetFloat("_ZTest", 5f);
|
||||
outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
|
||||
break;
|
||||
case Mode.OutlineAndSilhouette:
|
||||
outlineMaskMaterial.SetFloat("_ZTest", 4f);
|
||||
outlineFillMaterial.SetFloat("_ZTest", 8f);
|
||||
outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
|
||||
break;
|
||||
case Mode.SilhouetteOnly:
|
||||
outlineMaskMaterial.SetFloat("_ZTest", 4f);
|
||||
outlineFillMaterial.SetFloat("_ZTest", 5f);
|
||||
outlineFillMaterial.SetFloat("_OutlineWidth", 0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Common/Outline.cs.meta
Normal file
3
Assets/Scripts/Common/Common/Outline.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 944328972a42400fa3fa1289ba2a1e2e
|
||||
timeCreated: 1742387511
|
||||
30
Assets/Scripts/Common/Common/PermanentCommon.cs
Normal file
30
Assets/Scripts/Common/Common/PermanentCommon.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using NBC;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
/// <summary>
|
||||
/// 常驻公共脚本
|
||||
/// </summary>
|
||||
public class PermanentCommon
|
||||
{
|
||||
private static bool _init;
|
||||
private static PermanentCommon _inst;
|
||||
|
||||
public static PermanentCommon Inst
|
||||
{
|
||||
get { return _inst ??= new PermanentCommon(); }
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
if (_init) return;
|
||||
_init = true;
|
||||
}
|
||||
|
||||
public static void Dispose()
|
||||
{
|
||||
_init = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/Common/PermanentCommon.cs.meta
Normal file
3
Assets/Scripts/Common/Common/PermanentCommon.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3816467cfd1648e685a33ebfd1d9fb7d
|
||||
timeCreated: 1748184924
|
||||
3
Assets/Scripts/Common/Common/Services.meta
Normal file
3
Assets/Scripts/Common/Common/Services.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 011d59a9e9454122bc76461e942de184
|
||||
timeCreated: 1748489400
|
||||
3
Assets/Scripts/Common/Common/Services/Camera.meta
Normal file
3
Assets/Scripts/Common/Common/Services/Camera.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4049be1823c447dd941297033391e07a
|
||||
timeCreated: 1766472832
|
||||
12
Assets/Scripts/Common/Common/Services/Camera/CameraAsset.cs
Normal file
12
Assets/Scripts/Common/Common/Services/Camera/CameraAsset.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Cinemachine;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class CameraAsset : MonoBehaviour
|
||||
{
|
||||
public CinemachineVirtualCamera fppVCam;
|
||||
|
||||
public CinemachineVirtualCamera tppVCam;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5dd3e6b2217c463e94e32f15c4ea3c5c
|
||||
timeCreated: 1765306413
|
||||
@@ -0,0 +1,69 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public enum CameraShowMode
|
||||
{
|
||||
None = 0,
|
||||
FPP,
|
||||
TPP,
|
||||
}
|
||||
|
||||
public class CameraManager : MonoService<CameraManager>
|
||||
{
|
||||
public CameraShowMode Mode = CameraShowMode.None;
|
||||
|
||||
[SerializeField] private CameraAsset _cameraAsset;
|
||||
private CameraShowMode _lastMode = CameraShowMode.None;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (_lastMode == Mode) return;
|
||||
if (Mode == CameraShowMode.TPP)
|
||||
{
|
||||
//第三人称视角
|
||||
SetTPPCam();
|
||||
}
|
||||
else if (Mode == CameraShowMode.FPP)
|
||||
{
|
||||
//第一人称视角
|
||||
SetFPPCam();
|
||||
}
|
||||
|
||||
_lastMode = Mode;
|
||||
}
|
||||
|
||||
|
||||
private void SetTPPCam()
|
||||
{
|
||||
_cameraAsset.fppVCam.Priority = 0;
|
||||
_cameraAsset.tppVCam.Priority = 10;
|
||||
}
|
||||
|
||||
private void SetFPPCam()
|
||||
{
|
||||
var player = FPlayer.Instance;
|
||||
if (player != null)
|
||||
{
|
||||
_cameraAsset.fppVCam.LookAt = player.FppLook;
|
||||
_cameraAsset.fppVCam.Follow = player.ModelAsset.NeckTransform;
|
||||
}
|
||||
|
||||
_cameraAsset.fppVCam.Priority = 10;
|
||||
_cameraAsset.tppVCam.Priority = 0;
|
||||
// StartCoroutine(SnapToTarget());
|
||||
}
|
||||
|
||||
public void SetFppLook(Transform fppCamLook)
|
||||
{
|
||||
_cameraAsset.fppVCam.LookAt = fppCamLook;
|
||||
}
|
||||
|
||||
public void SetFppFollow(Transform fppCamFollow)
|
||||
{
|
||||
_cameraAsset.fppVCam.Follow = fppCamFollow;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1115c38f55a6434ba8ab2de810f955be
|
||||
timeCreated: 1766472617
|
||||
3
Assets/Scripts/Common/Common/Services/Input.meta
Normal file
3
Assets/Scripts/Common/Common/Services/Input.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d846463d130b4191a5a4a9d2e2dfe45b
|
||||
timeCreated: 1748180579
|
||||
@@ -0,0 +1,46 @@
|
||||
using NBC;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public static class InputCursorExtension
|
||||
{
|
||||
public static void InputInit()
|
||||
{
|
||||
UI.Inst.On(UIEvents.UIShow, UIShow, null, 1);
|
||||
UI.Inst.On(UIEvents.UIHide, UIHide, null, 1);
|
||||
}
|
||||
|
||||
public static void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
private static void UIShow(EventArgs ev)
|
||||
{
|
||||
CheckUICursor();
|
||||
}
|
||||
|
||||
private static void UIHide(EventArgs ev)
|
||||
{
|
||||
CheckUICursor();
|
||||
}
|
||||
|
||||
|
||||
private static void CheckUICursor()
|
||||
{
|
||||
var uis = UI.Inst.GetAllUI();
|
||||
bool showCursor = false;
|
||||
foreach (var ui in uis)
|
||||
{
|
||||
if (!ui.IsShowing) continue;
|
||||
if (ui.IsShowCursor)
|
||||
{
|
||||
showCursor = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Log.Info($"showCursor={showCursor}");
|
||||
InputManager.IsUIStopInput = showCursor;
|
||||
InputManager.SetMouseCursor(showCursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79ba55353f994d4e947699ffd0f12751
|
||||
timeCreated: 1766410875
|
||||
43
Assets/Scripts/Common/Common/Services/Input/InputIconData.cs
Normal file
43
Assets/Scripts/Common/Common/Services/Input/InputIconData.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
using NBC;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class InputIconData
|
||||
{
|
||||
public string MapName;
|
||||
public Dictionary<string, string> KeyboardIcons = new Dictionary<string, string>();
|
||||
|
||||
public string GetIcon(string actionName)
|
||||
{
|
||||
if (KeyboardIcons.TryGetValue(actionName, out var keyboardIcon))
|
||||
{
|
||||
return keyboardIcon;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public void CacheInputActionIcons(ReadOnlyArray<InputAction> actions)
|
||||
{
|
||||
KeyboardIcons.Clear();
|
||||
foreach (var inputAction in actions)
|
||||
{
|
||||
foreach (var binding in inputAction.bindings)
|
||||
{
|
||||
var path = binding.effectivePath.Replace("<", "").Replace(">", "").Replace("/", "_");
|
||||
if (path.Contains("Keyboard") || path.Contains("keyboard"))
|
||||
{
|
||||
path = path.Replace("Keyboard", "keyboard");
|
||||
KeyboardIcons.TryAdd(inputAction.name, path);
|
||||
|
||||
Log.Info($"ActionIcons {inputAction.name}={path}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6eb3efcd3474440ea2c7d6549db02c4c
|
||||
timeCreated: 1770015242
|
||||
383
Assets/Scripts/Common/Common/Services/Input/InputManager.cs
Normal file
383
Assets/Scripts/Common/Common/Services/Input/InputManager.cs
Normal file
@@ -0,0 +1,383 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using FairyGUI;
|
||||
using NBC;
|
||||
// using Rewired;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public enum ControllerType
|
||||
{
|
||||
KeyboardMouse = 0,
|
||||
GamePad = 1
|
||||
}
|
||||
|
||||
public enum UIInputButtonShowMode
|
||||
{
|
||||
None,
|
||||
MenuLeft,
|
||||
MenuRight,
|
||||
SubMenuLeft,
|
||||
SubMenuRight,
|
||||
BottomLeft,
|
||||
BottomRight,
|
||||
}
|
||||
|
||||
public class UIInputInvoke
|
||||
{
|
||||
public object UIObject;
|
||||
public InputInvokeAttribute InputInvoke;
|
||||
public MethodInfo MethodInfo;
|
||||
}
|
||||
|
||||
public class InputManager : MonoService<InputManager>
|
||||
{
|
||||
public static bool IsOp1;
|
||||
public static bool IsOp2;
|
||||
|
||||
|
||||
public const string InputMapUI = "UI";
|
||||
public const string InputMapPlayer = "Player";
|
||||
|
||||
public static event Action<bool> OnOp1Action;
|
||||
public static event Action<bool> OnOp2Action;
|
||||
|
||||
/// <summary>
|
||||
/// 执行输入事件
|
||||
/// </summary>
|
||||
public static event Action<string> OnUIPerformed;
|
||||
|
||||
/// <summary>
|
||||
/// 执行输入事件完毕
|
||||
/// </summary>
|
||||
public static event Action<string> OnUICanceled;
|
||||
|
||||
/// <summary>
|
||||
/// 执行输入事件
|
||||
/// </summary>
|
||||
public static event Action<string> OnPlayerPerformed;
|
||||
|
||||
/// <summary>
|
||||
/// 执行输入事件完毕
|
||||
/// </summary>
|
||||
public static event Action<string> OnPlayerCanceled;
|
||||
|
||||
/// <summary>
|
||||
/// 执行输入事件
|
||||
/// </summary>
|
||||
public static event Action<InputAction.CallbackContext> OnPlayerValuePerformed;
|
||||
|
||||
/// <summary>
|
||||
/// 执行输入事件完毕
|
||||
/// </summary>
|
||||
public static event Action<InputAction.CallbackContext> OnPlayerValueCanceled;
|
||||
|
||||
/// <summary>
|
||||
/// 触发交互游戏对象
|
||||
/// </summary>
|
||||
public static event Action<InteractiveObject> OnInteractiveObjectAction;
|
||||
|
||||
public static event Action OnUIInvokeChange;
|
||||
|
||||
|
||||
public static PlayerInputControl PlayerInputControl { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 手柄输入
|
||||
/// </summary>
|
||||
public static bool IsControllerInput;
|
||||
|
||||
/// <summary>
|
||||
/// ui阻止游戏输入
|
||||
/// </summary>
|
||||
public static bool IsUIStopInput;
|
||||
|
||||
public static ControllerType ControllerType = ControllerType.KeyboardMouse;
|
||||
|
||||
|
||||
private InputActionMap _uiInputActionMap;
|
||||
|
||||
protected override void OnAwake()
|
||||
{
|
||||
InputCursorExtension.InputInit();
|
||||
DontDestroyOnLoad(gameObject);
|
||||
PlayerInputControl = new PlayerInputControl();
|
||||
PlayerInputControl.Enable();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
AddEvent();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
RemoveEvent();
|
||||
InputCursorExtension.Dispose();
|
||||
}
|
||||
|
||||
|
||||
public static void SetMouseCursor(bool val)
|
||||
{
|
||||
if (val)
|
||||
{
|
||||
if (ControllerType == ControllerType.KeyboardMouse)
|
||||
{
|
||||
Cursor.visible = true;
|
||||
}
|
||||
|
||||
Cursor.lockState = CursorLockMode.None;
|
||||
}
|
||||
else if (ControllerType == ControllerType.KeyboardMouse)
|
||||
{
|
||||
Cursor.visible = false;
|
||||
}
|
||||
|
||||
Cursor.visible = val;
|
||||
if (!val)
|
||||
{
|
||||
Cursor.lockState = CursorLockMode.Confined;
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector2 GetMovementInput()
|
||||
{
|
||||
if (IsUIStopInput) return Vector2.zero;
|
||||
return PlayerInputControl.Player.Move?.ReadValue<Vector2>() ?? Vector2.zero;
|
||||
}
|
||||
|
||||
public static Vector2 GetLookInput()
|
||||
{
|
||||
if (IsUIStopInput) return Vector2.zero;
|
||||
return PlayerInputControl.Player.Look?.ReadValue<Vector2>() ?? Vector2.zero;
|
||||
}
|
||||
|
||||
|
||||
private void AddEvent()
|
||||
{
|
||||
CacheInputActionIcons(PlayerInputControl.asset.actionMaps);
|
||||
foreach (var actionMap in PlayerInputControl.asset.actionMaps)
|
||||
{
|
||||
actionMap.Enable();
|
||||
if (actionMap.name == InputMapUI)
|
||||
{
|
||||
_uiInputActionMap = actionMap;
|
||||
foreach (var action in actionMap.actions)
|
||||
{
|
||||
if (action.type == InputActionType.Button)
|
||||
{
|
||||
action.performed += OnUIButtonPerformed;
|
||||
action.canceled += OnUIButtonCanceled;
|
||||
}
|
||||
|
||||
//var fileName = binding.effectivePath.Replace("<", "").Replace(">", "").Replace("/", "_");
|
||||
}
|
||||
}
|
||||
else if (actionMap.name == InputMapPlayer)
|
||||
{
|
||||
foreach (var action in actionMap.actions)
|
||||
{
|
||||
if (action.type == InputActionType.Button)
|
||||
{
|
||||
action.performed += OnPlayerButtonPerformed;
|
||||
action.canceled += OnPlayerButtonCanceled;
|
||||
}
|
||||
else if (action.type == InputActionType.Value)
|
||||
{
|
||||
action.performed += OnInputPlayerValuePerformed;
|
||||
action.canceled += OnInputPlayerValueCanceled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveEvent()
|
||||
{
|
||||
OnUIPerformed = null;
|
||||
OnUICanceled = null;
|
||||
OnPlayerPerformed = null;
|
||||
OnPlayerCanceled = null;
|
||||
}
|
||||
|
||||
private void OnUIButtonPerformed(InputAction.CallbackContext context)
|
||||
{
|
||||
OnUIPerformed?.Invoke(context.action.name);
|
||||
}
|
||||
|
||||
private void OnUIButtonCanceled(InputAction.CallbackContext context)
|
||||
{
|
||||
OnUICanceled?.Invoke(context.action.name);
|
||||
InvokeUIInput(context.action.name);
|
||||
}
|
||||
|
||||
private void OnPlayerButtonPerformed(InputAction.CallbackContext context)
|
||||
{
|
||||
if (IsUIStopInput) return;
|
||||
var actionName = context.action.name;
|
||||
if (actionName == "Op1")
|
||||
{
|
||||
IsOp1 = true;
|
||||
OnOp1Action?.Invoke(true);
|
||||
}
|
||||
else if (actionName == "Op2")
|
||||
{
|
||||
OnOp2Action?.Invoke(true);
|
||||
}
|
||||
|
||||
OnPlayerPerformed?.Invoke(actionName);
|
||||
}
|
||||
|
||||
private void OnPlayerButtonCanceled(InputAction.CallbackContext context)
|
||||
{
|
||||
if (IsUIStopInput) return;
|
||||
var actionName = context.action.name;
|
||||
if (actionName == "Op1")
|
||||
{
|
||||
IsOp1 = false;
|
||||
OnOp1Action?.Invoke(false);
|
||||
}
|
||||
else if (actionName == "Op2")
|
||||
{
|
||||
OnOp2Action?.Invoke(false);
|
||||
}
|
||||
|
||||
OnPlayerCanceled?.Invoke(actionName);
|
||||
}
|
||||
|
||||
private void OnInputPlayerValuePerformed(InputAction.CallbackContext context)
|
||||
{
|
||||
if (IsUIStopInput) return;
|
||||
OnPlayerValuePerformed?.Invoke(context);
|
||||
}
|
||||
|
||||
private void OnInputPlayerValueCanceled(InputAction.CallbackContext context)
|
||||
{
|
||||
if (IsUIStopInput) return;
|
||||
OnPlayerValueCanceled?.Invoke(context);
|
||||
}
|
||||
|
||||
|
||||
public void OnInteractiveObject(InteractiveObject interactiveObject)
|
||||
{
|
||||
Debug.LogError($"OnInteractiveObject {interactiveObject != null}");
|
||||
OnInteractiveObjectAction?.Invoke(interactiveObject);
|
||||
}
|
||||
|
||||
public void SendUIInput(string actionName)
|
||||
{
|
||||
OnUIPerformed?.Invoke(actionName);
|
||||
OnUICanceled?.Invoke(actionName);
|
||||
InvokeUIInput(actionName);
|
||||
}
|
||||
|
||||
#region UI界面按键管理
|
||||
|
||||
private readonly Dictionary<object, List<UIInputInvoke>> _panelActions =
|
||||
new Dictionary<object, List<UIInputInvoke>>();
|
||||
|
||||
// private Dictionary<string, string> _keyboardIcons = new Dictionary<string, string>();
|
||||
|
||||
private Dictionary<string, InputIconData> InputIconData = new Dictionary<string, InputIconData>();
|
||||
|
||||
public void On(object obj)
|
||||
{
|
||||
var ms = Reflection.GetMethodsAttribute<InputInvokeAttribute>(obj.GetType());
|
||||
List<UIInputInvoke> inputInvokes = new List<UIInputInvoke>();
|
||||
foreach (var kv in ms)
|
||||
{
|
||||
var invokeData = new UIInputInvoke()
|
||||
{
|
||||
MethodInfo = kv.Key,
|
||||
UIObject = obj,
|
||||
InputInvoke = kv.Value
|
||||
};
|
||||
inputInvokes.Add(invokeData);
|
||||
}
|
||||
|
||||
if (inputInvokes.Count > 0)
|
||||
{
|
||||
_panelActions[obj] = inputInvokes;
|
||||
}
|
||||
|
||||
OnUIInvokeChange?.Invoke();
|
||||
}
|
||||
|
||||
public void Off(object obj)
|
||||
{
|
||||
_panelActions.Remove(obj, out List<UIInputInvoke> inputInvokes);
|
||||
OnUIInvokeChange?.Invoke();
|
||||
}
|
||||
|
||||
|
||||
public void InvokeUIInput(string actionName)
|
||||
{
|
||||
foreach (var obj in _panelActions.Keys)
|
||||
{
|
||||
var invokes = _panelActions[obj];
|
||||
foreach (var uiInputInvoke in invokes)
|
||||
{
|
||||
if (uiInputInvoke.InputInvoke.Name != actionName) continue;
|
||||
if (uiInputInvoke.UIObject is IUIPanel panel)
|
||||
{
|
||||
if (!panel.IsShowing) continue;
|
||||
if (!panel.IsTop) continue;
|
||||
}
|
||||
else if (uiInputInvoke.UIObject is GObject gObject)
|
||||
{
|
||||
if (!gObject.visible) continue;
|
||||
}
|
||||
|
||||
uiInputInvoke.MethodInfo.Invoke(uiInputInvoke.UIObject, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<UIInputInvoke> GetUsableInvokes()
|
||||
{
|
||||
List<UIInputInvoke> ret = new List<UIInputInvoke>();
|
||||
|
||||
foreach (var keyValuePair in _panelActions.Values)
|
||||
{
|
||||
foreach (var uiInputInvoke in keyValuePair)
|
||||
{
|
||||
if (uiInputInvoke.UIObject is IUIPanel { IsTop: true })
|
||||
{
|
||||
ret.Add(uiInputInvoke);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public string GetInputIcon(string map, string actionName)
|
||||
{
|
||||
if (InputIconData.TryGetValue(map, out var data))
|
||||
{
|
||||
return data.GetIcon(actionName);
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
private void CacheInputActionIcons(ReadOnlyArray<InputActionMap> actionMaps)
|
||||
{
|
||||
foreach (var actionMap in actionMaps)
|
||||
{
|
||||
var data = new InputIconData();
|
||||
data.CacheInputActionIcons(actionMap.actions);
|
||||
InputIconData[actionMap.name] = data;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2101c084ab66498bb634f122db410852
|
||||
timeCreated: 1766410867
|
||||
24
Assets/Scripts/Common/Common/Services/MonoService.cs
Normal file
24
Assets/Scripts/Common/Common/Services/MonoService.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using NBC;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public abstract class MonoService : MonoBehaviour
|
||||
{
|
||||
}
|
||||
|
||||
public abstract class MonoService<T> : MonoService where T : MonoService
|
||||
{
|
||||
public static T Instance { get; private set; }
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
Instance = this as T;
|
||||
OnAwake();
|
||||
}
|
||||
|
||||
protected virtual void OnAwake()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 62c58708f36041db9bb11a7e4d16c62c
|
||||
timeCreated: 1748491579
|
||||
3
Assets/Scripts/Common/Common/Services/Preview.meta
Normal file
3
Assets/Scripts/Common/Common/Services/Preview.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65341d2b856a4aef82e238b10798b430
|
||||
timeCreated: 1771091754
|
||||
@@ -0,0 +1,15 @@
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class PreviewManager : MonoService<PreviewManager>
|
||||
{
|
||||
private Scene _scene;
|
||||
|
||||
protected override void OnAwake()
|
||||
{
|
||||
_scene = SceneManager.CreateScene("RuntimePreviewScene",
|
||||
new CreateSceneParameters(LocalPhysicsMode.None));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3ee9b922c69484282c9080842cb1d02
|
||||
timeCreated: 1771091765
|
||||
3
Assets/Scripts/Common/Common/Services/Settings.meta
Normal file
3
Assets/Scripts/Common/Common/Services/Settings.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6111c0ab89e74c9fada884e4e4051549
|
||||
timeCreated: 1748489421
|
||||
3
Assets/Scripts/Common/Common/Services/Settings/Base.meta
Normal file
3
Assets/Scripts/Common/Common/Services/Settings/Base.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c12ca701ad9f433d9e6e7eaf04f507d0
|
||||
timeCreated: 1748570535
|
||||
@@ -0,0 +1,18 @@
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace NBF.Setting
|
||||
{
|
||||
public abstract class ControllerInputOption : InputOption
|
||||
{
|
||||
protected override bool IsBindingContains(InputBinding binding)
|
||||
{
|
||||
var path = binding.path;
|
||||
if (path.Contains("<Keyboard>") || path.Contains("<Mouse>"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3ed7d01cac8436fb64fef818e33f173
|
||||
timeCreated: 1770998136
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace NBF.Setting
|
||||
{
|
||||
public abstract class ControllerOption : OptionBase
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75e11d5298cd48718d39a3e2af82472f
|
||||
timeCreated: 1749634909
|
||||
@@ -0,0 +1,18 @@
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace NBF.Setting
|
||||
{
|
||||
public abstract class GamepadOption : InputOption
|
||||
{
|
||||
protected override bool IsBindingContains(InputBinding binding)
|
||||
{
|
||||
var path = binding.path;
|
||||
if (path.Contains("<Gamepad>"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49041e6a08b744038368d7010acf61ea
|
||||
timeCreated: 1750408186
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using NBF.Setting;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public interface ISettings
|
||||
{
|
||||
List<OptionBase> GetOptionsByTab(string group);
|
||||
IEnumerable<string> GetAllTabs();
|
||||
T GetSettingOption<T>() where T : OptionBase;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2cb28b8c7664cc28fe0b0a0a4516704
|
||||
timeCreated: 1748678126
|
||||
@@ -0,0 +1,96 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace NBF.Setting
|
||||
{
|
||||
public abstract class InputOption : OptionBase
|
||||
{
|
||||
private int _bindingIndex = 0;
|
||||
public abstract InputAction InputAction { get; }
|
||||
|
||||
public int BindingIndex => _bindingIndex;
|
||||
|
||||
protected override int DefaultValue => 0;
|
||||
|
||||
/// <summary>
|
||||
/// 保存的值
|
||||
/// </summary>
|
||||
protected string InputSaveValue;
|
||||
|
||||
public override bool HaveNotApple()
|
||||
{
|
||||
return !InputAction.SaveBindingOverridesAsJson().Equals(InputSaveValue);
|
||||
}
|
||||
|
||||
public override void Apply()
|
||||
{
|
||||
// 保存绑定
|
||||
InputSaveValue = InputAction.SaveBindingOverridesAsJson();
|
||||
PlayerPrefs.SetString(SaveKey, InputSaveValue);
|
||||
OnApply();
|
||||
}
|
||||
|
||||
public override void Load()
|
||||
{
|
||||
for (int i = 0; i < InputAction.bindings.Count; i++)
|
||||
{
|
||||
var binding = InputAction.bindings[i];
|
||||
if (IsBindingContains(binding))
|
||||
{
|
||||
_bindingIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var value = PlayerPrefs.GetString(SaveKey, string.Empty);
|
||||
InputSaveValue = value;
|
||||
if (!string.IsNullOrEmpty(InputSaveValue))
|
||||
{
|
||||
InputAction.LoadBindingOverridesFromJson(InputSaveValue);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
if (InputAction.bindings[BindingIndex].isComposite)
|
||||
{
|
||||
// It's a composite. Remove overrides from part bindings.
|
||||
for (var i = BindingIndex + 1;
|
||||
i < InputAction.bindings.Count && InputAction.bindings[i].isPartOfComposite;
|
||||
++i)
|
||||
InputAction.RemoveBindingOverride(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
InputAction.RemoveBindingOverride(BindingIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Cancel()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(InputSaveValue))
|
||||
{
|
||||
InputAction.LoadBindingOverridesFromJson(InputSaveValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
public override string GetDisplayString()
|
||||
{
|
||||
if (InputAction != null)
|
||||
{
|
||||
return InputAction.GetBindingDisplayString(BindingIndex);
|
||||
}
|
||||
|
||||
return base.GetDisplayString();
|
||||
}
|
||||
|
||||
protected virtual bool IsBindingContains(InputBinding binding)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0df4bee5d9b54ada8be3757d7fe02e30
|
||||
timeCreated: 1749634814
|
||||
@@ -0,0 +1,18 @@
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace NBF.Setting
|
||||
{
|
||||
public abstract class KeyBoardOption : InputOption
|
||||
{
|
||||
protected override bool IsBindingContains(InputBinding binding)
|
||||
{
|
||||
var path = binding.path;
|
||||
if (path.Contains("<Keyboard>") || path.Contains("<Mouse>"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 509d2fb0106b42b79854cca29707207d
|
||||
timeCreated: 1749634771
|
||||
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF.Setting
|
||||
{
|
||||
public interface IMultiOption : IOptionBase
|
||||
{
|
||||
List<string> GetOptionNames();
|
||||
bool IsDropdown { get; }
|
||||
}
|
||||
|
||||
public abstract class MultiOption<T> : OptionBase, IMultiOption
|
||||
{
|
||||
protected OptionTable<T> OptionTable = new OptionTable<T>();
|
||||
|
||||
|
||||
protected void AddOption(string name, T value)
|
||||
{
|
||||
OptionTable.Add(name, value);
|
||||
}
|
||||
|
||||
public List<string> GetOptionNames() => OptionTable.GetNames();
|
||||
|
||||
public virtual bool IsDropdown => false;
|
||||
|
||||
|
||||
protected void SelectOption(T value, int defaultIndex = 0)
|
||||
{
|
||||
SetValue(TryGetIndex(value, out var index) ? index : defaultIndex);
|
||||
}
|
||||
|
||||
protected void SelectOption(Predicate<T> predicate, int defaultIndex = 0)
|
||||
{
|
||||
SetValue(TryGetIndex(predicate, out var index) ? index : defaultIndex);
|
||||
}
|
||||
|
||||
protected bool TryGetIndex(T option, out int index)
|
||||
{
|
||||
return TryGetIndex(entry => entry.Equals(option), out index);
|
||||
}
|
||||
|
||||
protected bool TryGetIndex(Predicate<T> predicate, out int index)
|
||||
{
|
||||
index = -1;
|
||||
|
||||
var entries = OptionTable.GetValues();
|
||||
|
||||
for (var i = 0; i < entries.Count; i++)
|
||||
{
|
||||
if (!predicate(entries[i])) continue;
|
||||
index = i;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public T GetSelectedOption() => OptionTable.GetValue(Value);
|
||||
|
||||
public override string GetDisplayString()
|
||||
{
|
||||
return OptionTable.GetName(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b25650e359243468131db1f9b951ae7
|
||||
timeCreated: 1748571045
|
||||
@@ -0,0 +1,124 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF.Setting
|
||||
{
|
||||
public interface IOptionBase
|
||||
{
|
||||
string Name { get; }
|
||||
void Initialize(ISettings root);
|
||||
void Apply();
|
||||
int GetValue();
|
||||
void SetValue(int index);
|
||||
bool HaveNotApple();
|
||||
ISettings Root { get; }
|
||||
string GetDisplayString();
|
||||
}
|
||||
|
||||
public abstract class OptionBase : IOptionBase
|
||||
{
|
||||
protected string SaveKey => $"Setting_{Group}_{Name}";
|
||||
|
||||
public abstract string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 所在组
|
||||
/// </summary>
|
||||
public abstract string Group { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 所在分切页
|
||||
/// </summary>
|
||||
public abstract string Tab { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认值
|
||||
/// </summary>
|
||||
protected abstract int DefaultValue { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前的值
|
||||
/// </summary>
|
||||
protected int Value;
|
||||
|
||||
/// <summary>
|
||||
/// 保存的值
|
||||
/// </summary>
|
||||
protected int SaveValue;
|
||||
|
||||
public virtual bool HaveNotApple()
|
||||
{
|
||||
return !Value.Equals(SaveValue);
|
||||
}
|
||||
|
||||
public ISettings Root { get; private set; }
|
||||
|
||||
|
||||
public void Initialize(ISettings root)
|
||||
{
|
||||
Root = root;
|
||||
Load();
|
||||
OnInitialize();
|
||||
if (!PlayerPrefs.HasKey(SaveKey))
|
||||
{
|
||||
OnSetDefaultValue();
|
||||
}
|
||||
|
||||
Apply();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载用户的设置
|
||||
/// </summary>
|
||||
public virtual void Load()
|
||||
{
|
||||
var value = PlayerPrefs.GetInt(SaveKey, DefaultValue);
|
||||
Value = value;
|
||||
SaveValue = value;
|
||||
}
|
||||
|
||||
public virtual void Apply()
|
||||
{
|
||||
PlayerPrefs.SetInt(SaveKey, Value);
|
||||
SaveValue = Value;
|
||||
OnApply();
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
Value = DefaultValue;
|
||||
}
|
||||
|
||||
public virtual void Cancel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public virtual string GetDisplayString()
|
||||
{
|
||||
return GetValue().ToString();
|
||||
}
|
||||
|
||||
public virtual int GetValue()
|
||||
{
|
||||
return Value;
|
||||
}
|
||||
|
||||
public virtual void SetValue(int value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
|
||||
protected virtual void OnInitialize()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnSetDefaultValue()
|
||||
{
|
||||
Value = DefaultValue;
|
||||
SaveValue = DefaultValue;
|
||||
}
|
||||
|
||||
protected abstract void OnApply();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd2d6f346b1145debf370bc3ac71bd7e
|
||||
timeCreated: 1748570612
|
||||
@@ -0,0 +1,44 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace NBF.Setting
|
||||
{
|
||||
public class OptionTable<T>
|
||||
{
|
||||
public struct OptionEntry
|
||||
{
|
||||
public string Name;
|
||||
public T Value;
|
||||
|
||||
public OptionEntry(string name, T value)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
List<OptionEntry> entries = new List<OptionEntry>();
|
||||
|
||||
public void Add(string name, T value)
|
||||
{
|
||||
entries.Add(new OptionEntry(name, value));
|
||||
}
|
||||
|
||||
public List<string> GetNames() => entries.Select(x => x.Name).ToList();
|
||||
public List<T> GetValues() => entries.Select(x => x.Value).ToList();
|
||||
|
||||
public T GetValue(int index)
|
||||
{
|
||||
if (entries == null) return default;
|
||||
if (index < 0 || index >= entries.Count) return default;
|
||||
return entries[index].Value;
|
||||
}
|
||||
|
||||
public string GetName(int index)
|
||||
{
|
||||
if (entries == null) return string.Empty;
|
||||
if (index < 0 || index >= entries.Count) return string.Empty;
|
||||
return entries[index].Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a7241b5524db446eb4f73ae3a8d7b0ec
|
||||
timeCreated: 1748571519
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace NBF.Setting
|
||||
{
|
||||
/// <summary>
|
||||
/// 范围设置
|
||||
/// </summary>
|
||||
public abstract class RangeOption : OptionBase
|
||||
{
|
||||
public abstract int MinValue { get; }
|
||||
public abstract int MaxValue { get; }
|
||||
|
||||
public virtual int ShowRate => 0;
|
||||
|
||||
public override void SetValue(int value)
|
||||
{
|
||||
if (value > MaxValue) value = MaxValue;
|
||||
else if (value < MinValue) value = MinValue;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override string GetDisplayString()
|
||||
{
|
||||
if (ShowRate > 0)
|
||||
{
|
||||
return Math.Round(GetValue() / (ShowRate * 1f), 1).ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
return base.GetDisplayString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3531567c76fc48d5939644966fe22057
|
||||
timeCreated: 1748572844
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace NBF.Setting
|
||||
{
|
||||
public abstract class ToggleOption : MultiOption<bool>
|
||||
{
|
||||
protected override void OnInitialize()
|
||||
{
|
||||
AddOption("Off", false);
|
||||
AddOption("On", true);
|
||||
|
||||
SelectOption(DefaultValue == 1);
|
||||
}
|
||||
|
||||
public bool IsEnabled() => GetSelectedOption();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user