首次提交

This commit is contained in:
Bob.Song
2026-03-05 18:07:55 +08:00
commit e125bb869e
4534 changed files with 563920 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: caf75b28905c41ab8e414e696c3423f9
timeCreated: 1756363998

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5a18bd4a09c14040b9ea1de796d645f1
timeCreated: 1743783137

View File

@@ -0,0 +1,12 @@
using UnityEngine;
namespace NBF
{
/// <summary>
/// 鱼饵
/// </summary>
public class BaitAsset : PreviewableAsset
{
public Transform hook;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 524c26f472e74fa1ad167db68e562324
timeCreated: 1743824319

View 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;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3e885da772834bb289c2368be2f6eb5b
timeCreated: 1743824616

View File

@@ -0,0 +1,14 @@
using UnityEngine;
namespace NBF
{
public class FishAsset : PreviewableAsset
{
public Transform root;
/// <summary>
/// 弯曲节点
/// </summary>
public Transform[] spines;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c12ba26d0bd74238ab26aee49ef6fd5d
timeCreated: 1743824172

View 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"
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2e9e67584f094dcbba9e61f37a55a5b4
timeCreated: 1743824179

View File

@@ -0,0 +1,12 @@
using UnityEngine;
namespace NBF
{
public class HookAsset : PreviewableAsset
{
/// <summary>
/// 鱼饵挂点
/// </summary>
public Transform baitConnector;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b6eea50c041f42d5bd95d9e56c3a9c6f
timeCreated: 1743824134

View File

@@ -0,0 +1,8 @@
using UnityEngine;
namespace NBF
{
public class LineAsset : PreviewableAsset
{
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8059c6be171e47edb0390fa091285100
timeCreated: 1743824214

View 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;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 897c0165284148879a9d158ea8010a15
timeCreated: 1743824269

View 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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 553e656eacf648afb33751a88352d216
timeCreated: 1757836335

View File

@@ -0,0 +1,13 @@
using System;
using UnityEngine;
namespace NBF
{
/// <summary>
/// 可以3D预览的资产
/// </summary>
public class PreviewableAsset : MonoBehaviour
{
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a000ba87cd97499eb23feecf39521ecb
timeCreated: 1750736840

View File

@@ -0,0 +1,8 @@
using UnityEngine;
namespace NBF
{
public class PropAsset : PreviewableAsset
{
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ea4d172189e248949431bb24b98369cb
timeCreated: 1743824159

View 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;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8898b66b55404fd3be13b7dcdcfda463
timeCreated: 1743785540

View 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()
{
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 45b047324a3349b9aea42f50cbd1ba71
timeCreated: 1743783252

View 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;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: cdfd33eb69534a1e87cd523df4bfb430
timeCreated: 1743781816

View File

@@ -0,0 +1,8 @@
using UnityEngine;
namespace NBF
{
public class SpinnerLureAsset : PreviewableAsset
{
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ed88dcaac7774ce79b04d90a3fa50533
timeCreated: 1745487261

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bedf4887d50d409fb132fee064bc8b37
timeCreated: 1770108259

View 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");
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d6c5972785cf41e997b1bd6164a04e00
timeCreated: 1770108402

View 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);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9a0a734b63534f5e8f244a76a4a8f48d
timeCreated: 1770122480

View 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);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1d992ccf80d34101a9e62b066d753dc3
timeCreated: 1770108262

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c8426c4b03da403284afe458076b9c10
timeCreated: 1742387508

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7cb50811095d496fad57afd7535d0f73
timeCreated: 1748180763

View 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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fa024ae7ea104f809ace6beff59c12d8
timeCreated: 1748188551

View 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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 647174a4726c4c4c92193aa7dcd3ddad
timeCreated: 1748509835

View 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);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c40f26e5da0a454b93cd5d1e94157699
timeCreated: 1742635242

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ef884391e7a4450a9cfc633e1c7a8785
timeCreated: 1742999159

View 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
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: da1c9ef59c57429083f79d8c2a1bec86
timeCreated: 1742999162

View 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
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6a25ab9f9b4140c7bd3e463da484301e
timeCreated: 1765284104

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1977fd60c4b24f33bc4143aaed9fba8a
timeCreated: 1755792367

View File

@@ -0,0 +1,10 @@
using System;
using UnityEngine;
namespace NBF
{
public class InteractiveObject : MonoBehaviour
{
[Header("交互类型")] public UIDef.InteractiveType Type;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: aa29ad8321da4a29a6fb475e9e97f87e
timeCreated: 1747577976

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: cdaa795bad2ccc34faab0c9036785b02

View 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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 944328972a42400fa3fa1289ba2a1e2e
timeCreated: 1742387511

View 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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3816467cfd1648e685a33ebfd1d9fb7d
timeCreated: 1748184924

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 011d59a9e9454122bc76461e942de184
timeCreated: 1748489400

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4049be1823c447dd941297033391e07a
timeCreated: 1766472832

View File

@@ -0,0 +1,12 @@
using Cinemachine;
using UnityEngine;
namespace NBF
{
public class CameraAsset : MonoBehaviour
{
public CinemachineVirtualCamera fppVCam;
public CinemachineVirtualCamera tppVCam;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5dd3e6b2217c463e94e32f15c4ea3c5c
timeCreated: 1765306413

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1115c38f55a6434ba8ab2de810f955be
timeCreated: 1766472617

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d846463d130b4191a5a4a9d2e2dfe45b
timeCreated: 1748180579

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 79ba55353f994d4e947699ffd0f12751
timeCreated: 1766410875

View 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}");
}
}
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6eb3efcd3474440ea2c7d6549db02c4c
timeCreated: 1770015242

View 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
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2101c084ab66498bb634f122db410852
timeCreated: 1766410867

View 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()
{
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 62c58708f36041db9bb11a7e4d16c62c
timeCreated: 1748491579

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 65341d2b856a4aef82e238b10798b430
timeCreated: 1771091754

View File

@@ -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));
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d3ee9b922c69484282c9080842cb1d02
timeCreated: 1771091765

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6111c0ab89e74c9fada884e4e4051549
timeCreated: 1748489421

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c12ca701ad9f433d9e6e7eaf04f507d0
timeCreated: 1748570535

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c3ed7d01cac8436fb64fef818e33f173
timeCreated: 1770998136

View File

@@ -0,0 +1,6 @@
namespace NBF.Setting
{
public abstract class ControllerOption : OptionBase
{
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 75e11d5298cd48718d39a3e2af82472f
timeCreated: 1749634909

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 49041e6a08b744038368d7010acf61ea
timeCreated: 1750408186

View File

@@ -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;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d2cb28b8c7664cc28fe0b0a0a4516704
timeCreated: 1748678126

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0df4bee5d9b54ada8be3757d7fe02e30
timeCreated: 1749634814

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 509d2fb0106b42b79854cca29707207d
timeCreated: 1749634771

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5b25650e359243468131db1f9b951ae7
timeCreated: 1748571045

View File

@@ -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();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: dd2d6f346b1145debf370bc3ac71bd7e
timeCreated: 1748570612

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a7241b5524db446eb4f73ae3a8d7b0ec
timeCreated: 1748571519

View File

@@ -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();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3531567c76fc48d5939644966fe22057
timeCreated: 1748572844

View File

@@ -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