From d3a550c8f6c3fd47b2a5c9f76876030c16eee92c Mon Sep 17 00:00:00 2001 From: MuHua-123 <2960208585@qq.com> Date: Fri, 7 Mar 2025 23:08:34 +0800 Subject: [PATCH] 1 --- Assets/ModuleCore/ModuleCharacter.meta | 8 ++ .../ModuleCharacter/AnimalMachine.meta | 8 ++ .../AnimalMachine/AnimalChasingState.cs | 32 ++++++++ .../AnimalMachine/AnimalChasingState.cs.meta | 11 +++ .../AnimalMachine/AnimalEatingState.cs | 39 +++++++++ .../AnimalMachine/AnimalEatingState.cs.meta | 11 +++ .../AnimalMachine/AnimalFood.cs | 8 ++ .../AnimalMachine/AnimalFood.cs.meta | 11 +++ .../AnimalMachine/AnimalIdleState.cs | 30 +++++++ .../AnimalMachine/AnimalIdleState.cs.meta | 11 +++ .../AnimalMachine/AnimalMachine.cs | 81 +++++++++++++++++++ .../AnimalMachine/AnimalMachine.cs.meta | 11 +++ .../AnimalMachine/AnimalRoamingState.cs | 30 +++++++ .../AnimalMachine/AnimalRoamingState.cs.meta | 11 +++ .../ModuleCharacter/HumanoidMachine.meta | 8 ++ .../Character/Runtime/Character/Character.cs | 4 - .../Runtime/Character/FSM/Machine.cs | 8 -- .../Runtime/Character/PlayerController.cs | 3 + 18 files changed, 313 insertions(+), 12 deletions(-) create mode 100644 Assets/ModuleCore/ModuleCharacter.meta create mode 100644 Assets/ModuleCore/ModuleCharacter/AnimalMachine.meta create mode 100644 Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalChasingState.cs create mode 100644 Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalChasingState.cs.meta create mode 100644 Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalEatingState.cs create mode 100644 Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalEatingState.cs.meta create mode 100644 Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalFood.cs create mode 100644 Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalFood.cs.meta create mode 100644 Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalIdleState.cs create mode 100644 Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalIdleState.cs.meta create mode 100644 Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalMachine.cs create mode 100644 Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalMachine.cs.meta create mode 100644 Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalRoamingState.cs create mode 100644 Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalRoamingState.cs.meta create mode 100644 Assets/ModuleCore/ModuleCharacter/HumanoidMachine.meta diff --git a/Assets/ModuleCore/ModuleCharacter.meta b/Assets/ModuleCore/ModuleCharacter.meta new file mode 100644 index 0000000..aa4ed20 --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ebb2815476f460d48b87b8d80a3c1faa +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ModuleCore/ModuleCharacter/AnimalMachine.meta b/Assets/ModuleCore/ModuleCharacter/AnimalMachine.meta new file mode 100644 index 0000000..fe2c6c5 --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter/AnimalMachine.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4cbc8837586bb7248990d0581e20725f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalChasingState.cs b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalChasingState.cs new file mode 100644 index 0000000..18a8184 --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalChasingState.cs @@ -0,0 +1,32 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using MuHua; + +public class AnimalChasingState : MachineState where T : Component { + public T target; + public string ToDefault = "Eating"; + public readonly AnimalMachine animal; + public AnimalChasingState(Machine machine) : base(machine) => animal = machine as AnimalMachine; + + public override void Enter() { + bool valid = animal.Find(out target); + if (!valid) { animal.ChangeState("Idle"); } + } + + public override void Exit() { + animal.movement.StopMoving(); + animal.animator.SetFloat("MoveSpeed", 0); + } + + public override void Trigger() { + + } + + public override void Update() { + if (target == null) { animal.ChangeState(ToDefault); return; } + bool complete = animal.movement.UpdateMove(target.transform.position); + animal.animator.SetFloat("MoveSpeed", animal.movement.currentSpeed); + if (complete) { animal.ChangeState(ToDefault); } + } +} diff --git a/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalChasingState.cs.meta b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalChasingState.cs.meta new file mode 100644 index 0000000..356bd82 --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalChasingState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 246d20af4dd47a14b9151feca52b870d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalEatingState.cs b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalEatingState.cs new file mode 100644 index 0000000..96dda00 --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalEatingState.cs @@ -0,0 +1,39 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using MuHua; + +public class AnimalEatingState : MachineState { + public string ToDefault = "Idle"; + + private AnimalFood target; + + public AnimalMachine animal; + public AnimalEatingState(Machine machine) : base(machine) => animal = machine as AnimalMachine; + + public override void Enter() { + if (!animal.Find(out target)) { Exit(); return; } + + // 判断target距离是否小于0.3f + float distance = Vector3.Distance(animal.transform.position, target.transform.position); + if (distance >= 0.1f) { Exit(); return; } + + animal.animator.SetBool("Eating", true); + } + + public override void Exit() { + animal.animator.SetBool("Eating", false); + } + + public override void Trigger() { + animal.hunger += target.nutritionValue; + animal.hunger = Mathf.Clamp(animal.hunger, 0, animal.maxHunger); + GameObject.Destroy(target.gameObject); + + animal.ChangeState(ToDefault); + } + + public override void Update() { + + } +} diff --git a/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalEatingState.cs.meta b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalEatingState.cs.meta new file mode 100644 index 0000000..8922e0e --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalEatingState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5d6c47e58145a2b44a20a3535cadc301 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalFood.cs b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalFood.cs new file mode 100644 index 0000000..e5410b9 --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalFood.cs @@ -0,0 +1,8 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class AnimalFood : MonoBehaviour +{ + public float nutritionValue = 20.0f; // 饱食度增加值 +} diff --git a/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalFood.cs.meta b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalFood.cs.meta new file mode 100644 index 0000000..401e554 --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalFood.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d83ffa2b763f0214298151e204ea0872 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalIdleState.cs b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalIdleState.cs new file mode 100644 index 0000000..120be5a --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalIdleState.cs @@ -0,0 +1,30 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using MuHua; + +public class AnimalIdleState : MachineState { + public string ToDefault = "Roaming"; + + private float idleTime; + + public AnimalMachine animal; + public AnimalIdleState(Machine machine) : base(machine) => animal = machine as AnimalMachine; + + public override void Enter() { + idleTime = Random.Range(3.0f, 5.0f); + } + + public override void Exit() { + + } + + public override void Trigger() { + + } + + public override void Update() { + idleTime -= Time.deltaTime; + if (idleTime <= 0) { animal.ChangeState(ToDefault); } + } +} diff --git a/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalIdleState.cs.meta b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalIdleState.cs.meta new file mode 100644 index 0000000..f721abd --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalIdleState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8defd42d4b3f4a544bbeb381cb525533 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalMachine.cs b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalMachine.cs new file mode 100644 index 0000000..633e4c4 --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalMachine.cs @@ -0,0 +1,81 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using MuHua; + +public class AnimalMachine : Machine { + [Header("饥饿度参数")] + public float hunger = 100.0f; // 饥饿度,从0到100 + public float maxHunger = 100.0f; // 最大饥饿度 + public float searchRadius = 10.0f; // 搜索食物的半径 + + [Header("控制组件")] + public Movement movement; // 运动控制器 + public Animator animator; // 动画控制器 + + private float hungerTimer = 0.0f; // 计时器 + private float chasingCooldownTimer = 0.0f; // 追逐状态冷却计时器 + private const float chasingCooldown = 5.0f; // 追逐状态冷却时间 + + protected override void InitializeStates() { + RegisterState("Idle", new AnimalIdleState(this)); + RegisterState("Roaming", new AnimalRoamingState(this)); + RegisterState("Chasing", new AnimalChasingState(this)); + RegisterState("Eating", new AnimalEatingState(this)); + + ChangeState("Idle"); + } + + protected override void Update() { + base.Update(); + + // 更新计时器 + hungerTimer += Time.deltaTime; + chasingCooldownTimer += Time.deltaTime; + + if (hungerTimer >= 1.0f) { ConsumeHunger(); } + } + + public virtual void ConsumeHunger() { + // 重置计时器 + hungerTimer = 0.0f; + // 每次消耗1点饥饿度 + hunger -= 1.0f; + if (hunger < 0.0f) { hunger = 0.0f; } + + // 如果饥饿度低于最大饥饿度的70%,有50%的概率触发Chasing状态 + // 如果饥饿度低于最大饥饿度的30%,有90%的概率触发Chasing状态 + float foraging = hunger < maxHunger * 0.3f ? 0.9f : 0.5f; + bool valid = hunger < maxHunger * 0.7f && Random.value < foraging; + + // 如果触发Chasing状态,且冷却时间已过,切换到Chasing状态 + if (valid && chasingCooldownTimer >= chasingCooldown) { + ChangeState("Chasing"); + chasingCooldownTimer = 0.0f; // 重置冷却计时器 + } + } + + // 从指定范围内查找指定类型的组件 + public virtual bool Find(out T value) where T : Component { + Collider[] colliders = Physics.OverlapSphere(transform.position, searchRadius); + foreach (Collider collider in colliders) { + T component = collider.GetComponent(); + if (component != null) { + value = component; + return true; + } + } + value = null; + return false; + } + + public override bool UpdateMove(Vector3 position) { + return movement.UpdateMove(position); + } + public override void AnimationTrigger(string value) { + throw new System.NotImplementedException(); + } + public override void AnimationEnd() { + throw new System.NotImplementedException(); + } +} diff --git a/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalMachine.cs.meta b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalMachine.cs.meta new file mode 100644 index 0000000..c4babbc --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalMachine.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a513572e2996d4748acb2838b4cadc89 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalRoamingState.cs b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalRoamingState.cs new file mode 100644 index 0000000..f0cc3c6 --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalRoamingState.cs @@ -0,0 +1,30 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using MuHua; + +public class AnimalRoamingState : MachineState { + public Vector3 targetPosition; + public string ToDefault = "Idle"; + public readonly AnimalMachine animal; + public AnimalRoamingState(Machine machine) : base(machine) => animal = machine as AnimalMachine; + + public override void Enter() { + targetPosition = animal.movement.RandomTargetPosition(); + } + + public override void Exit() { + animal.movement.StopMoving(); + animal.animator.SetFloat("MoveSpeed", 0); + } + + public override void Trigger() { + + } + + public override void Update() { + bool complete = animal.movement.UpdateMove(targetPosition); + animal.animator.SetFloat("MoveSpeed", animal.movement.currentSpeed); + if (complete) { animal.ChangeState(ToDefault); } + } +} diff --git a/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalRoamingState.cs.meta b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalRoamingState.cs.meta new file mode 100644 index 0000000..d99d063 --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter/AnimalMachine/AnimalRoamingState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 494833b7d85b90743956831570b1c49e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ModuleCore/ModuleCharacter/HumanoidMachine.meta b/Assets/ModuleCore/ModuleCharacter/HumanoidMachine.meta new file mode 100644 index 0000000..65a1fc8 --- /dev/null +++ b/Assets/ModuleCore/ModuleCharacter/HumanoidMachine.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fc54f6ddf4030054f974974bf79889d6 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/Character/Runtime/Character/Character.cs b/Packages/Character/Runtime/Character/Character.cs index f987f83..71677cf 100644 --- a/Packages/Character/Runtime/Character/Character.cs +++ b/Packages/Character/Runtime/Character/Character.cs @@ -4,10 +4,6 @@ using UnityEngine; namespace MuHua { public abstract class Character : MonoBehaviour { - - public Movement movement; // 运动控制器 - public Animator animator; // 动画控制器 - /// 更新移动 public abstract bool UpdateMove(Vector3 position); diff --git a/Packages/Character/Runtime/Character/FSM/Machine.cs b/Packages/Character/Runtime/Character/FSM/Machine.cs index 1e76e7f..61270d0 100644 --- a/Packages/Character/Runtime/Character/FSM/Machine.cs +++ b/Packages/Character/Runtime/Character/FSM/Machine.cs @@ -29,13 +29,5 @@ namespace MuHua { } } #endregion - - public override bool UpdateMove(Vector3 position) { - return movement.UpdateMove(position); - } - public override void AnimationTrigger(string value) { - throw new System.NotImplementedException(); - } - public override void AnimationEnd() => currentState?.Trigger(); } } \ No newline at end of file diff --git a/Packages/Character/Runtime/Character/PlayerController.cs b/Packages/Character/Runtime/Character/PlayerController.cs index 407d80b..773b4a1 100644 --- a/Packages/Character/Runtime/Character/PlayerController.cs +++ b/Packages/Character/Runtime/Character/PlayerController.cs @@ -4,6 +4,9 @@ using UnityEngine; namespace MuHua { public class PlayerController : Character { + public Movement movement; // 运动控制器 + public Animator animator; // 动画控制器 + public override bool UpdateMove(Vector3 position) { return movement.UpdateMove(position); }