结构大修改,改成朴实无华的结构,不过度架构。能跑就行
This commit is contained in:
3
Assets/Scripts/Fishing2~/Common.meta
Normal file
3
Assets/Scripts/Fishing2~/Common.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0eb35ab0b70344b4a2b6054f7a7ecd1b
|
||||
timeCreated: 1756822717
|
||||
98
Assets/Scripts/Fishing2~/Common/CameraComponent.cs
Normal file
98
Assets/Scripts/Fishing2~/Common/CameraComponent.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using Fantasy.Async;
|
||||
using NBC;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
using Fantasy.Event;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public enum CameraShowMode
|
||||
{
|
||||
None = 0,
|
||||
FPP,
|
||||
TPP,
|
||||
}
|
||||
|
||||
public class CameraComponent : Entity
|
||||
{
|
||||
public CameraShowMode Mode = CameraShowMode.None;
|
||||
|
||||
private CameraAsset _cameraAsset;
|
||||
private CameraShowMode _lastMode = CameraShowMode.None;
|
||||
|
||||
public class CameraComponentAwakeSystem : AwakeSystem<CameraComponent>
|
||||
{
|
||||
protected override void Awake(CameraComponent self)
|
||||
{
|
||||
self._cameraAsset = Game.Instance.gameObject.GetComponentInChildren<CameraAsset>();
|
||||
}
|
||||
}
|
||||
|
||||
public class CameraComponentUpdateSystem : UpdateSystem<CameraComponent>
|
||||
{
|
||||
protected override void Update(CameraComponent self)
|
||||
{
|
||||
self.UpdateCamera();
|
||||
}
|
||||
}
|
||||
|
||||
public class CameraComponentDestroySystem : DestroySystem<CameraComponent>
|
||||
{
|
||||
protected override void Destroy(CameraComponent self)
|
||||
{
|
||||
self._cameraAsset = null;
|
||||
self._lastMode = CameraShowMode.None;
|
||||
self.Mode = CameraShowMode.None;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void UpdateCamera()
|
||||
{
|
||||
if (_lastMode == Mode) return;
|
||||
if (Mode == CameraShowMode.TPP)
|
||||
{
|
||||
//第三人称视角
|
||||
SetTPPCam();
|
||||
}
|
||||
else if (Mode == CameraShowMode.FPP)
|
||||
{
|
||||
//第一人称视角
|
||||
SetFPPCam();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void SetTPPCam()
|
||||
{
|
||||
_cameraAsset.fppVCam.Priority = 0;
|
||||
_cameraAsset.tppVCam.Priority = 10;
|
||||
}
|
||||
|
||||
private void SetFPPCam()
|
||||
{
|
||||
var map = App.Main.GetComponent<Map>();
|
||||
var unityComponent = map.SelfMapUnit.GetComponent<UnitUnityComponent>();
|
||||
if (unityComponent != null)
|
||||
{
|
||||
_cameraAsset.fppVCam.LookAt = unityComponent.RootAsset.FppLook;
|
||||
_cameraAsset.fppVCam.Follow = unityComponent.ModelAsset.NeckTransform;
|
||||
unityComponent.ModelAsset.LookIk.solver.target = unityComponent.RootAsset.FppLook;
|
||||
}
|
||||
|
||||
_cameraAsset.fppVCam.Priority = 10;
|
||||
_cameraAsset.tppVCam.Priority = 0;
|
||||
}
|
||||
|
||||
public void SetFppLook(Transform fppCamLook)
|
||||
{
|
||||
_cameraAsset.fppVCam.LookAt = fppCamLook;
|
||||
}
|
||||
|
||||
public void SetFppFollow(Transform fppCamFollow)
|
||||
{
|
||||
_cameraAsset.fppVCam.Follow = fppCamFollow;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Common/CameraComponent.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Common/CameraComponent.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aee3947bbf944ecb9e955d2ac1d9e3a5
|
||||
timeCreated: 1756822741
|
||||
104
Assets/Scripts/Fishing2~/Common/CursorComponent.cs
Normal file
104
Assets/Scripts/Fishing2~/Common/CursorComponent.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
// using Fantasy.Async;
|
||||
// using Fantasy.Entitas;
|
||||
// using Fantasy.Entitas.Interface;
|
||||
// using Fantasy.Event;
|
||||
// using NBC;
|
||||
// using UnityEngine;
|
||||
//
|
||||
// namespace NBF.Fishing2
|
||||
// {
|
||||
// public class CursorUIShowEvent : AsyncEventSystem<UIShowEvent>
|
||||
// {
|
||||
// protected override async FTask Handler(UIShowEvent self)
|
||||
// {
|
||||
// var cursorComponent = App.Main.GetComponent<CursorComponent>();
|
||||
// cursorComponent.UpdateCursor();
|
||||
// }
|
||||
// // protected override FTask Handler(UIShowEvent self)
|
||||
// // {
|
||||
// // throw new System.NotImplementedException();
|
||||
// // }
|
||||
// }
|
||||
//
|
||||
// public class CursorUIHideEvent : AsyncEventSystem<UIHideEvent>
|
||||
// {
|
||||
// protected override async FTask Handler(UIHideEvent self)
|
||||
// {
|
||||
// var cursorComponent = App.Main.GetComponent<CursorComponent>();
|
||||
// cursorComponent.UpdateCursor();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public class CursorComponent : Entity
|
||||
// {
|
||||
// #region System
|
||||
//
|
||||
//
|
||||
//
|
||||
// // public class CursorComponentAwakeSystem : AwakeSystem<CursorComponent>
|
||||
// // {
|
||||
// // protected override void Awake(CursorComponent self)
|
||||
// // {
|
||||
// //
|
||||
// // }
|
||||
// // }
|
||||
// //
|
||||
// // public class CursorComponentUpdateSystem : UpdateSystem<CursorComponent>
|
||||
// // {
|
||||
// // protected override void Update(CursorComponent self)
|
||||
// // {
|
||||
// // }
|
||||
// // }
|
||||
// //
|
||||
// // public class CursorComponentDestroySystem : DestroySystem<CursorComponent>
|
||||
// // {
|
||||
// // protected override void Destroy(CursorComponent self)
|
||||
// // {
|
||||
// // }
|
||||
// // }
|
||||
//
|
||||
// #endregion
|
||||
//
|
||||
// public void UpdateCursor()
|
||||
// {
|
||||
// bool showCursor = false;
|
||||
// var uis = App.UI.GetAllUI();
|
||||
// foreach (var ui in uis)
|
||||
// {
|
||||
// if (ui.IsShowing && ui.IsShowCursor)
|
||||
// {
|
||||
// showCursor = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// SetMouseCursor(showCursor);
|
||||
// }
|
||||
//
|
||||
// public ControllerType controllerType = ControllerType.GamePad;
|
||||
//
|
||||
// public void SetMouseCursor(bool val)
|
||||
// {
|
||||
// Log.Info($"设置鼠标光标==={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;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
3
Assets/Scripts/Fishing2~/Common/CursorComponent.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Common/CursorComponent.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a04f3272f2604244b8cd9d9923bb35b0
|
||||
timeCreated: 1765374579
|
||||
222
Assets/Scripts/Fishing2~/Common/InputComponent.cs
Normal file
222
Assets/Scripts/Fishing2~/Common/InputComponent.cs
Normal file
@@ -0,0 +1,222 @@
|
||||
using System;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public enum ControllerType
|
||||
{
|
||||
KeyboardMouse = 0,
|
||||
GamePad = 1
|
||||
}
|
||||
|
||||
public class InputComponent : Entity
|
||||
{
|
||||
public PlayerInputControl PlayerInputControl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 执行输入事件
|
||||
/// </summary>
|
||||
public event Action<string> OnUIPerformed;
|
||||
|
||||
/// <summary>
|
||||
/// 执行输入事件完毕
|
||||
/// </summary>
|
||||
public event Action<string> OnUICanceled;
|
||||
|
||||
/// <summary>
|
||||
/// 执行输入事件
|
||||
/// </summary>
|
||||
public event Action<string> OnPlayerPerformed;
|
||||
|
||||
/// <summary>
|
||||
/// 执行输入事件完毕
|
||||
/// </summary>
|
||||
public event Action<string> OnPlayerCanceled;
|
||||
|
||||
/// <summary>
|
||||
/// 执行输入事件
|
||||
/// </summary>
|
||||
public event Action<InputAction.CallbackContext> OnPlayerValuePerformed;
|
||||
|
||||
/// <summary>
|
||||
/// 执行输入事件完毕
|
||||
/// </summary>
|
||||
public event Action<InputAction.CallbackContext> OnPlayerValueCanceled;
|
||||
|
||||
/// <summary>
|
||||
/// 触发交互游戏对象
|
||||
/// </summary>
|
||||
public event Action<InteractiveObject> OnInteractiveObjectAction;
|
||||
|
||||
/// <summary>
|
||||
/// 手柄输入
|
||||
/// </summary>
|
||||
public static bool IsControllerInput;
|
||||
|
||||
/// <summary>
|
||||
/// ui阻止游戏输入
|
||||
/// </summary>
|
||||
public static bool IsUIStopInput;
|
||||
|
||||
|
||||
#region Event
|
||||
|
||||
public class InputComponentAwakeSystem : AwakeSystem<InputComponent>
|
||||
{
|
||||
protected override void Awake(InputComponent self)
|
||||
{
|
||||
self.PlayerInputControl = new PlayerInputControl();
|
||||
self.PlayerInputControl.Enable();
|
||||
|
||||
foreach (var actionMap in self.PlayerInputControl.asset.actionMaps)
|
||||
{
|
||||
actionMap.Enable();
|
||||
if (actionMap.name == "UI")
|
||||
{
|
||||
foreach (var action in actionMap.actions)
|
||||
{
|
||||
if (action.type == InputActionType.Button)
|
||||
{
|
||||
action.performed += self.OnUIButtonPerformed;
|
||||
action.canceled += self.OnUIButtonCanceled;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (actionMap.name == "Player")
|
||||
{
|
||||
foreach (var action in actionMap.actions)
|
||||
{
|
||||
if (action.type == InputActionType.Button)
|
||||
{
|
||||
action.performed += self.OnPlayerButtonPerformed;
|
||||
action.canceled += self.OnPlayerButtonCanceled;
|
||||
}
|
||||
else if (action.type == InputActionType.Value)
|
||||
{
|
||||
action.performed += self.OnInputPlayerValuePerformed;
|
||||
action.canceled += self.OnInputPlayerValueCanceled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class InputComponentDestroySystem : DestroySystem<InputComponent>
|
||||
{
|
||||
protected override void Destroy(InputComponent self)
|
||||
{
|
||||
foreach (var actionMap in self.PlayerInputControl.asset.actionMaps)
|
||||
{
|
||||
actionMap.Enable();
|
||||
if (actionMap.name == "UI")
|
||||
{
|
||||
foreach (var action in actionMap.actions)
|
||||
{
|
||||
if (action.type == InputActionType.Button)
|
||||
{
|
||||
action.performed -= self.OnUIButtonPerformed;
|
||||
action.canceled -= self.OnUIButtonCanceled;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (actionMap.name == "Player")
|
||||
{
|
||||
foreach (var action in actionMap.actions)
|
||||
{
|
||||
if (action.type == InputActionType.Button)
|
||||
{
|
||||
action.performed -= self.OnPlayerButtonPerformed;
|
||||
action.canceled -= self.OnPlayerButtonCanceled;
|
||||
}
|
||||
else if (action.type == InputActionType.Value)
|
||||
{
|
||||
action.performed -= self.OnInputPlayerValuePerformed;
|
||||
action.canceled -= self.OnInputPlayerValueCanceled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void OnUIButtonPerformed(InputAction.CallbackContext context)
|
||||
{
|
||||
OnUIPerformed?.Invoke(context.action.name);
|
||||
}
|
||||
|
||||
private void OnUIButtonCanceled(InputAction.CallbackContext context)
|
||||
{
|
||||
OnUICanceled?.Invoke(context.action.name);
|
||||
}
|
||||
|
||||
private void OnPlayerButtonPerformed(InputAction.CallbackContext context)
|
||||
{
|
||||
if (IsUIStopInput) return;
|
||||
var actionName = context.action.name;
|
||||
// if (actionName == "Op1")
|
||||
// {
|
||||
// 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")
|
||||
// {
|
||||
// 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);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public Vector2 GetMovementInput()
|
||||
{
|
||||
if (IsUIStopInput) return Vector2.zero;
|
||||
return PlayerInputControl.Player.Move?.ReadValue<Vector2>() ?? Vector2.zero;
|
||||
}
|
||||
|
||||
public Vector2 GetLookInput()
|
||||
{
|
||||
if (IsUIStopInput) return Vector2.zero;
|
||||
return PlayerInputControl.Player.Look?.ReadValue<Vector2>() ?? Vector2.zero;
|
||||
}
|
||||
|
||||
public void SendUIInput(string actionName)
|
||||
{
|
||||
OnUIPerformed?.Invoke(actionName);
|
||||
OnUICanceled?.Invoke(actionName);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Common/InputComponent.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Common/InputComponent.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09132878c89a444a88421b7434394235
|
||||
timeCreated: 1756826439
|
||||
9
Assets/Scripts/Fishing2~/Common/SettingComponent.cs
Normal file
9
Assets/Scripts/Fishing2~/Common/SettingComponent.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Fantasy.Entitas;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public class SettingComponent : Entity
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Common/SettingComponent.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Common/SettingComponent.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c6adcf67ef545f99c590d1078a76eea
|
||||
timeCreated: 1756826460
|
||||
3
Assets/Scripts/Fishing2~/Helper.meta
Normal file
3
Assets/Scripts/Fishing2~/Helper.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c1174e9753b43ac9dd5fa664e92021b
|
||||
timeCreated: 1756450590
|
||||
25
Assets/Scripts/Fishing2~/Helper/MoveHelper.cs
Normal file
25
Assets/Scripts/Fishing2~/Helper/MoveHelper.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using System.Collections.Generic;
|
||||
using Fantasy.Async;
|
||||
using NBC;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public static class MoveHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 可以多次调用,多次调用的话会取消上一次的协程
|
||||
/// </summary>
|
||||
/// <param name="unit"></param>
|
||||
/// <param name="targetPos"></param>
|
||||
/// <returns></returns>
|
||||
public static async FTask<int> MoveToAsync(this MapUnit unit, float3 targetPos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static async FTask MoveToAsync(this MapUnit unit, List<float3> path)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Helper/MoveHelper.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Helper/MoveHelper.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2ce11e50e0d749bfa5915208b1ce1a44
|
||||
timeCreated: 1756822516
|
||||
13
Assets/Scripts/Fishing2~/Helper/PathHelper.cs
Normal file
13
Assets/Scripts/Fishing2~/Helper/PathHelper.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public static class PathHelper
|
||||
{
|
||||
public static string GetFullPath(string path)
|
||||
{
|
||||
return Path.Combine("gfx", path);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Helper/PathHelper.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Helper/PathHelper.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 774fd7a393874949863a694a79823e1c
|
||||
timeCreated: 1761145384
|
||||
83
Assets/Scripts/Fishing2~/Helper/ProtoHelper.cs
Normal file
83
Assets/Scripts/Fishing2~/Helper/ProtoHelper.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System.Linq;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public static class ProtoHelper
|
||||
{
|
||||
public static MapUnitInfo ToMapUnitInfo(this RoleInfo self)
|
||||
{
|
||||
MapUnitInfo mapUnit = new MapUnitInfo();
|
||||
mapUnit.Id = self.RoleId;
|
||||
mapUnit.RoleInfo = self.ToSimpleInfo();
|
||||
// mapUnit.Gears = self.Gears;
|
||||
return mapUnit;
|
||||
}
|
||||
|
||||
public static RoleSimpleInfo ToSimpleInfo(this RoleInfo self)
|
||||
{
|
||||
var ret = new RoleSimpleInfo();
|
||||
ret.NickName = self.BaseInfo.NickName;
|
||||
ret.RoleId = self.RoleId;
|
||||
ret.Country = self.BaseInfo.Country;
|
||||
ret.Head = self.BaseInfo.Head;
|
||||
ret.Level = self.BaseInfo.Level;
|
||||
// ret.Vip = self.BaseInfo.Vip;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#region Vector
|
||||
|
||||
public static Vector3Info ToVector3Info(this Vector3 self)
|
||||
{
|
||||
var ret = new Vector3Info();
|
||||
ret.x = self.x;
|
||||
ret.y = self.y;
|
||||
ret.z = self.z;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public static QuaternionInfo ToQuaternionInfo(this Quaternion self)
|
||||
{
|
||||
var ret = new QuaternionInfo();
|
||||
ret.x = self.x;
|
||||
ret.y = self.y;
|
||||
ret.z = self.z;
|
||||
ret.w = self.w;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public static Vector3 ToVector3(this Vector3Info self)
|
||||
{
|
||||
var ret = new Vector3
|
||||
{
|
||||
x = self.x,
|
||||
y = self.y,
|
||||
z = self.z
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public static Quaternion ToQuaternion(this QuaternionInfo self)
|
||||
{
|
||||
var ret = new Quaternion
|
||||
{
|
||||
x = self.x,
|
||||
y = self.y,
|
||||
z = self.z,
|
||||
w = self.w
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Helper/ProtoHelper.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Helper/ProtoHelper.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 850c683faae3419abd3693f7e87accae
|
||||
timeCreated: 1756738767
|
||||
25
Assets/Scripts/Fishing2~/Helper/UnitHelper.cs
Normal file
25
Assets/Scripts/Fishing2~/Helper/UnitHelper.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Fantasy.Async;
|
||||
using NBC;
|
||||
using Fantasy.Entitas;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public static class UnitHelper
|
||||
{
|
||||
public static async FTask InitMapUnit(this MapUnit self)
|
||||
{
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
|
||||
|
||||
public static bool IsSelf(this MapUnit self)
|
||||
{
|
||||
if (self.Id == Game.SelfId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Helper/UnitHelper.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Helper/UnitHelper.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82c91df89554417c87a3658709ef406d
|
||||
timeCreated: 1756450600
|
||||
3
Assets/Scripts/Fishing2~/Map.meta
Normal file
3
Assets/Scripts/Fishing2~/Map.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9626380655a42298daf90e7333172ae
|
||||
timeCreated: 1756363915
|
||||
3
Assets/Scripts/Fishing2~/Map/Handler.meta
Normal file
3
Assets/Scripts/Fishing2~/Map/Handler.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9720afaa3bc94081b63a7c0571e4c86a
|
||||
timeCreated: 1757251153
|
||||
@@ -0,0 +1,20 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
using NBF.Fishing2;
|
||||
using Log = NBC.Log;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public class Map2C_ChangeMapHandler : Message<Map2C_ChangeMap>
|
||||
{
|
||||
protected override async FTask Run(Session session, Map2C_ChangeMap message)
|
||||
{
|
||||
Log.Info($"收到地图切换消息=={message.MapId}");
|
||||
// await MapHelper.ChangeMap(message.MapId);
|
||||
|
||||
// await MapHelper.CreateRoomTest(message.MapId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9aca13592484450582e818dd128a23c2
|
||||
timeCreated: 1756301493
|
||||
@@ -0,0 +1,32 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
using NBC;
|
||||
using Log = NBC.Log;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public class Map2C_RoleEnterMapNotifyHandler : Message<Map2C_RoleEnterRoomNotify>
|
||||
{
|
||||
protected override async FTask Run(Session session, Map2C_RoleEnterRoomNotify message)
|
||||
{
|
||||
Log.Info($"收到进入房间推送 id={message.Info.Id} ");
|
||||
var map = App.Main.GetComponent<Map>();
|
||||
if (map == null || !map.IsRoomMap)
|
||||
{
|
||||
Log.Info("房间不是好友房间,不处理进入请求");
|
||||
return;
|
||||
}
|
||||
|
||||
var info = message.Info;
|
||||
var unit = map.GetUnit(info.Id);
|
||||
if (unit == null)
|
||||
{
|
||||
unit = map.CreateMapUnit(info);
|
||||
}
|
||||
|
||||
await unit.CreateView();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0934eeab5b8445b824f1337f774379e
|
||||
timeCreated: 1757251141
|
||||
@@ -0,0 +1,27 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
using NBC;
|
||||
using Log = NBC.Log;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public class Map2C_RoleExitMapNotifyHandler : Message<Map2C_RoleExitRoomNotify>
|
||||
{
|
||||
protected override async FTask Run(Session session, Map2C_RoleExitRoomNotify message)
|
||||
{
|
||||
Log.Info($"收到离开房间推送 id={message.Id} ");
|
||||
var map = App.Main.GetComponent<Map>();
|
||||
if (map == null)
|
||||
{
|
||||
Log.Info("地图不存在,不处理退出请求");
|
||||
return;
|
||||
}
|
||||
if (map.Units.Remove(message.Id, out var unit))
|
||||
{
|
||||
unit.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18ae467167c44db1873fee88067d2f9a
|
||||
timeCreated: 1757251193
|
||||
94
Assets/Scripts/Fishing2~/Map/Map.cs
Normal file
94
Assets/Scripts/Fishing2~/Map/Map.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public class Map : Entity
|
||||
{
|
||||
public int MapId;
|
||||
|
||||
public string RoomCode;
|
||||
|
||||
/// <summary>
|
||||
/// 自己的实体id
|
||||
/// </summary>
|
||||
public long SelfId;
|
||||
|
||||
/// <summary>
|
||||
/// 好友房地图
|
||||
/// </summary>
|
||||
public bool IsRoomMap => !string.IsNullOrEmpty(RoomCode);
|
||||
|
||||
/// <summary>
|
||||
/// 地图中的单位
|
||||
/// </summary>
|
||||
public Dictionary<long, MapUnit> Units = new Dictionary<long, MapUnit>();
|
||||
|
||||
/// <summary>
|
||||
/// 自己的实体
|
||||
/// </summary>
|
||||
public MapUnit SelfMapUnit => GetUnit(SelfId);
|
||||
|
||||
|
||||
#region System
|
||||
|
||||
public class MapDestroySystem : DestroySystem<Map>
|
||||
{
|
||||
protected override void Destroy(Map self)
|
||||
{
|
||||
self.MapId = 0;
|
||||
self.SelfId = 0;
|
||||
self.RoomCode = string.Empty;
|
||||
self.Units.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public MapUnit CreateMapUnit(MapUnitInfo unitInfo)
|
||||
{
|
||||
var mapUnit = Create<MapUnit>(Scene, unitInfo.Id, true, true);
|
||||
mapUnit.SetUnitInfo(unitInfo);
|
||||
Add(mapUnit);
|
||||
return mapUnit;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个单位
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public MapUnit GetUnit(long id)
|
||||
{
|
||||
return Units.GetValueOrDefault(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 进入地图
|
||||
/// </summary>
|
||||
/// <param name="map"></param>
|
||||
/// <param name="unit"></param>
|
||||
/// <returns></returns>
|
||||
public bool Add(MapUnit unit)
|
||||
{
|
||||
Units.Add(unit.Id, unit);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 离开地图
|
||||
/// </summary>
|
||||
/// <param name="self"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public bool Remove(long id)
|
||||
{
|
||||
return Units.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Map/Map.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Map/Map.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2acb8a2309ee4443a812939b0e02c18f
|
||||
timeCreated: 1756049289
|
||||
11
Assets/Scripts/Fishing2~/Map/MapManageComponent.cs
Normal file
11
Assets/Scripts/Fishing2~/Map/MapManageComponent.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Fantasy.Entitas;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
/// <summary>
|
||||
/// 地图管理组件
|
||||
/// </summary>
|
||||
public class MapManageComponent : Entity
|
||||
{
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Map/MapManageComponent.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Map/MapManageComponent.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 226c840e80f840ae8a4ff54bc7c6645a
|
||||
timeCreated: 1756304063
|
||||
3
Assets/Scripts/Fishing2~/Message.meta
Normal file
3
Assets/Scripts/Fishing2~/Message.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b35630cbcbbb4792a821de847fabbd69
|
||||
timeCreated: 1757820526
|
||||
3
Assets/Scripts/Fishing2~/Message/Event.meta
Normal file
3
Assets/Scripts/Fishing2~/Message/Event.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c197c410c838437996d832515a62026e
|
||||
timeCreated: 1757835465
|
||||
35
Assets/Scripts/Fishing2~/Message/Event/NumericChangeEvent.cs
Normal file
35
Assets/Scripts/Fishing2~/Message/Event/NumericChangeEvent.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
// using System.Collections.Generic;
|
||||
// using Fantasy;
|
||||
// using Fantasy.Event;
|
||||
//
|
||||
// namespace NBF.Fishing2
|
||||
// {
|
||||
// public class NumericChangeEvent : EventSystem<NumericChange>
|
||||
// {
|
||||
// protected override void Handler(NumericChange self)
|
||||
// {
|
||||
// if (self.Old == self.New) return;
|
||||
// if (self.NumericType == NumericType.Flashlight)
|
||||
// {
|
||||
// var flashlight = self.MapUnit.GetComponent<FlashlightComponent>();
|
||||
// flashlight.Change(self.New);
|
||||
// if (self.MapUnit.IsSelf())
|
||||
// {
|
||||
// var list = new List<KeyValueInt64>
|
||||
// {
|
||||
// new KeyValueInt64()
|
||||
// {
|
||||
// Key = self.NumericType,
|
||||
// Value = self.New
|
||||
// }
|
||||
// };
|
||||
// //如果是自己的,则同步给其他玩家
|
||||
// Net.Send(new C2Map_RolePropertyChange()
|
||||
// {
|
||||
// Propertys = list
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2dae2fd757bc46b7b47a7b548b36ed54
|
||||
timeCreated: 1757835696
|
||||
33
Assets/Scripts/Fishing2~/Message/Map2C_LookNotifyHandler.cs
Normal file
33
Assets/Scripts/Fishing2~/Message/Map2C_LookNotifyHandler.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
using NBC;
|
||||
using Log = NBC.Log;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public class Map2C_LookNotifyHandler : Message<Map2C_LookeNotify>
|
||||
{
|
||||
protected override async FTask Run(Session session, Map2C_LookeNotify message)
|
||||
{
|
||||
Log.Info($"收到朝向推送 id={message.Id} ");
|
||||
var map = App.Main.GetComponent<Map>();
|
||||
var unit = map.Units[message.Id];
|
||||
if (unit.IsSelf())
|
||||
{
|
||||
Log.Info("自己的旋转消息,不处理");
|
||||
}
|
||||
else
|
||||
{
|
||||
var moveComponent = unit.GetComponent<CharacterControllerComponent>();
|
||||
if (moveComponent != null)
|
||||
{
|
||||
moveComponent.OnServerLook(message.Rotation.ToVector3(), message.Timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1f00b074c7f48248773361036d3bfcf
|
||||
timeCreated: 1757238435
|
||||
36
Assets/Scripts/Fishing2~/Message/Map2C_MoveNotifyHandler.cs
Normal file
36
Assets/Scripts/Fishing2~/Message/Map2C_MoveNotifyHandler.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
using NBC;
|
||||
using Log = NBC.Log;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public class Map2C_MoveNotifyHandler : Message<Map2C_MoveNotify>
|
||||
{
|
||||
protected override async FTask Run(Session session, Map2C_MoveNotify message)
|
||||
{
|
||||
Log.Info($"收到移动推送 id={message.Id} stop={message.IsStop}");
|
||||
// session.Scene
|
||||
// session.Scene.GetComponent<MapUnitInfo>(message.Id),
|
||||
var map = App.Main.GetComponent<Map>();
|
||||
var unit = map.Units[message.Id];
|
||||
var moveComponent = unit.GetComponent<CharacterControllerComponent>();
|
||||
if (moveComponent != null)
|
||||
{
|
||||
if (message.IsStop)
|
||||
{
|
||||
moveComponent.OnServerStopMove(message.Position.ToVector3(), message.Timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
moveComponent.OnServerStartMove(message.Position.ToVector3(),
|
||||
message.Direction.ToVector3(), 3, message.Timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2306a332c3f842e78fd8d70c9ef1f8ed
|
||||
timeCreated: 1757148423
|
||||
@@ -0,0 +1,26 @@
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using Fantasy.Network;
|
||||
using Fantasy.Network.Interface;
|
||||
using NBC;
|
||||
using Log = NBC.Log;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public class Map2C_RolePropertyChangeNotifyHandler : Message<Map2C_RolePropertyChangeNotify>
|
||||
{
|
||||
protected override async FTask Run(Session session, Map2C_RolePropertyChangeNotify message)
|
||||
{
|
||||
Log.Info($"收到角色属性推送 id={message.Id}");
|
||||
var map = App.Main.GetComponent<Map>();
|
||||
var unit = map.Units[message.Id];
|
||||
var numericComponent = unit.GetComponent<NumericComponent>();
|
||||
foreach (var property in message.Propertys)
|
||||
{
|
||||
numericComponent.Set(property.Key, property.Value);
|
||||
}
|
||||
|
||||
await FTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b507863390534ecca584e3a787180493
|
||||
timeCreated: 1757820797
|
||||
3
Assets/Scripts/Fishing2~/Mono.meta
Normal file
3
Assets/Scripts/Fishing2~/Mono.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53262d3faa5141deb0c8809a4354daa0
|
||||
timeCreated: 1756820602
|
||||
13
Assets/Scripts/Fishing2~/Mono/CameraAsset.cs
Normal file
13
Assets/Scripts/Fishing2~/Mono/CameraAsset.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Cinemachine;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public class CameraAsset : MonoBehaviour
|
||||
{
|
||||
public CinemachineVirtualCamera fppVCam;
|
||||
|
||||
public CinemachineVirtualCamera tppVCam;
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Mono/CameraAsset.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Mono/CameraAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5dd3e6b2217c463e94e32f15c4ea3c5c
|
||||
timeCreated: 1765306413
|
||||
58
Assets/Scripts/Fishing2~/Mono/PlayerArm.cs
Normal file
58
Assets/Scripts/Fishing2~/Mono/PlayerArm.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using RootMotion.FinalIK;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class PlayerArm : MonoBehaviour
|
||||
{
|
||||
public bool IsLeft;
|
||||
public LimbIK IK;
|
||||
public Transform RodContainer;
|
||||
public Transform LeftRigMagnet;
|
||||
public FingerRig FingerRig;
|
||||
public PlayerShoulder Shoulder;//PlayerShoulder
|
||||
|
||||
[HideInInspector] public float interactionTargetWeight;
|
||||
|
||||
|
||||
public void SetReelHandle(ReelAsset asset)
|
||||
{
|
||||
IK.solver.target = asset.handle;
|
||||
IK.enabled = true;
|
||||
|
||||
// var fingers = FingerRig.fingers;
|
||||
// foreach (var finger in fingers)
|
||||
// {
|
||||
// finger.target = asset.handleEnd;
|
||||
// }
|
||||
|
||||
// // 启用整体控制
|
||||
// FingerRig.weight = 1f;
|
||||
//
|
||||
// // 绑定大拇指和食指的目标
|
||||
// FingerRig.fingers[0].target = asset.handleEnd; // Thumb
|
||||
// FingerRig.fingers[1].target = asset.handleEnd; // Index
|
||||
//
|
||||
// FingerRig.fingers[0].weight = 1f;
|
||||
// FingerRig.fingers[1].weight = 1f;
|
||||
|
||||
// 其余手指握拳(不绑定 target)
|
||||
for (int i = 2; i < 5; i++)
|
||||
{
|
||||
FingerRig.fingers[i].target = null;
|
||||
FingerRig.fingers[i].weight = 1f;
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveTowardsInteraction()
|
||||
{
|
||||
if (!IK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IK.solver.SetIKPositionWeight(Mathf.MoveTowards(IK.solver.IKPositionWeight,
|
||||
interactionTargetWeight, Time.deltaTime * 2f));
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Mono/PlayerArm.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Mono/PlayerArm.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed33e261a2784ee0814ceaa6c88aefdf
|
||||
timeCreated: 1756821001
|
||||
37
Assets/Scripts/Fishing2~/Mono/PlayerShoulder.cs
Normal file
37
Assets/Scripts/Fishing2~/Mono/PlayerShoulder.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF
|
||||
{
|
||||
public class PlayerShoulder : MonoBehaviour
|
||||
{
|
||||
private Vector3 startEulerAngles;
|
||||
private const int MaxAngle = 30;
|
||||
private const int MinAngle = -30;
|
||||
|
||||
|
||||
public float TestZ;
|
||||
private void Awake()
|
||||
{
|
||||
startEulerAngles = transform.localEulerAngles;
|
||||
}
|
||||
|
||||
public void SetCameraEulerAngleX(float value)
|
||||
{
|
||||
value = (value > 180f) ? value - 360f : value;
|
||||
Debug.Log($"value={value}");
|
||||
var addValue = value * -1;
|
||||
if (addValue > MaxAngle)
|
||||
{
|
||||
addValue = MaxAngle;
|
||||
}
|
||||
else if (addValue < MinAngle)
|
||||
{
|
||||
addValue = MinAngle;
|
||||
}
|
||||
|
||||
transform.localEulerAngles =
|
||||
new Vector3(addValue + startEulerAngles.x, startEulerAngles.y, TestZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Mono/PlayerShoulder.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Mono/PlayerShoulder.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f85286904d2d45738c4b415f3503d4ab
|
||||
timeCreated: 1756820965
|
||||
3
Assets/Scripts/Fishing2~/Unit.meta
Normal file
3
Assets/Scripts/Fishing2~/Unit.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1fb0ee12d9cf40408478e8f9ad9aafdd
|
||||
timeCreated: 1755915944
|
||||
3
Assets/Scripts/Fishing2~/Unit/Equipment.meta
Normal file
3
Assets/Scripts/Fishing2~/Unit/Equipment.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35bf130c632b4a31b064a6d0706aba65
|
||||
timeCreated: 1757835845
|
||||
@@ -0,0 +1,69 @@
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
/// <summary>
|
||||
/// 手电筒组件
|
||||
/// </summary>
|
||||
public class FlashlightComponent : Entity
|
||||
{
|
||||
private GameObject _fishingLight;
|
||||
|
||||
|
||||
public class FlashlightComponentAwakeSystem : AwakeSystem<FlashlightComponent>
|
||||
{
|
||||
protected override void Awake(FlashlightComponent self)
|
||||
{
|
||||
var numericComponent = self.Parent.GetComponent<NumericComponent>();
|
||||
var unityComponent = self.Parent.GetComponent<UnitUnityComponent>();
|
||||
// self._fishingLight = unityComponent.Asset.FishingLight;
|
||||
// self.Change(numericComponent[NumericType.Flashlight]);
|
||||
|
||||
var mapUnit = self.Parent as MapUnit;
|
||||
if (mapUnit.IsSelf())
|
||||
{
|
||||
var inputComponent = self.Scene.GetComponent<InputComponent>();
|
||||
inputComponent.OnPlayerPerformed += self.OnPlayerCanceled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class FlashlightComponentDestroySystem : DestroySystem<FlashlightComponent>
|
||||
{
|
||||
protected override void Destroy(FlashlightComponent self)
|
||||
{
|
||||
self._fishingLight = null;
|
||||
var mapUnit = self.Parent as MapUnit;
|
||||
if (mapUnit.IsSelf())
|
||||
{
|
||||
var inputComponent = self.Scene.GetComponent<InputComponent>();
|
||||
if (inputComponent != null)
|
||||
{
|
||||
inputComponent.OnPlayerPerformed -= self.OnPlayerCanceled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void OnPlayerCanceled(string action)
|
||||
{
|
||||
if (action == InputDef.Player.UseTorch)
|
||||
{
|
||||
var numericComponent = Parent.GetComponent<NumericComponent>();
|
||||
if (numericComponent != null)
|
||||
{
|
||||
var oldValue = numericComponent[NumericType.Flashlight];
|
||||
numericComponent[NumericType.Flashlight] = oldValue > 0 ? 0 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Change(long value)
|
||||
{
|
||||
_fishingLight.SetActive(value > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b498c6d3db5b4d44a1dc99b547416d59
|
||||
timeCreated: 1757836076
|
||||
3
Assets/Scripts/Fishing2~/Unit/Event.meta
Normal file
3
Assets/Scripts/Fishing2~/Unit/Event.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c61b32e7992466f9771eac80763078e
|
||||
timeCreated: 1765523393
|
||||
3
Assets/Scripts/Fishing2~/Unit/Gear.meta
Normal file
3
Assets/Scripts/Fishing2~/Unit/Gear.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 70bbe8d6e0c04cdaa553cacaee37fe59
|
||||
timeCreated: 1755921259
|
||||
16
Assets/Scripts/Fishing2~/Unit/Gear/MapUnitGear.cs
Normal file
16
Assets/Scripts/Fishing2~/Unit/Gear/MapUnitGear.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using Fantasy.Entitas;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
/// <summary>
|
||||
/// 玩家组件
|
||||
/// </summary>
|
||||
public class MapUnitGear : Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// 绑定的子组件
|
||||
/// </summary>
|
||||
public List<MapUnitGearPart> Binding = new List<MapUnitGearPart>();
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Unit/Gear/MapUnitGear.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Unit/Gear/MapUnitGear.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01c5cf0e015042fbae5000cff14bb419
|
||||
timeCreated: 1766325287
|
||||
12
Assets/Scripts/Fishing2~/Unit/Gear/MapUnitGearPart.cs
Normal file
12
Assets/Scripts/Fishing2~/Unit/Gear/MapUnitGearPart.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Fantasy.Entitas;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public class MapUnitGearPart : Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置表id
|
||||
/// </summary>
|
||||
public int ConfigId { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a83db5681be745a3b692da5c82496a40
|
||||
timeCreated: 1766325663
|
||||
120
Assets/Scripts/Fishing2~/Unit/MapUnit.cs
Normal file
120
Assets/Scripts/Fishing2~/Unit/MapUnit.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System.Collections.Generic;
|
||||
using Fantasy;
|
||||
using Fantasy.Async;
|
||||
using NBC;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
/// <summary>
|
||||
/// 单位
|
||||
/// </summary>
|
||||
public class MapUnit : Entity
|
||||
{
|
||||
public int ConfigId { get; set; } //配置表id
|
||||
|
||||
/// <summary>
|
||||
/// 钓组信息
|
||||
/// </summary>
|
||||
public List<MapUnitGear> Gears = new List<MapUnitGear>();
|
||||
|
||||
/// <summary>
|
||||
/// 是否在地面
|
||||
/// </summary>
|
||||
public bool IsGrounded { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否在水里
|
||||
/// </summary>
|
||||
public bool IsInWater { get; set; }
|
||||
|
||||
public float Speed { get; set; }
|
||||
public float RotationSpeed { get; set; }
|
||||
|
||||
private Vector3 position; //坐标
|
||||
|
||||
public Vector3 Position
|
||||
{
|
||||
get => position;
|
||||
set
|
||||
{
|
||||
// Vector3 oldPos = position;
|
||||
position = value;
|
||||
// Scene.EventComponent.Publish(new ChangePosition() { MapUnit = this, OldPos = oldPos });
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 Forward
|
||||
{
|
||||
get => math.mul(Rotation, math.forward());
|
||||
set => Rotation = Quaternion.LookRotation(value, math.up());
|
||||
}
|
||||
|
||||
private Quaternion rotation;
|
||||
|
||||
public Quaternion Rotation
|
||||
{
|
||||
get => rotation;
|
||||
set
|
||||
{
|
||||
rotation = value;
|
||||
// Scene.EventComponent.Publish(new ChangeRotation() { MapUnit = this });
|
||||
}
|
||||
}
|
||||
|
||||
public MapUnitState State { get; set; }
|
||||
|
||||
public string StateArgs { get; set; }
|
||||
|
||||
#region System
|
||||
|
||||
public class MapUnitDestroySystem : DestroySystem<MapUnit>
|
||||
{
|
||||
protected override void Destroy(MapUnit self)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void ChangeState(MapUnitState state, string args)
|
||||
{
|
||||
Scene.EventComponent.Publish(new ChangeState() { MapUnit = this, State = state, Args = args });
|
||||
}
|
||||
|
||||
|
||||
public void SetUnitInfo(MapUnitInfo unitInfo)
|
||||
{
|
||||
GetOrAddComponent<ObjectWait>();
|
||||
var unitBasic = GetOrAddComponent<MapUnitBasic>();
|
||||
unitBasic.UpdateInfo(unitInfo);
|
||||
|
||||
// unitInfo.Gears
|
||||
|
||||
var numericComponent = GetOrAddComponent<NumericComponent>();
|
||||
foreach (var kv in unitInfo.Propertys)
|
||||
{
|
||||
numericComponent.Set(kv.Key, kv.Value);
|
||||
}
|
||||
}
|
||||
|
||||
#region View
|
||||
|
||||
public async FTask CreateView()
|
||||
{
|
||||
var unitUnity = GetComponent<UnitUnityComponent>();
|
||||
if (unitUnity != null)
|
||||
{
|
||||
unitUnity.Dispose();
|
||||
}
|
||||
|
||||
unitUnity = AddComponent<UnitUnityComponent>();
|
||||
await unitUnity.InitUnityObject();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Unit/MapUnit.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Unit/MapUnit.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff176fc098254fe2a1b48ea26eaf8857
|
||||
timeCreated: 1755915448
|
||||
39
Assets/Scripts/Fishing2~/Unit/MapUnitBasic.cs
Normal file
39
Assets/Scripts/Fishing2~/Unit/MapUnitBasic.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using Fantasy;
|
||||
using NBC;
|
||||
using Fantasy.Entitas;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public class MapUnitBasic : Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// 昵称
|
||||
/// </summary>
|
||||
public string NickName;
|
||||
|
||||
/// <summary>
|
||||
/// 头像
|
||||
/// </summary>
|
||||
public string Head;
|
||||
|
||||
/// <summary>
|
||||
/// 国家
|
||||
/// </summary>
|
||||
public string Country;
|
||||
|
||||
/// <summary>
|
||||
/// 等级
|
||||
/// </summary>
|
||||
public int Level;
|
||||
|
||||
|
||||
public void UpdateInfo(MapUnitInfo mapUnitInfo)
|
||||
{
|
||||
if (mapUnitInfo.RoleInfo == null) return;
|
||||
NickName = mapUnitInfo.RoleInfo.NickName;
|
||||
Head = mapUnitInfo.RoleInfo.Head;
|
||||
Country = mapUnitInfo.RoleInfo.Country;
|
||||
Level = mapUnitInfo.RoleInfo.Level;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Unit/MapUnitBasic.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Unit/MapUnitBasic.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fac7cf28f53b4a929d2584c9a95fd242
|
||||
timeCreated: 1756881253
|
||||
3
Assets/Scripts/Fishing2~/Unit/Move.meta
Normal file
3
Assets/Scripts/Fishing2~/Unit/Move.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 309507c5427f4a95bb64f526ce60ded0
|
||||
timeCreated: 1757820516
|
||||
@@ -0,0 +1,427 @@
|
||||
using System.Collections.Generic;
|
||||
using Fantasy;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
using Fantasy.Helper;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using Log = NBC.Log;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
[System.Serializable]
|
||||
public struct MoveState
|
||||
{
|
||||
public Vector3 startPosition; // 开始移动时的位置
|
||||
public Vector3 moveDirection; // 移动方向(标准化向量)
|
||||
public float moveSpeed; // 移动速度
|
||||
public bool isMoving; // 是否正在移动
|
||||
public double serverTimestamp; // 服务器时间戳
|
||||
}
|
||||
|
||||
public class CharacterControllerComponent : Entity
|
||||
{
|
||||
public bool IsSelf;
|
||||
public bool Run;
|
||||
public CharacterController characterController;
|
||||
public PlayerModelAsset PlayerModelAsset;
|
||||
|
||||
public readonly Queue<MoveState> MoveStateQueue = new Queue<MoveState>();
|
||||
|
||||
public Transform transform => characterController.transform;
|
||||
private MoveState currentMoveState;
|
||||
|
||||
// private Vector3 networkFacingDirection;
|
||||
|
||||
// 添加目标位置和旋转用于插值
|
||||
private Vector3 targetPosition;
|
||||
private Quaternion targetRotation;
|
||||
|
||||
// 插值平滑参数
|
||||
public float positionLerpSpeed = 10f;
|
||||
public float rotationLerpSpeed = 10f;
|
||||
|
||||
|
||||
private float currentSpeed = 0f;
|
||||
private float acceleration = 10f; // 加速度
|
||||
|
||||
/// <summary>
|
||||
/// 重力加速度
|
||||
/// </summary>
|
||||
private float gravity = 9.81f;
|
||||
|
||||
|
||||
private Vector3 currentVelocity = Vector3.zero;
|
||||
private float verticalVelocity = 0f;
|
||||
|
||||
private float groundedGravity = -0.5f; // 小的向下力确保角色保持在地面
|
||||
private float airControl = 0.5f; // 空中控制系数
|
||||
|
||||
#region System
|
||||
|
||||
public class MoveComponentDestroySystem : DestroySystem<CharacterControllerComponent>
|
||||
{
|
||||
protected override void Destroy(CharacterControllerComponent self)
|
||||
{
|
||||
self.characterController = null;
|
||||
self.IsSelf = false;
|
||||
self.Run = false;
|
||||
var mapUnit = self.Parent as MapUnit;
|
||||
if (mapUnit.IsSelf())
|
||||
{
|
||||
var inputComponent = self.Scene.GetComponent<InputComponent>();
|
||||
if (inputComponent != null)
|
||||
{
|
||||
inputComponent.OnPlayerPerformed -= self.OnPlayerCanceled;
|
||||
inputComponent.OnPlayerPerformed -= self.OnPlayerPerformed;
|
||||
|
||||
inputComponent.OnPlayerValueCanceled -= self.OnPlayerValueCanceled;
|
||||
inputComponent.OnPlayerValuePerformed -= self.OnPlayerValuePerformed;
|
||||
}
|
||||
}
|
||||
|
||||
self.PlayerModelAsset = null;
|
||||
}
|
||||
}
|
||||
|
||||
public class MoveComponentAwakeSystem : AwakeSystem<CharacterControllerComponent>
|
||||
{
|
||||
protected override void Awake(CharacterControllerComponent self)
|
||||
{
|
||||
var unitUnityComponent = self.Parent.GetComponent<UnitUnityComponent>();
|
||||
self.PlayerModelAsset = unitUnityComponent.ModelAsset;
|
||||
self.characterController = unitUnityComponent.GameObject.GetComponent<CharacterController>();
|
||||
self.lastSyncedFacing = self.characterController.transform.forward;
|
||||
// 初始化目标位置和旋转
|
||||
self.targetPosition = self.characterController.transform.position;
|
||||
self.targetRotation = self.characterController.transform.rotation;
|
||||
self.characterController.enabled = true;
|
||||
var mapUnit = self.Parent as MapUnit;
|
||||
if (mapUnit.IsSelf())
|
||||
{
|
||||
self.IsSelf = true;
|
||||
var inputComponent = self.Scene.GetComponent<InputComponent>();
|
||||
inputComponent.OnPlayerPerformed += self.OnPlayerCanceled;
|
||||
inputComponent.OnPlayerPerformed += self.OnPlayerPerformed;
|
||||
|
||||
inputComponent.OnPlayerValueCanceled += self.OnPlayerValueCanceled;
|
||||
inputComponent.OnPlayerValuePerformed += self.OnPlayerValuePerformed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MoveComponentUpdateSystem : UpdateSystem<CharacterControllerComponent>
|
||||
{
|
||||
protected override void Update(CharacterControllerComponent self)
|
||||
{
|
||||
self.ProcessMoveStates();
|
||||
self.CheckRotationSync();
|
||||
// 插值更新位置和旋转
|
||||
self.InterpolatePositionAndRotation();
|
||||
var mapUnit = self.Parent as MapUnit;
|
||||
mapUnit.Position = self.characterController.transform.position;
|
||||
mapUnit.Rotation = self.characterController.transform.rotation;
|
||||
var f = mapUnit.Forward;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Input
|
||||
|
||||
private void OnPlayerPerformed(string action)
|
||||
{
|
||||
if (action == InputDef.Player.Run)
|
||||
{
|
||||
Run = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPlayerCanceled(string action)
|
||||
{
|
||||
if (action == InputDef.Player.Run)
|
||||
{
|
||||
Run = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPlayerValueCanceled(InputAction.CallbackContext context)
|
||||
{
|
||||
var name = context.action.name;
|
||||
if (name == InputDef.Player.Move)
|
||||
{
|
||||
var v2 = context.ReadValue<Vector2>();
|
||||
SendMoveMessage(v2, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPlayerValuePerformed(InputAction.CallbackContext context)
|
||||
{
|
||||
// var mapUnit = Parent as MapUnit;
|
||||
// Log.Info($"OnPlayerValuePerformed IsSelf={mapUnit.IsSelf()} id={mapUnit.Id}");
|
||||
var name = context.action.name;
|
||||
if (name == InputDef.Player.Move)
|
||||
{
|
||||
var v2 = context.ReadValue<Vector2>();
|
||||
SendMoveMessage(v2, false);
|
||||
}
|
||||
else if (name == InputDef.Player.Look)
|
||||
{
|
||||
var v2 = context.ReadValue<Vector2>();
|
||||
UpdatePlayerRotation(v2);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Message
|
||||
|
||||
private void SendMoveMessage(Vector3 movementInput, bool isStop = false)
|
||||
{
|
||||
var mapUnit = Parent as MapUnit;
|
||||
|
||||
Vector3 movementDirection = Vector3.zero;
|
||||
|
||||
// 发送本地相对坐标而不是世界坐标
|
||||
if (!isStop)
|
||||
{
|
||||
movementDirection = new Vector3(movementInput.x, 0, movementInput.y);
|
||||
}
|
||||
|
||||
Net.Send(new C2Map_Move()
|
||||
{
|
||||
Direction = movementDirection.ToVector3Info(),
|
||||
IsStop = isStop,
|
||||
IsRun = Run,
|
||||
Timestamp = TimeHelper.Now,
|
||||
Position = mapUnit.Position.ToVector3Info(),
|
||||
Rotation = mapUnit.Forward.ToVector3Info(),
|
||||
});
|
||||
}
|
||||
|
||||
private void SendLookMessage()
|
||||
{
|
||||
Log.Info("发送朝向同步消息");
|
||||
Net.Send(new C2Map_Look()
|
||||
{
|
||||
Rotation = characterController.transform.forward.ToVector3Info(),
|
||||
Timestamp = TimeHelper.Now
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 接收服务器移动开始通知
|
||||
/// </summary>
|
||||
/// <param name="startPosition"></param>
|
||||
/// <param name="moveDirection"></param>
|
||||
/// <param name="speed"></param>
|
||||
/// <param name="timestamp"></param>
|
||||
public void OnServerStartMove(Vector3 startPosition, Vector3 moveDirection, float speed, double timestamp)
|
||||
{
|
||||
MoveState moveState = new MoveState
|
||||
{
|
||||
startPosition = startPosition,
|
||||
moveDirection = moveDirection.normalized,
|
||||
moveSpeed = speed,
|
||||
isMoving = true,
|
||||
serverTimestamp = timestamp
|
||||
};
|
||||
|
||||
MoveStateQueue.Enqueue(moveState);
|
||||
Log.Info($"MoveStateQueue Count={MoveStateQueue.Count}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 接收服务器移动停止通知
|
||||
/// </summary>
|
||||
/// <param name="finalPosition"></param>
|
||||
/// <param name="timestamp"></param>
|
||||
public void OnServerStopMove(Vector3 finalPosition, double timestamp)
|
||||
{
|
||||
MoveState moveState = new MoveState
|
||||
{
|
||||
startPosition = finalPosition,
|
||||
moveDirection = Vector3.zero,
|
||||
moveSpeed = 0f,
|
||||
isMoving = false,
|
||||
serverTimestamp = timestamp
|
||||
};
|
||||
|
||||
MoveStateQueue.Enqueue(moveState);
|
||||
Log.Info($"MoveStateQueue Count={MoveStateQueue.Count}");
|
||||
}
|
||||
|
||||
|
||||
public void OnServerLook(Vector3 rotation, double timestamp)
|
||||
{
|
||||
// 设置目标旋转用于插值
|
||||
targetRotation = Quaternion.LookRotation(rotation);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Move
|
||||
|
||||
private void ProcessMoveStates()
|
||||
{
|
||||
// 只有在当前状态不是移动状态时,才处理下一个状态
|
||||
if (MoveStateQueue.Count > 0)
|
||||
{
|
||||
currentMoveState = MoveStateQueue.Dequeue();
|
||||
|
||||
if (currentMoveState.isMoving)
|
||||
{
|
||||
StartMovement(currentMoveState);
|
||||
}
|
||||
else
|
||||
{
|
||||
StopMovement(currentMoveState);
|
||||
}
|
||||
}
|
||||
|
||||
// 如果正在移动,持续更新
|
||||
if (currentMoveState.isMoving)
|
||||
{
|
||||
UpdateMovement();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void StartMovement(MoveState moveState)
|
||||
{
|
||||
targetPosition = moveState.startPosition;
|
||||
Debug.Log($"开始移动 - 位置: {moveState.startPosition}");
|
||||
}
|
||||
|
||||
private void StopMovement(MoveState moveState)
|
||||
{
|
||||
targetPosition = moveState.startPosition;
|
||||
Debug.Log($"停止移动 - 最终位置: {moveState.startPosition}");
|
||||
}
|
||||
|
||||
private void UpdateMovement()
|
||||
{
|
||||
// 将本地相对方向转换为世界方向
|
||||
Vector3 localDirection = currentMoveState.moveDirection;
|
||||
Vector3 characterRight = Vector3.ProjectOnPlane(characterController.transform.right, Vector3.up).normalized;
|
||||
Vector3 characterForward = Vector3.ProjectOnPlane(characterController.transform.forward, Vector3.up).normalized;
|
||||
Vector3 movementDirection = characterForward * localDirection.z + characterRight * localDirection.x;
|
||||
|
||||
float targetSpeed = currentMoveState.moveSpeed;
|
||||
|
||||
// 平滑加速
|
||||
if (movementDirection.magnitude > 0.1f)
|
||||
{
|
||||
currentSpeed = Mathf.Lerp(currentSpeed, targetSpeed, acceleration * Time.deltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentSpeed = Mathf.Lerp(currentSpeed, 0f, acceleration * 2f * Time.deltaTime);
|
||||
}
|
||||
|
||||
// 处理重力
|
||||
if (characterController.isGrounded)
|
||||
{
|
||||
verticalVelocity = groundedGravity;
|
||||
|
||||
// 地面移动 - 完全控制
|
||||
currentVelocity = Vector3.Lerp(currentVelocity, movementDirection.normalized * currentSpeed,
|
||||
acceleration * Time.deltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
verticalVelocity -= gravity * Time.deltaTime;
|
||||
|
||||
// 空中移动 - 有限控制
|
||||
Vector3 targetAirVelocity = movementDirection.normalized * currentSpeed * airControl;
|
||||
currentVelocity = Vector3.Lerp(currentVelocity,
|
||||
new Vector3(targetAirVelocity.x, currentVelocity.y, targetAirVelocity.z),
|
||||
acceleration * Time.deltaTime);
|
||||
}
|
||||
|
||||
// 组合移动
|
||||
Vector3 totalMovement = currentVelocity * Time.deltaTime;
|
||||
totalMovement.y = verticalVelocity * Time.deltaTime;
|
||||
|
||||
Log.Info($"移动=== Id={Parent.Id} 位置: {characterController.transform.position} 移动量: {totalMovement}");
|
||||
|
||||
characterController.Move(totalMovement);
|
||||
}
|
||||
|
||||
// 添加位置和旋转插值方法
|
||||
private void InterpolatePositionAndRotation()
|
||||
{
|
||||
// 只对非本地玩家进行插值
|
||||
if (!IsSelf)
|
||||
{
|
||||
// 插值位置
|
||||
// characterController.transform.position = Vector3.Lerp(
|
||||
// characterController.transform.position,
|
||||
// targetPosition,
|
||||
// positionLerpSpeed * Time.deltaTime);
|
||||
|
||||
// 插值旋转 - 使用更平滑的插值方法
|
||||
characterController.transform.rotation = Quaternion.Slerp(
|
||||
characterController.transform.rotation,
|
||||
targetRotation,
|
||||
rotationLerpSpeed * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Look
|
||||
|
||||
public float rotationSyncInterval = 0.15f;
|
||||
public float minRotationChange = 10f;
|
||||
|
||||
private Vector3 _rotationInput = Vector3.zero;
|
||||
private float rotationSyncTimer;
|
||||
private Vector3 lastSyncedFacing;
|
||||
private bool isRotating = false;
|
||||
|
||||
[Tooltip("视角旋转敏感度")] public Vector2 sensitivity = new Vector2(0.015f, 0.015f);
|
||||
|
||||
private void UpdatePlayerRotation(Vector2 lookValue)
|
||||
{
|
||||
// Look
|
||||
Vector2 lookInput = lookValue * sensitivity;
|
||||
|
||||
// 处理水平旋转 (Yaw)
|
||||
if (lookInput.x != 0.0f)
|
||||
{
|
||||
_rotationInput.y += lookInput.x;
|
||||
isRotating = true;
|
||||
}
|
||||
|
||||
// 应用旋转到角色和相机
|
||||
if (_rotationInput != Vector3.zero)
|
||||
{
|
||||
characterController.transform.rotation *= Quaternion.Euler(0, _rotationInput.y, 0);
|
||||
_rotationInput = Vector3.zero;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查朝向同步
|
||||
private void CheckRotationSync()
|
||||
{
|
||||
if (!IsSelf) return;
|
||||
rotationSyncTimer += Time.deltaTime;
|
||||
if (rotationSyncTimer >= rotationSyncInterval)
|
||||
{
|
||||
float angleChange = Vector3.Angle(transform.forward, lastSyncedFacing);
|
||||
|
||||
// 修改:即使在旋转中也定期同步朝向,避免累积误差
|
||||
if (angleChange >= minRotationChange || isRotating)
|
||||
{
|
||||
SendLookMessage();
|
||||
lastSyncedFacing = transform.forward;
|
||||
rotationSyncTimer = 0f;
|
||||
isRotating = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 36fb267f0f5149caa23ac1b6cf005067
|
||||
timeCreated: 1757164955
|
||||
108
Assets/Scripts/Fishing2~/Unit/Move/CharacterLookComponent.cs
Normal file
108
Assets/Scripts/Fishing2~/Unit/Move/CharacterLookComponent.cs
Normal file
@@ -0,0 +1,108 @@
|
||||
using ECM2.Examples.FirstPerson;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public class CharacterLookComponent : Entity
|
||||
{
|
||||
// private UnitUnityComponent _UnitUnityComponent;
|
||||
public FirstPersonCharacter FirstPerson { get; set; }
|
||||
private float lookXRot;
|
||||
private float lookYRot;
|
||||
private Vector2 _moveInput;
|
||||
|
||||
public float MouseSensitivity = 0.1f;
|
||||
[Space(15f)] public bool invertLook = true;
|
||||
|
||||
public float minPitch = -60f;
|
||||
|
||||
public float maxPitch = 60f;
|
||||
|
||||
|
||||
private InputComponent _inputComponent;
|
||||
private Quaternion lastRotation;
|
||||
public MapUnit MapUnit;
|
||||
|
||||
#region System
|
||||
|
||||
public class LookComponentDestroySystem : DestroySystem<CharacterLookComponent>
|
||||
{
|
||||
protected override void Destroy(CharacterLookComponent self)
|
||||
{
|
||||
self.FirstPerson = null;
|
||||
// var mapUnit = self.Parent as MapUnit;
|
||||
|
||||
self._inputComponent = null;
|
||||
}
|
||||
}
|
||||
|
||||
public class LookComponentAwakeSystem : AwakeSystem<CharacterLookComponent>
|
||||
{
|
||||
protected override void Awake(CharacterLookComponent self)
|
||||
{
|
||||
var mapUnit = self.Parent as MapUnit;
|
||||
self.MapUnit = mapUnit;
|
||||
var unitUnityComponent = self.Parent.GetComponent<UnitUnityComponent>();
|
||||
self.FirstPerson = unitUnityComponent.FirstPerson;
|
||||
self._inputComponent = self.Scene.GetComponent<InputComponent>();
|
||||
}
|
||||
}
|
||||
|
||||
public class LookComponentUpdateSystem : UpdateSystem<CharacterLookComponent>
|
||||
{
|
||||
protected override void Update(CharacterLookComponent self)
|
||||
{
|
||||
self.UpdateLookInput();
|
||||
}
|
||||
}
|
||||
|
||||
// public class LookComponentLateUpdateSystem : LateUpdateSystem<CharacterLookComponent>
|
||||
// {
|
||||
// protected override void LateUpdate(CharacterLookComponent self)
|
||||
// {
|
||||
// self.UpdateLookInput();
|
||||
// }
|
||||
// }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
private void UpdateLookInput()
|
||||
{
|
||||
|
||||
// TPPLookTarget.position = base.transform.position;
|
||||
// if (CameraView.Value == CameraViewType.TPP)
|
||||
// {
|
||||
// lookXRot -= MouseInput.Value.y;
|
||||
// lookXRot = Mathf.Clamp(lookXRot, -25f, 55f);
|
||||
// lookYRot += MouseInput.Value.x;
|
||||
// lookYRot = Mathf.Repeat(lookYRot, 360f);
|
||||
// TPPLookTarget.localEulerAngles = new Vector3(lookXRot, lookYRot, 0f);
|
||||
// }
|
||||
// else if (CameraView.Value == CameraViewType.FPP)
|
||||
{
|
||||
// if (_IsInVehicle && PlayerState.Value == State.vehicle)
|
||||
// {
|
||||
// lookXRot -= MouseInput.Value.y;
|
||||
// lookXRot = Mathf.Clamp(lookXRot, VehicleLookXMinMax.x, VehicleLookXMinMax.y);
|
||||
// lookYRot += MouseInput.Value.x;
|
||||
// lookYRot = Mathf.Clamp(lookYRot, VehicleLookYMinMax.x, VehicleLookYMinMax.y);
|
||||
// VehicleLookTargetParent.localEulerAngles = new Vector3(lookXRot, lookYRot, 0f);
|
||||
// _character.CameraPitch = 0f;
|
||||
// }
|
||||
// else
|
||||
{
|
||||
Vector2 value = _inputComponent.GetLookInput();
|
||||
FirstPerson.AddControlYawInput(value.x * (float)MouseSensitivity);
|
||||
FirstPerson.AddControlPitchInput((invertLook ? (0f - value.y) : value.y) * (float)MouseSensitivity,
|
||||
minPitch, maxPitch);
|
||||
// lookXRot = base.transform.eulerAngles.x;
|
||||
// lookYRot = base.transform.eulerAngles.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 316d2e71f8b3473e961ac86ce4568704
|
||||
timeCreated: 1765283815
|
||||
214
Assets/Scripts/Fishing2~/Unit/Move/CharacterMovementComponent.cs
Normal file
214
Assets/Scripts/Fishing2~/Unit/Move/CharacterMovementComponent.cs
Normal file
@@ -0,0 +1,214 @@
|
||||
using ECM2;
|
||||
using ECM2.Examples.FirstPerson;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public class CharacterMovementComponent : Entity
|
||||
{
|
||||
public bool IsSelf;
|
||||
public bool Run;
|
||||
|
||||
private Vector2 _moveInput;
|
||||
public MapUnit MapUnit;
|
||||
|
||||
private FirstPersonCharacter _Character;
|
||||
private Quaternion lastRotation;
|
||||
|
||||
#region System
|
||||
|
||||
public class MovementComponentDestroySystem : DestroySystem<CharacterMovementComponent>
|
||||
{
|
||||
protected override void Destroy(CharacterMovementComponent self)
|
||||
{
|
||||
// self.characterController = null;
|
||||
self.IsSelf = false;
|
||||
self.Run = false;
|
||||
var mapUnit = self.Parent as MapUnit;
|
||||
if (mapUnit.IsSelf())
|
||||
{
|
||||
var inputComponent = self.Scene.GetComponent<InputComponent>();
|
||||
if (inputComponent != null)
|
||||
{
|
||||
inputComponent.OnPlayerPerformed -= self.OnPlayerCanceled;
|
||||
inputComponent.OnPlayerPerformed -= self.OnPlayerPerformed;
|
||||
|
||||
inputComponent.OnPlayerValueCanceled -= self.OnPlayerValueCanceled;
|
||||
inputComponent.OnPlayerValuePerformed -= self.OnPlayerValuePerformed;
|
||||
}
|
||||
}
|
||||
|
||||
// self.PlayerAsset = null;
|
||||
}
|
||||
}
|
||||
|
||||
public class MovementComponentAwakeSystem : AwakeSystem<CharacterMovementComponent>
|
||||
{
|
||||
protected override void Awake(CharacterMovementComponent self)
|
||||
{
|
||||
var unitUnityComponent = self.Parent.GetComponent<UnitUnityComponent>();
|
||||
self._Character = unitUnityComponent.FirstPerson;
|
||||
var mapUnit = self.Parent as MapUnit;
|
||||
self.MapUnit = mapUnit;
|
||||
if (mapUnit.IsSelf())
|
||||
{
|
||||
self.IsSelf = true;
|
||||
var inputComponent = self.Scene.GetComponent<InputComponent>();
|
||||
inputComponent.OnPlayerPerformed += self.OnPlayerCanceled;
|
||||
inputComponent.OnPlayerPerformed += self.OnPlayerPerformed;
|
||||
|
||||
inputComponent.OnPlayerValueCanceled += self.OnPlayerValueCanceled;
|
||||
inputComponent.OnPlayerValuePerformed += self.OnPlayerValuePerformed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MovementComponentUpdateSystem : UpdateSystem<CharacterMovementComponent>
|
||||
{
|
||||
protected override void Update(CharacterMovementComponent self)
|
||||
{
|
||||
self.UpdateGrounded();
|
||||
self.UpdateWater();
|
||||
self.ProcessMoveStates();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Input
|
||||
|
||||
private void OnPlayerPerformed(string action)
|
||||
{
|
||||
if (action == InputDef.Player.Run)
|
||||
{
|
||||
Run = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPlayerCanceled(string action)
|
||||
{
|
||||
if (action == InputDef.Player.Run)
|
||||
{
|
||||
Run = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPlayerValueCanceled(InputAction.CallbackContext context)
|
||||
{
|
||||
var name = context.action.name;
|
||||
if (name == InputDef.Player.Move)
|
||||
{
|
||||
// var v2 = context.ReadValue<Vector2>();
|
||||
_moveInput = Vector2.zero;
|
||||
// SendMoveMessage(v2, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPlayerValuePerformed(InputAction.CallbackContext context)
|
||||
{
|
||||
// var mapUnit = Parent as MapUnit;
|
||||
// Log.Info($"OnPlayerValuePerformed IsSelf={mapUnit.IsSelf()} id={mapUnit.Id}");
|
||||
var name = context.action.name;
|
||||
if (name == InputDef.Player.Move)
|
||||
{
|
||||
var v2 = context.ReadValue<Vector2>();
|
||||
_moveInput = v2;
|
||||
// SendMoveMessage(v2, false);
|
||||
}
|
||||
else if (name == InputDef.Player.Look)
|
||||
{
|
||||
var v2 = context.ReadValue<Vector2>();
|
||||
// UpdatePlayerRotation(v2);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Move
|
||||
|
||||
private void UpdateGrounded()
|
||||
{
|
||||
MapUnit.IsGrounded = _Character.IsGrounded();
|
||||
MapUnit.Speed = _Character.velocity.magnitude;
|
||||
|
||||
|
||||
Quaternion rotation = _Character.transform.rotation;
|
||||
|
||||
// 计算当前帧与上一帧的旋转差异
|
||||
Quaternion rotationDelta = rotation * Quaternion.Inverse(lastRotation);
|
||||
|
||||
// 将四元数转换为角度轴表示
|
||||
rotationDelta.ToAngleAxis(out float angle, out Vector3 axis);
|
||||
|
||||
// 确保角度在0-360范围内
|
||||
if (angle > 180f) angle -= 360f;
|
||||
|
||||
// 获取Y轴旋转分量(归一化处理)
|
||||
float yRotation = 0f;
|
||||
if (Mathf.Abs(angle) > 0.001f && Mathf.Abs(axis.y) > 0.1f)
|
||||
{
|
||||
// 计算Y轴方向的旋转角度(考虑旋转轴方向)
|
||||
yRotation = angle * Mathf.Sign(axis.y);
|
||||
}
|
||||
|
||||
float maxTurnSpeed = 180f; // 度/秒
|
||||
// 转换为角速度并归一化到[-1, 1]
|
||||
float angularSpeed = yRotation / Time.deltaTime;
|
||||
float turnValue = Mathf.Clamp(angularSpeed / maxTurnSpeed, -1f, 1f);
|
||||
|
||||
|
||||
MapUnit.RotationSpeed = turnValue;
|
||||
|
||||
lastRotation = rotation;
|
||||
}
|
||||
|
||||
private void UpdateWater()
|
||||
{
|
||||
// SceneSettings.Instance.Water.w
|
||||
}
|
||||
|
||||
private void ProcessMoveStates()
|
||||
{
|
||||
// if (CameraView.Value == CameraViewType.TPP)
|
||||
// {
|
||||
// float num = (IsRunPressed.Value ? MovementSpeed.Value : (MovementSpeed.Value * 0.5f));
|
||||
// num = (IsFlyModeEnabled ? (num * (float)FlySpeed) : num);
|
||||
// Vector3 zero = Vector3.zero;
|
||||
// zero += Vector3.right * MovementDirection.Value.x;
|
||||
// zero += Vector3.forward * MovementDirection.Value.y;
|
||||
// zero = zero.relativeTo(_CameraTPPTarget, _Character.GetUpVector());
|
||||
// _Character.RotateTowards(zero, Time.deltaTime * _RotateTPPSpeed);
|
||||
// float value = Vector3.Dot(_Character.GetForwardVector(), zero);
|
||||
// Vector3 vector = _Character.GetForwardVector() * Mathf.Clamp01(value) * num;
|
||||
// if (checkWaterBound)
|
||||
// {
|
||||
// SetMovementDirectionWithRaycastCheck(vector);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// _Character.SetMovementDirection(vector);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
{
|
||||
float num2 = Run ? 7 : 5; //(IsRunPressed.Value ? MovementSpeed.Value : (MovementSpeed.Value * 0.5f));
|
||||
// num2 = (IsFlyModeEnabled ? (num2 * (float)FlySpeed) : num2);
|
||||
Vector3 vector2 = _Character.GetRightVector() * _moveInput.x * num2;
|
||||
vector2 += _Character.GetForwardVector() * _moveInput.y * num2;
|
||||
// if (checkWaterBound)
|
||||
// {
|
||||
// SetMovementDirectionWithRaycastCheck(vector2);
|
||||
// }
|
||||
// else
|
||||
{
|
||||
_Character.SetMovementDirection(vector2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f032bbea4a2a4ab099d2f4800670ad48
|
||||
timeCreated: 1765282951
|
||||
3
Assets/Scripts/Fishing2~/Unit/Parts.meta
Normal file
3
Assets/Scripts/Fishing2~/Unit/Parts.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f63b5a4df9be4d1c839c3c1cc56c1275
|
||||
timeCreated: 1756048419
|
||||
@@ -0,0 +1,15 @@
|
||||
using Fantasy.Entitas;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
/// <summary>
|
||||
/// 手电筒组件
|
||||
/// </summary>
|
||||
public class UnitFlashlightComponent : Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// 打开手电筒
|
||||
/// </summary>
|
||||
public bool OpenLight { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f151cee0d5f43ff90c3aa013214b1ea
|
||||
timeCreated: 1756048476
|
||||
3
Assets/Scripts/Fishing2~/Unit/Skin.meta
Normal file
3
Assets/Scripts/Fishing2~/Unit/Skin.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f655e37e9dd4b5885e127f44e01100d
|
||||
timeCreated: 1756048586
|
||||
11
Assets/Scripts/Fishing2~/Unit/Skin/UnitSkinComponent.cs
Normal file
11
Assets/Scripts/Fishing2~/Unit/Skin/UnitSkinComponent.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Fantasy.Entitas;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
/// <summary>
|
||||
/// Unity皮肤组件
|
||||
/// </summary>
|
||||
public class UnitSkinComponent : Entity
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40c5cce71c8443aa82ea4108e72c887b
|
||||
timeCreated: 1756048599
|
||||
22
Assets/Scripts/Fishing2~/Unit/UnitEventType.cs
Normal file
22
Assets/Scripts/Fishing2~/Unit/UnitEventType.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public struct ChangePosition
|
||||
{
|
||||
public MapUnit MapUnit;
|
||||
public float3 OldPos;
|
||||
}
|
||||
|
||||
public struct ChangeRotation
|
||||
{
|
||||
public MapUnit MapUnit;
|
||||
}
|
||||
|
||||
public struct ChangeState
|
||||
{
|
||||
public MapUnit MapUnit;
|
||||
public MapUnitState State;
|
||||
public string Args;
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Fishing2~/Unit/UnitEventType.cs.meta
Normal file
3
Assets/Scripts/Fishing2~/Unit/UnitEventType.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cd2dd8a7207544b19be4b51b2a6ef215
|
||||
timeCreated: 1755915609
|
||||
3
Assets/Scripts/Fishing2~/Unit/Unity.meta
Normal file
3
Assets/Scripts/Fishing2~/Unit/Unity.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2120457449841468649709d6b193c35
|
||||
timeCreated: 1756821388
|
||||
@@ -0,0 +1,113 @@
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
using NBC;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
public class CharacterAnimatorComponent : Entity
|
||||
{
|
||||
#region 参数定义
|
||||
|
||||
public static readonly int IsSwiming = Animator.StringToHash("Swim");
|
||||
|
||||
public static readonly int ThrowFar = Animator.StringToHash("ThrowFar");
|
||||
|
||||
public static readonly int BoatDriving = Animator.StringToHash("BoatDriving");
|
||||
|
||||
public static readonly int BaitInWater = Animator.StringToHash("BaitInWater");
|
||||
|
||||
public static readonly int HeldRod = Animator.StringToHash("HeldRod");
|
||||
|
||||
public static readonly int RodArming = Animator.StringToHash("RodArming");
|
||||
|
||||
public static readonly int Forward = Animator.StringToHash("Forward");
|
||||
|
||||
public static readonly int Turn = Animator.StringToHash("Turn");
|
||||
|
||||
public static readonly int OnGround = Animator.StringToHash("OnGround");
|
||||
|
||||
public static readonly int RodRight = Animator.StringToHash("rod right");
|
||||
|
||||
public static readonly int RodForward = Animator.StringToHash("rod forward");
|
||||
|
||||
public static readonly int PreciseCast = Animator.StringToHash("Precise Cast");
|
||||
|
||||
public static readonly int PreciseIdle = Animator.StringToHash("Precise Idle");
|
||||
|
||||
|
||||
public static readonly string Torso = "Torso";
|
||||
|
||||
#endregion
|
||||
|
||||
public Animator Animator { get; private set; }
|
||||
public MapUnit MapUnit;
|
||||
|
||||
private bool _isTorsoLayerEnabled;
|
||||
|
||||
#region System
|
||||
|
||||
public class CharacterAnimatorComponentDestroySystem : DestroySystem<CharacterAnimatorComponent>
|
||||
{
|
||||
protected override void Destroy(CharacterAnimatorComponent self)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class CharacterAnimatorComponentAwakeSystem : AwakeSystem<CharacterAnimatorComponent>
|
||||
{
|
||||
protected override void Awake(CharacterAnimatorComponent self)
|
||||
{
|
||||
self.MapUnit = self.Parent as MapUnit;
|
||||
var unitUnityComponent = self.Parent.GetComponent<UnitUnityComponent>();
|
||||
self.Animator = unitUnityComponent.ModelAsset.Animator;
|
||||
}
|
||||
}
|
||||
|
||||
// public class CharacterAnimatorComponentUpdateSystem : UpdateSystem<CharacterAnimatorComponent>
|
||||
// {
|
||||
// protected override void Update(CharacterAnimatorComponent self)
|
||||
// {
|
||||
// // self.UpdateAnimator();
|
||||
// }
|
||||
// }
|
||||
|
||||
public class CharacterAnimatorComponentLateUpdateSystem : LateUpdateSystem<CharacterAnimatorComponent>
|
||||
{
|
||||
protected override void LateUpdate(CharacterAnimatorComponent self)
|
||||
{
|
||||
self.UpdateAnimator();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
private void UpdateAnimator()
|
||||
{
|
||||
Animator.SetBool(OnGround, MapUnit.IsGrounded);
|
||||
float value3 = Mathf.Lerp(Animator.GetFloat(Forward), MapUnit.Speed / 5f, Time.deltaTime * 20f);
|
||||
Animator.SetFloat(Forward, value3);
|
||||
|
||||
// 平滑处理
|
||||
// float smoothedTurn = Mathf.SmoothDamp(Animator.GetFloat(Turn),
|
||||
// MapUnit.RotationSpeed,
|
||||
// ref turnSmoothVelocity,
|
||||
// smoothingTime
|
||||
// );
|
||||
|
||||
float smoothedTurn = Mathf.Lerp(Animator.GetFloat(Turn), MapUnit.RotationSpeed, Time.deltaTime * 10f);
|
||||
Animator.SetFloat(Turn, smoothedTurn);
|
||||
|
||||
|
||||
float layerWeight = Animator.GetLayerWeight(Animator.GetLayerIndex(Torso));
|
||||
SetLayerWeight(Torso,
|
||||
Mathf.MoveTowards(layerWeight, _isTorsoLayerEnabled ? 1f : 0f, Time.deltaTime * 3f));
|
||||
}
|
||||
|
||||
public void SetLayerWeight(string layer, float weight)
|
||||
{
|
||||
Animator.SetLayerWeight(Animator.GetLayerIndex(layer), weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c8042507191477295dbdac2c7dd7c59
|
||||
timeCreated: 1765353895
|
||||
74
Assets/Scripts/Fishing2~/Unit/Unity/UnitUnityComponent.cs
Normal file
74
Assets/Scripts/Fishing2~/Unit/Unity/UnitUnityComponent.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using ECM2;
|
||||
using ECM2.Examples.FirstPerson;
|
||||
using Fantasy.Async;
|
||||
using NBC;
|
||||
using Fantasy.Entitas;
|
||||
using Fantasy.Entitas.Interface;
|
||||
using RootMotion.FinalIK;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NBF.Fishing2
|
||||
{
|
||||
/// <summary>
|
||||
/// Unit 对应的unity对象组件
|
||||
/// </summary>
|
||||
public class UnitUnityComponent : Entity
|
||||
{
|
||||
public GameObject GameObject { get; set; }
|
||||
public GameObject ModelGameObject { get; set; }
|
||||
|
||||
public Transform Transform { get; set; }
|
||||
|
||||
public PlayerModelAsset ModelAsset { get; set; }
|
||||
|
||||
public CharacterMovement Character { get; set; }
|
||||
public FirstPersonCharacter FirstPerson { get; set; }
|
||||
|
||||
public PlayerRootAsset RootAsset { get; set; }
|
||||
|
||||
#region System
|
||||
|
||||
public class UnitUnityComponentDestroySystem : DestroySystem<UnitUnityComponent>
|
||||
{
|
||||
protected override void Destroy(UnitUnityComponent self)
|
||||
{
|
||||
if (self.GameObject != null)
|
||||
{
|
||||
Object.Destroy(self.GameObject);
|
||||
}
|
||||
|
||||
self.ModelAsset = null;
|
||||
self.GameObject = null;
|
||||
self.Transform = null;
|
||||
self.Character = null;
|
||||
self.FirstPerson = null;
|
||||
self.RootAsset = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public async FTask InitUnityObject()
|
||||
{
|
||||
var gameObject = PrefabsHelper.CreatePlayer(SceneSettings.Instance.Node);
|
||||
GameObject = gameObject;
|
||||
Transform = gameObject.transform;
|
||||
Transform.localPosition = new Vector3(484, 1, 422);
|
||||
Parent.GetOrAddComponent<FlashlightComponent>();
|
||||
Character = gameObject.GetComponent<CharacterMovement>();
|
||||
FirstPerson = gameObject.GetComponent<FirstPersonCharacter>();
|
||||
RootAsset = gameObject.GetComponent<PlayerRootAsset>();
|
||||
// Parent.GetOrAddComponent<CharacterControllerComponent>();
|
||||
|
||||
var modelObject = PrefabsHelper.CreatePlayer(RootAsset.Root, "Human_Male");
|
||||
modelObject.transform.localPosition = Vector3.zero;
|
||||
ModelGameObject = modelObject;
|
||||
ModelAsset = modelObject.GetComponent<PlayerModelAsset>();
|
||||
|
||||
|
||||
Parent.GetOrAddComponent<CharacterMovementComponent>();
|
||||
Parent.GetOrAddComponent<CharacterLookComponent>();
|
||||
Parent.GetOrAddComponent<CharacterAnimatorComponent>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0d2c42a4bc1347cebc390147a1a95c54
|
||||
timeCreated: 1755921030
|
||||
Reference in New Issue
Block a user