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.
160 lines
6.2 KiB
C#
160 lines
6.2 KiB
C#
// Animancer // Copyright 2020 Kybernetik //
|
|
|
|
#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value.
|
|
|
|
using Animancer.Examples.StateMachines.Brains;
|
|
using Animancer.FSM;
|
|
using UnityEngine;
|
|
|
|
namespace Animancer.Examples.AnimatorControllers
|
|
{
|
|
/// <summary>
|
|
/// A <see cref="CreatureState"/> which allows the player to play golf using the
|
|
/// <see cref="Events.GolfHitController"/> script.
|
|
/// </summary>
|
|
[AddComponentMenu(Strings.MenuPrefix + "Examples/Hybrid - Golf Mini Game")]
|
|
[HelpURL(Strings.APIDocumentationURL + ".Examples.AnimatorControllers/GolfMiniGame")]
|
|
public sealed class GolfMiniGame : CreatureBrain
|
|
{
|
|
/************************************************************************************************************************/
|
|
|
|
[SerializeField] private Events.GolfHitController _GolfHitController;
|
|
[SerializeField] private Transform _GolfClub;
|
|
[SerializeField] private Transform _ExitPoint;
|
|
[SerializeField] private GameObject _RegularControls;
|
|
[SerializeField] private GameObject _GolfControls;
|
|
|
|
private Vector3 _GolfClubStartPosition;
|
|
private Quaternion _GolfClubStartRotation;
|
|
private CreatureBrain _PreviousBrain;
|
|
|
|
private enum State { Entering, Turning, Playing, Exiting, }
|
|
private State _State;
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
private void Awake()
|
|
{
|
|
_GolfClubStartPosition = _GolfClub.localPosition;
|
|
_GolfClubStartRotation = _GolfClub.localRotation;
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
/// <summary>
|
|
/// When a <see cref="Creature"/> enters this trigger, try to make it enter this state.
|
|
/// </summary>
|
|
private void OnTriggerEnter(Collider collider)
|
|
{
|
|
if (enabled)
|
|
return;
|
|
|
|
var creature = collider.GetComponent<Creature>();
|
|
if (creature == null ||
|
|
!creature.Idle.TryEnterState())
|
|
return;
|
|
|
|
_State = State.Entering;
|
|
_PreviousBrain = creature.Brain;
|
|
Creature = creature;
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
private void FixedUpdate()
|
|
{
|
|
switch (_State)
|
|
{
|
|
case State.Entering:
|
|
if (MoveTowards(_GolfHitController.transform.position))
|
|
StartTurning();
|
|
break;
|
|
|
|
case State.Turning:
|
|
if (Quaternion.Angle(Creature.Animancer.transform.rotation, _GolfHitController.transform.rotation) < 1)
|
|
StartPlaying();
|
|
break;
|
|
|
|
case State.Playing:
|
|
break;
|
|
|
|
case State.Exiting:
|
|
if (MoveTowards(_ExitPoint.position))
|
|
Creature.Brain = _PreviousBrain;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
private bool MoveTowards(Vector3 destination)
|
|
{
|
|
var step = Creature.Stats.GetMoveSpeed(false) * Time.deltaTime;
|
|
var direction = destination - Creature.Rigidbody.position;
|
|
var distance = direction.magnitude;
|
|
MovementDirection = direction / distance;// Normalize.
|
|
return distance <= step;
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
private void StartTurning()
|
|
{
|
|
_State = State.Turning;
|
|
MovementDirection = _GolfHitController.transform.forward;
|
|
|
|
// Disable the Creature's movement and move them next to the golf ball.
|
|
Creature.Rigidbody.velocity = Vector3.zero;
|
|
Creature.Rigidbody.isKinematic = true;
|
|
Creature.Rigidbody.position = _GolfHitController.transform.position;
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
private void StartPlaying()
|
|
{
|
|
_State = State.Playing;
|
|
|
|
// Put the GolfClub in their hand, specifically as a child of the "Holder.R" object which is positioned
|
|
// correctly for holding objects.
|
|
var rightHand = Creature.Animancer.Animator.GetBoneTransform(HumanBodyBones.RightHand);
|
|
rightHand = rightHand.Find("Holder.R");
|
|
_GolfClub.parent = rightHand;
|
|
_GolfClub.localPosition = Vector3.zero;
|
|
_GolfClub.localRotation = Quaternion.identity;
|
|
|
|
// Activate the GolfHitController so it can now take control of the creature.
|
|
_GolfHitController.gameObject.SetActive(true);
|
|
|
|
// Swap the displayed controls.
|
|
_RegularControls.SetActive(false);
|
|
_GolfControls.SetActive(true);
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
|
|
public void Quit()
|
|
{
|
|
// Basically just undo everything StartTurning and StartPlaying did.
|
|
|
|
_State = State.Exiting;
|
|
|
|
_GolfHitController.gameObject.SetActive(false);
|
|
_RegularControls.SetActive(true);
|
|
_GolfControls.SetActive(false);
|
|
|
|
_GolfClub.parent = transform;
|
|
_GolfClub.localPosition = _GolfClubStartPosition;
|
|
_GolfClub.localRotation = _GolfClubStartRotation;
|
|
|
|
Creature.Rigidbody.isKinematic = false;
|
|
|
|
// The creature will still be in the Idle state from when the mini game started.
|
|
// But it only plays its animation when first entered so we force the creature to re-enter that state.
|
|
Creature.Idle.TryReEnterState();
|
|
}
|
|
|
|
/************************************************************************************************************************/
|
|
}
|
|
}
|