Initial commit

This commit is contained in:
2026-06-18 16:37:02 +01:00
commit c8e34b8ed8
6996 changed files with 4355895 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8e0da8384bb296e45ba9274ce956eb74
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,876 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was auto-generated by com.unity.inputsystem:InputActionCodeGenerator
// version 1.19.0
// from Assets/Synty/AnimationBaseLocomotion/Samples/Scripts/InputSystem/Controls.inputactions
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Utilities;
/// <summary>
/// Provides programmatic access to <see cref="InputActionAsset" />, <see cref="InputActionMap" />, <see cref="InputAction" /> and <see cref="InputControlScheme" /> instances defined in asset "Assets/Synty/AnimationBaseLocomotion/Samples/Scripts/InputSystem/Controls.inputactions".
/// </summary>
/// <remarks>
/// This class is source generated and any manual edits will be discarded if the associated asset is reimported or modified.
/// </remarks>
/// <example>
/// <code>
/// using namespace UnityEngine;
/// using UnityEngine.InputSystem;
///
/// // Example of using an InputActionMap named "Player" from a UnityEngine.MonoBehaviour implementing callback interface.
/// public class Example : MonoBehaviour, MyActions.IPlayerActions
/// {
/// private MyActions_Actions m_Actions; // Source code representation of asset.
/// private MyActions_Actions.PlayerActions m_Player; // Source code representation of action map.
///
/// void Awake()
/// {
/// m_Actions = new MyActions_Actions(); // Create asset object.
/// m_Player = m_Actions.Player; // Extract action map object.
/// m_Player.AddCallbacks(this); // Register callback interface IPlayerActions.
/// }
///
/// void OnDestroy()
/// {
/// m_Actions.Dispose(); // Destroy asset object.
/// }
///
/// void OnEnable()
/// {
/// m_Player.Enable(); // Enable all actions within map.
/// }
///
/// void OnDisable()
/// {
/// m_Player.Disable(); // Disable all actions within map.
/// }
///
/// #region Interface implementation of MyActions.IPlayerActions
///
/// // Invoked when "Move" action is either started, performed or canceled.
/// public void OnMove(InputAction.CallbackContext context)
/// {
/// Debug.Log($"OnMove: {context.ReadValue&lt;Vector2&gt;()}");
/// }
///
/// // Invoked when "Attack" action is either started, performed or canceled.
/// public void OnAttack(InputAction.CallbackContext context)
/// {
/// Debug.Log($"OnAttack: {context.ReadValue&lt;float&gt;()}");
/// }
///
/// #endregion
/// }
/// </code>
/// </example>
public partial class @Controls: IInputActionCollection2, IDisposable
{
/// <summary>
/// Provides access to the underlying asset instance.
/// </summary>
public InputActionAsset asset { get; }
/// <summary>
/// Constructs a new instance.
/// </summary>
public @Controls()
{
asset = InputActionAsset.FromJson(@"{
""version"": 1,
""name"": ""Controls"",
""maps"": [
{
""name"": ""Player"",
""id"": ""2c49ff3e-ee54-41db-a904-9d6a34278604"",
""actions"": [
{
""name"": ""Jump"",
""type"": ""Button"",
""id"": ""9c4baf7e-dd4a-45cb-b8b5-518f23ef2f3f"",
""expectedControlType"": """",
""processors"": """",
""interactions"": """",
""initialStateCheck"": false
},
{
""name"": ""Move"",
""type"": ""Value"",
""id"": ""105f8ab6-711b-48c9-afe5-81516e9a23b4"",
""expectedControlType"": ""Vector2"",
""processors"": """",
""interactions"": """",
""initialStateCheck"": true
},
{
""name"": ""Look"",
""type"": ""Value"",
""id"": ""c7314668-554f-4d3e-9860-066f89d79485"",
""expectedControlType"": ""Vector2"",
""processors"": """",
""interactions"": """",
""initialStateCheck"": true
},
{
""name"": ""Sprint"",
""type"": ""Button"",
""id"": ""8a1c0259-4ff4-47ce-8b18-87fa6457e43a"",
""expectedControlType"": ""Button"",
""processors"": """",
""interactions"": """",
""initialStateCheck"": false
},
{
""name"": ""ToggleWalk"",
""type"": ""Button"",
""id"": ""81a5840a-1451-4af7-b390-f2f1e3099eb9"",
""expectedControlType"": """",
""processors"": """",
""interactions"": """",
""initialStateCheck"": false
},
{
""name"": ""Aim"",
""type"": ""Button"",
""id"": ""e440026d-b50a-4df1-ba03-48302673e522"",
""expectedControlType"": """",
""processors"": """",
""interactions"": """",
""initialStateCheck"": false
},
{
""name"": ""Crouch"",
""type"": ""Button"",
""id"": ""0a2dd0bc-e6ed-4515-b034-169169050ceb"",
""expectedControlType"": """",
""processors"": """",
""interactions"": """",
""initialStateCheck"": false
},
{
""name"": ""LockOn"",
""type"": ""Button"",
""id"": ""a87fb759-f0bc-4a42-9e92-7f6bdec29e48"",
""expectedControlType"": """",
""processors"": """",
""interactions"": """",
""initialStateCheck"": false
},
{
""name"": ""Attack"",
""type"": ""Button"",
""id"": ""de77d5e0-9fcc-4fdb-a221-b03fb4064ffd"",
""expectedControlType"": """",
""processors"": """",
""interactions"": """",
""initialStateCheck"": false
}
],
""bindings"": [
{
""name"": """",
""id"": ""4973493d-c628-41b1-8283-30a38a35726a"",
""path"": ""<Keyboard>/space"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard and Mouse"",
""action"": ""Jump"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""42025cc3-3d37-4b12-a885-8eca8f556f97"",
""path"": ""<Gamepad>/buttonSouth"",
""interactions"": """",
""processors"": """",
""groups"": ""Gamepad"",
""action"": ""Jump"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""1ab14112-e754-49ce-9d7a-515a9ab24396"",
""path"": ""<Gamepad>/leftStick"",
""interactions"": """",
""processors"": """",
""groups"": ""Gamepad"",
""action"": ""Move"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": ""2D Vector WASD"",
""id"": ""d68d1f5f-0e48-4c97-943a-5200d814ba4c"",
""path"": ""2DVector"",
""interactions"": """",
""processors"": """",
""groups"": """",
""action"": ""Move"",
""isComposite"": true,
""isPartOfComposite"": false
},
{
""name"": ""up"",
""id"": ""4601556f-fe76-459e-833c-8424f28ccfaf"",
""path"": ""<Keyboard>/w"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard and Mouse"",
""action"": ""Move"",
""isComposite"": false,
""isPartOfComposite"": true
},
{
""name"": ""down"",
""id"": ""0758e0d3-c53f-4406-b0c5-6b65928f6495"",
""path"": ""<Keyboard>/s"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard and Mouse"",
""action"": ""Move"",
""isComposite"": false,
""isPartOfComposite"": true
},
{
""name"": ""left"",
""id"": ""34ab6656-510b-4543-a02c-457d9d87d373"",
""path"": ""<Keyboard>/a"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard and Mouse"",
""action"": ""Move"",
""isComposite"": false,
""isPartOfComposite"": true
},
{
""name"": ""right"",
""id"": ""861a3c64-a95a-4fb2-90f1-2f7fc3994ebd"",
""path"": ""<Keyboard>/d"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard and Mouse"",
""action"": ""Move"",
""isComposite"": false,
""isPartOfComposite"": true
},
{
""name"": ""2D Vector Arrowkeys"",
""id"": ""cd992d5a-4846-4403-aad0-3c9049a191e5"",
""path"": ""2DVector"",
""interactions"": """",
""processors"": """",
""groups"": """",
""action"": ""Move"",
""isComposite"": true,
""isPartOfComposite"": false
},
{
""name"": ""up"",
""id"": ""35439dc7-4c62-4730-a600-57bd079992aa"",
""path"": ""<Keyboard>/upArrow"",
""interactions"": """",
""processors"": """",
""groups"": """",
""action"": ""Move"",
""isComposite"": false,
""isPartOfComposite"": true
},
{
""name"": ""down"",
""id"": ""8a40e7f9-06f6-4fea-82c8-a9bbfa9f3a45"",
""path"": ""<Keyboard>/downArrow"",
""interactions"": """",
""processors"": """",
""groups"": """",
""action"": ""Move"",
""isComposite"": false,
""isPartOfComposite"": true
},
{
""name"": ""left"",
""id"": ""a529365f-0079-4cdd-ad19-c2176ebc12a7"",
""path"": ""<Keyboard>/leftArrow"",
""interactions"": """",
""processors"": """",
""groups"": """",
""action"": ""Move"",
""isComposite"": false,
""isPartOfComposite"": true
},
{
""name"": ""right"",
""id"": ""032d5647-9197-4ab1-b0ed-73f9c573abaa"",
""path"": ""<Keyboard>/rightArrow"",
""interactions"": """",
""processors"": """",
""groups"": """",
""action"": ""Move"",
""isComposite"": false,
""isPartOfComposite"": true
},
{
""name"": """",
""id"": ""fd44343a-ca07-4f0a-95d7-29164ac381f0"",
""path"": ""<Mouse>/delta"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard and Mouse"",
""action"": ""Look"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""8a2bfa46-4ead-4a8f-aac0-c0bc4f585928"",
""path"": ""<Gamepad>/rightStick"",
""interactions"": """",
""processors"": ""ScaleVector2(x=4,y=4)"",
""groups"": ""Gamepad"",
""action"": ""Look"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""354b4cd8-944c-4d23-87b4-d26e6403b2a7"",
""path"": ""<Keyboard>/shift"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard and Mouse"",
""action"": ""Sprint"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""13547036-1d58-45f2-a2d8-c9f0706a8fb9"",
""path"": ""<Gamepad>/rightShoulder"",
""interactions"": """",
""processors"": """",
""groups"": ""Gamepad"",
""action"": ""Sprint"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""ab91ddfe-c482-4b55-aa59-bf1974a526b3"",
""path"": ""<Keyboard>/capsLock"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard and Mouse"",
""action"": ""ToggleWalk"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""b5d9ab6f-92ae-4d6a-85ce-20210c1efe16"",
""path"": ""<Gamepad>/leftStickPress"",
""interactions"": """",
""processors"": """",
""groups"": ""Gamepad"",
""action"": ""ToggleWalk"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""2d594f48-6585-4401-95f6-10f27afb0d84"",
""path"": ""<Mouse>/rightButton"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard and Mouse"",
""action"": ""Aim"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""9f00b84c-77a0-4264-88a7-aa6ace188e6e"",
""path"": ""<Gamepad>/leftTrigger"",
""interactions"": """",
""processors"": """",
""groups"": ""Gamepad"",
""action"": ""Aim"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""73eda66d-2118-4a22-9d70-18cc9ea08e74"",
""path"": ""<Keyboard>/ctrl"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard and Mouse"",
""action"": ""Crouch"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""78facee1-242d-43a5-b71f-75bfdb0ed6e1"",
""path"": ""<Gamepad>/buttonEast"",
""interactions"": """",
""processors"": """",
""groups"": ""Gamepad"",
""action"": ""Crouch"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""9f68216e-e598-4037-a000-2ca8be91e0ba"",
""path"": ""<Mouse>/middleButton"",
""interactions"": """",
""processors"": """",
""groups"": ""Keyboard and Mouse"",
""action"": ""LockOn"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""bab278b9-2663-41cb-9167-ffb39759d9a9"",
""path"": ""<Gamepad>/rightStickPress"",
""interactions"": """",
""processors"": """",
""groups"": ""Gamepad"",
""action"": ""LockOn"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""4194b83a-b4c6-41bd-a725-7425bf85e416"",
""path"": ""<Mouse>/leftButton"",
""interactions"": """",
""processors"": """",
""groups"": "";Keyboard and Mouse"",
""action"": ""Attack"",
""isComposite"": false,
""isPartOfComposite"": false
},
{
""name"": """",
""id"": ""06036358-a299-402f-98d8-7a37b311367f"",
""path"": ""<Gamepad>/rightTrigger"",
""interactions"": """",
""processors"": """",
""groups"": "";Gamepad"",
""action"": ""Attack"",
""isComposite"": false,
""isPartOfComposite"": false
}
]
}
],
""controlSchemes"": [
{
""name"": ""Keyboard and Mouse"",
""bindingGroup"": ""Keyboard and Mouse"",
""devices"": [
{
""devicePath"": ""<Keyboard>"",
""isOptional"": false,
""isOR"": false
},
{
""devicePath"": ""<Mouse>"",
""isOptional"": false,
""isOR"": false
}
]
},
{
""name"": ""Gamepad"",
""bindingGroup"": ""Gamepad"",
""devices"": [
{
""devicePath"": ""<DualShockGamepad>"",
""isOptional"": true,
""isOR"": false
}
]
}
]
}");
// Player
m_Player = asset.FindActionMap("Player", throwIfNotFound: true);
m_Player_Jump = m_Player.FindAction("Jump", throwIfNotFound: true);
m_Player_Move = m_Player.FindAction("Move", throwIfNotFound: true);
m_Player_Look = m_Player.FindAction("Look", throwIfNotFound: true);
m_Player_Sprint = m_Player.FindAction("Sprint", throwIfNotFound: true);
m_Player_ToggleWalk = m_Player.FindAction("ToggleWalk", throwIfNotFound: true);
m_Player_Aim = m_Player.FindAction("Aim", throwIfNotFound: true);
m_Player_Crouch = m_Player.FindAction("Crouch", throwIfNotFound: true);
m_Player_LockOn = m_Player.FindAction("LockOn", throwIfNotFound: true);
m_Player_Attack = m_Player.FindAction("Attack", throwIfNotFound: true);
}
~@Controls()
{
UnityEngine.Debug.Assert(!m_Player.enabled, "This will cause a leak and performance issues, Controls.Player.Disable() has not been called.");
}
/// <summary>
/// Destroys this asset and all associated <see cref="InputAction"/> instances.
/// </summary>
public void Dispose()
{
UnityEngine.Object.Destroy(asset);
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.bindingMask" />
public InputBinding? bindingMask
{
get => asset.bindingMask;
set => asset.bindingMask = value;
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.devices" />
public ReadOnlyArray<InputDevice>? devices
{
get => asset.devices;
set => asset.devices = value;
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.controlSchemes" />
public ReadOnlyArray<InputControlScheme> controlSchemes => asset.controlSchemes;
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.Contains(InputAction)" />
public bool Contains(InputAction action)
{
return asset.Contains(action);
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.GetEnumerator()" />
public IEnumerator<InputAction> GetEnumerator()
{
return asset.GetEnumerator();
}
/// <inheritdoc cref="IEnumerable.GetEnumerator()" />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.Enable()" />
public void Enable()
{
asset.Enable();
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.Disable()" />
public void Disable()
{
asset.Disable();
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.bindings" />
public IEnumerable<InputBinding> bindings => asset.bindings;
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.FindAction(string, bool)" />
public InputAction FindAction(string actionNameOrId, bool throwIfNotFound = false)
{
return asset.FindAction(actionNameOrId, throwIfNotFound);
}
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionAsset.FindBinding(InputBinding, out InputAction)" />
public int FindBinding(InputBinding bindingMask, out InputAction action)
{
return asset.FindBinding(bindingMask, out action);
}
// Player
private readonly InputActionMap m_Player;
private List<IPlayerActions> m_PlayerActionsCallbackInterfaces = new List<IPlayerActions>();
private readonly InputAction m_Player_Jump;
private readonly InputAction m_Player_Move;
private readonly InputAction m_Player_Look;
private readonly InputAction m_Player_Sprint;
private readonly InputAction m_Player_ToggleWalk;
private readonly InputAction m_Player_Aim;
private readonly InputAction m_Player_Crouch;
private readonly InputAction m_Player_LockOn;
private readonly InputAction m_Player_Attack;
/// <summary>
/// Provides access to input actions defined in input action map "Player".
/// </summary>
public struct PlayerActions
{
private @Controls m_Wrapper;
/// <summary>
/// Construct a new instance of the input action map wrapper class.
/// </summary>
public PlayerActions(@Controls wrapper) { m_Wrapper = wrapper; }
/// <summary>
/// Provides access to the underlying input action "Player/Jump".
/// </summary>
public InputAction @Jump => m_Wrapper.m_Player_Jump;
/// <summary>
/// Provides access to the underlying input action "Player/Move".
/// </summary>
public InputAction @Move => m_Wrapper.m_Player_Move;
/// <summary>
/// Provides access to the underlying input action "Player/Look".
/// </summary>
public InputAction @Look => m_Wrapper.m_Player_Look;
/// <summary>
/// Provides access to the underlying input action "Player/Sprint".
/// </summary>
public InputAction @Sprint => m_Wrapper.m_Player_Sprint;
/// <summary>
/// Provides access to the underlying input action "Player/ToggleWalk".
/// </summary>
public InputAction @ToggleWalk => m_Wrapper.m_Player_ToggleWalk;
/// <summary>
/// Provides access to the underlying input action "Player/Aim".
/// </summary>
public InputAction @Aim => m_Wrapper.m_Player_Aim;
/// <summary>
/// Provides access to the underlying input action "Player/Crouch".
/// </summary>
public InputAction @Crouch => m_Wrapper.m_Player_Crouch;
/// <summary>
/// Provides access to the underlying input action "Player/LockOn".
/// </summary>
public InputAction @LockOn => m_Wrapper.m_Player_LockOn;
/// <summary>
/// Provides access to the underlying input action "Player/Attack".
/// </summary>
public InputAction @Attack => m_Wrapper.m_Player_Attack;
/// <summary>
/// Provides access to the underlying input action map instance.
/// </summary>
public InputActionMap Get() { return m_Wrapper.m_Player; }
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionMap.Enable()" />
public void Enable() { Get().Enable(); }
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionMap.Disable()" />
public void Disable() { Get().Disable(); }
/// <inheritdoc cref="UnityEngine.InputSystem.InputActionMap.enabled" />
public bool enabled => Get().enabled;
/// <summary>
/// Implicitly converts an <see ref="PlayerActions" /> to an <see ref="InputActionMap" /> instance.
/// </summary>
public static implicit operator InputActionMap(PlayerActions set) { return set.Get(); }
/// <summary>
/// Adds <see cref="InputAction.started"/>, <see cref="InputAction.performed"/> and <see cref="InputAction.canceled"/> callbacks provided via <param cref="instance" /> on all input actions contained in this map.
/// </summary>
/// <param name="instance">Callback instance.</param>
/// <remarks>
/// If <paramref name="instance" /> is <c>null</c> or <paramref name="instance"/> have already been added this method does nothing.
/// </remarks>
/// <seealso cref="PlayerActions" />
public void AddCallbacks(IPlayerActions instance)
{
if (instance == null || m_Wrapper.m_PlayerActionsCallbackInterfaces.Contains(instance)) return;
m_Wrapper.m_PlayerActionsCallbackInterfaces.Add(instance);
@Jump.started += instance.OnJump;
@Jump.performed += instance.OnJump;
@Jump.canceled += instance.OnJump;
@Move.started += instance.OnMove;
@Move.performed += instance.OnMove;
@Move.canceled += instance.OnMove;
@Look.started += instance.OnLook;
@Look.performed += instance.OnLook;
@Look.canceled += instance.OnLook;
@Sprint.started += instance.OnSprint;
@Sprint.performed += instance.OnSprint;
@Sprint.canceled += instance.OnSprint;
@ToggleWalk.started += instance.OnToggleWalk;
@ToggleWalk.performed += instance.OnToggleWalk;
@ToggleWalk.canceled += instance.OnToggleWalk;
@Aim.started += instance.OnAim;
@Aim.performed += instance.OnAim;
@Aim.canceled += instance.OnAim;
@Crouch.started += instance.OnCrouch;
@Crouch.performed += instance.OnCrouch;
@Crouch.canceled += instance.OnCrouch;
@LockOn.started += instance.OnLockOn;
@LockOn.performed += instance.OnLockOn;
@LockOn.canceled += instance.OnLockOn;
@Attack.started += instance.OnAttack;
@Attack.performed += instance.OnAttack;
@Attack.canceled += instance.OnAttack;
}
/// <summary>
/// Removes <see cref="InputAction.started"/>, <see cref="InputAction.performed"/> and <see cref="InputAction.canceled"/> callbacks provided via <param cref="instance" /> on all input actions contained in this map.
/// </summary>
/// <remarks>
/// Calling this method when <paramref name="instance" /> have not previously been registered has no side-effects.
/// </remarks>
/// <seealso cref="PlayerActions" />
private void UnregisterCallbacks(IPlayerActions instance)
{
@Jump.started -= instance.OnJump;
@Jump.performed -= instance.OnJump;
@Jump.canceled -= instance.OnJump;
@Move.started -= instance.OnMove;
@Move.performed -= instance.OnMove;
@Move.canceled -= instance.OnMove;
@Look.started -= instance.OnLook;
@Look.performed -= instance.OnLook;
@Look.canceled -= instance.OnLook;
@Sprint.started -= instance.OnSprint;
@Sprint.performed -= instance.OnSprint;
@Sprint.canceled -= instance.OnSprint;
@ToggleWalk.started -= instance.OnToggleWalk;
@ToggleWalk.performed -= instance.OnToggleWalk;
@ToggleWalk.canceled -= instance.OnToggleWalk;
@Aim.started -= instance.OnAim;
@Aim.performed -= instance.OnAim;
@Aim.canceled -= instance.OnAim;
@Crouch.started -= instance.OnCrouch;
@Crouch.performed -= instance.OnCrouch;
@Crouch.canceled -= instance.OnCrouch;
@LockOn.started -= instance.OnLockOn;
@LockOn.performed -= instance.OnLockOn;
@LockOn.canceled -= instance.OnLockOn;
@Attack.started -= instance.OnAttack;
@Attack.performed -= instance.OnAttack;
@Attack.canceled -= instance.OnAttack;
}
/// <summary>
/// Unregisters <param cref="instance" /> and unregisters all input action callbacks via <see cref="PlayerActions.UnregisterCallbacks(IPlayerActions)" />.
/// </summary>
/// <seealso cref="PlayerActions.UnregisterCallbacks(IPlayerActions)" />
public void RemoveCallbacks(IPlayerActions instance)
{
if (m_Wrapper.m_PlayerActionsCallbackInterfaces.Remove(instance))
UnregisterCallbacks(instance);
}
/// <summary>
/// Replaces all existing callback instances and previously registered input action callbacks associated with them with callbacks provided via <param cref="instance" />.
/// </summary>
/// <remarks>
/// If <paramref name="instance" /> is <c>null</c>, calling this method will only unregister all existing callbacks but not register any new callbacks.
/// </remarks>
/// <seealso cref="PlayerActions.AddCallbacks(IPlayerActions)" />
/// <seealso cref="PlayerActions.RemoveCallbacks(IPlayerActions)" />
/// <seealso cref="PlayerActions.UnregisterCallbacks(IPlayerActions)" />
public void SetCallbacks(IPlayerActions instance)
{
foreach (var item in m_Wrapper.m_PlayerActionsCallbackInterfaces)
UnregisterCallbacks(item);
m_Wrapper.m_PlayerActionsCallbackInterfaces.Clear();
AddCallbacks(instance);
}
}
/// <summary>
/// Provides a new <see cref="PlayerActions" /> instance referencing this action map.
/// </summary>
public PlayerActions @Player => new PlayerActions(this);
private int m_KeyboardandMouseSchemeIndex = -1;
/// <summary>
/// Provides access to the input control scheme.
/// </summary>
/// <seealso cref="UnityEngine.InputSystem.InputControlScheme" />
public InputControlScheme KeyboardandMouseScheme
{
get
{
if (m_KeyboardandMouseSchemeIndex == -1) m_KeyboardandMouseSchemeIndex = asset.FindControlSchemeIndex("Keyboard and Mouse");
return asset.controlSchemes[m_KeyboardandMouseSchemeIndex];
}
}
private int m_GamepadSchemeIndex = -1;
/// <summary>
/// Provides access to the input control scheme.
/// </summary>
/// <seealso cref="UnityEngine.InputSystem.InputControlScheme" />
public InputControlScheme GamepadScheme
{
get
{
if (m_GamepadSchemeIndex == -1) m_GamepadSchemeIndex = asset.FindControlSchemeIndex("Gamepad");
return asset.controlSchemes[m_GamepadSchemeIndex];
}
}
/// <summary>
/// Interface to implement callback methods for all input action callbacks associated with input actions defined by "Player" which allows adding and removing callbacks.
/// </summary>
/// <seealso cref="PlayerActions.AddCallbacks(IPlayerActions)" />
/// <seealso cref="PlayerActions.RemoveCallbacks(IPlayerActions)" />
public interface IPlayerActions
{
/// <summary>
/// Method invoked when associated input action "Jump" is either <see cref="UnityEngine.InputSystem.InputAction.started" />, <see cref="UnityEngine.InputSystem.InputAction.performed" /> or <see cref="UnityEngine.InputSystem.InputAction.canceled" />.
/// </summary>
/// <seealso cref="UnityEngine.InputSystem.InputAction.started" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
void OnJump(InputAction.CallbackContext context);
/// <summary>
/// Method invoked when associated input action "Move" is either <see cref="UnityEngine.InputSystem.InputAction.started" />, <see cref="UnityEngine.InputSystem.InputAction.performed" /> or <see cref="UnityEngine.InputSystem.InputAction.canceled" />.
/// </summary>
/// <seealso cref="UnityEngine.InputSystem.InputAction.started" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
void OnMove(InputAction.CallbackContext context);
/// <summary>
/// Method invoked when associated input action "Look" is either <see cref="UnityEngine.InputSystem.InputAction.started" />, <see cref="UnityEngine.InputSystem.InputAction.performed" /> or <see cref="UnityEngine.InputSystem.InputAction.canceled" />.
/// </summary>
/// <seealso cref="UnityEngine.InputSystem.InputAction.started" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
void OnLook(InputAction.CallbackContext context);
/// <summary>
/// Method invoked when associated input action "Sprint" is either <see cref="UnityEngine.InputSystem.InputAction.started" />, <see cref="UnityEngine.InputSystem.InputAction.performed" /> or <see cref="UnityEngine.InputSystem.InputAction.canceled" />.
/// </summary>
/// <seealso cref="UnityEngine.InputSystem.InputAction.started" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
void OnSprint(InputAction.CallbackContext context);
/// <summary>
/// Method invoked when associated input action "ToggleWalk" is either <see cref="UnityEngine.InputSystem.InputAction.started" />, <see cref="UnityEngine.InputSystem.InputAction.performed" /> or <see cref="UnityEngine.InputSystem.InputAction.canceled" />.
/// </summary>
/// <seealso cref="UnityEngine.InputSystem.InputAction.started" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
void OnToggleWalk(InputAction.CallbackContext context);
/// <summary>
/// Method invoked when associated input action "Aim" is either <see cref="UnityEngine.InputSystem.InputAction.started" />, <see cref="UnityEngine.InputSystem.InputAction.performed" /> or <see cref="UnityEngine.InputSystem.InputAction.canceled" />.
/// </summary>
/// <seealso cref="UnityEngine.InputSystem.InputAction.started" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
void OnAim(InputAction.CallbackContext context);
/// <summary>
/// Method invoked when associated input action "Crouch" is either <see cref="UnityEngine.InputSystem.InputAction.started" />, <see cref="UnityEngine.InputSystem.InputAction.performed" /> or <see cref="UnityEngine.InputSystem.InputAction.canceled" />.
/// </summary>
/// <seealso cref="UnityEngine.InputSystem.InputAction.started" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
void OnCrouch(InputAction.CallbackContext context);
/// <summary>
/// Method invoked when associated input action "LockOn" is either <see cref="UnityEngine.InputSystem.InputAction.started" />, <see cref="UnityEngine.InputSystem.InputAction.performed" /> or <see cref="UnityEngine.InputSystem.InputAction.canceled" />.
/// </summary>
/// <seealso cref="UnityEngine.InputSystem.InputAction.started" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
void OnLockOn(InputAction.CallbackContext context);
/// <summary>
/// Method invoked when associated input action "Attack" is either <see cref="UnityEngine.InputSystem.InputAction.started" />, <see cref="UnityEngine.InputSystem.InputAction.performed" /> or <see cref="UnityEngine.InputSystem.InputAction.canceled" />.
/// </summary>
/// <seealso cref="UnityEngine.InputSystem.InputAction.started" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.performed" />
/// <seealso cref="UnityEngine.InputSystem.InputAction.canceled" />
void OnAttack(InputAction.CallbackContext context);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6fecbbd7545b2634583b9c95c6a5b77f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,421 @@
{
"version": 1,
"name": "Controls",
"maps": [
{
"name": "Player",
"id": "2c49ff3e-ee54-41db-a904-9d6a34278604",
"actions": [
{
"name": "Jump",
"type": "Button",
"id": "9c4baf7e-dd4a-45cb-b8b5-518f23ef2f3f",
"expectedControlType": "",
"processors": "",
"interactions": "",
"initialStateCheck": false
},
{
"name": "Move",
"type": "Value",
"id": "105f8ab6-711b-48c9-afe5-81516e9a23b4",
"expectedControlType": "Vector2",
"processors": "",
"interactions": "",
"initialStateCheck": true
},
{
"name": "Look",
"type": "Value",
"id": "c7314668-554f-4d3e-9860-066f89d79485",
"expectedControlType": "Vector2",
"processors": "",
"interactions": "",
"initialStateCheck": true
},
{
"name": "Sprint",
"type": "Button",
"id": "8a1c0259-4ff4-47ce-8b18-87fa6457e43a",
"expectedControlType": "Button",
"processors": "",
"interactions": "",
"initialStateCheck": false
},
{
"name": "ToggleWalk",
"type": "Button",
"id": "81a5840a-1451-4af7-b390-f2f1e3099eb9",
"expectedControlType": "",
"processors": "",
"interactions": "",
"initialStateCheck": false
},
{
"name": "Aim",
"type": "Button",
"id": "e440026d-b50a-4df1-ba03-48302673e522",
"expectedControlType": "",
"processors": "",
"interactions": "",
"initialStateCheck": false
},
{
"name": "Crouch",
"type": "Button",
"id": "0a2dd0bc-e6ed-4515-b034-169169050ceb",
"expectedControlType": "",
"processors": "",
"interactions": "",
"initialStateCheck": false
},
{
"name": "LockOn",
"type": "Button",
"id": "a87fb759-f0bc-4a42-9e92-7f6bdec29e48",
"expectedControlType": "",
"processors": "",
"interactions": "",
"initialStateCheck": false
},
{
"name": "Attack",
"type": "Button",
"id": "de77d5e0-9fcc-4fdb-a221-b03fb4064ffd",
"expectedControlType": "",
"processors": "",
"interactions": "",
"initialStateCheck": false
}
],
"bindings": [
{
"name": "",
"id": "4973493d-c628-41b1-8283-30a38a35726a",
"path": "<Keyboard>/space",
"interactions": "",
"processors": "",
"groups": "Keyboard and Mouse",
"action": "Jump",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "42025cc3-3d37-4b12-a885-8eca8f556f97",
"path": "<Gamepad>/buttonSouth",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "Jump",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "1ab14112-e754-49ce-9d7a-515a9ab24396",
"path": "<Gamepad>/leftStick",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "Move",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "2D Vector WASD",
"id": "d68d1f5f-0e48-4c97-943a-5200d814ba4c",
"path": "2DVector",
"interactions": "",
"processors": "",
"groups": "",
"action": "Move",
"isComposite": true,
"isPartOfComposite": false
},
{
"name": "up",
"id": "4601556f-fe76-459e-833c-8424f28ccfaf",
"path": "<Keyboard>/w",
"interactions": "",
"processors": "",
"groups": "Keyboard and Mouse",
"action": "Move",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "down",
"id": "0758e0d3-c53f-4406-b0c5-6b65928f6495",
"path": "<Keyboard>/s",
"interactions": "",
"processors": "",
"groups": "Keyboard and Mouse",
"action": "Move",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "left",
"id": "34ab6656-510b-4543-a02c-457d9d87d373",
"path": "<Keyboard>/a",
"interactions": "",
"processors": "",
"groups": "Keyboard and Mouse",
"action": "Move",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "right",
"id": "861a3c64-a95a-4fb2-90f1-2f7fc3994ebd",
"path": "<Keyboard>/d",
"interactions": "",
"processors": "",
"groups": "Keyboard and Mouse",
"action": "Move",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "2D Vector Arrowkeys",
"id": "cd992d5a-4846-4403-aad0-3c9049a191e5",
"path": "2DVector",
"interactions": "",
"processors": "",
"groups": "",
"action": "Move",
"isComposite": true,
"isPartOfComposite": false
},
{
"name": "up",
"id": "35439dc7-4c62-4730-a600-57bd079992aa",
"path": "<Keyboard>/upArrow",
"interactions": "",
"processors": "",
"groups": "",
"action": "Move",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "down",
"id": "8a40e7f9-06f6-4fea-82c8-a9bbfa9f3a45",
"path": "<Keyboard>/downArrow",
"interactions": "",
"processors": "",
"groups": "",
"action": "Move",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "left",
"id": "a529365f-0079-4cdd-ad19-c2176ebc12a7",
"path": "<Keyboard>/leftArrow",
"interactions": "",
"processors": "",
"groups": "",
"action": "Move",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "right",
"id": "032d5647-9197-4ab1-b0ed-73f9c573abaa",
"path": "<Keyboard>/rightArrow",
"interactions": "",
"processors": "",
"groups": "",
"action": "Move",
"isComposite": false,
"isPartOfComposite": true
},
{
"name": "",
"id": "fd44343a-ca07-4f0a-95d7-29164ac381f0",
"path": "<Mouse>/delta",
"interactions": "",
"processors": "",
"groups": "Keyboard and Mouse",
"action": "Look",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "8a2bfa46-4ead-4a8f-aac0-c0bc4f585928",
"path": "<Gamepad>/rightStick",
"interactions": "",
"processors": "ScaleVector2(x=4,y=4)",
"groups": "Gamepad",
"action": "Look",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "354b4cd8-944c-4d23-87b4-d26e6403b2a7",
"path": "<Keyboard>/shift",
"interactions": "",
"processors": "",
"groups": "Keyboard and Mouse",
"action": "Sprint",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "13547036-1d58-45f2-a2d8-c9f0706a8fb9",
"path": "<Gamepad>/rightShoulder",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "Sprint",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "ab91ddfe-c482-4b55-aa59-bf1974a526b3",
"path": "<Keyboard>/capsLock",
"interactions": "",
"processors": "",
"groups": "Keyboard and Mouse",
"action": "ToggleWalk",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "b5d9ab6f-92ae-4d6a-85ce-20210c1efe16",
"path": "<Gamepad>/leftStickPress",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "ToggleWalk",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "2d594f48-6585-4401-95f6-10f27afb0d84",
"path": "<Mouse>/rightButton",
"interactions": "",
"processors": "",
"groups": "Keyboard and Mouse",
"action": "Aim",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "9f00b84c-77a0-4264-88a7-aa6ace188e6e",
"path": "<Gamepad>/leftTrigger",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "Aim",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "73eda66d-2118-4a22-9d70-18cc9ea08e74",
"path": "<Keyboard>/ctrl",
"interactions": "",
"processors": "",
"groups": "Keyboard and Mouse",
"action": "Crouch",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "78facee1-242d-43a5-b71f-75bfdb0ed6e1",
"path": "<Gamepad>/buttonEast",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "Crouch",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "9f68216e-e598-4037-a000-2ca8be91e0ba",
"path": "<Mouse>/middleButton",
"interactions": "",
"processors": "",
"groups": "Keyboard and Mouse",
"action": "LockOn",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "bab278b9-2663-41cb-9167-ffb39759d9a9",
"path": "<Gamepad>/rightStickPress",
"interactions": "",
"processors": "",
"groups": "Gamepad",
"action": "LockOn",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "4194b83a-b4c6-41bd-a725-7425bf85e416",
"path": "<Mouse>/leftButton",
"interactions": "",
"processors": "",
"groups": ";Keyboard and Mouse",
"action": "Attack",
"isComposite": false,
"isPartOfComposite": false
},
{
"name": "",
"id": "06036358-a299-402f-98d8-7a37b311367f",
"path": "<Gamepad>/rightTrigger",
"interactions": "",
"processors": "",
"groups": ";Gamepad",
"action": "Attack",
"isComposite": false,
"isPartOfComposite": false
}
]
}
],
"controlSchemes": [
{
"name": "Keyboard and Mouse",
"bindingGroup": "Keyboard and Mouse",
"devices": [
{
"devicePath": "<Keyboard>",
"isOptional": false,
"isOR": false
},
{
"devicePath": "<Mouse>",
"isOptional": false,
"isOR": false
}
]
},
{
"name": "Gamepad",
"bindingGroup": "Gamepad",
"devices": [
{
"devicePath": "<DualShockGamepad>",
"isOptional": true,
"isOR": false
}
]
}
]
}

View File

@@ -0,0 +1,14 @@
fileFormatVersion: 2
guid: a7f8d78e4def66b45b53cbfc404ab4b4
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 8404be70184654265930450def6a9037, type: 3}
generateWrapperCode: 1
wrapperCodePath:
wrapperClassName:
wrapperCodeNamespace:

View File

@@ -0,0 +1,186 @@
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// Sample scripts are included only as examples and are not intended as production-ready.
using System;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Serialization;
namespace Synty.AnimationBaseLocomotion.Samples.InputSystem
{
public class InputReader : MonoBehaviour, Controls.IPlayerActions
{
public Vector2 _mouseDelta;
public Vector2 _moveComposite;
public float _movementInputDuration;
public bool _movementInputDetected;
private Controls _controls;
public Action onAimActivated;
public Action onAimDeactivated;
public Action onCrouchActivated;
public Action onCrouchDeactivated;
public Action onJumpPerformed;
public Action onLockOnToggled;
public Action onAttackPerformed;
public Action onSprintActivated;
public Action onSprintDeactivated;
public Action onWalkToggled;
/// <inheritdoc cref="OnEnable" />
private void OnEnable()
{
if (_controls == null)
{
_controls = new Controls();
_controls.Player.SetCallbacks(this);
}
_controls.Player.Enable();
}
/// <inheritdoc cref="OnDisable" />
public void OnDisable()
{
_controls.Player.Disable();
}
/// <summary>
/// Defines the action to perform when the OnLook callback is called.
/// </summary>
/// <param name="context">The context of the callback.</param>
public void OnLook(InputAction.CallbackContext context)
{
_mouseDelta = context.ReadValue<Vector2>();
}
/// <summary>
/// Defines the action to perform when the OnMove callback is called.
/// </summary>
/// <param name="context">The context of the callback.</param>
public void OnMove(InputAction.CallbackContext context)
{
_moveComposite = context.ReadValue<Vector2>();
_movementInputDetected = _moveComposite.magnitude > 0;
}
/// <summary>
/// Defines the action to perform when the OnJump callback is called.
/// </summary>
/// <param name="context">The context of the callback.</param>
public void OnJump(InputAction.CallbackContext context)
{
if (!context.performed)
{
return;
}
onJumpPerformed?.Invoke();
}
/// <summary>
/// Defines the action to perform when the OnToggleWalk callback is called.
/// </summary>
/// <param name="context">The context of the callback.</param>
public void OnToggleWalk(InputAction.CallbackContext context)
{
if (!context.performed)
{
return;
}
onWalkToggled?.Invoke();
}
/// <summary>
/// Defines the action to perform when the OnSprint callback is called.
/// </summary>
/// <param name="context">The context of the callback.</param>
public void OnSprint(InputAction.CallbackContext context)
{
if (context.started)
{
onSprintActivated?.Invoke();
}
else if (context.canceled)
{
onSprintDeactivated?.Invoke();
}
}
/// <summary>
/// Defines the action to perform when the OnCrouch callback is called.
/// </summary>
/// <param name="context">The context of the callback.</param>
public void OnCrouch(InputAction.CallbackContext context)
{
if (context.started)
{
onCrouchActivated?.Invoke();
}
else if (context.canceled)
{
onCrouchDeactivated?.Invoke();
}
}
/// <summary>
/// Defines the action to perform when the OnAim callback is called.
/// </summary>
/// <param name="context">The context of the callback.</param>
public void OnAim(InputAction.CallbackContext context)
{
if (context.started)
{
onAimActivated?.Invoke();
}
if (context.canceled)
{
onAimDeactivated?.Invoke();
}
}
/// <summary>
/// Defines the action to perform when the OnLockOn callback is called.
/// </summary>
/// <param name="context">The context of the callback.</param>
public void OnLockOn(InputAction.CallbackContext context)
{
if (!context.performed)
{
return;
}
onLockOnToggled?.Invoke();
onSprintDeactivated?.Invoke();
}
/// <summary>
/// Defines the action to perform when the OnAttack callback is called.
/// </summary>
/// <param name="context">The context of the callback.</param>
public void OnAttack(InputAction.CallbackContext context)
{
if (!context.performed)
{
return;
}
onAttackPerformed?.Invoke();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e00b029906eec204b82c90899d4343a6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,214 @@
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// Sample scripts are included only as examples and are not intended as production-ready.
using Synty.AnimationBaseLocomotion.Samples.InputSystem;
using UnityEngine;
namespace Synty.AnimationBaseLocomotion.Samples
{
public class SampleCameraController : MonoBehaviour
{
private const int _LAG_DELTA_TIME_ADJUSTMENT = 20;
[Tooltip("The character game object")]
[SerializeField]
private GameObject _syntyCharacter;
[Tooltip("Main camera used for player perspective")]
[SerializeField]
private Camera _mainCamera;
[SerializeField]
private Transform _playerTarget;
[SerializeField]
private Transform _lockOnTarget;
[SerializeField]
private bool _invertCamera;
[SerializeField]
private bool _hideCursor;
[SerializeField]
private bool _isLockedOn;
[SerializeField]
private float _mouseSensitivity = 5f;
[SerializeField]
private float _cameraDistance = 5f;
[SerializeField]
private float _cameraHeightOffset;
[SerializeField]
private float _cameraHorizontalOffset;
[SerializeField]
private float _cameraTiltOffset;
[SerializeField]
private Vector2 _cameraTiltBounds = new Vector2(-10f, 45f);
[SerializeField]
private float _positionalCameraLag = 1f;
[SerializeField]
private float _rotationalCameraLag = 1f;
private float _cameraInversion;
private InputReader _inputReader;
private float _lastAngleX;
private float _lastAngleY;
private Vector3 _lastPosition;
private float _newAngleX;
private float _newAngleY;
private Vector3 _newPosition;
private float _rotationX;
private float _rotationY;
private Transform _syntyCamera;
/// <inheritdoc cref="Start" />
private void Start()
{
_syntyCamera = gameObject.transform.GetChild(0);
_inputReader = _syntyCharacter.GetComponent<InputReader>();
_playerTarget = _syntyCharacter.transform.Find("SyntyPlayer_LookAt");
_lockOnTarget = _syntyCharacter.transform.Find("TargetLockOnPos");
if (_hideCursor)
{
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
_cameraInversion = _invertCamera ? 1 : -1;
transform.position = _playerTarget.position;
transform.rotation = _playerTarget.rotation;
_lastPosition = transform.position;
_syntyCamera.localPosition = new Vector3(_cameraHorizontalOffset, _cameraHeightOffset, _cameraDistance * -1);
_syntyCamera.localEulerAngles = new Vector3(_cameraTiltOffset, 0f, 0f);
}
/// <inheritdoc cref="Update" />
private void Update()
{
float positionalFollowSpeed = 1 / (_positionalCameraLag / _LAG_DELTA_TIME_ADJUSTMENT);
float rotationalFollowSpeed = 1 / (_rotationalCameraLag / _LAG_DELTA_TIME_ADJUSTMENT);
_rotationX = _inputReader._mouseDelta.y * _cameraInversion * _mouseSensitivity;
_rotationY = _inputReader._mouseDelta.x * _mouseSensitivity;
_newAngleX += _rotationX;
_newAngleX = Mathf.Clamp(_newAngleX, _cameraTiltBounds.x, _cameraTiltBounds.y);
_newAngleX = Mathf.Lerp(_lastAngleX, _newAngleX, rotationalFollowSpeed * Time.deltaTime);
if (_isLockedOn)
{
Vector3 aimVector = _lockOnTarget.position - _playerTarget.position;
Quaternion targetRotation = Quaternion.LookRotation(aimVector);
targetRotation = Quaternion.Lerp(transform.rotation, targetRotation, rotationalFollowSpeed * Time.deltaTime);
_newAngleY = targetRotation.eulerAngles.y;
}
else
{
_newAngleY += _rotationY;
_newAngleY = Mathf.Lerp(_lastAngleY, _newAngleY, rotationalFollowSpeed * Time.deltaTime);
}
_newPosition = _playerTarget.position;
_newPosition = Vector3.Lerp(_lastPosition, _newPosition, positionalFollowSpeed * Time.deltaTime);
transform.position = _newPosition;
transform.eulerAngles = new Vector3(_newAngleX, _newAngleY, 0);
_syntyCamera.localPosition = new Vector3(_cameraHorizontalOffset, _cameraHeightOffset, _cameraDistance * -1);
_syntyCamera.localEulerAngles = new Vector3(_cameraTiltOffset, 0f, 0f);
_lastPosition = _newPosition;
_lastAngleX = _newAngleX;
_lastAngleY = _newAngleY;
}
/// <summary>
/// Locks the camera to aim at a specified target.
/// </summary>
/// <param name="enable">Whether lock on is enabled or not.</param>
/// <param name="newLockOnTarget">The target to lock on to.</param>
public void LockOn(bool enable, Transform newLockOnTarget)
{
_isLockedOn = enable;
if (newLockOnTarget != null)
{
_lockOnTarget = newLockOnTarget;
}
}
/// <summary>
/// Gets the position of the camera.
/// </summary>
/// <returns>The position of the camera.</returns>
public Vector3 GetCameraPosition()
{
return _mainCamera.transform.position;
}
/// <summary>
/// Gets the forward vector of the camera.
/// </summary>
/// <returns>The forward vector of the camera.</returns>
public Vector3 GetCameraForward()
{
return _mainCamera.transform.forward;
}
/// <summary>
/// Gets the forward vector of the camera with the Y value zeroed.
/// </summary>
/// <returns>The forward vector of the camera with the Y value zeroed.</returns>
public Vector3 GetCameraForwardZeroedY()
{
return new Vector3(_mainCamera.transform.forward.x, 0, _mainCamera.transform.forward.z);
}
/// <summary>
/// Gets the normalised forward vector of the camera with the Y value zeroed.
/// </summary>
/// <returns>The normalised forward vector of the camera with the Y value zeroed.</returns>
public Vector3 GetCameraForwardZeroedYNormalised()
{
return GetCameraForwardZeroedY().normalized;
}
/// <summary>
/// Gets the right vector of the camera with the Y value zeroed.
/// </summary>
/// <returns>The right vector of the camera with the Y value zeroed.</returns>
public Vector3 GetCameraRightZeroedY()
{
return new Vector3(_mainCamera.transform.right.x, 0, _mainCamera.transform.right.z);
}
/// <summary>
/// Gets the normalised right vector of the camera with the Y value zeroed.
/// </summary>
/// <returns>The normalised right vector of the camera with the Y value zeroed.</returns>
public Vector3 GetCameraRightZeroedYNormalised()
{
return GetCameraRightZeroedY().normalized;
}
/// <summary>
/// Gets the X value of the camera tilt.
/// </summary>
/// <returns>The X value of the camera tilt.</returns>
public float GetCameraTiltX()
{
return _mainCamera.transform.eulerAngles.x;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f35617dd18fdbac4fb05187bac222064
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,82 @@
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// Sample scripts are included only as examples and are not intended as production-ready.
using UnityEngine;
namespace Synty.AnimationBaseLocomotion.Samples
{
public class SampleObjectLockOn : MonoBehaviour
{
public Material _highlightMat;
public Material _targetMat;
private Transform _highlightOrb;
private MeshRenderer _meshRenderer;
/// <inheritdoc cref="Start" />
private void Start()
{
_highlightOrb = transform.Find("TargetHighlight");
_meshRenderer = _highlightOrb.GetComponent<MeshRenderer>();
if (_meshRenderer == null)
{
Debug.LogError("This script requires a MeshRenderer component on the GameObject.");
}
}
/// <summary>
/// Adds this object as a potential lock on target if the player is within range of the target.
/// </summary>
/// <param name="otherCollider">The collider to check.</param>
private void OnTriggerEnter(Collider otherCollider)
{
SamplePlayerAnimationController playerAnimationController = otherCollider.GetComponent<SamplePlayerAnimationController>();
// Only interested in player collisions if they have the controller script.
if (playerAnimationController != null)
{
playerAnimationController.AddTargetCandidate(gameObject);
}
}
/// <summary>
/// Removes this object as a potential lock on target if the player is within range of the target.
/// </summary>
/// <param name="otherCollider">The collider to check.</param>
private void OnTriggerExit(Collider otherCollider)
{
SamplePlayerAnimationController playerAnimationController = otherCollider.GetComponent<SamplePlayerAnimationController>();
// Only interested in player collisions if they have the controller script.
if (playerAnimationController != null)
{
playerAnimationController.RemoveTarget(gameObject);
Highlight(false, false);
}
}
/// <summary>
/// Sets the highlight status of this object, and which highlight to use.
/// </summary>
/// <param name="enable">Whether the highlight is enabled on this object; or not.</param>
/// <param name="targetLock">Whether this object is locked on to; or not.</param>
public void Highlight(bool enable, bool targetLock)
{
Material currentMaterial = targetLock ? _targetMat : _highlightMat;
if (_highlightOrb != null)
{
_highlightOrb.gameObject.SetActive(enable);
if (enable)
{
_meshRenderer.material = currentMaterial;
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 75ec016dd7c8fec49afb4be540ee2566
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,1568 @@
// Copyright (c) 2024 Synty Studios Limited. All rights reserved.
//
// Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA)
// available at: https://syntystore.com/pages/end-user-licence-agreement
//
// Sample scripts are included only as examples and are not intended as production-ready.
using Synty.AnimationBaseLocomotion.Samples.InputSystem;
using System.Collections.Generic;
using UnityEngine;
namespace Synty.AnimationBaseLocomotion.Samples
{
public class SamplePlayerAnimationController : MonoBehaviour
{
public static SamplePlayerAnimationController Instance;
void Awake()
{
Instance = this;
}
#region Enum
private enum AnimationState
{
Base,
Locomotion,
Jump,
Fall,
Crouch
}
private enum GaitState
{
Idle,
Walk,
Run,
Sprint
}
#endregion
#region Animation Variable Hashes
private readonly int _movementInputTappedHash = Animator.StringToHash("MovementInputTapped");
private readonly int _movementInputPressedHash = Animator.StringToHash("MovementInputPressed");
private readonly int _movementInputHeldHash = Animator.StringToHash("MovementInputHeld");
private readonly int _shuffleDirectionXHash = Animator.StringToHash("ShuffleDirectionX");
private readonly int _shuffleDirectionZHash = Animator.StringToHash("ShuffleDirectionZ");
private readonly int _moveSpeedHash = Animator.StringToHash("MoveSpeed");
private readonly int _currentGaitHash = Animator.StringToHash("CurrentGait");
private readonly int _isJumpingAnimHash = Animator.StringToHash("IsJumping");
private readonly int _fallingDurationHash = Animator.StringToHash("FallingDuration");
private readonly int _inclineAngleHash = Animator.StringToHash("InclineAngle");
private readonly int _strafeDirectionXHash = Animator.StringToHash("StrafeDirectionX");
private readonly int _strafeDirectionZHash = Animator.StringToHash("StrafeDirectionZ");
private readonly int _forwardStrafeHash = Animator.StringToHash("ForwardStrafe");
private readonly int _cameraRotationOffsetHash = Animator.StringToHash("CameraRotationOffset");
private readonly int _isStrafingHash = Animator.StringToHash("IsStrafing");
private readonly int _isTurningInPlaceHash = Animator.StringToHash("IsTurningInPlace");
private readonly int _isCrouchingHash = Animator.StringToHash("IsCrouching");
private readonly int _isWalkingHash = Animator.StringToHash("IsWalking");
private readonly int _isStoppedHash = Animator.StringToHash("IsStopped");
private readonly int _isStartingHash = Animator.StringToHash("IsStarting");
private readonly int _isGroundedHash = Animator.StringToHash("IsGrounded");
private readonly int _leanValueHash = Animator.StringToHash("LeanValue");
private readonly int _headLookXHash = Animator.StringToHash("HeadLookX");
private readonly int _headLookYHash = Animator.StringToHash("HeadLookY");
private readonly int _bodyLookXHash = Animator.StringToHash("BodyLookX");
private readonly int _bodyLookYHash = Animator.StringToHash("BodyLookY");
private readonly int _locomotionStartDirectionHash = Animator.StringToHash("LocomotionStartDirection");
#endregion
#region Player Settings Variables
#region Scripts/Objects
[Header("External Components")]
[Tooltip("Script controlling camera behavior")]
[SerializeField]
private SampleCameraController _cameraController;
[Tooltip("InputReader handles player input")]
[SerializeField]
private InputReader _inputReader;
[Tooltip("Animator component for controlling player animations")]
[SerializeField]
private Animator _animator;
[Tooltip("Character Controller component for controlling player movement")]
[SerializeField]
private CharacterController _controller;
#endregion
#region Locomotion Settings
[Header("Player Locomotion")]
[Header("Main Settings")]
[Tooltip("Whether the character always faces the camera facing direction")]
[SerializeField]
private bool _alwaysStrafe = true;
[Tooltip("Slowest movement speed of the player when set to a walk state or half press tick")]
[SerializeField]
private float _walkSpeed = 1.4f;
[Tooltip("Default movement speed of the player")]
[SerializeField]
private float _runSpeed = 2.5f;
[Tooltip("Top movement speed of the player")]
[SerializeField]
private float _sprintSpeed = 7f;
[Tooltip("Damping factor for changing speed")]
[SerializeField]
private float _speedChangeDamping = 10f;
[Tooltip("Rotation smoothing factor.")]
[SerializeField]
private float _rotationSmoothing = 10f;
[Tooltip("Offset for camera rotation.")]
[SerializeField]
private float _cameraRotationOffset;
#endregion
#region Shuffle Settings
[Header("Shuffles")]
[Tooltip("Threshold for button hold duration.")]
[SerializeField]
private float _buttonHoldThreshold = 0.15f;
[Tooltip("Direction of shuffling on the X-axis.")]
[SerializeField]
private float _shuffleDirectionX;
[Tooltip("Direction of shuffling on the Z-axis.")]
[SerializeField]
private float _shuffleDirectionZ;
#endregion
#region Capsule Settings
[Header("Capsule Values")]
[Tooltip("Standing height of the player capsule.")]
[SerializeField]
private float _capsuleStandingHeight = 1.8f;
[Tooltip("Standing center of the player capsule.")]
[SerializeField]
private float _capsuleStandingCentre = 0.93f;
[Tooltip("Crouching height of the player capsule.")]
[SerializeField]
private float _capsuleCrouchingHeight = 1.2f;
[Tooltip("Crouching center of the player capsule.")]
[SerializeField]
private float _capsuleCrouchingCentre = 0.6f;
#endregion
#region Strafing
[Header("Player Strafing")]
[Tooltip("Minimum threshold for forward strafing angle.")]
[SerializeField]
private float _forwardStrafeMinThreshold = -55.0f;
[Tooltip("Maximum threshold for forward strafing angle.")]
[SerializeField]
private float _forwardStrafeMaxThreshold = 125.0f;
[Tooltip("Current forward strafing value.")]
[SerializeField]
private float _forwardStrafe = 1f;
#endregion
#region Grounded Settings
[Header("Grounded Angle")]
[Tooltip("Position of the rear ray for grounded angle check.")]
[SerializeField]
private Transform _rearRayPos;
[Tooltip("Position of the front ray for grounded angle check.")]
[SerializeField]
private Transform _frontRayPos;
[Tooltip("Layer mask for checking ground.")]
[SerializeField]
private LayerMask _groundLayerMask;
[Tooltip("Current incline angle.")]
[SerializeField]
private float _inclineAngle;
[Tooltip("Useful for rough ground")]
[SerializeField]
private float _groundedOffset = -0.14f;
#endregion
#region In-Air Settings
[Header("Player In-Air")]
[Tooltip("Force applied when the player jumps.")]
[SerializeField]
private float _jumpForce = 10f;
[Tooltip("Multiplier for gravity when in the air.")]
[SerializeField]
private float _gravityMultiplier = 2f;
[Tooltip("Duration of falling.")]
[SerializeField]
private float _fallingDuration;
#endregion
#region Head Look Settings
[Header("Player Head Look")]
[Tooltip("Flag indicating if head turning is enabled.")]
[SerializeField]
private bool _enableHeadTurn = true;
[Tooltip("Delay for head turning.")]
[SerializeField]
private float _headLookDelay;
[Tooltip("X-axis value for head turning.")]
[SerializeField]
private float _headLookX;
[Tooltip("Y-axis value for head turning.")]
[SerializeField]
private float _headLookY;
[Tooltip("Curve for X-axis head turning.")]
[SerializeField]
private AnimationCurve _headLookXCurve;
#endregion
#region Body Look Settings
[Header("Player Body Look")]
[Tooltip("Flag indicating if body turning is enabled.")]
[SerializeField]
private bool _enableBodyTurn = true;
[Tooltip("Delay for body turning.")]
[SerializeField]
private float _bodyLookDelay;
[Tooltip("X-axis value for body turning.")]
[SerializeField]
private float _bodyLookX;
[Tooltip("Y-axis value for body turning.")]
[SerializeField]
private float _bodyLookY;
[Tooltip("Curve for X-axis body turning.")]
[SerializeField]
private AnimationCurve _bodyLookXCurve;
#endregion
#region Lean Settings
[Header("Player Lean")]
[Tooltip("Flag indicating if leaning is enabled.")]
[SerializeField]
private bool _enableLean = true;
[Tooltip("Delay for leaning.")]
[SerializeField]
private float _leanDelay;
[Tooltip("Current value for leaning.")]
[SerializeField]
private float _leanValue;
[Tooltip("Curve for leaning.")]
[SerializeField]
private AnimationCurve _leanCurve;
[Tooltip("Delay for head leaning looks.")]
[SerializeField]
private float _leansHeadLooksDelay;
[Tooltip("Flag indicating if an animation clip has ended.")]
[SerializeField]
private bool _animationClipEnd;
#endregion
#endregion
#region Runtime Properties
private readonly List<GameObject> _currentTargetCandidates = new List<GameObject>();
private AnimationState _currentState = AnimationState.Base;
private bool _cannotStandUp;
private bool _crouchKeyPressed;
private bool _isAiming;
private bool _isCrouching;
private bool _isGrounded = true;
private bool _isLockedOn;
private bool _isSliding;
private bool _isSprinting;
private bool _isStarting;
private bool _isStopped = true;
private bool _isStrafing;
private bool _isTurningInPlace;
private bool _isWalking;
private bool _movementInputHeld;
private bool _movementInputPressed;
private bool _movementInputTapped;
private float _currentMaxSpeed;
private float _locomotionStartDirection;
private float _locomotionStartTimer;
private float _lookingAngle;
private float _newDirectionDifferenceAngle;
private float _speed2D;
private float _strafeAngle;
private float _strafeDirectionX;
private float _strafeDirectionZ;
private GameObject _currentLockOnTarget;
private GaitState _currentGait;
private Transform _targetLockOnPos;
private Vector3 _currentRotation = new Vector3(0f, 0f, 0f);
private Vector3 _moveDirection;
private Vector3 _previousRotation;
private Vector3 _velocity;
public bool IsAttacking { get; set; } // Added for Combat integration
#endregion
#region Base State Variables
private const float _ANIMATION_DAMP_TIME = 5f;
private const float _STRAFE_DIRECTION_DAMP_TIME = 20f;
private float _targetMaxSpeed;
private float _fallStartTime;
private float _rotationRate;
private float _initialLeanValue;
private float _initialTurnValue;
private Vector3 _cameraForward;
private Vector3 _targetVelocity;
#endregion
#region Animation Controller
#region Start
/// <inheritdoc cref="Start" />
private void Start()
{
_targetLockOnPos = transform.Find("TargetLockOnPos");
_inputReader.onLockOnToggled += ToggleLockOn;
_inputReader.onWalkToggled += ToggleWalk;
_inputReader.onSprintActivated += ActivateSprint;
_inputReader.onSprintDeactivated += DeactivateSprint;
_inputReader.onCrouchActivated += ActivateCrouch;
_inputReader.onCrouchDeactivated += DeactivateCrouch;
_inputReader.onAimActivated += ActivateAim;
_inputReader.onAimDeactivated += DeactivateAim;
_isStrafing = _alwaysStrafe;
SwitchState(AnimationState.Locomotion);
}
#endregion
#region Aim and Lock-on
/// <summary>
/// Activates the aim action of the player.
/// </summary>
private void ActivateAim()
{
_isAiming = true;
_isStrafing = !_isSprinting;
}
/// <summary>
/// Deactivates the aim action of the player.
/// </summary>
private void DeactivateAim()
{
_isAiming = false;
_isStrafing = !_isSprinting && (_alwaysStrafe || _isLockedOn);
}
/// <summary>
/// Adds an object to the list of target candidates.
/// </summary>
/// <param name="newTarget">The object to add.</param>
public void AddTargetCandidate(GameObject newTarget)
{
if (newTarget != null)
{
_currentTargetCandidates.Add(newTarget);
}
}
/// <summary>
/// Removes an object to the list of target candidates if present.
/// </summary>
/// <param name="targetToRemove">The object to remove if present.</param>
public void RemoveTarget(GameObject targetToRemove)
{
if (_currentTargetCandidates.Contains(targetToRemove))
{
_currentTargetCandidates.Remove(targetToRemove);
}
}
/// <summary>
/// Toggle the lock-on state.
/// </summary>
private void ToggleLockOn()
{
EnableLockOn(!_isLockedOn);
}
/// <summary>
/// Sets the lock-on state to the given state.
/// </summary>
/// <param name="enable">The state to set lock-on to.</param>
private void EnableLockOn(bool enable)
{
_isLockedOn = enable;
_isStrafing = false;
_isStrafing = enable ? !_isSprinting : _alwaysStrafe || _isAiming;
_cameraController.LockOn(enable, _targetLockOnPos);
if (enable && _currentLockOnTarget != null)
{
_currentLockOnTarget.GetComponent<SampleObjectLockOn>().Highlight(true, true);
}
}
#endregion
#region Walking State
/// <summary>
/// Toggle the walking state.
/// </summary>
private void ToggleWalk()
{
EnableWalk(!_isWalking);
}
/// <summary>
/// Sets the walking state to that of the passed in state.
/// </summary>
/// <param name="enable">The state to set.</param>
private void EnableWalk(bool enable)
{
_isWalking = enable && _isGrounded && !_isSprinting;
}
#endregion
#region Sprinting State
/// <summary>
/// Activates sprinting behaviour.
/// </summary>
private void ActivateSprint()
{
if (!_isCrouching)
{
EnableWalk(false);
_isSprinting = true;
_isStrafing = false;
}
}
/// <summary>
/// Deactivates sprinting behaviour.
/// </summary>
private void DeactivateSprint()
{
_isSprinting = false;
if (_alwaysStrafe || _isAiming || _isLockedOn)
{
_isStrafing = true;
}
}
#endregion
#region Crouching State
/// <summary>
/// Activates crouching behaviour
/// </summary>
private void ActivateCrouch()
{
_crouchKeyPressed = true;
if (_isGrounded)
{
CapsuleCrouchingSize(true);
DeactivateSprint();
_isCrouching = true;
}
}
/// <summary>
/// Deactivates crouching behaviour.
/// </summary>
private void DeactivateCrouch()
{
_crouchKeyPressed = false;
if (!_cannotStandUp && !_isSliding)
{
CapsuleCrouchingSize(false);
_isCrouching = false;
}
}
/// <summary>
/// Activates sliding behaviour.
/// </summary>
public void ActivateSliding()
{
_isSliding = true;
}
/// <summary>
/// Deactivates sliding behaviour
/// </summary>
public void DeactivateSliding()
{
_isSliding = false;
}
/// <summary>
/// Adjusts the capsule size for the player, depending on the passed in boolean value.
/// </summary>
/// <param name="crouching">Whether the player is crouching or not.</param>
private void CapsuleCrouchingSize(bool crouching)
{
if (crouching)
{
_controller.center = new Vector3(0f, _capsuleCrouchingCentre, 0f);
_controller.height = _capsuleCrouchingHeight;
}
else
{
_controller.center = new Vector3(0f, _capsuleStandingCentre, 0f);
_controller.height = _capsuleStandingHeight;
}
}
#endregion
#endregion
#region Shared State
#region State Change
/// <summary>
/// Switch the current state to the passed in state.
/// </summary>
/// <param name="newState">The state to switch to.</param>
private void SwitchState(AnimationState newState)
{
ExitCurrentState();
EnterState(newState);
}
/// <summary>
/// Enter the given state.
/// </summary>
/// <param name="stateToEnter">The state to enter.</param>
private void EnterState(AnimationState stateToEnter)
{
_currentState = stateToEnter;
switch (_currentState)
{
case AnimationState.Base:
EnterBaseState();
break;
case AnimationState.Locomotion:
EnterLocomotionState();
break;
case AnimationState.Jump:
EnterJumpState();
break;
case AnimationState.Fall:
EnterFallState();
break;
case AnimationState.Crouch:
EnterCrouchState();
break;
}
}
/// <summary>
/// Exit the current state.
/// </summary>
private void ExitCurrentState()
{
switch (_currentState)
{
case AnimationState.Locomotion:
ExitLocomotionState();
break;
case AnimationState.Jump:
ExitJumpState();
break;
case AnimationState.Crouch:
ExitCrouchState();
break;
}
}
#endregion
#region Updates
/// <inheritdoc cref="Update" />
private void Update()
{
switch (_currentState)
{
case AnimationState.Locomotion:
UpdateLocomotionState();
break;
case AnimationState.Jump:
UpdateJumpState();
break;
case AnimationState.Fall:
UpdateFallState();
break;
case AnimationState.Crouch:
UpdateCrouchState();
break;
}
}
/// <summary>
/// Updates the animator to have the latest values.
/// </summary>
private void UpdateAnimatorController()
{
_animator.SetFloat(_leanValueHash, _leanValue);
_animator.SetFloat(_headLookXHash, _headLookX);
_animator.SetFloat(_headLookYHash, _headLookY);
_animator.SetFloat(_bodyLookXHash, _bodyLookX);
_animator.SetFloat(_bodyLookYHash, _bodyLookY);
_animator.SetFloat(_isStrafingHash, _isStrafing ? 1.0f : 0.0f);
_animator.SetFloat(_inclineAngleHash, _inclineAngle);
_animator.SetFloat(_moveSpeedHash, _speed2D);
_animator.SetInteger(_currentGaitHash, (int) _currentGait);
_animator.SetFloat(_strafeDirectionXHash, _strafeDirectionX);
_animator.SetFloat(_strafeDirectionZHash, _strafeDirectionZ);
_animator.SetFloat(_forwardStrafeHash, _forwardStrafe);
_animator.SetFloat(_cameraRotationOffsetHash, _cameraRotationOffset);
_animator.SetBool(_movementInputHeldHash, _movementInputHeld);
_animator.SetBool(_movementInputPressedHash, _movementInputPressed);
_animator.SetBool(_movementInputTappedHash, _movementInputTapped);
_animator.SetFloat(_shuffleDirectionXHash, _shuffleDirectionX);
_animator.SetFloat(_shuffleDirectionZHash, _shuffleDirectionZ);
_animator.SetBool(_isTurningInPlaceHash, _isTurningInPlace);
_animator.SetBool(_isCrouchingHash, _isCrouching);
_animator.SetFloat(_fallingDurationHash, _fallingDuration);
_animator.SetBool(_isGroundedHash, _isGrounded);
_animator.SetBool(_isWalkingHash, _isWalking);
_animator.SetBool(_isStoppedHash, _isStopped);
_animator.SetFloat(_locomotionStartDirectionHash, _locomotionStartDirection);
}
#endregion
#endregion
#region Base State
#region Setup
/// <summary>
/// Performs the actions required when entering the base state.
/// </summary>
private void EnterBaseState()
{
_previousRotation = transform.forward;
}
/// <summary>
/// Calculates the input type and sets the required internal states.
/// </summary>
private void CalculateInput()
{
// --- ADDED FOR COMBAT: Intercept input if swinging ---
if (IsAttacking)
{
_moveDirection = Vector3.zero;
_inputReader._movementInputDuration = 0;
_movementInputTapped = false;
_movementInputPressed = false;
_movementInputHeld = false;
return;
}
if (_inputReader._movementInputDetected)
{
if (_inputReader._movementInputDuration == 0)
{
_movementInputTapped = true;
}
else if (_inputReader._movementInputDuration > 0 && _inputReader._movementInputDuration < _buttonHoldThreshold)
{
_movementInputTapped = false;
_movementInputPressed = true;
_movementInputHeld = false;
}
else
{
_movementInputTapped = false;
_movementInputPressed = false;
_movementInputHeld = true;
}
_inputReader._movementInputDuration += Time.deltaTime;
}
else
{
_inputReader._movementInputDuration = 0;
_movementInputTapped = false;
_movementInputPressed = false;
_movementInputHeld = false;
}
_moveDirection = (_cameraController.GetCameraForwardZeroedYNormalised() * _inputReader._moveComposite.y)
+ (_cameraController.GetCameraRightZeroedYNormalised() * _inputReader._moveComposite.x);
}
#endregion
#region Movement
/// <summary>
/// Performs the movement of the player
/// </summary>
private void Move()
{
_controller.Move(_velocity * Time.deltaTime);
if (_isLockedOn)
{
if (_currentLockOnTarget != null)
{
_targetLockOnPos.position = _currentLockOnTarget.transform.position;
}
}
}
/// <summary>
/// Applies gravity to the player.
/// </summary>
private void ApplyGravity()
{
if (_velocity.y > Physics.gravity.y)
{
_velocity.y += Physics.gravity.y * _gravityMultiplier * Time.deltaTime;
}
}
/// <summary>
/// Calculates the movement direction of the player, and sets the relevant flags.
/// </summary>
private void CalculateMoveDirection()
{
CalculateInput();
if (!_isGrounded)
{
_targetMaxSpeed = _currentMaxSpeed;
}
else if (_isCrouching)
{
_targetMaxSpeed = _walkSpeed;
}
else if (_isSprinting)
{
_targetMaxSpeed = _sprintSpeed;
}
else if (_isWalking)
{
_targetMaxSpeed = _walkSpeed;
}
else
{
_targetMaxSpeed = _runSpeed;
}
_currentMaxSpeed = Mathf.Lerp(_currentMaxSpeed, _targetMaxSpeed, _ANIMATION_DAMP_TIME * Time.deltaTime);
_targetVelocity.x = _moveDirection.x * _currentMaxSpeed;
_targetVelocity.z = _moveDirection.z * _currentMaxSpeed;
_velocity.z = Mathf.Lerp(_velocity.z, _targetVelocity.z, _speedChangeDamping * Time.deltaTime);
_velocity.x = Mathf.Lerp(_velocity.x, _targetVelocity.x, _speedChangeDamping * Time.deltaTime);
_speed2D = new Vector3(_velocity.x, 0f, _velocity.z).magnitude;
_speed2D = Mathf.Round(_speed2D * 1000f) / 1000f;
Vector3 playerForwardVector = transform.forward;
_newDirectionDifferenceAngle = playerForwardVector != _moveDirection
? Vector3.SignedAngle(playerForwardVector, _moveDirection, Vector3.up)
: 0f;
CalculateGait();
}
/// <summary>
/// <pre>
/// Calculates the character gait.
/// Calculate what the current locomotion gait is (Walk, Run, Sprint)
/// (for use in jumps, landings etc when deciding which animation to use)
/// Gait values will be:
/// Idle = 0, Walk = 1, Run = 2, Sprint = 3
/// </pre>
/// </summary>
private void CalculateGait()
{
float runThreshold = (_walkSpeed + _runSpeed) / 2;
float sprintThreshold = (_runSpeed + _sprintSpeed) / 2;
if (_speed2D < 0.01)
{
_currentGait = GaitState.Idle;
}
else if (_speed2D < runThreshold)
{
_currentGait = GaitState.Walk;
}
else if (_speed2D < sprintThreshold)
{
_currentGait = GaitState.Run;
}
else
{
_currentGait = GaitState.Sprint;
}
}
/// <summary>
/// Calculates the face move direction based on the locomotion of the character.
/// </summary>
private void FaceMoveDirection()
{
Vector3 characterForward = new Vector3(transform.forward.x, 0f, transform.forward.z).normalized;
Vector3 characterRight = new Vector3(transform.right.x, 0f, transform.right.z).normalized;
Vector3 directionForward = new Vector3(_moveDirection.x, 0f, _moveDirection.z).normalized;
_cameraForward = _cameraController.GetCameraForwardZeroedYNormalised();
Quaternion strafingTargetRotation = Quaternion.LookRotation(_cameraForward);
_strafeAngle = characterForward != directionForward ? Vector3.SignedAngle(characterForward, directionForward, Vector3.up) : 0f;
_isTurningInPlace = false;
if (_isStrafing)
{
if (_moveDirection.magnitude > 0.01)
{
if (_cameraForward != Vector3.zero)
{
// Shuffle direction values - these are separate from the strafe values as we don't want to lerp, we need to know immediately
// what direction to shuffle, and then lock the value so it doesn't return to zero once we lose input (so the blend tree works
// to the end of the anim clip)
_shuffleDirectionZ = Vector3.Dot(characterForward, directionForward);
_shuffleDirectionX = Vector3.Dot(characterRight, directionForward);
UpdateStrafeDirection(
Vector3.Dot(characterForward, directionForward),
Vector3.Dot(characterRight, directionForward)
);
_cameraRotationOffset = Mathf.Lerp(_cameraRotationOffset, 0f, _rotationSmoothing * Time.deltaTime);
float targetValue = _strafeAngle > _forwardStrafeMinThreshold && _strafeAngle < _forwardStrafeMaxThreshold ? 1f : 0f;
if (Mathf.Abs(_forwardStrafe - targetValue) <= 0.001f)
{
_forwardStrafe = targetValue;
}
else
{
float t = Mathf.Clamp01(_STRAFE_DIRECTION_DAMP_TIME * Time.deltaTime);
_forwardStrafe = Mathf.SmoothStep(_forwardStrafe, targetValue, t);
}
}
transform.rotation = Quaternion.Slerp(transform.rotation, strafingTargetRotation, _rotationSmoothing * Time.deltaTime);
}
else
{
UpdateStrafeDirection(1f, 0f);
float t = 20 * Time.deltaTime;
float newOffset = 0f;
if (characterForward != _cameraForward)
{
newOffset = Vector3.SignedAngle(characterForward, _cameraForward, Vector3.up);
}
_cameraRotationOffset = Mathf.Lerp(_cameraRotationOffset, newOffset, t);
if (Mathf.Abs(_cameraRotationOffset) > 10)
{
_isTurningInPlace = true;
}
}
}
else
{
UpdateStrafeDirection(1f, 0f);
_cameraRotationOffset = Mathf.Lerp(_cameraRotationOffset, 0f, _rotationSmoothing * Time.deltaTime);
_shuffleDirectionZ = 1;
_shuffleDirectionX = 0;
Vector3 faceDirection = new Vector3(_velocity.x, 0f, _velocity.z);
if (faceDirection == Vector3.zero)
{
return;
}
transform.rotation = Quaternion.Slerp(
transform.rotation,
Quaternion.LookRotation(faceDirection),
_rotationSmoothing * Time.deltaTime
);
}
}
/// <summary>
/// Checks if the player has stopped moving.
/// </summary>
private void CheckIfStopped()
{
_isStopped = _moveDirection.magnitude == 0 && _speed2D < .5;
}
/// <summary>
/// Checks if the player has started moving.
/// </summary>
private void CheckIfStarting()
{
_locomotionStartTimer = VariableOverrideDelayTimer(_locomotionStartTimer);
bool isStartingCheck = false;
if (_locomotionStartTimer <= 0.0f)
{
if (_moveDirection.magnitude > 0.01 && _speed2D < 1 && !_isStrafing)
{
isStartingCheck = true;
}
if (isStartingCheck)
{
if (!_isStarting)
{
_locomotionStartDirection = _newDirectionDifferenceAngle;
_animator.SetFloat(_locomotionStartDirectionHash, _locomotionStartDirection);
}
float delayTime = 0.2f;
_leanDelay = delayTime;
_headLookDelay = delayTime;
_bodyLookDelay = delayTime;
_locomotionStartTimer = delayTime;
}
}
else
{
isStartingCheck = true;
}
_isStarting = isStartingCheck;
_animator.SetBool(_isStartingHash, _isStarting);
}
/// <summary>
/// Updates the strafe direction variables to those provided.
/// </summary>
/// <param name="TargetZ">The value to set for Z axis.</param>
/// <param name="TargetX">The value to set for X axis.</param>
private void UpdateStrafeDirection(float TargetZ, float TargetX)
{
_strafeDirectionZ = Mathf.Lerp(_strafeDirectionZ, TargetZ, _ANIMATION_DAMP_TIME * Time.deltaTime);
_strafeDirectionX = Mathf.Lerp(_strafeDirectionX, TargetX, _ANIMATION_DAMP_TIME * Time.deltaTime);
_strafeDirectionZ = Mathf.Round(_strafeDirectionZ * 1000f) / 1000f;
_strafeDirectionX = Mathf.Round(_strafeDirectionX * 1000f) / 1000f;
}
#endregion
#region Ground Checks
/// <summary>
/// Checks if the character is grounded.
/// </summary>
private void GroundedCheck()
{
Vector3 spherePosition = new Vector3(
_controller.transform.position.x,
_controller.transform.position.y - _groundedOffset,
_controller.transform.position.z
);
_isGrounded = Physics.CheckSphere(spherePosition, _controller.radius, _groundLayerMask, QueryTriggerInteraction.Ignore);
if (_isGrounded)
{
GroundInclineCheck();
}
}
/// <summary>
/// Checks for ground incline and sets the required variables.
/// </summary>
private void GroundInclineCheck()
{
float rayDistance = Mathf.Infinity;
_rearRayPos.rotation = Quaternion.Euler(transform.rotation.x, 0, 0);
_frontRayPos.rotation = Quaternion.Euler(transform.rotation.x, 0, 0);
Physics.Raycast(_rearRayPos.position, _rearRayPos.TransformDirection(-Vector3.up), out RaycastHit rearHit, rayDistance, _groundLayerMask);
Physics.Raycast(
_frontRayPos.position,
_frontRayPos.TransformDirection(-Vector3.up),
out RaycastHit frontHit,
rayDistance,
_groundLayerMask
);
Vector3 hitDifference = frontHit.point - rearHit.point;
float xPlaneLength = new Vector2(hitDifference.x, hitDifference.z).magnitude;
_inclineAngle = Mathf.Lerp(_inclineAngle, Mathf.Atan2(hitDifference.y, xPlaneLength) * Mathf.Rad2Deg, 20f * Time.deltaTime);
}
/// <summary>
/// Checks the height of the ceiling above the player to make sure there is room to stand up if crouching.
/// </summary>
private void CeilingHeightCheck()
{
float rayDistance = Mathf.Infinity;
float minimumStandingHeight = _capsuleStandingHeight - _frontRayPos.localPosition.y;
Vector3 midpoint = new Vector3(transform.position.x, transform.position.y + _frontRayPos.localPosition.y, transform.position.z);
if (Physics.Raycast(midpoint, transform.TransformDirection(Vector3.up), out RaycastHit ceilingHit, rayDistance, _groundLayerMask))
{
_cannotStandUp = ceilingHit.distance < minimumStandingHeight;
}
else
{
_cannotStandUp = false;
}
}
#endregion
#region Falling
/// <summary>
/// Resets the falling duration variables.
/// </summary>
private void ResetFallingDuration()
{
_fallStartTime = Time.time;
_fallingDuration = 0f;
}
/// <summary>
/// Updates the falling duration variables.
/// </summary>
private void UpdateFallingDuration()
{
_fallingDuration = Time.time - _fallStartTime;
}
#endregion
#region Checks
/// <summary>
/// Checks if body turns can be enabled, and enabled or disables as required.
/// </summary>
private void CheckEnableTurns()
{
_headLookDelay = VariableOverrideDelayTimer(_headLookDelay);
_enableHeadTurn = _headLookDelay == 0.0f && !_isStarting;
_bodyLookDelay = VariableOverrideDelayTimer(_bodyLookDelay);
_enableBodyTurn = _bodyLookDelay == 0.0f && !(_isStarting || _isTurningInPlace);
}
/// <summary>
/// Checks if lean can be enabled, then enabled or disables as required.
/// </summary>
private void CheckEnableLean()
{
_leanDelay = VariableOverrideDelayTimer(_leanDelay);
_enableLean = _leanDelay == 0.0f && !(_isStarting || _isTurningInPlace);
}
#endregion
#region Lean and Offsets
/// <summary>
/// Calculates the required rotational additives based on the passed in parameters.
/// </summary>
/// <param name="leansActivated">If leans are activated or not.</param>
/// <param name="headLookActivated">If head look is activated or not.</param>
/// <param name="bodyLookActivated">If body look is activated or not.</param>
private void CalculateRotationalAdditives(bool leansActivated, bool headLookActivated, bool bodyLookActivated)
{
if (headLookActivated || leansActivated || bodyLookActivated)
{
_currentRotation = transform.forward;
_rotationRate = _currentRotation != _previousRotation
? Vector3.SignedAngle(_currentRotation, _previousRotation, Vector3.up) / Time.deltaTime * -1f
: 0f;
}
_initialLeanValue = leansActivated ? _rotationRate : 0f;
float leanSmoothness = 5;
float maxLeanRotationRate = 275.0f;
float referenceValue = _speed2D / _sprintSpeed;
_leanValue = CalculateSmoothedValue(
_leanValue,
_initialLeanValue,
maxLeanRotationRate,
leanSmoothness,
_leanCurve,
referenceValue,
true
);
float headTurnSmoothness = 5f;
if (headLookActivated && _isTurningInPlace)
{
_initialTurnValue = _cameraRotationOffset;
_headLookX = Mathf.Lerp(_headLookX, _initialTurnValue / 200, 5f * Time.deltaTime);
}
else
{
_initialTurnValue = headLookActivated ? _rotationRate : 0f;
_headLookX = CalculateSmoothedValue(
_headLookX,
_initialTurnValue,
maxLeanRotationRate,
headTurnSmoothness,
_headLookXCurve,
_headLookX,
false
);
}
float bodyTurnSmoothness = 5f;
_initialTurnValue = bodyLookActivated ? _rotationRate : 0f;
_bodyLookX = CalculateSmoothedValue(
_bodyLookX,
_initialTurnValue,
maxLeanRotationRate,
bodyTurnSmoothness,
_bodyLookXCurve,
_bodyLookX,
false
);
float cameraTilt = _cameraController.GetCameraTiltX();
cameraTilt = (cameraTilt > 180f ? cameraTilt - 360f : cameraTilt) / -180;
cameraTilt = Mathf.Clamp(cameraTilt, -0.1f, 1.0f);
_headLookY = cameraTilt;
_bodyLookY = cameraTilt;
_previousRotation = _currentRotation;
}
/// <summary>
/// Calculates a smoothed value between the given variable and target variable, from the given parameters.
/// </summary>
/// <param name="mainVariable">The variable to smooth.</param>
/// <param name="newValue">The target new value.</param>
/// <param name="maxRateChange">The max rate of change.</param>
/// <param name="smoothness">The smoothness amount.</param>
/// <param name="referenceCurve">The reference curve.</param>
/// <param name="referenceValue">The reference value.</param>
/// <param name="isMultiplier">If the value is a multiplier or not.</param>
/// <returns>The smoothed value.</returns>
private float CalculateSmoothedValue(
float mainVariable,
float newValue,
float maxRateChange,
float smoothness,
AnimationCurve referenceCurve,
float referenceValue,
bool isMultiplier
)
{
float changeVariable = newValue / maxRateChange;
changeVariable = Mathf.Clamp(changeVariable, -1.0f, 1.0f);
if (isMultiplier)
{
float multiplier = referenceCurve.Evaluate(referenceValue);
changeVariable *= multiplier;
}
else
{
changeVariable = referenceCurve.Evaluate(changeVariable);
}
if (!changeVariable.Equals(mainVariable))
{
changeVariable = Mathf.Lerp(mainVariable, changeVariable, smoothness * Time.deltaTime);
}
return changeVariable;
}
/// <summary>
/// Provides a clamped override delay to avoid animation transition issues.
/// </summary>
/// <param name="timeVariable">The time variable to use.</param>
/// <returns>A clamped override delay.</returns>
private float VariableOverrideDelayTimer(float timeVariable)
{
if (timeVariable > 0.0f)
{
timeVariable -= Time.deltaTime;
timeVariable = Mathf.Clamp(timeVariable, 0.0f, 1.0f);
}
else
{
timeVariable = 0.0f;
}
return timeVariable;
}
#endregion
#region Lock-on System
/// <summary>
/// Updates and sets the best target for lock on from the list of available targets.
/// </summary>
private void UpdateBestTarget()
{
GameObject newBestTarget;
if (_currentTargetCandidates.Count == 0)
{
newBestTarget = null;
}
else if (_currentTargetCandidates.Count == 1)
{
newBestTarget = _currentTargetCandidates[0];
}
else
{
newBestTarget = null;
float bestTargetScore = 0f;
foreach (GameObject target in _currentTargetCandidates)
{
target.GetComponent<SampleObjectLockOn>().Highlight(false, false);
float distance = Vector3.Distance(transform.position, target.transform.position);
float distanceScore = 1 / distance * 100;
Vector3 targetDirection = target.transform.position - _cameraController.GetCameraPosition();
float angleInView = Vector3.Dot(targetDirection.normalized, _cameraController.GetCameraForward());
float angleScore = angleInView * 40;
float totalScore = distanceScore + angleScore;
if (totalScore > bestTargetScore)
{
bestTargetScore = totalScore;
newBestTarget = target;
}
}
}
if (!_isLockedOn)
{
_currentLockOnTarget = newBestTarget;
if (_currentLockOnTarget != null)
{
_currentLockOnTarget.GetComponent<SampleObjectLockOn>().Highlight(true, false);
}
}
else
{
if (_currentTargetCandidates.Contains(_currentLockOnTarget))
{
_currentLockOnTarget.GetComponent<SampleObjectLockOn>().Highlight(true, true);
}
else
{
_currentLockOnTarget = newBestTarget;
EnableLockOn(false);
}
}
}
#endregion
#endregion
#region Locomotion State
/// <summary>
/// Sets up the locomotion state upon entry.
/// </summary>
private void EnterLocomotionState()
{
_inputReader.onJumpPerformed += LocomotionToJumpState;
}
/// <summary>
/// Updates the locomotion state.
/// </summary>
private void UpdateLocomotionState()
{
UpdateBestTarget();
GroundedCheck();
if (!_isGrounded)
{
SwitchState(AnimationState.Fall);
}
if (_isCrouching)
{
SwitchState(AnimationState.Crouch);
}
CheckEnableTurns();
CheckEnableLean();
CalculateRotationalAdditives(_enableLean, _enableHeadTurn, _enableBodyTurn);
CalculateMoveDirection();
CheckIfStarting();
CheckIfStopped();
FaceMoveDirection();
Move();
UpdateAnimatorController();
}
/// <summary>
/// Performs the required actions when exiting the locomotion state.
/// </summary>
private void ExitLocomotionState()
{
_inputReader.onJumpPerformed -= LocomotionToJumpState;
}
/// <summary>
/// Moves from the locomotion to the jump state.
/// </summary>
private void LocomotionToJumpState()
{
SwitchState(AnimationState.Jump);
}
#endregion
#region Jump State
/// <summary>
/// Sets up the Jump state upon entry.
/// </summary>
private void EnterJumpState()
{
_animator.SetBool(_isJumpingAnimHash, true);
_isSliding = false;
_velocity = new Vector3(_velocity.x, _jumpForce, _velocity.z);
}
/// <summary>
/// updates the jump state.
/// </summary>
private void UpdateJumpState()
{
UpdateBestTarget();
ApplyGravity();
if (_velocity.y <= 0f)
{
_animator.SetBool(_isJumpingAnimHash, false);
SwitchState(AnimationState.Fall);
}
GroundedCheck();
CalculateRotationalAdditives(false, _enableHeadTurn, _enableBodyTurn);
CalculateMoveDirection();
FaceMoveDirection();
Move();
UpdateAnimatorController();
}
/// <summary>
/// Performs the required actions upon exiting the jump state.
/// </summary>
private void ExitJumpState()
{
_animator.SetBool(_isJumpingAnimHash, false);
}
#endregion
#region Fall State
/// <summary>
/// Sets up the fall state upon entry.
/// </summary>
private void EnterFallState()
{
ResetFallingDuration();
_velocity.y = 0f;
DeactivateCrouch();
_isSliding = false;
}
/// <summary>
/// Updates the fall state.
/// </summary>
private void UpdateFallState()
{
UpdateBestTarget();
GroundedCheck();
CalculateRotationalAdditives(false, _enableHeadTurn, _enableBodyTurn);
CalculateMoveDirection();
FaceMoveDirection();
ApplyGravity();
Move();
UpdateAnimatorController();
if (_controller.isGrounded)
{
SwitchState(AnimationState.Locomotion);
}
UpdateFallingDuration();
}
#endregion
#region Crouch State
/// <summary>
/// Sets up the crouch state upon entry.
/// </summary>
private void EnterCrouchState()
{
_inputReader.onJumpPerformed += CrouchToJumpState;
}
/// <summary>
/// Updates the crouch state.
/// </summary>
private void UpdateCrouchState()
{
UpdateBestTarget();
GroundedCheck();
if (!_isGrounded)
{
DeactivateCrouch();
CapsuleCrouchingSize(false);
SwitchState(AnimationState.Fall);
}
CeilingHeightCheck();
if (!_crouchKeyPressed && !_cannotStandUp)
{
DeactivateCrouch();
SwitchToLocomotionState();
}
if (!_isCrouching)
{
CapsuleCrouchingSize(false);
SwitchToLocomotionState();
}
CheckEnableTurns();
CheckEnableLean();
CalculateRotationalAdditives(false, _enableHeadTurn, false);
CalculateMoveDirection();
CheckIfStarting();
CheckIfStopped();
FaceMoveDirection();
Move();
UpdateAnimatorController();
}
/// <summary>
/// Performs the required actions upon exiting the crouch state.
/// </summary>
private void ExitCrouchState()
{
_inputReader.onJumpPerformed -= CrouchToJumpState;
}
/// <summary>
/// Moves from the crouch state to the jump state.
/// </summary>
private void CrouchToJumpState()
{
if (!_cannotStandUp)
{
DeactivateCrouch();
SwitchState(AnimationState.Jump);
}
}
/// <summary>
/// Moves from the crouch state to the locomotion state.
/// </summary>
private void SwitchToLocomotionState()
{
DeactivateCrouch();
SwitchState(AnimationState.Locomotion);
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 095b8cf16ffa0984f8a9b6237c5e15ad
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,137 @@
using UnityEngine;
using Synty.AnimationBaseLocomotion.Samples.InputSystem;
namespace Synty.AnimationBaseLocomotion.Samples
{
[RequireComponent(typeof(SamplePlayerAnimationController))]
public class SyntyPlayerCombat : MonoBehaviour
{
[Header("References")]
public SamplePlayerAnimationController movementController;
public Animator animator;
public InputReader inputReader;
[Header("Combat Settings")]
public float comboWindow = 1.2f;
public Transform weaponHitPoint;
public float attackRadius = 3.5f; // Big radius for Musou sweeps
public int damage = 10;
public float knockbackForce = 25f;
public LayerMask enemyLayer;
private int baseDamage;
private float baseKnockback;
private Coroutine buffCoroutine;
private float lastAttackTime;
private int comboStep = 0;
void Reset()
{
movementController = GetComponent<SamplePlayerAnimationController>();
animator = GetComponent<Animator>();
inputReader = GetComponent<InputReader>();
}
private void OnEnable()
{
if (inputReader != null)
{
inputReader.onAttackPerformed += PerformAttack;
}
}
private void OnDisable()
{
if (inputReader != null)
{
inputReader.onAttackPerformed -= PerformAttack;
}
}
void Start()
{
baseDamage = damage;
baseKnockback = knockbackForce;
}
void Update()
{
// Reset the combo step and unlock movement if the player stops pressing attack
if (comboStep > 0 && Time.time - lastAttackTime > comboWindow)
{
comboStep = 0;
movementController.IsAttacking = false;
}
// Attack input is handled via the InputReader's onAttackPerformed event
}
private void PerformAttack()
{
lastAttackTime = Time.time;
// Lock movement in the Synty controller
movementController.IsAttacking = true;
comboStep++;
if (comboStep > 3) comboStep = 1; // Loop the 3-hit combo
animator.SetTrigger("Attack" + comboStep);
}
// --- ANIMATION EVENTS ---
/// <summary>
/// Trigger this via Animation Event at the exact frame the sword connects.
/// </summary>
public void ExecuteAttackHit()
{
Collider[] hitEnemies = Physics.OverlapSphere(weaponHitPoint.position, attackRadius, enemyLayer);
foreach (Collider enemy in hitEnemies)
{
// Assumes the EnemyAI script from the Swarm architecture
EnemyAI health = enemy.GetComponentInParent<EnemyAI>();
if (health != null)
{
health.TakeDamage(damage, transform.position, knockbackForce);
}
}
}
/// <summary>
/// Trigger this via Animation Event at the very end of the attack animation clip.
/// </summary>
public void EndAttack()
{
movementController.IsAttacking = false;
}
void OnDrawGizmosSelected()
{
if (weaponHitPoint != null)
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(weaponHitPoint.position, attackRadius);
}
}
public void ApplyStrengthBuff(float multiplier, float duration)
{
// If we grab a second strength pickup while one is already active, reset the timer
if (buffCoroutine != null) StopCoroutine(buffCoroutine);
buffCoroutine = StartCoroutine(StrengthRoutine(multiplier, duration));
}
private System.Collections.IEnumerator StrengthRoutine(float multiplier, float duration)
{
Debug.Log("<color=red>Strength Buff Active!</color>");
damage = Mathf.RoundToInt(baseDamage * multiplier);
knockbackForce = baseKnockback * multiplier;
yield return new WaitForSeconds(duration);
Debug.Log("<color=white>Strength Buff Faded.</color>");
damage = baseDamage;
knockbackForce = baseKnockback;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9c2359c56a31a94468e3fe5439bdb2d2