1
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf7a593380ccdea49bd7b165329298e2
|
||||
guid: f0aeb4e44882d754a94ca38a40711e98
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
public class AnimatorStandard : IAnimator {
|
||||
private string layer;
|
||||
private string current;
|
||||
private Animator animator;
|
||||
|
||||
private void Awake() => animator = GetComponent<Animator>();
|
||||
|
||||
public override void Transition(string name) {
|
||||
if (current == name) { animator.Play(name); }
|
||||
else { animator.CrossFade(name, 0.1f); }
|
||||
current = name;
|
||||
|
||||
// 判断当前动画,如果不是相同动画就增加过渡
|
||||
// AnimatorStateInfo currentState = animator.GetCurrentAnimatorStateInfo(0);
|
||||
// Debug.Log($"{currentState.normalizedTime} , {this.kinesis.AnimName}");
|
||||
}
|
||||
|
||||
public override void SetFloat(string name, float value) => animator.SetFloat(name, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8394161d0e9670f4a83246f5a5da722b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
[RequireComponent(typeof(Animator))]
|
||||
public abstract class IAnimator : MonoBehaviour {
|
||||
/// <summary> 动画过渡 </summary>
|
||||
public abstract void Transition(string name);
|
||||
/// <summary> 设置参数 </summary>
|
||||
public abstract void SetFloat(string name, float value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e64668e8630d6c149bd637156aa1c42d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
public class CharacterPlayer : ICharacter {
|
||||
|
||||
private void Awake() => Transitionkinesis(new KinesisIdle(this));
|
||||
|
||||
public override void Transitionkinesis(Ikinesis kinesis) {
|
||||
if (currentKinesis != null && !currentKinesis.Transition(kinesis)) { return; }
|
||||
currentKinesis = kinesis;
|
||||
currentKinesis.Startkinesis();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,18 +4,18 @@ using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
public abstract class ICharacter : MonoBehaviour {
|
||||
public Ikinesis kinesis;
|
||||
public Ikinesis currentKinesis;
|
||||
|
||||
public void Update() => kinesis.Update();
|
||||
public void Update() => currentKinesis.Update();
|
||||
|
||||
/// <summary> 更新动作 </summary>
|
||||
public abstract void Updatekinesis(Ikinesis kinesis);
|
||||
/// <summary> 过渡动作 </summary>
|
||||
public abstract void Transitionkinesis(Ikinesis kinesis);
|
||||
|
||||
/// <summary> 触发动画特效 </summary>
|
||||
public virtual void AnimationEffects() => kinesis.AnimationEffects();
|
||||
public virtual void AnimationEffects() => currentKinesis.AnimationEffects();
|
||||
/// <summary> 动画结束 </summary>
|
||||
public virtual void AnimationEnd() => kinesis.AnimationEnd();
|
||||
public virtual void AnimationEnd() => currentKinesis.AnimationEnd();
|
||||
/// <summary> 动画退出 </summary>
|
||||
public virtual void AnimationExit() => kinesis.AnimationExit();
|
||||
public virtual void AnimationExit() => currentKinesis.AnimationExit();
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -4,9 +4,9 @@ using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace MuHua {
|
||||
public class PlayerController : MonoBehaviour {
|
||||
public class ControllerPlayer : MonoBehaviour {
|
||||
public Transform cameraController; // 相机对象
|
||||
public PlayerCharacter character;
|
||||
public CharacterPlayer character;
|
||||
|
||||
private Vector2 moveInput;
|
||||
|
||||
@@ -29,8 +29,8 @@ namespace MuHua {
|
||||
|
||||
// 相对于玩家的移动方向
|
||||
Vector3 position = character.transform.position + new Vector3(moveDirection.x, 0, moveDirection.z) * 0.5f;
|
||||
PlayerKinesisMove kinesis = new PlayerKinesisMove(position, character);
|
||||
character.Updatekinesis(kinesis);
|
||||
KinesisMove kinesis = new KinesisMove(character, position);
|
||||
character.Transitionkinesis(kinesis);
|
||||
}
|
||||
|
||||
#region 输入系统
|
||||
+5
-5
@@ -7,14 +7,14 @@ namespace MuHua {
|
||||
/// 角色动作
|
||||
/// </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 abstract bool Transition(Ikinesis kinesis);
|
||||
|
||||
public virtual void Startkinesis() { }
|
||||
|
||||
/// <summary> 触发动画特效 </summary>
|
||||
public virtual void AnimationEffects() { }
|
||||
/// <summary> 动画结束 </summary>
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
public class KinesisAttack : Ikinesis {
|
||||
public bool animEnd = false;
|
||||
public string animName;
|
||||
public IAnimator animator;
|
||||
|
||||
public KinesisAttack(ICharacter character, string name = "Attack01") {
|
||||
animName = name;
|
||||
animator = character.GetComponent<IAnimator>();
|
||||
}
|
||||
|
||||
public override bool Transition(Ikinesis kinesis) => animEnd;
|
||||
|
||||
public override void Startkinesis() => animator.Transition(animName);
|
||||
|
||||
public override void AnimationEnd() => animEnd = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
public class KinesisIdle : Ikinesis {
|
||||
public IAnimator animator;
|
||||
|
||||
public KinesisIdle(ICharacter character) => animator = character.GetComponent<IAnimator>();
|
||||
|
||||
public override bool Transition(Ikinesis kinesis) => true;
|
||||
|
||||
public override void Startkinesis() => animator.Transition("Idle");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
public class KinesisMove : Ikinesis {
|
||||
public Vector3 position;
|
||||
public IMovement movement;
|
||||
public IAnimator animator;
|
||||
public ICharacter character;
|
||||
|
||||
public KinesisMove(ICharacter character, Vector3 position) {
|
||||
this.position = position;
|
||||
this.character = character;
|
||||
movement = character.GetComponent<IMovement>();
|
||||
animator = character.GetComponent<IAnimator>();
|
||||
}
|
||||
|
||||
public override bool Transition(Ikinesis kinesis) => true;
|
||||
|
||||
public override void Startkinesis() => animator.Transition("Move");
|
||||
|
||||
public override void Update() {
|
||||
if (movement.UpdateMove(position, 5)) { character.Transitionkinesis(new KinesisIdle(character)); }
|
||||
|
||||
animator.SetFloat("MoveSpeed", movement.CurrentSpeed);
|
||||
animator.SetFloat("MoveX", movement.Direction.x);
|
||||
animator.SetFloat("MoveZ", movement.Direction.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using MuHua;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
public class KinesisTurn : Ikinesis {
|
||||
|
||||
|
||||
public override bool Transition(Ikinesis kinesis) {
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 891f774ac729c45409682ff40c2d4615
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0559d32326453c64bb54d392731648a2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a2af9ed6fc4426e49807173a25d3d2cb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+2
-2
@@ -6,14 +6,14 @@ namespace MuHua {
|
||||
/// <summary>
|
||||
/// 运动控制器
|
||||
/// </summary>
|
||||
public abstract class Movement : MonoBehaviour {
|
||||
public abstract class IMovement : MonoBehaviour {
|
||||
/// <summary> 当前速度 </summary>
|
||||
public abstract float CurrentSpeed { get; }
|
||||
/// <summary> 当前方向 </summary>
|
||||
public abstract Vector3 Direction { get; }
|
||||
|
||||
/// <summary> 更新移动 </summary>
|
||||
public abstract bool UpdateMove(Vector3 position);
|
||||
public abstract bool UpdateMove(Vector3 position, float moveSpeed);
|
||||
/// <summary> 获取随机位置 </summary>
|
||||
public abstract Vector3 RandomTargetPosition();
|
||||
/// <summary> 停止移动 </summary>
|
||||
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MuHua {
|
||||
/// <summary>
|
||||
/// 标准运动实现
|
||||
/// </summary>
|
||||
public class MovementStandard : IMovement {
|
||||
public Vector3 position;
|
||||
public float moveSpeed = 5.0f; // 最大移动速度
|
||||
public float acceleration = 20.0f; // 加速度
|
||||
public float steeringSpeed = 180.0f; // 加速度
|
||||
public float currentSpeed = 0.0f; // 当前速度
|
||||
public Vector3 direction; // 面向
|
||||
public CharacterController controller;
|
||||
|
||||
private float _targetRotation = 0.0f;
|
||||
private float _rotationVelocity;
|
||||
private float _verticalVelocity;
|
||||
|
||||
public override float CurrentSpeed => currentSpeed;
|
||||
|
||||
public override Vector3 Direction => direction;
|
||||
|
||||
private void Awake() => position = transform.position;
|
||||
|
||||
private void Update() {
|
||||
// 计算相对于世界坐标系的移动方向
|
||||
Vector3 moveDirection = (position - transform.position).normalized;
|
||||
float distance = Vector3.Distance(transform.position, position);
|
||||
|
||||
// float targetSpeed = _input.sprint ? SprintSpeed : MoveSpeed;
|
||||
float targetSpeed = moveSpeed;
|
||||
|
||||
// 注意:Vector2的==运算符使用近似值,因此不易出现浮点误差,并且比幅度便宜
|
||||
// 如果没有输入,将目标速度设置为0
|
||||
if (distance < 0.2f) { targetSpeed = 0.0f; }
|
||||
|
||||
// 角色当前水平速度的参考
|
||||
//float currentHorizontalSpeed = new Vector3(controller.velocity.x, 0.0f, controller.velocity.z).magnitude;
|
||||
|
||||
float speedOffset = 0.1f;
|
||||
//float inputMagnitude = moveDirection.magnitude;
|
||||
|
||||
// 加速或减速至目标速度
|
||||
if (currentSpeed < targetSpeed - speedOffset || currentSpeed > targetSpeed + speedOffset) {
|
||||
// 产生弯曲的结果,而不是线性的结果,从而产生更有机的速度变化
|
||||
// 注意Lerp中的T是夹紧的,所以我们不需要夹紧我们的速度
|
||||
currentSpeed = Mathf.Lerp(currentSpeed, targetSpeed, Time.deltaTime * acceleration);
|
||||
|
||||
// 四舍五入到小数点后3位
|
||||
//currentSpeed = Mathf.Round(currentSpeed * 1000f) / 1000f;
|
||||
}
|
||||
else { currentSpeed = targetSpeed; }
|
||||
|
||||
// 注意:矢量2!=运算符使用近似值,因此不易出现浮点误差,而且比幅度便宜
|
||||
// 如果有移动输入,则在玩家移动时旋转玩家
|
||||
// if (moveDirection != Vector3.zero) {
|
||||
// _targetRotation = Mathf.Atan2(moveDirection.x, moveDirection.z) * Mathf.Rad2Deg;
|
||||
// float rotation = Mathf.SmoothDampAngle(transform.eulerAngles.y, _targetRotation, ref _rotationVelocity, steeringSpeed);
|
||||
|
||||
// // 相对于相机位置旋转到面向输入方向
|
||||
// transform.rotation = Quaternion.Euler(0.0f, rotation, 0.0f);
|
||||
// }
|
||||
|
||||
|
||||
//Vector3 targetDirection = Quaternion.Euler(0.0f, _targetRotation, 0.0f) * Vector3.forward;
|
||||
|
||||
// 移动角色
|
||||
// controller.Move(targetDirection.normalized * (currentSpeed * Time.deltaTime) + new Vector3(0.0f, _verticalVelocity, 0.0f) * Time.deltaTime);
|
||||
|
||||
// 平滑加速和减速
|
||||
//currentSpeed = Mathf.MoveTowards(currentSpeed, moveSpeed, acceleration * Time.deltaTime);
|
||||
|
||||
// 移动玩家
|
||||
//transform.Translate(moveDirection * currentSpeed * Time.deltaTime, Space.World);
|
||||
|
||||
controller.Move(moveDirection * currentSpeed * Time.deltaTime);
|
||||
|
||||
// 如果有移动输入,则更新玩家的朝向
|
||||
if (distance > 0.1f) {
|
||||
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);
|
||||
}
|
||||
|
||||
public override bool UpdateMove(Vector3 position, float moveSpeed) {
|
||||
this.position = position;
|
||||
this.moveSpeed = moveSpeed;
|
||||
|
||||
// 如果到达目标位置,返回 true
|
||||
float 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,20 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user