Skip to content

Instantly share code, notes, and snippets.

@whoisryosuke
Last active October 12, 2021 00:27
Show Gist options
  • Select an option

  • Save whoisryosuke/f7b12ca2077853435ba45cb1754444c1 to your computer and use it in GitHub Desktop.

Select an option

Save whoisryosuke/f7b12ca2077853435ba45cb1754444c1 to your computer and use it in GitHub Desktop.
Unity - 3D Player Movement using Unity's Player Input package - via: https://www.youtube.com/watch?v=537B1kJp9YQ
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
// Handles actual movement of character + triggering things like animation
// This game has a "shooting mode" which is activated by Left Shift
// So you'll see shooting logic as well
public class PlayerLocomotionController : MonoBehaviour
{
private Animator _animator;
private PlayerMovementInputController _movement;
private Vector2 smoothDeltaPosition = Vector2.zero;
public Vector2 velocity = Vector2.zero;
public float magnitude = 0.25f;
public bool shouldMove;
public bool shouldTurn;
public float turn;
public GameObject look;
public GameObject arrow;
public Transform arrowBone;
public GameObject arrowPrefab;
private void OnEnable()
{
_movement = GetComponent<PlayerMovementInputController>();
_animator = GetComponent<Animator>();
}
public void Update()
{
Vector3 worldDeltaPosition = _movement.nextPosition - transform.position;
//Map to local space
float dX = Vector3.Dot(transform.right, worldDeltaPosition);
float dY = Vector3.Dot(transform.forward, worldDeltaPosition);
Vector2 deltaPosition = new Vector2(dX, dY);
float smooth = Mathf.Min(1.0f, Time.deltaTime / 0.15f);
smoothDeltaPosition = Vector2.Lerp(smoothDeltaPosition, deltaPosition, smooth);
if (Time.deltaTime > 1e-5f)
{
velocity = smoothDeltaPosition / Time.deltaTime;
}
shouldMove = velocity.magnitude > magnitude;
bool isAiming = (_movement.aimValue == 1f);
if (isAiming)
{
if ((_movement.fireValue == 1f))
{
_animator.SetTrigger("Fire");
arrow.SetActive(false);
StartCoroutine(FireArrow());
}
if (_animator.GetCurrentAnimatorStateInfo(2).IsName("Fire"))
{
arrow.SetActive(false);
}
else
{
arrow.SetActive(true);
}
_movement.fireValue = 0f;
}
_animator.SetBool("IsAiming", isAiming);
_animator.SetBool("IsMoving", shouldMove);
_animator.SetFloat("VelocityX", velocity.x);
_animator.SetFloat("VelocityY", Mathf.Abs(velocity.y));
}
private void OnAnimatorMove()
{
//Update the position based on the next position;
transform.position = _movement.nextPosition;
}
[SerializeField]
private Transform fireTransform;
IEnumerator FireArrow()
{
GameObject projectile = Instantiate(arrowPrefab);
projectile.transform.forward = look.transform.forward;
projectile.transform.position = fireTransform.position + fireTransform.forward;
//Wait for the position to update
yield return new WaitForSeconds(0.1f);
projectile.GetComponent<ArrowProjectile>().Fire();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.InputSystem;
// This class handles taking user input and converting to proper movement
// This does not move the character - only rotates.
// `nextPosition` contains movement - handled by PlayerLocomotionController (see below)
[RequireComponent(typeof(PlayerInput))]
[RequireComponent(typeof(NavMeshAgent))]
public class PlayerMovementInputController : MonoBehaviour
{
private NavMeshAgent _agent;
// These all sync with Player Input using the callbacks below (e.g. `onMove`)
public Vector2 _move;
public Vector2 _look;
public float aimValue;
public float fireValue;
public Vector3 nextPosition;
public Quaternion nextRotation;
public float rotationPower = 3f;
public float rotationLerp = 0.5f;
public float speed = 1f;
// The main camera in scene (usually MainCamera)
public Camera camera;
// An empty game object marker inside your Player - like near head
public GameObject followTransform;
private void Awake()
{
_agent = GetComponent<NavMeshAgent>();
}
public void OnMove(InputValue value)
{
_move = value.Get<Vector2>();
}
public void OnLook(InputValue value)
{
_look = value.Get<Vector2>();
}
public void OnAim(InputValue value)
{
aimValue = value.Get<float>();
}
public void OnFire(InputValue value)
{
fireValue = value.Get<float>();
}
private void Update()
{
#region Player Based Rotation
//Move the player based on the X input on the controller
//transform.rotation *= Quaternion.AngleAxis(_look.x * rotationPower, Vector3.up);
#endregion
#region Follow Transform Rotation
//Rotate the Follow Target transform based on the input
followTransform.transform.rotation *= Quaternion.AngleAxis(_look.x * rotationPower, Vector3.up);
#endregion
#region Vertical Rotation
followTransform.transform.rotation *= Quaternion.AngleAxis(-_look.y * rotationPower / 2, Vector3.right);
var angles = followTransform.transform.localEulerAngles;
angles.z = 0;
var angle = followTransform.transform.localEulerAngles.x;
//Clamp the Up/Down rotation
if (angle > 180 && angle < 340)
{
angles.x = 340;
}
else if (angle < 180 && angle > 40)
{
angles.x = 40;
}
followTransform.transform.localEulerAngles = angles;
#endregion
nextRotation = Quaternion.Lerp(followTransform.transform.rotation, nextRotation, Time.deltaTime * rotationLerp);
if (_move.x == 0 && _move.y == 0)
{
nextPosition = transform.position;
if (aimValue == 1)
{
//Set the player rotation based on the look transform
transform.rotation = Quaternion.Euler(0, followTransform.transform.rotation.eulerAngles.y, 0);
//reset the y rotation of the look transform
followTransform.transform.localEulerAngles = new Vector3(angles.x, 0, 0);
}
return;
}
float moveSpeed = speed / 100f;
Vector3 position = (transform.forward * _move.y * moveSpeed) + (transform.right * _move.x * moveSpeed);
nextPosition = transform.position + position;
//Set the player rotation based on the look transform
transform.rotation = Quaternion.Euler(0, followTransform.transform.rotation.eulerAngles.y, 0);
//reset the y rotation of the look transform
followTransform.transform.localEulerAngles = new Vector3(angles.x, 0, 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment