修改角色包
This commit is contained in:
@@ -3,30 +3,30 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using MuHua;
|
||||
|
||||
public class AnimalChasingState<T> : 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 class AnimalChasingState<T> : IStateMachine where T : Component {
|
||||
// public T target;
|
||||
// public string ToDefault = "Eating";
|
||||
// public readonly AnimalMachine animal;
|
||||
// public AnimalChasingState(StateMachine 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 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 Exit() {
|
||||
// animal.movement.StopMoving();
|
||||
// animal.animator.SetFloat("MoveSpeed", 0);
|
||||
// }
|
||||
|
||||
public override void Trigger() {
|
||||
// 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); }
|
||||
}
|
||||
}
|
||||
// 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); }
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -3,37 +3,37 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using MuHua;
|
||||
|
||||
public class AnimalEatingState : MachineState {
|
||||
public string ToDefault = "Idle";
|
||||
// public class AnimalEatingState : IStateMachine {
|
||||
// public string ToDefault = "Idle";
|
||||
|
||||
private AnimalFood target;
|
||||
// private AnimalFood target;
|
||||
|
||||
public AnimalMachine animal;
|
||||
public AnimalEatingState(Machine machine) : base(machine) => animal = machine as AnimalMachine;
|
||||
// public AnimalMachine animal;
|
||||
// public AnimalEatingState(StateMachine machine) : base(machine) => animal = machine as AnimalMachine;
|
||||
|
||||
public override void Enter() {
|
||||
if (!animal.Find(out target)) { Exit(); return; }
|
||||
// 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; }
|
||||
// // 判断target距离是否小于0.3f
|
||||
// float distance = Vector3.Distance(animal.transform.position, target.transform.position);
|
||||
// if (distance >= 0.1f) { Exit(); return; }
|
||||
|
||||
animal.animator.SetBool("Eating", true);
|
||||
}
|
||||
// animal.animator.SetBool("Eating", true);
|
||||
// }
|
||||
|
||||
public override void Exit() {
|
||||
animal.animator.SetBool("Eating", false);
|
||||
}
|
||||
// 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);
|
||||
// public override void Trigger() {
|
||||
// animal.hunger += target.nutritionValue;
|
||||
// animal.hunger = Mathf.Clamp(animal.hunger, 0, animal.maxHunger);
|
||||
// GameObject.Destroy(target.gameObject);
|
||||
|
||||
animal.ChangeState(ToDefault);
|
||||
}
|
||||
// animal.ChangeState(ToDefault);
|
||||
// }
|
||||
|
||||
public override void Update() {
|
||||
// public override void Update() {
|
||||
|
||||
}
|
||||
}
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -3,28 +3,28 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using MuHua;
|
||||
|
||||
public class AnimalIdleState : MachineState {
|
||||
public string ToDefault = "Roaming";
|
||||
// public class AnimalIdleState : IStateMachine {
|
||||
// public string ToDefault = "Roaming";
|
||||
|
||||
private float idleTime;
|
||||
// private float idleTime;
|
||||
|
||||
public AnimalMachine animal;
|
||||
public AnimalIdleState(Machine machine) : base(machine) => animal = machine as AnimalMachine;
|
||||
// public AnimalMachine animal;
|
||||
// public AnimalIdleState(StateMachine machine) : base(machine) => animal = machine as AnimalMachine;
|
||||
|
||||
public override void Enter() {
|
||||
idleTime = Random.Range(3.0f, 5.0f);
|
||||
}
|
||||
// public override void Enter() {
|
||||
// idleTime = Random.Range(3.0f, 5.0f);
|
||||
// }
|
||||
|
||||
public override void Exit() {
|
||||
// public override void Exit() {
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
public override void Trigger() {
|
||||
// public override void Trigger() {
|
||||
|
||||
}
|
||||
// }
|
||||
|
||||
public override void Update() {
|
||||
idleTime -= Time.deltaTime;
|
||||
if (idleTime <= 0) { animal.ChangeState(ToDefault); }
|
||||
}
|
||||
}
|
||||
// public override void Update() {
|
||||
// idleTime -= Time.deltaTime;
|
||||
// if (idleTime <= 0) { animal.ChangeState(ToDefault); }
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -3,79 +3,79 @@ 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; // 搜索食物的半径
|
||||
// public class AnimalMachine : StateMachine {
|
||||
// [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; // 动画控制器
|
||||
// [Header("控制组件")]
|
||||
// public Movement movement; // 运动控制器
|
||||
// public Animator animator; // 动画控制器
|
||||
|
||||
private float hungerTimer = 0.0f; // 计时器
|
||||
private float chasingCooldownTimer = 0.0f; // 追逐状态冷却计时器
|
||||
private const float chasingCooldown = 5.0f; // 追逐状态冷却时间
|
||||
// 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<AnimalFood>(this));
|
||||
RegisterState("Eating", new AnimalEatingState(this));
|
||||
// protected override void InitializeStates() {
|
||||
// RegisterState("Idle", new AnimalIdleState(this));
|
||||
// RegisterState("Roaming", new AnimalRoamingState(this));
|
||||
// RegisterState("Chasing", new AnimalChasingState<AnimalFood>(this));
|
||||
// RegisterState("Eating", new AnimalEatingState(this));
|
||||
|
||||
ChangeState("Idle");
|
||||
}
|
||||
// ChangeState("Idle");
|
||||
// }
|
||||
|
||||
protected override void Update() {
|
||||
base.Update();
|
||||
// protected override void Update() {
|
||||
// base.Update();
|
||||
|
||||
// 更新计时器
|
||||
hungerTimer += Time.deltaTime;
|
||||
chasingCooldownTimer += Time.deltaTime;
|
||||
// // 更新计时器
|
||||
// hungerTimer += Time.deltaTime;
|
||||
// chasingCooldownTimer += Time.deltaTime;
|
||||
|
||||
if (hungerTimer >= 1.0f) { ConsumeHunger(); }
|
||||
}
|
||||
// if (hungerTimer >= 1.0f) { ConsumeHunger(); }
|
||||
// }
|
||||
|
||||
public virtual void ConsumeHunger() {
|
||||
// 重置计时器
|
||||
hungerTimer = 0.0f;
|
||||
// 每次消耗1点饥饿度
|
||||
hunger -= 1.0f;
|
||||
if (hunger < 0.0f) { hunger = 0.0f; }
|
||||
// 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;
|
||||
// // 如果饥饿度低于最大饥饿度的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; // 重置冷却计时器
|
||||
}
|
||||
}
|
||||
// // 如果触发Chasing状态,且冷却时间已过,切换到Chasing状态
|
||||
// if (valid && chasingCooldownTimer >= chasingCooldown) {
|
||||
// ChangeState("Chasing");
|
||||
// chasingCooldownTimer = 0.0f; // 重置冷却计时器
|
||||
// }
|
||||
// }
|
||||
|
||||
// 从指定范围内查找指定类型的组件
|
||||
public virtual bool Find<T>(out T value) where T : Component {
|
||||
Collider[] colliders = Physics.OverlapSphere(transform.position, searchRadius);
|
||||
foreach (Collider collider in colliders) {
|
||||
T component = collider.GetComponent<T>();
|
||||
if (component != null) {
|
||||
value = component;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
// // 从指定范围内查找指定类型的组件
|
||||
// public virtual bool Find<T>(out T value) where T : Component {
|
||||
// Collider[] colliders = Physics.OverlapSphere(transform.position, searchRadius);
|
||||
// foreach (Collider collider in colliders) {
|
||||
// T component = collider.GetComponent<T>();
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
// // 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();
|
||||
// // }
|
||||
// }
|
||||
|
||||
@@ -3,28 +3,28 @@ 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 class AnimalRoamingState : IStateMachine {
|
||||
// public Vector3 targetPosition;
|
||||
// public string ToDefault = "Idle";
|
||||
// public readonly AnimalMachine animal;
|
||||
// public AnimalRoamingState(StateMachine machine) : base(machine) => animal = machine as AnimalMachine;
|
||||
|
||||
public override void Enter() {
|
||||
targetPosition = animal.movement.RandomTargetPosition();
|
||||
}
|
||||
// public override void Enter() {
|
||||
// targetPosition = animal.movement.RandomTargetPosition();
|
||||
// }
|
||||
|
||||
public override void Exit() {
|
||||
animal.movement.StopMoving();
|
||||
animal.animator.SetFloat("MoveSpeed", 0);
|
||||
}
|
||||
// public override void Exit() {
|
||||
// animal.movement.StopMoving();
|
||||
// animal.animator.SetFloat("MoveSpeed", 0);
|
||||
// }
|
||||
|
||||
public override void Trigger() {
|
||||
// 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); }
|
||||
}
|
||||
}
|
||||
// public override void Update() {
|
||||
// bool complete = animal.movement.UpdateMove(targetPosition);
|
||||
// animal.animator.SetFloat("MoveSpeed", animal.movement.currentSpeed);
|
||||
// if (complete) { animal.ChangeState(ToDefault); }
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
public abstract class Character : MonoBehaviour {
|
||||
/// <summary> 更新移动 </summary>
|
||||
public abstract bool UpdateMove(Vector3 position);
|
||||
|
||||
/// <summary> 动画触发 </summary>
|
||||
public abstract void AnimationTrigger(string value);
|
||||
/// <summary> 动画结束 </summary>
|
||||
public abstract void AnimationEnd();
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
/// <summary>
|
||||
/// 有限状态机
|
||||
/// </summary>
|
||||
public abstract class Machine : Character {
|
||||
protected MachineState currentState;
|
||||
protected Dictionary<string, MachineState> states = new Dictionary<string, MachineState>();
|
||||
|
||||
protected virtual void Start() => InitializeStates();
|
||||
protected virtual void Update() => currentState?.Update();
|
||||
|
||||
#region 状态机功能
|
||||
protected abstract void InitializeStates();
|
||||
protected virtual void RegisterState(string stateType, MachineState state) {
|
||||
if (!states.ContainsKey(stateType)) { states.Add(stateType, state); }
|
||||
}
|
||||
public virtual void ChangeState(string stateType) {
|
||||
if (states.ContainsKey(stateType)) {
|
||||
currentState?.Exit();
|
||||
currentState = states[stateType];
|
||||
currentState.Enter();
|
||||
}
|
||||
else {
|
||||
Debug.LogWarning($"State {stateType} is not registered.");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
/// <summary>
|
||||
/// 状态接口
|
||||
/// </summary>
|
||||
public abstract class MachineState {
|
||||
protected readonly Machine machine;
|
||||
|
||||
public MachineState(Machine machine) => this.machine = machine;
|
||||
|
||||
/// <summary> 进入状态 </summary>
|
||||
public abstract void Enter();
|
||||
/// <summary> 更新状态 </summary>
|
||||
public abstract void Update();
|
||||
/// <summary> 退出状态 </summary>
|
||||
public abstract void Exit();
|
||||
/// <summary> 触发状态 </summary>
|
||||
public abstract void Trigger();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
public abstract class ICharacter : MonoBehaviour {
|
||||
public Ikinesis kinesis;
|
||||
|
||||
public void Update() => kinesis.Update();
|
||||
|
||||
/// <summary> 更新动作 </summary>
|
||||
public abstract void Updatekinesis(Ikinesis kinesis);
|
||||
|
||||
/// <summary> 触发动画特效 </summary>
|
||||
public virtual void AnimationEffects() => kinesis.AnimationEffects();
|
||||
/// <summary> 动画结束 </summary>
|
||||
public virtual void AnimationEnd() => kinesis.AnimationEnd();
|
||||
/// <summary> 动画退出 </summary>
|
||||
public virtual void AnimationExit() => kinesis.AnimationExit();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
/// <summary>
|
||||
/// 有限状态机
|
||||
/// </summary>
|
||||
public abstract class IMachine : MonoBehaviour {
|
||||
protected IMachineState currentState;
|
||||
protected Dictionary<string, IMachineState> states = new Dictionary<string, IMachineState>();
|
||||
|
||||
protected virtual void Start() => InitializeStates();
|
||||
protected virtual void Update() => currentState?.Update();
|
||||
|
||||
#region 状态机功能
|
||||
protected abstract void InitializeStates();
|
||||
protected virtual void RegisterState(string stateType, IMachineState state) {
|
||||
if (!states.ContainsKey(stateType)) { states.Add(stateType, state); }
|
||||
}
|
||||
public virtual void ChangeState(string stateType) {
|
||||
if (states.ContainsKey(stateType)) {
|
||||
currentState?.Exit();
|
||||
currentState = states[stateType];
|
||||
currentState.Enter();
|
||||
}
|
||||
else {
|
||||
Debug.LogWarning($"State {stateType} is not registered.");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
/// <summary>
|
||||
/// 状态接口
|
||||
/// </summary>
|
||||
public abstract class IMachineState {
|
||||
protected readonly IMachine machine;
|
||||
|
||||
public IMachineState(IMachine machine) => this.machine = machine;
|
||||
|
||||
/// <summary> 进入状态 </summary>
|
||||
public abstract void Enter();
|
||||
/// <summary> 更新状态 </summary>
|
||||
public abstract void Update();
|
||||
/// <summary> 退出状态 </summary>
|
||||
public abstract void Exit();
|
||||
/// <summary> 触发状态 </summary>
|
||||
public abstract void Trigger();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
/// <summary>
|
||||
/// 角色动作
|
||||
/// </summary>
|
||||
public abstract class Ikinesis {
|
||||
/// <summary> 动画名字 </summary>
|
||||
public abstract string AnimName { get; }
|
||||
/// <summary> 是否可以打断 </summary>
|
||||
public abstract bool Interrupt { get; }
|
||||
|
||||
/// <summary> 持续更新 </summary>
|
||||
public virtual void Update() { }
|
||||
|
||||
/// <summary> 触发动画特效 </summary>
|
||||
public virtual void AnimationEffects() { }
|
||||
/// <summary> 动画结束 </summary>
|
||||
public virtual void AnimationEnd() { }
|
||||
/// <summary> 动画退出 </summary>
|
||||
public virtual void AnimationExit() { }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e096ab8673cda9e42be867d97aae83eb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,21 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
public class PlayerController : Character {
|
||||
public Movement movement; // 运动控制器
|
||||
public Animator animator; // 动画控制器
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf7a593380ccdea49bd7b165329298e2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
/// <summary>
|
||||
/// 运动控制器
|
||||
/// </summary>
|
||||
public abstract class Movement : MonoBehaviour {
|
||||
/// <summary> 当前速度 </summary>
|
||||
public abstract float CurrentSpeed { get; }
|
||||
/// <summary> 当前方向 </summary>
|
||||
public abstract Vector3 Direction { get; }
|
||||
|
||||
/// <summary> 更新移动 </summary>
|
||||
public abstract bool UpdateMove(Vector3 position);
|
||||
/// <summary> 获取随机位置 </summary>
|
||||
public abstract Vector3 RandomTargetPosition();
|
||||
/// <summary> 停止移动 </summary>
|
||||
public abstract void StopMoving();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
/// <summary>
|
||||
/// 标准运动实现
|
||||
/// </summary>
|
||||
public class MovementStandard : Movement {
|
||||
public float moveSpeed = 5.0f; // 最大移动速度
|
||||
public float acceleration = 20.0f; // 加速度
|
||||
public float steeringSpeed = 180.0f; // 加速度
|
||||
public float currentSpeed = 0.0f; // 当前速度
|
||||
public Vector3 direction; // 面向
|
||||
|
||||
public override float CurrentSpeed => currentSpeed;
|
||||
|
||||
public override Vector3 Direction => direction;
|
||||
|
||||
public override bool UpdateMove(Vector3 position) {
|
||||
// 计算相对于世界坐标系的移动方向
|
||||
Vector3 moveDirection = (position - transform.position).normalized;
|
||||
float distance = Vector3.Distance(transform.position, position);
|
||||
|
||||
// 平滑加速和减速
|
||||
currentSpeed = distance > 0.2f
|
||||
? Mathf.MoveTowards(currentSpeed, moveSpeed, acceleration * Time.deltaTime)
|
||||
: Mathf.MoveTowards(currentSpeed, 0, acceleration * Time.deltaTime);
|
||||
|
||||
// 移动玩家
|
||||
transform.Translate(moveDirection * currentSpeed * Time.deltaTime, Space.World);
|
||||
|
||||
// 如果有移动输入,则更新玩家的朝向
|
||||
if (distance != 0) {
|
||||
Quaternion toRotation = Quaternion.LookRotation(moveDirection, Vector3.up);
|
||||
transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, moveSpeed * Time.deltaTime * steeringSpeed);
|
||||
}
|
||||
|
||||
// 计算转向向量
|
||||
Vector3 localMoveDirection = transform.InverseTransformDirection(moveDirection * currentSpeed);
|
||||
localMoveDirection = localMoveDirection.normalized;
|
||||
// 对localMoveDirection的x和z进行分类处理
|
||||
float moveX = Convert.ToInt32(localMoveDirection.x);
|
||||
float moveZ = Convert.ToInt32(localMoveDirection.z);
|
||||
direction = new Vector3(moveX, 0, moveZ);
|
||||
|
||||
// 如果到达目标位置,返回 true
|
||||
distance = Vector3.Distance(transform.position, position);
|
||||
|
||||
return distance < 0.05f;
|
||||
}
|
||||
public override Vector3 RandomTargetPosition() {
|
||||
float randomX = UnityEngine.Random.Range(-10.0f, 10.0f);
|
||||
float randomZ = UnityEngine.Random.Range(-10.0f, 10.0f);
|
||||
return transform.position + new Vector3(randomX, 0, randomZ);
|
||||
}
|
||||
public override void StopMoving() {
|
||||
currentSpeed = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
/// <summary>
|
||||
/// 运动控制器
|
||||
/// </summary>
|
||||
public abstract class Movement : MonoBehaviour {
|
||||
public float moveSpeed = 5.0f; // 最大移动速度
|
||||
public float acceleration = 20.0f; // 加速度
|
||||
public float currentSpeed = 0.0f; // 当前速度
|
||||
public Vector3 front; // 面向
|
||||
|
||||
public abstract bool UpdateMove(Vector3 position);
|
||||
public abstract Vector3 RandomTargetPosition();
|
||||
public abstract void StopMoving();
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
/// <summary>
|
||||
/// 标准运动实现
|
||||
/// </summary>
|
||||
public class MovementStandard : Movement {
|
||||
public override bool UpdateMove(Vector3 position) {
|
||||
// 计算相对于世界坐标系的移动方向
|
||||
Vector3 moveDirection = (position - transform.position).normalized;
|
||||
float distance = Vector3.Distance(transform.position, position);
|
||||
|
||||
// 平滑加速和减速
|
||||
currentSpeed = distance > 0.2f
|
||||
? Mathf.MoveTowards(currentSpeed, moveSpeed, acceleration * Time.deltaTime)
|
||||
: Mathf.MoveTowards(currentSpeed, 0, acceleration * Time.deltaTime);
|
||||
|
||||
// 移动玩家
|
||||
transform.Translate(moveDirection * currentSpeed * Time.deltaTime, Space.World);
|
||||
|
||||
// 如果有移动输入,则更新玩家的朝向
|
||||
if (distance != 0) {
|
||||
Quaternion toRotation = Quaternion.LookRotation(moveDirection, Vector3.up);
|
||||
transform.rotation = Quaternion.RotateTowards(transform.rotation, toRotation, moveSpeed * Time.deltaTime * 100);
|
||||
}
|
||||
|
||||
// 计算转向向量
|
||||
Vector3 localMoveDirection = transform.InverseTransformDirection(moveDirection * currentSpeed);
|
||||
localMoveDirection = localMoveDirection.normalized;
|
||||
// 对localMoveDirection的x和z进行分类处理
|
||||
float moveX = Convert.ToInt32(localMoveDirection.x);
|
||||
float moveZ = Convert.ToInt32(localMoveDirection.z);
|
||||
front = new Vector3(moveX, 0, moveZ);
|
||||
|
||||
// 如果到达目标位置,返回 true
|
||||
distance = Vector3.Distance(transform.position, position);
|
||||
|
||||
return distance < 0.05f;
|
||||
}
|
||||
public override Vector3 RandomTargetPosition() {
|
||||
float randomX = UnityEngine.Random.Range(-10.0f, 10.0f);
|
||||
float randomZ = UnityEngine.Random.Range(-10.0f, 10.0f);
|
||||
return transform.position + new Vector3(randomX, 0, randomZ);
|
||||
}
|
||||
public override void StopMoving() {
|
||||
currentSpeed = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,16 @@
|
||||
{
|
||||
"name": "MuHua.Character"
|
||||
}
|
||||
"name": "MuHua.Character",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:75469ad4d38634e559750d17036d5f7c"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
public class PlayerCharacter : ICharacter {
|
||||
public Animator animator;
|
||||
public Movement movement;
|
||||
|
||||
private void Awake() => kinesis = new PlayerKinesisIdle();
|
||||
|
||||
public override void Updatekinesis(Ikinesis kinesis) {
|
||||
if (!this.kinesis.Interrupt) { return; }
|
||||
this.kinesis = kinesis;
|
||||
|
||||
//播放动画
|
||||
animator.Play(this.kinesis.AnimName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 28866a6768c3e7441aa12caefd6217b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace MuHua {
|
||||
public class PlayerController : MonoBehaviour {
|
||||
public Transform cameraController; // 相机对象
|
||||
public PlayerCharacter character;
|
||||
|
||||
private Vector2 moveInput;
|
||||
|
||||
private void Update() {
|
||||
if (moveInput == Vector2.zero) { return; }
|
||||
// 获取相机的前向和右向
|
||||
Vector3 cameraForward = cameraController.transform.forward;
|
||||
Vector3 cameraRight = cameraController.transform.right;
|
||||
|
||||
// 忽略相机的y轴
|
||||
cameraForward.y = 0;
|
||||
cameraRight.y = 0;
|
||||
|
||||
// 归一化向量
|
||||
cameraForward.Normalize();
|
||||
cameraRight.Normalize();
|
||||
|
||||
// 计算相对于相机的移动方向
|
||||
Vector3 moveDirection = (cameraForward * moveInput.y + cameraRight * moveInput.x).normalized;
|
||||
|
||||
// 相对于玩家的移动方向
|
||||
Vector3 position = character.transform.position + new Vector3(moveDirection.x, 0, moveDirection.z) * 0.5f;
|
||||
PlayerKinesisMove kinesis = new PlayerKinesisMove(position, character);
|
||||
character.Updatekinesis(kinesis);
|
||||
}
|
||||
|
||||
#region 输入系统
|
||||
public void OnMove(InputValue inputValue) {
|
||||
// 获取移动输入
|
||||
moveInput = inputValue.Get<Vector2>();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ff61e8e49afe14548a5ec4151e14ab34
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
public class PlayerKinesisAttack : Ikinesis {
|
||||
|
||||
public string animName = "Attack01";
|
||||
public bool animEnd = false;
|
||||
|
||||
public override string AnimName => animName;
|
||||
public override bool Interrupt => animEnd;
|
||||
|
||||
public override void AnimationEnd() => animEnd = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c910b7b6bba29d4381c9bb1d615ff77
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
public class PlayerKinesisIdle : Ikinesis {
|
||||
public override string AnimName => "Idle";
|
||||
public override bool Interrupt => true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 190d2b1706b7e0b42b9700950c4e2c18
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,31 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
public class PlayerKinesisMove : Ikinesis {
|
||||
public Vector3 position;
|
||||
public Movement movement;
|
||||
public Animator animator;
|
||||
public PlayerCharacter character;
|
||||
public Ikinesis transition = new PlayerKinesisIdle();
|
||||
|
||||
public override string AnimName => "Move";
|
||||
public override bool Interrupt => true;
|
||||
|
||||
public PlayerKinesisMove(Vector3 position, PlayerCharacter character) {
|
||||
this.position = position;
|
||||
this.movement = character.movement;
|
||||
this.animator = character.animator;
|
||||
this.character = character;
|
||||
}
|
||||
|
||||
public override void Update() {
|
||||
if (movement.UpdateMove(position)) { character.Updatekinesis(transition); }
|
||||
|
||||
animator.SetFloat("MoveSpeed", movement.CurrentSpeed);
|
||||
animator.SetFloat("MoveX", movement.Direction.x);
|
||||
animator.SetFloat("MoveZ", movement.Direction.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c4416dfc61926e439368a6fd3b26675
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -4,6 +4,7 @@
|
||||
"com.unity.collab-proxy": "2.5.2",
|
||||
"com.unity.collections": "1.2.4",
|
||||
"com.unity.feature.development": "1.0.1",
|
||||
"com.unity.inputsystem": "1.7.0",
|
||||
"com.unity.render-pipelines.universal": "14.0.11",
|
||||
"com.unity.textmeshpro": "3.0.6",
|
||||
"com.unity.timeline": "1.7.6",
|
||||
|
||||
@@ -86,6 +86,15 @@
|
||||
"dependencies": {},
|
||||
"url": "https://packages.unity.cn"
|
||||
},
|
||||
"com.unity.inputsystem": {
|
||||
"version": "1.7.0",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.modules.uielements": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.cn"
|
||||
},
|
||||
"com.unity.mathematics": {
|
||||
"version": "1.2.6",
|
||||
"depth": 1,
|
||||
|
||||
@@ -845,7 +845,7 @@ PlayerSettings:
|
||||
hmiLogStartupTiming: 0
|
||||
hmiCpuConfiguration:
|
||||
apiCompatibilityLevel: 3
|
||||
activeInputHandler: 0
|
||||
activeInputHandler: 2
|
||||
windowsGamepadBackendHint: 0
|
||||
cloudProjectId:
|
||||
framebufferDepthMemorylessMode: 0
|
||||
|
||||
Reference in New Issue
Block a user