using System;
using System.Collections.Generic;
using UnityEngine;
using RAIN.Action;
using RAIN.Path;
using RAIN.Core;
using RAIN.Animation;
namespace RAIN.Primitives
{
///
/// MoveAction is a primitive used to specify a target location to move to, speed at which to move, and optionally an animation to play while moving.
///
public class MoveAction : Action.Action
{
///
/// If the movement target is a GameObject (Transform) then moveContextVariableName contains the name of the variable holding the game object.
/// This may have been assigned by a DetectAction primitive.
///
public string moveContextVariableName = null;
///
/// If the look target is a GameObject (Transform) then moveContextVariableName contains the name of the variable holding the game object.
/// This may have been assigned by a DetectAction primitive.
///
public string lookContextVariableName = null;
///
/// moveTarget is the MoveLookTarget (Vector or Transform) that is moved to
///
public MoveLookTarget moveTarget = new MoveLookTarget();
///
/// lookTarget is the MoveLookTarget (Vector or Transform) that is face during movement
///
public MoveLookTarget lookTarget = new MoveLookTarget();
///
/// moveSpeed is the target speed for movement. This is limited by the Agent's overall MaxSpeed
///
public float moveSpeed = -1.0f;
///
/// lookSpeed is the target rotation speed for movement. This is limited by the Agent's overall MaxRotationRate
///
public float lookSpeed = -1.0f;
///
/// animationOverride is the animation state name of an animation that should be played during movement. If animation is driven by an AIAnimationController, this value will override
/// the controller's normal animation. Leave null or blank if no custom animation is desired
///
public string animationOverride = null;
///
/// animationOverrideBaseSpeed is the baseline speed of the animation state specified in animationOverride. The animation playback speed will be adjusted based on the difference
/// between actual movement speed and this base speed
///
public float animationOverrideBaseSpeed = 1.0f;
private bool _animationStarted = false;
public MoveAction() { }
///
/// ActionResult.Start
/// Sets up move and look targets from variables if necessary
///
///
///
/// SUCCESS
public override ActionResult Start(Agent agent, float deltaTime)
{
if (moveContextVariableName != null) moveTarget = GetTargetFromVariable(moveContextVariableName);
if (lookContextVariableName != null) lookTarget = GetTargetFromVariable(lookContextVariableName);
_animationStarted = false;
return ActionResult.SUCCESS;
}
///
/// ActionResult.Execute
/// Move toward the move target, look at the look target.
///
///
///
/// SUCCESS if the Agent has reached the target, RUNNING otherwise
public override ActionResult Execute(Agent agent, float deltaTime)
{
bool closeEnough = true;
float maxSpeed = agent.Kinematic.MaxSpeed;
float maxRotation = agent.Kinematic.MaxRotationRate;
if (moveSpeed >= 0) agent.Kinematic.MaxSpeed = Mathf.Min(moveSpeed, maxSpeed);
if (lookSpeed >= 0) agent.Kinematic.MaxRotationRate = Mathf.Min(lookSpeed, maxRotation);
if ((moveTarget != null) && (moveTarget.TargetType != MoveLookTarget.MoveLookTargetType.NONE))
{
agent.MoveTarget = moveTarget;
closeEnough = agent.Move(deltaTime);
}
if ((lookTarget != null) && (lookTarget.TargetType != MoveLookTarget.MoveLookTargetType.NONE))
{
agent.LookTarget = lookTarget;
closeEnough &= agent.Look(deltaTime);
}
if (!closeEnough && !_animationStarted)
{
if ((animationOverride != null) && (animationOverride.Trim().Length > 0))
{
agent.Avatar.BroadcastMessage("HandleAIAnimationStateMovementOverride", new AnimationParams(animationOverride, animationOverrideBaseSpeed), SendMessageOptions.DontRequireReceiver);
_animationStarted = true;
}
}
agent.Kinematic.MaxSpeed = maxSpeed;
agent.Kinematic.MaxRotationRate = maxRotation;
if (closeEnough) return ActionResult.SUCCESS;
return ActionResult.RUNNING;
}
///
/// ActionResult.Stop
/// Stops custom animation override if enabled
///
///
///
/// SUCCESS
public override ActionResult Stop(Agent agent, float deltaTime)
{
if (_animationStarted && (animationOverride != null) && (animationOverride.Trim().Length > 0))
{
agent.Avatar.BroadcastMessage("HandleAIAnimationStateMovementOverride", new AnimationParams(null, 0), SendMessageOptions.DontRequireReceiver);
}
_animationStarted = false;
return ActionResult.SUCCESS;
}
private MoveLookTarget GetTargetFromVariable(string variable)
{
if (!actionContext.ContextItemExists(variable)) return null;
MoveLookTarget target = null;
target = actionContext.GetContextItem(variable);
if (target != null) return target;
target = new MoveLookTarget();
Kinematic k = actionContext.GetContextItem(variable);
if (k != null)
{
target.KinematicTarget = k;
return target;
}
GameObject gobj = actionContext.GetContextItem(variable);
if (gobj != null)
{
target.TransformTarget = gobj.transform;
return target;
}
Vector3 v = actionContext.GetContextItem(variable);
target.VectorTarget = v;
return target;
}
}
}