架构大更
This commit is contained in:
@@ -1,168 +1,172 @@
|
||||
using MoreMountains.Feedbacks;
|
||||
using MoreMountains.Tools;
|
||||
using System.Collections;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using MoreMountains.Feedbacks;
|
||||
using MoreMountains.Tools;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MoreMountains.Feel
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple class controlling the hero character in the Barbarians demo scene
|
||||
/// It simulates a very simple character controller in an ARPG game
|
||||
/// A simple class controlling the hero character in the Barbarians demo scene
|
||||
/// It simulates a very simple character controller in an ARPG game
|
||||
/// </summary>
|
||||
[AddComponentMenu("")]
|
||||
public class Barbarian : MonoBehaviour
|
||||
{
|
||||
[Header("Cooldown")]
|
||||
/// a duration, in seconds, between two attacks, during which attacks are prevented
|
||||
[Tooltip("a duration, in seconds, between two attacks, during which attacks are prevented")]
|
||||
public float CooldownDuration = 0.1f;
|
||||
public class Barbarian : MonoBehaviour
|
||||
{
|
||||
[Header("Cooldown")]
|
||||
/// a duration, in seconds, between two attacks, during which attacks are prevented
|
||||
[Tooltip("a duration, in seconds, between two attacks, during which attacks are prevented")]
|
||||
public float CooldownDuration = 0.1f;
|
||||
|
||||
[Header("Feedbacks")]
|
||||
/// a feedback to call when the attack starts
|
||||
[Tooltip("a feedback to call when the attack starts")]
|
||||
public MMFeedbacks AttackFeedback;
|
||||
/// a feedback to call when each individual attack phase starts
|
||||
[Tooltip("a feedback to call when each individual attack phase starts")]
|
||||
public MMFeedbacks IndividualAttackFeedback;
|
||||
/// a feedback to call when trying to attack while in cooldown
|
||||
[Tooltip("a feedback to call when trying to attack while in cooldown")]
|
||||
public MMFeedbacks DeniedFeedback;
|
||||
[Header("Feedbacks")]
|
||||
/// a feedback to call when the attack starts
|
||||
[Tooltip("a feedback to call when the attack starts")]
|
||||
public MMFeedbacks AttackFeedback;
|
||||
|
||||
[Header("Attack settings")]
|
||||
/// a curve on which to move the character when it attacks
|
||||
public MMTween.MMTweenCurve AttackCurve = MMTween.MMTweenCurve.EaseInOutOverhead;
|
||||
/// the duration of the attack in seconds
|
||||
public float AttackDuration = 2.5f;
|
||||
/// an offset at which to attack enemies
|
||||
public float AttackPositionOffset = 0.3f;
|
||||
/// a duration by which to reduce movement duration after every attack (making each attack faster than the previous one)
|
||||
public float IntervalDecrement = 0.1f;
|
||||
/// a feedback to call when each individual attack phase starts
|
||||
[Tooltip("a feedback to call when each individual attack phase starts")]
|
||||
public MMFeedbacks IndividualAttackFeedback;
|
||||
|
||||
protected List<Vector3> _targets;
|
||||
protected float _lastAttackStartedAt = -100f;
|
||||
protected Vector3 _initialPosition;
|
||||
protected Vector3 _initialLookAtTarget;
|
||||
protected Vector3 _lookAtTarget;
|
||||
protected BarbarianEnemy _enemy;
|
||||
/// a feedback to call when trying to attack while in cooldown
|
||||
[Tooltip("a feedback to call when trying to attack while in cooldown")]
|
||||
public MMFeedbacks DeniedFeedback;
|
||||
|
||||
/// <summary>
|
||||
/// On Awake we store our initial position
|
||||
/// </summary>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_initialPosition = this.transform.position;
|
||||
_initialLookAtTarget = this.transform.position + this.transform.forward * 10f;
|
||||
_lookAtTarget = _initialLookAtTarget;
|
||||
}
|
||||
[Header("Attack settings")]
|
||||
/// a curve on which to move the character when it attacks
|
||||
public MMTween.MMTweenCurve AttackCurve = MMTween.MMTweenCurve.EaseInOutOverhead;
|
||||
|
||||
/// <summary>
|
||||
/// On Update we look for input
|
||||
/// </summary>
|
||||
protected virtual void Update()
|
||||
{
|
||||
HandleInput();
|
||||
LookAtTarget();
|
||||
}
|
||||
/// the duration of the attack in seconds
|
||||
public float AttackDuration = 2.5f;
|
||||
|
||||
/// <summary>
|
||||
/// Makes the character look at the target it's attacking
|
||||
/// </summary>
|
||||
protected virtual void LookAtTarget()
|
||||
{
|
||||
Vector3 direction = _lookAtTarget - _initialPosition;
|
||||
this.transform.LookAt(_lookAtTarget + direction * 5f);
|
||||
}
|
||||
/// an offset at which to attack enemies
|
||||
public float AttackPositionOffset = 0.3f;
|
||||
|
||||
/// <summary>
|
||||
/// Detects input
|
||||
/// </summary>
|
||||
protected virtual void HandleInput()
|
||||
{
|
||||
if (FeelDemosInputHelper.CheckMainActionInputPressedThisFrame())
|
||||
{
|
||||
Attack();
|
||||
}
|
||||
}
|
||||
/// a duration by which to reduce movement duration after every attack (making each attack faster than the previous one)
|
||||
public float IntervalDecrement = 0.1f;
|
||||
|
||||
/// <summary>
|
||||
/// Performs an attack if possible, otherwise plays a denied feedback
|
||||
/// </summary>
|
||||
protected virtual void Attack()
|
||||
{
|
||||
if (Time.time - _lastAttackStartedAt < CooldownDuration + AttackDuration)
|
||||
{
|
||||
DeniedFeedback?.PlayFeedbacks();
|
||||
}
|
||||
else
|
||||
{
|
||||
AcquireTargets();
|
||||
StartCoroutine(AttackCoroutine());
|
||||
_lastAttackStartedAt = Time.time;
|
||||
}
|
||||
}
|
||||
protected BarbarianEnemy _enemy;
|
||||
protected Vector3 _initialLookAtTarget;
|
||||
protected Vector3 _initialPosition;
|
||||
protected float _lastAttackStartedAt = -100f;
|
||||
protected Vector3 _lookAtTarget;
|
||||
|
||||
/// <summary>
|
||||
/// Finds targets around the Barbarian and stores them
|
||||
/// </summary>
|
||||
protected virtual void AcquireTargets()
|
||||
{
|
||||
_targets = new List<Vector3>();
|
||||
protected List<Vector3> _targets;
|
||||
|
||||
Collider[] hitColliders = Physics.OverlapSphere(this.transform.position, 5f);
|
||||
foreach (var hitCollider in hitColliders)
|
||||
{
|
||||
Vector3 enemyPosition = hitCollider.transform.position;
|
||||
Vector3 direction = this.transform.position - enemyPosition;
|
||||
/// <summary>
|
||||
/// On Awake we store our initial position
|
||||
/// </summary>
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_initialPosition = transform.position;
|
||||
_initialLookAtTarget = transform.position + transform.forward * 10f;
|
||||
_lookAtTarget = _initialLookAtTarget;
|
||||
}
|
||||
|
||||
if (hitCollider.GetComponent<BarbarianEnemy>() != null)
|
||||
{
|
||||
_targets.Add(enemyPosition + direction * AttackPositionOffset);
|
||||
}
|
||||
}
|
||||
_targets.MMShuffle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A coroutine used to move to each stored target to attack them
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual IEnumerator AttackCoroutine()
|
||||
{
|
||||
float intervalDuration = AttackDuration / _targets.Count;
|
||||
|
||||
// we play our initial attack feedback
|
||||
AttackFeedback?.PlayFeedbacks();
|
||||
/// <summary>
|
||||
/// On Update we look for input
|
||||
/// </summary>
|
||||
protected virtual void Update()
|
||||
{
|
||||
HandleInput();
|
||||
LookAtTarget();
|
||||
}
|
||||
|
||||
int enemyCounter = 0;
|
||||
/// <summary>
|
||||
/// When we collide with an enemy, we apply damage to it
|
||||
/// </summary>
|
||||
/// <param name="other"></param>
|
||||
protected virtual void OnTriggerEnter(Collider other)
|
||||
{
|
||||
_enemy = other.GetComponent<BarbarianEnemy>();
|
||||
if (_enemy != null)
|
||||
{
|
||||
// we randomize the damage done and apply it to the enemy
|
||||
var damage = Random.Range(50, 250);
|
||||
_enemy.TakeDamage(damage);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Vector3 destination in _targets)
|
||||
{
|
||||
// for each new enemy, we play an attack feedback
|
||||
IndividualAttackFeedback?.PlayFeedbacks();
|
||||
MMTween.MoveTransform(this, this.transform, this.transform.position, destination, null, 0f, intervalDuration, AttackCurve);
|
||||
_lookAtTarget = destination;
|
||||
yield return MMCoroutine.WaitFor(intervalDuration - enemyCounter * IntervalDecrement);
|
||||
enemyCounter++;
|
||||
}
|
||||
/// <summary>
|
||||
/// Makes the character look at the target it's attacking
|
||||
/// </summary>
|
||||
protected virtual void LookAtTarget()
|
||||
{
|
||||
var direction = _lookAtTarget - _initialPosition;
|
||||
transform.LookAt(_lookAtTarget + direction * 5f);
|
||||
}
|
||||
|
||||
MMTween.MoveTransform(this, this.transform, this.transform.position, _initialPosition, null, 0f, intervalDuration, AttackCurve);
|
||||
_lookAtTarget = _initialLookAtTarget;
|
||||
}
|
||||
/// <summary>
|
||||
/// Detects input
|
||||
/// </summary>
|
||||
protected virtual void HandleInput()
|
||||
{
|
||||
if (FeelDemosInputHelper.CheckMainActionInputPressedThisFrame()) Attack();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When we collide with an enemy, we apply damage to it
|
||||
/// </summary>
|
||||
/// <param name="other"></param>
|
||||
protected virtual void OnTriggerEnter(Collider other)
|
||||
{
|
||||
_enemy = other.GetComponent<BarbarianEnemy>();
|
||||
if (_enemy != null)
|
||||
{
|
||||
// we randomize the damage done and apply it to the enemy
|
||||
int damage = Random.Range(50, 250);
|
||||
_enemy.TakeDamage(damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Performs an attack if possible, otherwise plays a denied feedback
|
||||
/// </summary>
|
||||
protected virtual void Attack()
|
||||
{
|
||||
if (Time.time - _lastAttackStartedAt < CooldownDuration + AttackDuration)
|
||||
{
|
||||
DeniedFeedback?.PlayFeedbacks();
|
||||
}
|
||||
else
|
||||
{
|
||||
AcquireTargets();
|
||||
StartCoroutine(AttackCoroutine());
|
||||
_lastAttackStartedAt = Time.time;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds targets around the Barbarian and stores them
|
||||
/// </summary>
|
||||
protected virtual void AcquireTargets()
|
||||
{
|
||||
_targets = new List<Vector3>();
|
||||
|
||||
var hitColliders = Physics.OverlapSphere(transform.position, 5f);
|
||||
foreach (var hitCollider in hitColliders)
|
||||
{
|
||||
var enemyPosition = hitCollider.transform.position;
|
||||
var direction = transform.position - enemyPosition;
|
||||
|
||||
if (hitCollider.GetComponent<BarbarianEnemy>() != null)
|
||||
_targets.Add(enemyPosition + direction * AttackPositionOffset);
|
||||
}
|
||||
|
||||
_targets.MMShuffle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A coroutine used to move to each stored target to attack them
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual IEnumerator AttackCoroutine()
|
||||
{
|
||||
var intervalDuration = AttackDuration / _targets.Count;
|
||||
|
||||
// we play our initial attack feedback
|
||||
AttackFeedback?.PlayFeedbacks();
|
||||
|
||||
var enemyCounter = 0;
|
||||
|
||||
foreach (var destination in _targets)
|
||||
{
|
||||
// for each new enemy, we play an attack feedback
|
||||
IndividualAttackFeedback?.PlayFeedbacks();
|
||||
MMTween.MoveTransform(this, transform, transform.position, destination, null, 0f, intervalDuration,
|
||||
AttackCurve);
|
||||
_lookAtTarget = destination;
|
||||
yield return MMCoroutine.WaitFor(intervalDuration - enemyCounter * IntervalDecrement);
|
||||
enemyCounter++;
|
||||
}
|
||||
|
||||
MMTween.MoveTransform(this, transform, transform.position, _initialPosition, null, 0f, intervalDuration,
|
||||
AttackCurve);
|
||||
_lookAtTarget = _initialLookAtTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user