切换主武器

This commit is contained in:
SoulliesOfficial
2025-12-23 19:47:06 -05:00
parent eaa688c7a9
commit 2a2aa728d5
275 changed files with 12579 additions and 2770 deletions

View File

@@ -18,7 +18,7 @@ namespace Cielonos.MainGame
float angularSpeed, float angularAcceleration, Vector3 initialDirection, bool stopWhenHit) : base(attackArea, stopWhenHit)
{
this.target = target;
this.targetTransform = target.transform;
this.targetTransform = target != null ? target.transform : null;
this.angularSpeed = angularSpeed;
this.angularAcceleration = angularAcceleration;
this.moveSpeed = moveSpeed;
@@ -30,6 +30,11 @@ namespace Cielonos.MainGame
{
if (target == null || target.statusSm.isDead)
{
moveSpeed += moveAcceleration * Time.deltaTime;
moveSpeed = Mathf.Max(moveSpeed, 0f);
unscaledVelocity = projectile.forward * moveSpeed;
scaledVelocity = unscaledVelocity * timeScaleCoefficient; //attackArea.creator.selfTimeModule
projectile.position += scaledVelocity * Time.deltaTime;
return;
}

View File

@@ -1,3 +1,4 @@
using System;
using Sirenix.OdinInspector;
using SLSUtilities.FunctionalAnimation;
using UnityEngine;
@@ -5,6 +6,7 @@ using UnityEngine.Serialization;
namespace Cielonos.MainGame.FunctionalAnimation
{
[Serializable]
public class ChangeCollisionLayers : FuncAnimPayloadBase
{
[Tooltip("是否在排除这些碰撞层,若为否则表示添加(通常是加回,恢复)这些碰撞层")]

View File

@@ -1,8 +1,10 @@
using System;
using SLSUtilities.FunctionalAnimation;
using UnityEngine;
namespace Cielonos.MainGame.FunctionalAnimation
{
[Serializable]
public class InvokeAnimScFunction : FuncAnimPayloadBase
{
public string functionKey = "FunctionKey";

View File

@@ -1,8 +1,10 @@
using System;
using SLSUtilities.FunctionalAnimation;
using UnityEngine;
namespace Cielonos.MainGame.FunctionalAnimation
{
[Serializable]
public class PlaySoundFX : FuncAnimPayloadBase
{
public string soundKey = "SoundKey";

View File

@@ -8,6 +8,7 @@ using UnityEngine.Serialization;
namespace Cielonos.MainGame.FunctionalAnimation
{
[Serializable]
public class SetBreakthroughResistance : FuncAnimPayloadBase
{
[InfoBox("设置角色的突破抗性状态,同时开启或关闭轮廓线效果。\n角色会被突破类型相同或更高的攻击打断不会被低于该突破类型的攻击打断。")]

View File

@@ -1,3 +1,4 @@
using System;
using Cielonos.MainGame.Characters;
using Sirenix.OdinInspector;
using SLSUtilities.FunctionalAnimation;
@@ -5,6 +6,7 @@ using UnityEngine;
namespace Cielonos.MainGame.FunctionalAnimation
{
[Serializable]
public class SetRootAdsorptionAdjustment : FuncAnimPayloadBase<bool>
{
[InfoBox("这个payload只能在运行时由代码调用不能直接放在动画事件里使用")]

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using Cielonos.MainGame.Characters;
using Sirenix.OdinInspector;
@@ -6,6 +7,7 @@ using UnityEngine;
namespace Cielonos.MainGame.FunctionalAnimation
{
[Serializable]
public class SetStatus : FuncAnimPayloadBase
{
[Tooltip("要添加或移除的状态列表")]

View File

@@ -1,8 +1,10 @@
using System;
using SLSUtilities.FunctionalAnimation;
using UnityEngine;
namespace Cielonos.MainGame.FunctionalAnimation
{
[Serializable]
public class SpawnVFX : FuncAnimPayloadBase
{
public string vfxKey = "VFXKey";

View File

@@ -1,8 +1,10 @@
using System;
using SLSUtilities.FunctionalAnimation;
using UnityEngine;
namespace Cielonos.MainGame.FunctionalAnimation
{
[Serializable]
public class SwitchFuncAnim : FuncAnimPayloadBase
{
public string animationName;

View File

@@ -1,4 +1,5 @@
using System;
using SickscoreGames.HUDNavigationSystem;
using Sirenix.OdinInspector;
using SLSFramework.General;
using SLSFramework.WwiseAssistance;
@@ -50,6 +51,9 @@ namespace Cielonos.MainGame.Characters
public ReactionSubcontroller reactionSc;
public FeedbackSubcontroller feedbackSc;
[TitleGroup("Navigation")]
public HUDNavigationElement navigationElement;
protected virtual void Awake()
{
InitializeSubcontrollers();

View File

@@ -1,23 +1,51 @@
using System.Collections.Generic;
using Cielonos.MainGame.Inventory;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Serialization;
namespace Cielonos.MainGame.Characters
{
public class BodyPartsSubcontroller : SubcontrollerBase<CharacterBase>
public partial class BodyPartsSubcontroller : SubcontrollerBase<CharacterBase>
{
[FormerlySerializedAs("centerPoint")] [Title("Main Parts")]
[Title("Main Parts")]
public Transform flexibleCenterPoint;
public Transform staticCenterPoint;
public Transform cameraLockingPoint;
public Transform footPoint;
public Transform head;
public Transform leftHand;
public Transform rightHand;
public Transform back;
public Transform hips;
public Transform leftFoot;
public Transform rightFoot;
[Title("Custom Parts")]
public Dictionary<string, Transform> customBodyParts;
}
public partial class BodyPartsSubcontroller
{
public Transform GetPart(ViewObjectData.AttachBodyPartType partType)
{
return partType switch
{
ViewObjectData.AttachBodyPartType.RightHand => rightHand,
ViewObjectData.AttachBodyPartType.LeftHand => leftHand,
ViewObjectData.AttachBodyPartType.Head => head,
ViewObjectData.AttachBodyPartType.FlexibleCenterPoint => flexibleCenterPoint,
ViewObjectData.AttachBodyPartType.Back => back,
ViewObjectData.AttachBodyPartType.Hips => hips,
ViewObjectData.AttachBodyPartType.RightFoot => rightFoot,
ViewObjectData.AttachBodyPartType.LeftFoot => leftFoot,
_ => null
};
}
public Transform GetPart(string partName)
{
return customBodyParts.GetValueOrDefault(partName);
}
}
}

View File

@@ -56,7 +56,7 @@ namespace Cielonos.MainGame.Characters
if (owner is Player player)
{
dashRotation.y = player.viewSc.isLockingTarget
dashRotation.y = player.viewSc.lockTargetModule.isUsingLockTargetCamera
? player.viewSc.cameraRotationSm.cinemachineEndLockYaw + angle
: player.viewSc.cameraRotationSm.cinemachineTargetYaw + angle;
}

View File

@@ -230,19 +230,19 @@ namespace Cielonos.MainGame.Characters
}
};
inputActions.Player.SwitchMainWeapon.performed += ctx =>
inputActions.Player.SwitchPreviousMainWeapon.performed += ctx =>
{
if (ctx.performed && isCursorLocked.Value)
{
operation.SwitchMainWeapon(ctx.ReadValue<float>());
operation.SwitchMainWeapon(-1);
}
};
inputActions.Player.FastSwitchMainWeapon.performed += ctx =>
inputActions.Player.SwitchNextMainWeapon.performed += ctx =>
{
if (ctx.performed && isCursorLocked.Value)
{
operation.FastSwitchMainWeapon();
operation.SwitchMainWeapon(1);
}
};

View File

@@ -0,0 +1,11 @@
using System.Collections.Generic;
using Cielonos.MainGame.Inventory;
using UnityEngine;
namespace Cielonos.MainGame.Characters
{
public class PlayerBackpack
{
public List<MainWeaponBase> mainWeapons = new List<MainWeaponBase>();
}
}

View File

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

View File

@@ -13,11 +13,24 @@ namespace Cielonos.MainGame.Characters
public PlayerEquipmentSubmodule(PlayerInventorySubcontroller owner) : base(owner)
{
preparedMainWeapons = new List<MainWeaponBase>();
foreach (MainWeaponBase mainWeapon in owner.backpack.mainWeapons)
{
ObtainMainWeapon(mainWeapon);
}
EquipMainWeapon(preparedMainWeapons[0]);
}
public void ObtainMainWeapon(MainWeaponBase newWeapon)
{
if (!preparedMainWeapons.Contains(newWeapon))
{
preparedMainWeapons.Add(newWeapon);
newWeapon.Initialize();
}
}
public void EquipMainWeapon(MainWeaponBase newWeapon)
{
newWeapon.Initialize();
currentMainWeapon = newWeapon;
currentMainWeapon.OnEquipped();
currentMainWeapon.RegisterFullBodyFuncAnims();
@@ -27,8 +40,23 @@ namespace Cielonos.MainGame.Characters
public void RemoveMainWeapon()
{
Debug.Log("Unequipping main weapon: " + currentMainWeapon);
currentMainWeapon.OnUnequipped();
currentMainWeapon = null;
}
public void DiscardMainWeapon(MainWeaponBase weaponToDiscard)
{
if (preparedMainWeapons.Contains(weaponToDiscard))
{
if (currentMainWeapon == weaponToDiscard)
{
RemoveMainWeapon();
}
preparedMainWeapons.Remove(weaponToDiscard);
Object.Destroy(weaponToDiscard);
}
}
}
}

View File

@@ -1,4 +1,4 @@
using Cielonos.MainGame.Inventory;
using Cielonos.MainGame.Inventory;
using UnityEngine;
namespace Cielonos.MainGame.Characters
@@ -8,15 +8,14 @@ namespace Cielonos.MainGame.Characters
public Player player => owner;
private PlayerInputSubcontroller inputSc => player.inputSc;
private PlayerOperationSubcontroller operationSc => player.operationSc;
public MainWeaponBase testMainWeapon;
public PlayerBackpack backpack;
public PlayerEquipmentSubmodule equipmentSm;
public override void Initialize()
{
base.Initialize();
RegisterOperations();
equipmentSm = new PlayerEquipmentSubmodule(this);
equipmentSm.EquipMainWeapon(testMainWeapon);
equipmentSm ??= new PlayerEquipmentSubmodule(this);
}
}
@@ -38,6 +37,8 @@ namespace Cielonos.MainGame.Characters
operationSc.OnMainWeaponQuaternaryPress += MainWeaponSpecialBPress;
operationSc.OnMainWeaponQuaternaryRelease += MainWeaponSpecialBRelease;
operationSc.OnSwitchMainWeapon += SwitchMainWeapon;
/*
operationSc.OnSwitchMainWeapon += delegate(float dir) { SwitchMainWeapon(dir > 0 ? 1 : -1); };
operationSc.OnUseSupportEquipment0Press += delegate { SupportEquipmentPress(0); };
@@ -73,6 +74,15 @@ namespace Cielonos.MainGame.Characters
public partial class PlayerInventorySubcontroller
{
private void SwitchMainWeapon(int direction)
{
int currentIndex = equipmentSm.preparedMainWeapons.IndexOf(currentMainWeapon);
equipmentSm.RemoveMainWeapon();
int newIndex = (currentIndex + direction + equipmentSm.preparedMainWeapons.Count) % equipmentSm.preparedMainWeapons.Count;
Debug.Log($"Switching main weapon from index {currentIndex} to {newIndex}");
equipmentSm.EquipMainWeapon(equipmentSm.preparedMainWeapons[newIndex]);
}
public void MainWeaponPrimaryPress()
{
if (currentMainWeapon != null)

View File

@@ -44,7 +44,7 @@ namespace Cielonos.MainGame.Characters
public event Action OnMainWeaponQuaternaryHold;
public event Action OnMainWeaponQuaternaryRelease;
public event Action<float> OnSwitchMainWeapon;
public event Action<int> OnSwitchMainWeapon;
public event Action OnOpenMainWeaponRoulette;
public event Action OnCloseMainWeaponRoulette;
public event Action OnFastSwitchMainWeapon;
@@ -95,7 +95,7 @@ namespace Cielonos.MainGame.Characters
public void MainWeaponQuaternaryHold() => OnMainWeaponQuaternaryHold?.Invoke();
public void MainWeaponSpecialBRelease() => OnMainWeaponQuaternaryRelease?.Invoke();
public void SwitchMainWeapon(float direction) => OnSwitchMainWeapon?.Invoke(direction);
public void SwitchMainWeapon(int direction) => OnSwitchMainWeapon?.Invoke(direction);
public void OpenMainWeaponRoulette() => OnOpenMainWeaponRoulette?.Invoke();

View File

@@ -1,6 +1,8 @@
using DG.Tweening;
using Sirenix.OdinInspector;
using SLSFramework.General;
using UnityEngine;
using Ease = DG.Tweening.Ease;
namespace Cielonos.MainGame.Characters
{
@@ -18,7 +20,6 @@ namespace Cielonos.MainGame.Characters
public float cinemachineTargetPitch;
public float topClamp = 70.0f;
public float bottomClamp = -30.0f;
public float cameraAngleOverride = 0.0f;
public bool lockCameraPosition = false;
[Title("Combat Recenter Settings")]
@@ -61,13 +62,16 @@ namespace Cielonos.MainGame.Characters
cinemachineTargetYaw = MathExtensions.ClampAngle(cinemachineTargetYaw, float.MinValue, float.MaxValue);
cinemachineTargetPitch = MathExtensions.ClampAngle(cinemachineTargetPitch, bottomClamp, topClamp);
viewSc.cameraRoot.rotation = Quaternion.Euler(
cinemachineTargetPitch + cameraAngleOverride /*- viewSc.muzzleLiftModule.currentMuzzlePositionY*/, cinemachineTargetYaw, 0.0f);
if (viewSc.isLockingTarget)
if (viewSc.lockTargetModule.isUsingLockTargetCamera)
{
cinemachineEndLockYaw = viewSc.lockOnCamera.transform.eulerAngles.y;
cinemachineEndLockYaw = viewSc.lockingTargetCamera.transform.eulerAngles.y;
}
else
{
viewSc.cameraRoot.rotation = Quaternion.Euler(
cinemachineTargetPitch /*- viewSc.muzzleLiftModule.currentMuzzlePositionY*/, cinemachineTargetYaw, 0.0f);
}
/*
@@ -108,23 +112,34 @@ namespace Cielonos.MainGame.Characters
recenterTimer = duration;
isRecentering = true;
}
private bool tt;
// 将此方法添加到你控制相机旋转的脚本中 (例如 PlayerCameraController)
public void SyncRotationWithCamera(Camera camera = null)
/// <summary>
/// 同步相机旋转到当前摄像机朝向
/// </summary>
public void SyncRotationWithCamera()
{
camera ??= viewSc.playerCamera;
// 确保获取的是当前正在起作用的锁定相机的旋转
var camera = viewSc.currentCamera;
Vector3 currentEuler = camera.transform.eulerAngles;
cinemachineTargetYaw = currentEuler.y;
float currentPitch = currentEuler.x;
if (currentPitch > 180)
{
currentPitch -= 360;
}
cinemachineTargetPitch = currentPitch - cameraAngleOverride;
float yaw = currentEuler.y;
float pitch = currentEuler.x;
// --- 核心修复:处理欧拉角跨度问题 ---
// 如果 pitch > 180 (例如 355), 则转为负数 ( -5 )
if (pitch > 180) pitch -= 360;
isRecentering = false;
// 强制执行一次旋转更新,防止下一帧才生效导致的微小跳动 (可选)
// viewSc.cameraRoot.rotation = Quaternion.Euler(
// cinemachineTargetPitch + cameraAngleOverride, cinemachineTargetYaw, 0.0f);
// 更新目标值
cinemachineTargetYaw = yaw;
cinemachineTargetPitch = pitch;
// --- 立即应用旋转 ---
// 强制立即更新一次 cameraRoot防止等待下一帧 Update 产生的跳变
viewSc.cameraRoot.rotation = Quaternion.Euler(cinemachineTargetPitch, cinemachineTargetYaw, 0.0f);
}
}
}

View File

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

View File

@@ -0,0 +1,138 @@
using System;
using DG.Tweening;
using SickscoreGames.HUDNavigationSystem;
using UniRx;
using UnityEngine;
using UnityEngine.UI;
using SLSFramework.General;
using Ease = DG.Tweening.Ease;
namespace Cielonos.MainGame.Characters
{
public partial class LockTargetSubmodule : SubmoduleBase<PlayerViewSubcontroller>
{
private Player player => owner.player;
private PlayerViewSubcontroller viewSc => owner;
private PlayerInputSubcontroller inputSc => player.inputSc;
private HUDNavigationSystem navigationSystem => HUDNavigationSystem.Instance;
private HUDNavigationCanvas navigationCanvas => HUDNavigationCanvas.Instance;
/// <summary>
/// 通常ACT类武器锁定目标时自动旋转摄像机即使用LockTargetCamera
/// TPS类远程武器不自动旋转仅在目标上显示锁定标记不切换摄像机
/// </summary>
public bool isAutoRotate;
/// <summary>
/// 是否正在锁定目标
/// </summary>
public bool isLocking;
/// <summary>
/// 是否正在使用锁定目标摄像机
/// </summary>
public bool isUsingLockTargetCamera => isLocking && isAutoRotate;
public bool isDuringSwitch;
public CharacterBase lockTarget;
public Transform targetPoint;
private Tweener iconTween;
public LockTargetSubmodule(PlayerViewSubcontroller owner) : base(owner)
{
isLocking = false;
isAutoRotate = false;
isDuringSwitch = false;
lockTarget = null;
targetPoint = null;
}
public void Update()
{
if (isUsingLockTargetCamera && !isDuringSwitch)
{
viewSc.cameraRoot.LookAt(targetPoint);
float distance = (targetPoint.position - viewSc.cameraRoot.transform.position).Flatten().magnitude;
if (isUsingLockTargetCamera && distance < 1f)
{
UnlockTarget();
}
}
}
}
public partial class LockTargetSubmodule
{
public void SwitchLockState()
{
if (isLocking)
{
UnlockTarget();
}
else
{
LockTarget(true);
}
}
public void LockTarget(bool isAutoRotate)
{
if(isDuringSwitch) return;
CharacterBase target = BattleManager.EnemySm.GetNearestEnemy(50f);
if (target != null)
{
this.isLocking = true;
this.isAutoRotate = isAutoRotate;
this.lockTarget = target;
this.isDuringSwitch = true;
if (isAutoRotate)
{
targetPoint = target.bodyPartsSc.cameraLockingPoint ?? target.bodyPartsSc.staticCenterPoint;
viewSc.currentCamera = viewSc.lockingTargetCamera;
viewSc.lockingTargetCamera.LookAt = targetPoint;
viewSc.stateDrivenCamera.GetComponent<Animator>().SetBool("isLockTarget", true);
viewSc.cameraRoot.DOLookAt(targetPoint.position, 0.5f)
.SetEase(Ease.InOutSine)
.OnComplete(() => { isDuringSwitch = false; })
.Play();
}
else
{
Observable.Timer(TimeSpan.FromSeconds(0.5f)).First().Subscribe(_ =>
{
isDuringSwitch = false;
});
}
lockTarget.navigationElement.showIndicator = true;
Image icon = lockTarget.navigationElement.Indicator.OnscreenIcon;
iconTween?.Kill(true);
iconTween = icon.GetComponent<RectTransform>().DOScale(1f, 0.5f).From(0f).SetEase(Ease.OutQuart).Play();
}
}
public void UnlockTarget()
{
if(isDuringSwitch) return;
if (isAutoRotate)
{
viewSc.cameraRotationSm.SyncRotationWithCamera();
viewSc.stateDrivenCamera.GetComponent<Animator>().SetBool("isLockTarget", false);
viewSc.stateDrivenCamera.InternalUpdateCameraState(Vector3.up, Time.deltaTime);
viewSc.currentCamera = viewSc.freeLookCamera;
}
this.isLocking = false;
this.isAutoRotate = false;
Image icon = lockTarget.navigationElement.Indicator.OnscreenIcon;
iconTween?.Kill(true);
iconTween = icon.GetComponent<RectTransform>().DOScale(0f, 0.5f).SetEase(Ease.OutQuart).OnComplete(() =>
{
lockTarget.navigationElement.showIndicator = false;
this.lockTarget = null;
this.targetPoint = null;
this.isDuringSwitch = false;
}).Play();
}
}
}

View File

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

View File

@@ -12,99 +12,45 @@ namespace Cielonos.MainGame.Characters
public class PlayerViewSubcontroller : SubcontrollerBase<Player>, IPlayerSubcontroller
{
public Player player => owner;
public Camera playerCamera;
public Transform cameraRoot;
public CinemachineStateDrivenCamera stateDrivenCamera;
public CinemachineCamera currentCamera;
public CinemachineCamera freeLookCamera;
public CinemachineCamera lockOnCamera;
[FormerlySerializedAs("isLockedOn")] public bool isLockingTarget = false;
public bool isLockedSetRoot;
public CinemachineCamera lockingTargetCamera;
public CharacterBase testEnemy;
public Transform testEnemyTarget;
public CameraRotationSubmodule cameraRotationSm;
public OcclusionFadeSubmodule occlusionFadeSm;
public LockTargetSubmodule lockTargetModule;
public override void Initialize()
{
base.Initialize();
cameraRotationSm = new CameraRotationSubmodule(this, player.transform.eulerAngles.y);
occlusionFadeSm = new OcclusionFadeSubmodule(this);
lockTargetModule = new LockTargetSubmodule(this);
}
private void Start()
{
testEnemyTarget = testEnemy.bodyPartsSc.staticCenterPoint;
//SwitchToLockTarget( testEnemyTarget );
currentCamera = freeLookCamera;
}
private void Update()
{
if (Keyboard.current.tabKey.wasPressedThisFrame)
{
if (!isLockingTarget)
{
SwitchToLockTarget( testEnemyTarget );
}
else
{
SwitchToFreeLook();
}
lockTargetModule.SwitchLockState();
}
}
private void LateUpdate()
{
cameraRotationSm.Update();
if (!isLockingTarget)
{
}
else
{
if(isLockedSetRoot) cameraRoot.LookAt(testEnemyTarget);
float distance = (testEnemyTarget.position - cameraRoot.transform.position).Flatten().magnitude;
if(distance < 1f) SwitchToFreeLook();
}
lockTargetModule.Update();
occlusionFadeSm.Update();
}
void SwitchToLockTarget(Transform target)
{
testEnemyTarget = target;
isLockingTarget = true;
isLockedSetRoot = false;
// --- CM3 核心操作 ---
// 1. 设置 LookAt 目标。在 CM3 中LookingAt 是 Target 结构体的一部分,或者直接赋值给 LookAt 属性
lockOnCamera.Target.LookAtTarget = testEnemyTarget;
// 2. 提高优先级,激活锁定相机
stateDrivenCamera.GetComponent<Animator>().SetBool("isLockTarget", true);
cameraRoot.DOLookAt(testEnemyTarget.position, 0.5f).SetEase(Ease.InOutSine).OnComplete(()=>isLockedSetRoot = true).Play();
// (可选) 你可以在这里播放锁定音效或显示 UI 准星
Debug.Log($"Locked on: {target.name}");
}
void SwitchToFreeLook()
{
cameraRotationSm.SyncRotationWithCamera(playerCamera);
isLockingTarget = false;
// --- CM3 核心操作 ---
// 1. 重置 LookAt 目标
//lockOnCamera.Target.LookAtTarget = null;
// 2. 降低优先级,切换回自由视角相机
stateDrivenCamera.GetComponent<Animator>().SetBool("isLockTarget", false);
// (可选) 你可以在这里播放解锁音效或隐藏 UI 准星
Debug.Log("Switched to Free Look");
}
}
}

View File

@@ -15,14 +15,14 @@ namespace Cielonos.MainGame.Inventory
public Player player => MainGameManager.Instance.player;
protected PlayerAnimationSubcontroller animationSc => player.animationSc;
protected FunctionalAnimationSubmodule fullBodyFuncAnimSm => animationSc.fullBodyFuncAnimSm;
public ItemViewObject viewObject;
[Title("Data")]
public List<FuncAnimData> fullBodyFuncAnims = new List<FuncAnimData>();
[HideInInspector]
private List<string> registeredFunctionNames = new List<string>();
[FormerlySerializedAs("objectData")]
public ViewObjectData viewObjectData;
public VFXData vfxData;
public ComboData comboData;
public AttackData attackData;
@@ -41,10 +41,12 @@ namespace Cielonos.MainGame.Inventory
[Title("Subcontrollers")]
public FeedbackSubcontroller feedbackSc;
[Title("View Objects")]
public Dictionary<string, ItemViewObject> viewObjects = new Dictionary<string, ItemViewObject>();
protected virtual void Update()
{
functionSm.Update(player.selfTimeSm.DeltaTime);
functionSm?.Update(player.selfTimeSm.DeltaTime);
}
}

View File

@@ -7,7 +7,6 @@ namespace Cielonos.MainGame.Inventory
{
public partial class ItemViewObject : SerializedMonoBehaviour
{
public GameObject item;
public Dictionary<string, GameObject> functionalParts;
public GameObject Part(string partName)

View File

@@ -1,3 +1,4 @@
using System.Collections.Generic;
using Cielonos.MainGame.Characters;
using MoreMountains.Feedbacks;
using MoreMountains.FeedbacksForThirdParty;
@@ -7,7 +8,6 @@ namespace Cielonos.MainGame.Inventory
{
public abstract partial class MainWeaponBase : ItemBase
{
public BaseAnimationGroup baseAnimationGroup;
}
@@ -16,17 +16,45 @@ namespace Cielonos.MainGame.Inventory
public virtual void OnEquipped()
{
baseAnimationGroup.SetUp(animationSc);
foreach (ViewObjectData.ViewObjectDataUnit unit in viewObjectData.viewObjectUnits)
{
Transform attachPoint = !unit.isCustomAttachPoint ?
player.bodyPartsSc.GetPart(unit.normalAttachBodyPart) :
player.bodyPartsSc.GetPart(unit.customAttachPartName);
if (attachPoint != null)
{
ItemViewObject view = Instantiate(unit.objectPrefab, attachPoint).GetComponent<ItemViewObject>();
if (unit.applyOffset)
{
view.transform.localPosition = unit.positionOffset;
view.transform.localEulerAngles = unit.rotationOffset;
}
viewObjects[unit.objectName] = view;
}
}
}
public virtual void OnUnequipped()
{
RemoveAllRegisteredFunctions();
foreach (ItemViewObject view in viewObjects.Values)
{
Destroy(view.gameObject);
}
viewObjects.Clear();
}
}
public partial class MainWeaponBase
{
protected Transform muzzle => viewObject.functionalParts["Muzzle"].transform;
protected override void Update()
{
if (player.inventorySc.equipmentSm.currentMainWeapon == this)
{
functionSm?.Update(player.selfTimeSm.DeltaTime);
}
}
}
public partial class MainWeaponBase

View File

@@ -1,6 +1,6 @@
using UnityEngine;
public class LockTargetCamera : MonoBehaviour
public class ContentData : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()

View File

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

View File

@@ -8,11 +8,11 @@ using UnityEngine;
namespace Cielonos.MainGame.Inventory
{
[CreateAssetMenu(fileName = "FunctionData", menuName = "Cielonos/Items/FunctionData")]
public class FunctionData : SerializedScriptableObject
public partial class FunctionData : SerializedScriptableObject
{
[DictionaryDrawerSettings(KeyLabel = "Attack Unit", DisplayMode = DictionaryDisplayOptions.ExpandedFoldout)]
[Searchable]
public Dictionary<string, ItemFunctionUnit> functionUnits;
public Dictionary<string, FunctionUnit> functionUnits = new Dictionary<string, FunctionUnit>();
[OnInspectorGUI("UpdateUnits")]
public void UpdateUnits()
@@ -23,9 +23,8 @@ namespace Cielonos.MainGame.Inventory
}
}
}
[Serializable]
public class ItemFunctionUnit
public partial class FunctionData
{
public enum IntervalReductionType
{
@@ -34,26 +33,30 @@ namespace Cielonos.MainGame.Inventory
AttackSpeed = 10
}
[ReadOnly]
public FunctionData parentData;
[Serializable]
public class FunctionUnit
{
[ReadOnly]
public FunctionData parentData;
[TitleGroup("Information")]
public bool shownInUI;
[TitleGroup("Information")]
public Sprite icon;
[TitleGroup("Information")]
public List<string> operation;
[TitleGroup("Information")]
public bool shownInUI;
[TitleGroup("Information")]
public Sprite icon;
[TitleGroup("Information")]
public List<string> operation;
[TitleGroup("Costs")]
public float energyCost;
[TitleGroup("Costs")]
public int ammoCost;
[TitleGroup("Costs")]
public float energyCost;
[TitleGroup("Costs")]
public int ammoCost;
[TitleGroup("Interval")]
public float interval;
[TitleGroup("Interval")]
public float intervalLowerLimit;
[TitleGroup("Interval")]
public IntervalReductionType intervalReductionType;
[TitleGroup("Interval")]
public float interval;
[TitleGroup("Interval")]
public float intervalLowerLimit;
[TitleGroup("Interval")]
public IntervalReductionType intervalReductionType;
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Serialization;
namespace Cielonos.MainGame.Inventory
{
[CreateAssetMenu(fileName = "ViewObjectData", menuName = "Cielonos/Items/ViewObjectData")]
public partial class ViewObjectData : SerializedScriptableObject
{
[ListDrawerSettings(ShowFoldout = true)]
public List<ViewObjectDataUnit> viewObjectUnits = new List<ViewObjectDataUnit>();
}
public partial class ViewObjectData
{
public enum AttachBodyPartType
{
RightHand,
LeftHand,
Head,
FlexibleCenterPoint,
Back,
Hips,
RightFoot,
LeftFoot,
}
[Serializable]
public class ViewObjectDataUnit
{
public string objectName;
public GameObject objectPrefab;
public bool isCustomAttachPoint;
[HideIf("isCustomAttachPoint")]
public AttachBodyPartType normalAttachBodyPart;
[ShowIf("isCustomAttachPoint")]
public string customAttachPartName;
public bool applyOffset;
[ShowIf("applyOffset")]
public Vector3 positionOffset;
[ShowIf("applyOffset")]
public Vector3 rotationOffset;
}
}
}

View File

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

View File

@@ -23,6 +23,10 @@ namespace Cielonos.MainGame.Inventory
{
PlayTargetedAnimation("LightAttack" + comboSm.GetCurrentNodeName(), currentTarget, 5f);
}
else
{
PlayTargetedAnimation("LightAttack" + comboSm.GetCurrentNodeName(), null, 5f);
}
}
}
@@ -37,6 +41,10 @@ namespace Cielonos.MainGame.Inventory
{
PlayTargetedAnimation("HeavyAttack", currentTarget, 3f);
}
else
{
PlayTargetedAnimation("HeavyAttack", null, 3f);
}
}
}
}
@@ -50,6 +58,11 @@ namespace Cielonos.MainGame.Inventory
private void LightAttack3() => GenerateProjectile("HeavyProjectile", currentTarget, 10f);
private void HeavyAttack() => GenerateGroundArea("GroundArea");
}
public partial class FutureWand : MainWeaponBase
{
private Transform muzzle => viewObjects["Wand"].functionalParts["Muzzle"].transform;
}
public partial class FutureWand
{

View File

@@ -12,12 +12,16 @@ namespace Cielonos.MainGame.Inventory
protected override void Update()
{
base.Update();
perfectBlockedTimer -= player.selfTimeSm.DeltaTime;
if (player.inventorySc.equipmentSm.currentMainWeapon == this)
{
functionSm?.Update(player.selfTimeSm.DeltaTime);
perfectBlockedTimer -= player.selfTimeSm.DeltaTime;
}
}
public override void OnEquipped()
{
base.OnEquipped();
RegisterFunctionsToAnimSc(
LightAttack0, LightAttack1, LightAttack2, LightAttack3,
TripleAttack_0, TripleAttack_1, TripleAttack_2,

View File

@@ -36,11 +36,11 @@ namespace Cielonos.MainGame.Inventory
{
private CharacterBase character => owner.owner.player;
public ItemFunctionUnit data;
public FunctionData.FunctionUnit data;
public float currentCooldown;
public float maxCooldown;
public RuntimeFunctionUnit(FunctionSubmodule owner, ItemFunctionUnit data) : base(owner)
public RuntimeFunctionUnit(FunctionSubmodule owner, FunctionData.FunctionUnit data) : base(owner)
{
this.data = data;
maxCooldown = data.interval;

View File

@@ -21,6 +21,15 @@ namespace Cielonos.MainGame
{
Application.targetFrameRate = 60;
}
private void Update()
{
float frame = 1.0f / Application.targetFrameRate;
if (frame < 10f && Time.time > 5f)
{
//Debug.Break();
}
}
}
public partial class MainGameManager