clean up & some documentation
parent
8e7750111b
commit
ce093646aa
|
@ -26,9 +26,6 @@ public partial class Character : CharacterBody2D, IFaction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Export]
|
|
||||||
public float Stealth { get; protected set; } = 0;
|
|
||||||
|
|
||||||
[Signal]
|
[Signal]
|
||||||
public delegate void HealthChangedEventHandler(Events.HealthChangedArgs args);
|
public delegate void HealthChangedEventHandler(Events.HealthChangedArgs args);
|
||||||
|
|
||||||
|
@ -168,6 +165,9 @@ public partial class Character : CharacterBody2D, IFaction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles the <c>Character</c>'s death.
|
||||||
|
/// </summary>
|
||||||
public virtual void Die()
|
public virtual void Die()
|
||||||
{
|
{
|
||||||
if (HurtAnimation.HasAnimation("death"))
|
if (HurtAnimation.HasAnimation("death"))
|
||||||
|
@ -190,11 +190,20 @@ public partial class Character : CharacterBody2D, IFaction
|
||||||
NetImpulse += impulse / Mass;
|
NetImpulse += impulse / Mass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stuns the <c>Chararacter</c> for an amount of time. If
|
||||||
|
/// <paramref name="time"/> is less than the <c>Character</c>'s current
|
||||||
|
/// stun time left, it will have no effect.
|
||||||
|
/// </summary>
|
||||||
public virtual void Stun(float time)
|
public virtual void Stun(float time)
|
||||||
{
|
{
|
||||||
StunTime = Mathf.Max(time, StunTime);
|
StunTime = Mathf.Max(time, StunTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draws the character so that its sprite and inventory items face the
|
||||||
|
/// character's direction.
|
||||||
|
/// </summary>
|
||||||
protected virtual void DrawTarget()
|
protected virtual void DrawTarget()
|
||||||
{
|
{
|
||||||
Vector2 target = Target;
|
Vector2 target = Target;
|
||||||
|
@ -213,6 +222,10 @@ public partial class Character : CharacterBody2D, IFaction
|
||||||
Inventory.Rotation = angle;
|
Inventory.Rotation = angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Use the current item the character is using. Prefer to call this over
|
||||||
|
/// <c>Item.Use</c> as it will check if the character is stunned or alive.
|
||||||
|
/// </summary>
|
||||||
public void UseCurrentItem()
|
public void UseCurrentItem()
|
||||||
{
|
{
|
||||||
if (StunTime > 0 || !IsAlive)
|
if (StunTime > 0 || !IsAlive)
|
||||||
|
@ -264,6 +277,9 @@ public partial class Character : CharacterBody2D, IFaction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Override this method to modify the damage the character takes.
|
||||||
|
/// </summary>
|
||||||
protected virtual float ReceiveDamage(
|
protected virtual float ReceiveDamage(
|
||||||
float damage,
|
float damage,
|
||||||
Character inflictor,
|
Character inflictor,
|
||||||
|
@ -285,6 +301,9 @@ public partial class Character : CharacterBody2D, IFaction
|
||||||
_curDamageText.ShowText();
|
_curDamageText.ShowText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles the character taking damage.
|
||||||
|
/// </summary>
|
||||||
protected virtual void OnReceivedDamage(
|
protected virtual void OnReceivedDamage(
|
||||||
float damage,
|
float damage,
|
||||||
Character inflictor,
|
Character inflictor,
|
||||||
|
@ -348,6 +367,7 @@ public partial class Character : CharacterBody2D, IFaction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For debugging purposes
|
/// For debugging purposes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -355,7 +375,12 @@ public partial class Character : CharacterBody2D, IFaction
|
||||||
{
|
{
|
||||||
OnReceivedDamage(damage, null, 0);
|
OnReceivedDamage(damage, null, 0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Plays a footstep sound. This should be called through an
|
||||||
|
/// <c>AnimationPlayer</c> to sync sounds with animations.
|
||||||
|
/// </summary>
|
||||||
public virtual void Footstep()
|
public virtual void Footstep()
|
||||||
{
|
{
|
||||||
if (GetNode("Effects/Footstep") is AudioStreamPlayer2D player)
|
if (GetNode("Effects/Footstep") is AudioStreamPlayer2D player)
|
||||||
|
@ -364,6 +389,15 @@ public partial class Character : CharacterBody2D, IFaction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns whether the <c>Character</c> has line of sight with
|
||||||
|
/// <paramref name="character"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="character">The character to check for LOS</param>
|
||||||
|
/// <param name="excludeClip">
|
||||||
|
/// Determines whether the raycast should pass through world clips (physics
|
||||||
|
/// layer 5)
|
||||||
|
/// </param>
|
||||||
public bool HasLineOfSight(Character character, bool excludeClip = false)
|
public bool HasLineOfSight(Character character, bool excludeClip = false)
|
||||||
{
|
{
|
||||||
var exclude = new Godot.Collections.Array<Godot.Rid>();
|
var exclude = new Godot.Collections.Array<Godot.Rid>();
|
||||||
|
|
|
@ -96,29 +96,9 @@ public partial class NPC : Character
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _Draw()
|
/// <summary>
|
||||||
{
|
/// Finds the NPC's best character to target.
|
||||||
#if DEBUG
|
/// </summary>
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
Vector2 vec = _weightDirs[i] * _weights[i] * 32;
|
|
||||||
Color c = Colors.Green;
|
|
||||||
if (_bestWeightIdx == i)
|
|
||||||
{
|
|
||||||
c = Colors.Blue;
|
|
||||||
}
|
|
||||||
else if (_weights[i] < 0)
|
|
||||||
{
|
|
||||||
c = Colors.Red;
|
|
||||||
vec = -vec;
|
|
||||||
}
|
|
||||||
DrawLine(Vector2.Zero, vec, c);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
base._Draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual Character FindBestTarget()
|
public virtual Character FindBestTarget()
|
||||||
{
|
{
|
||||||
float bestScore = float.MaxValue;
|
float bestScore = float.MaxValue;
|
||||||
|
@ -136,21 +116,9 @@ public partial class NPC : Character
|
||||||
|
|
||||||
float score = 0;
|
float score = 0;
|
||||||
score += Position.DistanceTo(character.Position);
|
score += Position.DistanceTo(character.Position);
|
||||||
score *= (character.Stealth + 1);
|
|
||||||
|
|
||||||
// if the character has enough stealth, the dot product of the
|
|
||||||
// enemy's current direction and to the character will affect
|
|
||||||
// the score
|
|
||||||
// TODO: implement
|
|
||||||
|
|
||||||
if (score < bestScore)
|
if (score < bestScore)
|
||||||
{
|
{
|
||||||
// if the character has enough stealth, they won't be
|
|
||||||
// targeted if the NPC is not able to see
|
|
||||||
if (!HasLineOfSight(character) && character.Stealth >= 1)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bestScore = score;
|
bestScore = score;
|
||||||
bestChar = character;
|
bestChar = character;
|
||||||
}
|
}
|
||||||
|
@ -170,132 +138,4 @@ public partial class NPC : Character
|
||||||
ThinkerStateMachine.PhysicsProcess(delta);
|
ThinkerStateMachine.PhysicsProcess(delta);
|
||||||
base._PhysicsProcess(delta);
|
base._PhysicsProcess(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ThinkProcess(double delta)
|
|
||||||
{
|
|
||||||
if ((_thinkTimeElapsed += delta) > ThinkTime)
|
|
||||||
{
|
|
||||||
_thinkTimeElapsed = 0;
|
|
||||||
Think();
|
|
||||||
#if DEBUG_NPC
|
|
||||||
QueueRedraw();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ShouldMove || (!ShouldMoveWhenUsingItem && Inventory.IsUsingItem))
|
|
||||||
{
|
|
||||||
Direction = Vector2.Zero;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Direction = _weightDirs[_bestWeightIdx];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateWeights(Vector2 pos)
|
|
||||||
{
|
|
||||||
// FIXME: TODO: remove all the spaghetti
|
|
||||||
Vector2 dir = Target.Normalized();
|
|
||||||
float distSq = GlobalPosition.DistanceSquaredTo(pos);
|
|
||||||
|
|
||||||
var spaceState = GetWorld2D().DirectSpaceState;
|
|
||||||
var exclude = new Godot.Collections.Array<Godot.Rid>();
|
|
||||||
exclude.Add(this.GetRid());
|
|
||||||
|
|
||||||
// calculate weights based on distance
|
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
float directDot = _weightDirs[i].Dot(dir);
|
|
||||||
// clamp dot from [-1, 1] to [0, 1]
|
|
||||||
directDot = (directDot + 1) / 2;
|
|
||||||
|
|
||||||
float strafeDot = Math.Abs(_weightDirs[i].Dot(dir.Clockwise90()));
|
|
||||||
float currDirDot = (_weightDirs[i].Dot(Direction) + 1) / 16;
|
|
||||||
strafeDot = Mathf.Pow((strafeDot + 1) / 2, 2) + currDirDot;
|
|
||||||
|
|
||||||
// favor strafing when getting closer
|
|
||||||
if (distSq > _preferredWeightDistanceSq)
|
|
||||||
{
|
|
||||||
_weights[i] = directDot;
|
|
||||||
}
|
|
||||||
else if (distSq > _maxWeightDistanceSq)
|
|
||||||
{
|
|
||||||
float dDotWeight = Mathf.Sqrt(distSq / 4096);
|
|
||||||
float sDotWeight = 1 - dDotWeight;
|
|
||||||
_weights[i] = (dDotWeight * directDot) +
|
|
||||||
(sDotWeight * strafeDot);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_weights[i] = strafeDot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// subtract weights that collide
|
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
var rayParams = new PhysicsRayQueryParameters2D
|
|
||||||
{
|
|
||||||
Exclude = exclude,
|
|
||||||
CollideWithBodies = true,
|
|
||||||
From = GlobalPosition,
|
|
||||||
To = GlobalPosition + (_weightDirs[i] * 24),
|
|
||||||
CollisionMask = 1 + 2 + 16
|
|
||||||
};
|
|
||||||
|
|
||||||
var result = spaceState.IntersectRay(rayParams);
|
|
||||||
|
|
||||||
// if we hit something
|
|
||||||
if (result.Count > 0)
|
|
||||||
{
|
|
||||||
// then we subtract the value of this from the other weights
|
|
||||||
float oldWeight = _weights[i];
|
|
||||||
for (int j = 0; j < 16; j++)
|
|
||||||
{
|
|
||||||
if (i == j)
|
|
||||||
{
|
|
||||||
_weights[i] = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float dot = _weightDirs[i].Dot(_weightDirs[j]);
|
|
||||||
_weights[j] -= _weights[j] * dot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
float bestWeight = 0;
|
|
||||||
for (int i = 0; i < 16; i++)
|
|
||||||
{
|
|
||||||
if (_weights[i] > bestWeight)
|
|
||||||
{
|
|
||||||
_bestWeightIdx = i;
|
|
||||||
bestWeight = _weights[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void Think()
|
|
||||||
{
|
|
||||||
// TODO: the entity should wander if it doesn't find a best target
|
|
||||||
Character bestTarget = FindBestTarget();
|
|
||||||
if (bestTarget is not null)
|
|
||||||
{
|
|
||||||
Vector2 pos = FindBestTarget().GlobalPosition;
|
|
||||||
Target = pos - GlobalPosition;
|
|
||||||
Vector2 dir = Target;
|
|
||||||
float dist = GlobalPosition.DistanceSquaredTo(pos);
|
|
||||||
UpdateWeights(pos);
|
|
||||||
|
|
||||||
if (dist < 1600 && CanAttack)
|
|
||||||
{
|
|
||||||
if (Inventory.SelectedItem is Weapon weapon)
|
|
||||||
{
|
|
||||||
UseCurrentItem();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,10 +51,6 @@ public sealed partial class Player : Character
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
base._Process(delta);
|
base._Process(delta);
|
||||||
|
|
||||||
var mod = Sprite.SelfModulate;
|
|
||||||
mod.A = 1 - (Stealth / 2);
|
|
||||||
Sprite.SelfModulate = mod;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _Input(InputEvent @event)
|
public override void _Input(InputEvent @event)
|
||||||
|
@ -65,6 +61,9 @@ public sealed partial class Player : Character
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Respawns the player with full health and plays spawn animation
|
||||||
|
/// </summary>
|
||||||
public void Spawn()
|
public void Spawn()
|
||||||
{
|
{
|
||||||
Health = 100;
|
Health = 100;
|
||||||
|
|
|
@ -23,6 +23,12 @@ public abstract partial class Item : Node2D
|
||||||
|
|
||||||
public Character CharacterOwner { get; set; }
|
public Character CharacterOwner { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines if the item is being used. This property determines if
|
||||||
|
/// a character can use another item or not.
|
||||||
|
/// See <see cref="Character.UseCurrentItem"/>
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
public virtual bool IsUsing => false;
|
public virtual bool IsUsing => false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -7,6 +7,9 @@ using SupaLidlGame.State.Weapon;
|
||||||
|
|
||||||
namespace SupaLidlGame.Items.Weapons;
|
namespace SupaLidlGame.Items.Weapons;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A basic melee weapon.
|
||||||
|
/// </summary>
|
||||||
public partial class Sword : Weapon, IParryable
|
public partial class Sword : Weapon, IParryable
|
||||||
{
|
{
|
||||||
public bool IsAttacking { get; protected set; }
|
public bool IsAttacking { get; protected set; }
|
||||||
|
@ -77,6 +80,9 @@ public partial class Sword : Weapon, IParryable
|
||||||
EnableParry(Time.GetTicksMsec());
|
EnableParry(Time.GetTicksMsec());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Makes this melee weapon be able to parry and be parried.
|
||||||
|
/// </summary>
|
||||||
public void EnableParry(ulong parryTimeOrigin)
|
public void EnableParry(ulong parryTimeOrigin)
|
||||||
{
|
{
|
||||||
IsParried = false;
|
IsParried = false;
|
||||||
|
@ -84,6 +90,9 @@ public partial class Sword : Weapon, IParryable
|
||||||
ParryTimeOrigin = parryTimeOrigin;
|
ParryTimeOrigin = parryTimeOrigin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Makes this melee weapon be able to parry and be parried.
|
||||||
|
/// </summary>
|
||||||
public void DisableParry()
|
public void DisableParry()
|
||||||
{
|
{
|
||||||
IsParryable = false;
|
IsParryable = false;
|
||||||
|
@ -113,6 +122,10 @@ public partial class Sword : Weapon, IParryable
|
||||||
base.DeuseAlt();
|
base.DeuseAlt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables the weapon's hitbox. Prefer to call this from a state machine
|
||||||
|
/// rather than managing state through the weapon script.
|
||||||
|
/// </summary>
|
||||||
public void Attack()
|
public void Attack()
|
||||||
{
|
{
|
||||||
//RemainingAttackTime = AttackTime;
|
//RemainingAttackTime = AttackTime;
|
||||||
|
@ -120,6 +133,9 @@ public partial class Sword : Weapon, IParryable
|
||||||
Hitbox.IsDisabled = false;
|
Hitbox.IsDisabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disables the weapon's hitbox and processes all hurtboxes it hit.
|
||||||
|
/// </summary>
|
||||||
public void Deattack()
|
public void Deattack()
|
||||||
{
|
{
|
||||||
IsAttacking = false;
|
IsAttacking = false;
|
||||||
|
@ -161,6 +177,9 @@ public partial class Sword : Weapon, IParryable
|
||||||
base._Process(delta);
|
base._Process(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processes all hits and applies damages to hurtboxes.
|
||||||
|
/// </summary>
|
||||||
public void ProcessHits()
|
public void ProcessHits()
|
||||||
{
|
{
|
||||||
if (IsParried)
|
if (IsParried)
|
||||||
|
@ -199,6 +218,10 @@ public partial class Sword : Weapon, IParryable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stuns the wepaon holder. This is unique to swords and melee weapons
|
||||||
|
/// if they can parry.
|
||||||
|
/// </summary>
|
||||||
public void Stun()
|
public void Stun()
|
||||||
{
|
{
|
||||||
IsParried = true;
|
IsParried = true;
|
||||||
|
@ -238,9 +261,4 @@ public partial class Sword : Weapon, IParryable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void SetAnimationCondition(string condition, bool value)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,28 @@ public abstract partial class StateMachine<T> : Node where T : Node, IState<T>
|
||||||
ChangeState(InitialState);
|
ChangeState(InitialState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes the state of the <c>StateMachine</c>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nextState">The next state to transition to.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true" /> if <paramref name="nextState" /> is a
|
||||||
|
/// valid state, otherwise <see langword="false" />
|
||||||
|
/// </returns>
|
||||||
public virtual bool ChangeState(T nextState)
|
public virtual bool ChangeState(T nextState)
|
||||||
{
|
{
|
||||||
return ChangeState(nextState, out Stack<T> _);
|
return ChangeState(nextState, out Stack<T> _);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes the state of the <c>StateMachine</c>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nextState">The next state to transition to.</param>
|
||||||
|
/// <param name="finalState">The actual state.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true" /> if <paramref name="nextState" /> is a
|
||||||
|
/// valid state, otherwise <see langword="false" />
|
||||||
|
/// </returns>
|
||||||
public bool ChangeState(T nextState, out T finalState)
|
public bool ChangeState(T nextState, out T finalState)
|
||||||
{
|
{
|
||||||
var status = ChangeState(nextState, out Stack<T> states);
|
var status = ChangeState(nextState, out Stack<T> states);
|
||||||
|
@ -30,6 +47,15 @@ public abstract partial class StateMachine<T> : Node where T : Node, IState<T>
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes the state of the <c>StateMachine</c>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nextState">The next state to transition to.</param>
|
||||||
|
/// <param name="states">Stack of all states that transitioned/proxied.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true" /> if <paramref name="nextState" /> is a
|
||||||
|
/// valid state, otherwise <see langword="false" />
|
||||||
|
/// </returns>
|
||||||
public bool ChangeState(T nextState, out Stack<T> states)
|
public bool ChangeState(T nextState, out Stack<T> states)
|
||||||
{
|
{
|
||||||
states = new Stack<T>();
|
states = new Stack<T>();
|
||||||
|
@ -71,14 +97,35 @@ public abstract partial class StateMachine<T> : Node where T : Node, IState<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Changes the current state to a state of type U which must inherit from T.
|
/// Changes the state of the <c>StateMachine</c> of type
|
||||||
|
/// <typeparamref name="U" /> which must inherit from
|
||||||
|
/// <typeparamref name="T" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <typeparam name="U">The type of the state to transition to.</typeparam>
|
||||||
|
/// <param name="state">The resulting state to be transitioned to.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true" /> if <paramref name="nextState" /> is a
|
||||||
|
/// valid state, otherwise <see langword="false" />
|
||||||
|
/// </returns>
|
||||||
public bool ChangeState<U>(out U state) where U : T
|
public bool ChangeState<U>(out U state) where U : T
|
||||||
{
|
{
|
||||||
state = this.FindChildOfType<U>();
|
state = this.FindChildOfType<U>();
|
||||||
return ChangeState(state);
|
return ChangeState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes the state of the <c>StateMachine</c> with node name
|
||||||
|
/// <paramref name="name" />.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="U">The type of the state to transition to.</typeparam>
|
||||||
|
/// <param name="name">
|
||||||
|
/// The name of the <typeparamref name="T" /> node.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="state">The resulting state to be transitioned to.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// <see langword="true" /> if <paramref name="nextState" /> is a
|
||||||
|
/// valid state, otherwise <see langword="false" />
|
||||||
|
/// </returns>
|
||||||
public bool ChangeState(string name, out T state)
|
public bool ChangeState(string name, out T state)
|
||||||
{
|
{
|
||||||
state = GetNode<T>(name);
|
state = GetNode<T>(name);
|
||||||
|
|
Loading…
Reference in New Issue