You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
6.1 KiB
C#
136 lines
6.1 KiB
C#
3 months ago
|
// Animancer // Copyright 2020 Kybernetik //
|
||
|
|
||
|
#pragma warning disable CS0618 // Type or member is obsolete (for MixerState in Animancer Lite).
|
||
|
#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value.
|
||
|
|
||
|
using Animancer.Examples.FineControl;
|
||
|
using UnityEngine;
|
||
|
|
||
|
namespace Animancer.Examples.Locomotion
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// A <see cref="SpiderBot"/> with a <see cref="MixerState.Transition2D"/> and <see cref="Rigidbody"/> to allow the
|
||
|
/// bot to move in any direction.
|
||
|
/// </summary>
|
||
|
[AddComponentMenu(Strings.MenuPrefix + "Examples/Locomotion - Spider Bot Advanced")]
|
||
|
[HelpURL(Strings.APIDocumentationURL + ".Examples.Locomotion/SpiderBotAdvanced")]
|
||
|
public sealed class SpiderBotAdvanced : SpiderBot
|
||
|
{
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
[SerializeField] private Rigidbody _Body;
|
||
|
[SerializeField] private float _TurnSpeed = 90;
|
||
|
[SerializeField] private float _MovementSpeed = 1.5f;
|
||
|
[SerializeField] private float _SprintMultiplier = 2;
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
[SerializeField]
|
||
|
private MixerState.Transition2D _Move;
|
||
|
|
||
|
protected override ITransition MovementAnimation
|
||
|
{
|
||
|
get { return _Move; }
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
private Vector3 _MovementDirection;
|
||
|
|
||
|
protected override bool IsMoving
|
||
|
{
|
||
|
get { return _MovementDirection != Vector3.zero; }
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
protected override void Awake()
|
||
|
{
|
||
|
base.Awake();
|
||
|
|
||
|
// Create the movement state but don't play it yet.
|
||
|
// This ensures that we can access _MovementAnimation.State in other methods before actually playing it.
|
||
|
Animancer.States.GetOrCreate(_Move);
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
protected override void Update()
|
||
|
{
|
||
|
// Calculate the movement direction and call the base method to wake up or go to sleep if necessary.
|
||
|
_MovementDirection = GetMovementDirection();
|
||
|
base.Update();
|
||
|
|
||
|
// If the movement state is playing and not fading out:
|
||
|
if (_Move.State.IsActive)
|
||
|
{
|
||
|
// Rotate towards the same Y angle as the camera.
|
||
|
var eulerAngles = transform.eulerAngles;
|
||
|
var targetEulerY = Camera.main.transform.eulerAngles.y;
|
||
|
eulerAngles.y = Mathf.MoveTowardsAngle(eulerAngles.y, targetEulerY, _TurnSpeed * Time.deltaTime);
|
||
|
transform.eulerAngles = eulerAngles;
|
||
|
|
||
|
// The movement direction is in world space, so we need to convert it to local space to be appropriate
|
||
|
// for the current rotation by using dot-products to determine how much of that direction lies along
|
||
|
// each axis. This would be unnecessary if we did not rotate at all.
|
||
|
_Move.State.Parameter = new Vector2(
|
||
|
Vector3.Dot(transform.right, _MovementDirection),
|
||
|
Vector3.Dot(transform.forward, _MovementDirection));
|
||
|
|
||
|
// Set its speed depending on whether you are sprinting or not.
|
||
|
var isSprinting = Input.GetMouseButton(0);
|
||
|
_Move.State.Speed = isSprinting ? _SprintMultiplier : 1;
|
||
|
}
|
||
|
else// Otherwise stop it entirely.
|
||
|
{
|
||
|
_Move.State.Parameter = Vector2.zero;
|
||
|
_Move.State.Speed = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
private Vector3 GetMovementDirection()
|
||
|
{
|
||
|
// Get a ray from the main camera in the direction of the mouse cursor.
|
||
|
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
|
||
|
|
||
|
// Do a raycast with it and stop trying to move it it does not hit anything.
|
||
|
// Note that this object is set to the Ignore Raycast layer so that the raycast will not hit it.
|
||
|
RaycastHit raycastHit;
|
||
|
if (!Physics.Raycast(ray, out raycastHit))// Note the exclamation mark !
|
||
|
return Vector3.zero;
|
||
|
|
||
|
// If the ray hit something, calculate the horizontal direction from this object to that point.
|
||
|
var direction = raycastHit.point - transform.position;
|
||
|
direction.y = 0;
|
||
|
|
||
|
// If we are close to the destination, stop moving.
|
||
|
// We could use an arbitrary small value like 0.1, but that would not work if the speed is too high.
|
||
|
// Instead, we can calculate the distance it will actually move in a single frame at max speed to determine
|
||
|
// if it would arrive or pass the destination next frame.
|
||
|
var distance = direction.magnitude;
|
||
|
if (distance < _MovementSpeed * _SprintMultiplier * Time.fixedDeltaTime)
|
||
|
{
|
||
|
return Vector3.zero;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Otherwise normalize the direction so that we do not change speed based on distance.
|
||
|
// Calling direction.Normalize() would do the same thing, but would calculate the magnitude again.
|
||
|
return direction / distance;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
|
||
|
private void FixedUpdate()
|
||
|
{
|
||
|
// Move the rigidbody in the desired direction.
|
||
|
_Body.velocity = _MovementDirection * _Move.State.Speed * _MovementSpeed;
|
||
|
}
|
||
|
|
||
|
/************************************************************************************************************************/
|
||
|
}
|
||
|
}
|