implementation of drecon in unity 2022 lts
forked from:
https://github.com/joanllobera/marathon-envs
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
7.3 KiB
212 lines
7.3 KiB
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Unity.MLAgents;
|
|
|
|
public class InputController : MonoBehaviour
|
|
{
|
|
[Header("Options")]
|
|
public float MaxVelocity = 8f;
|
|
[Range(0f,1f)]
|
|
public float ClipInput;
|
|
public bool NoJumpsInMockMode = true;
|
|
|
|
[Header("User or Mock input states")]
|
|
public Vector2 TargetMovementVector; // User-input desired horizontal center of mass velocity.
|
|
public float TargetMovementMagnatude;
|
|
public Vector2 MovementVector; // smoothed version of TargetMovementVector.
|
|
public float MovementMagnatude;
|
|
public Vector2 CameraRotation; // User-input desired rotation for camera.
|
|
public bool Jump; // User wants to jump
|
|
public bool Backflip; // User wants to backflip
|
|
public bool Stand;
|
|
public bool WalkOrRun;
|
|
|
|
[Header("Read only (or debug)")]
|
|
public Vector2 DesiredHorizontalVelocity; // MovementVector * Max Velovity
|
|
public Vector3 HorizontalDirection; // Normalized vector in direction of travel (assume right angle to floor)
|
|
public bool UseHumanInput = true;
|
|
public bool DemoMockIfNoInput = true; // Demo mock mode if no human input
|
|
public bool m_IsTraining = false;
|
|
|
|
float _delayUntilNextAction;
|
|
float _timeUnillDemo;
|
|
|
|
const float kGroundAcceleration = .6f/2;
|
|
const float kGroundDeceleration = .75f/4;
|
|
const float kDeadzone = .1f; // below this value is stationary
|
|
|
|
|
|
// Start is called before the first frame update
|
|
void Awake()
|
|
{
|
|
if(m_IsTraining)
|
|
UseHumanInput = !Academy.Instance.IsCommunicatorOn;
|
|
_timeUnillDemo = 1f;
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void Update()
|
|
{
|
|
|
|
}
|
|
void FixedUpdate()
|
|
{
|
|
DoUpdate(Time.fixedDeltaTime);
|
|
}
|
|
void DoUpdate(float deltaTime)
|
|
{
|
|
if (UseHumanInput)
|
|
GetHumanInput();
|
|
else
|
|
GetMockInput();
|
|
SmoothAcceleration(deltaTime);
|
|
}
|
|
public void OnReset()
|
|
{
|
|
MovementVector = Vector3.zero;
|
|
MovementMagnatude = MovementVector.magnitude;
|
|
SetRandomHorizontalDirection();
|
|
_delayUntilNextAction = -1f;
|
|
// DoUpdate(Time.fixedDeltaTime);
|
|
if (UseHumanInput)
|
|
GetHumanInput();
|
|
else
|
|
GetMockInput();
|
|
// handle direction
|
|
if (!Mathf.Approximately(TargetMovementVector.sqrMagnitude, 0f))
|
|
HorizontalDirection = new Vector3(TargetMovementVector.normalized.x, 0f, TargetMovementVector.normalized.y);
|
|
DesiredHorizontalVelocity = TargetMovementVector.normalized * MaxVelocity * TargetMovementVector.magnitude;
|
|
}
|
|
void SmoothAcceleration(float deltaTime)
|
|
{
|
|
// Determine change to speed based on whether there is currently any move input.
|
|
float acceleration = TargetMovementVector.magnitude > 0 ? kGroundAcceleration : kGroundDeceleration;
|
|
|
|
var difference = (MovementVector - TargetMovementVector);
|
|
if (difference.magnitude > MovementVector.magnitude)
|
|
{
|
|
acceleration *= 5f;
|
|
}
|
|
|
|
// Adjust the forward speed towards the desired speed.
|
|
MovementVector = Vector2.MoveTowards(MovementVector, TargetMovementVector, acceleration * deltaTime);
|
|
|
|
// Handle deadzone
|
|
if (TargetMovementVector.magnitude < kDeadzone && MovementVector.magnitude < kDeadzone)
|
|
{
|
|
TargetMovementVector = Vector2.zero;
|
|
TargetMovementMagnatude = TargetMovementVector.magnitude;
|
|
MovementVector = Vector2.zero;
|
|
WalkOrRun = false;
|
|
Stand = true;
|
|
}
|
|
else
|
|
{
|
|
WalkOrRun = true;
|
|
Stand = false;
|
|
}
|
|
MovementMagnatude = MovementVector.magnitude;
|
|
|
|
// handle direction
|
|
if (!Mathf.Approximately(MovementVector.sqrMagnitude, 0f))
|
|
HorizontalDirection = new Vector3(MovementVector.normalized.x, 0f, MovementVector.normalized.y);
|
|
DesiredHorizontalVelocity = MovementVector.normalized * MaxVelocity * MovementVector.magnitude;
|
|
}
|
|
void GetHumanInput()
|
|
{
|
|
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
|
|
return;
|
|
bool resetTimeUntilDemo = false;
|
|
_timeUnillDemo -= Time.deltaTime;
|
|
var newMovementVector = new Vector2(
|
|
Input.GetAxis("Horizontal"),
|
|
Input.GetAxis("Vertical")
|
|
);
|
|
if (ClipInput > 0f)
|
|
{
|
|
newMovementVector = new Vector2(
|
|
Mathf.Clamp(newMovementVector.x, -ClipInput, ClipInput),
|
|
Mathf.Clamp(newMovementVector.y, -ClipInput, ClipInput));
|
|
}
|
|
if (!Mathf.Approximately(newMovementVector.sqrMagnitude, 0f))
|
|
{
|
|
TargetMovementVector = newMovementVector;
|
|
TargetMovementMagnatude = TargetMovementVector.magnitude;
|
|
resetTimeUntilDemo = true;
|
|
}
|
|
else if (DemoMockIfNoInput && _timeUnillDemo <= 0)
|
|
{
|
|
GetMockInput();
|
|
_timeUnillDemo = 0f;
|
|
return;
|
|
}
|
|
CameraRotation = Vector2.zero;
|
|
Jump = Input.GetKey(KeyCode.Space); //Input.GetButtonDown("Fire1");
|
|
Backflip = Input.GetKey(KeyCode.B);
|
|
if (Jump || Backflip)
|
|
{
|
|
resetTimeUntilDemo = true;
|
|
}
|
|
if (resetTimeUntilDemo)
|
|
{
|
|
_timeUnillDemo = 3f;
|
|
}
|
|
}
|
|
void GetMockInput()
|
|
{
|
|
_delayUntilNextAction -= Time.deltaTime;
|
|
if (_delayUntilNextAction > 0)
|
|
return;
|
|
if (ChooseBackflip())
|
|
{
|
|
Backflip = true;
|
|
_delayUntilNextAction = 2f;
|
|
return;
|
|
}
|
|
Backflip = false;
|
|
Jump = false;
|
|
float direction = UnityEngine.Random.Range(0f, 360f);
|
|
float power = UnityEngine.Random.value;
|
|
// keep power above deadzone as we handle that below
|
|
power = kDeadzone + (power * (1f-kDeadzone));
|
|
// 2 in 5 times we are going to stand still
|
|
if (UnityEngine.Random.value < .4f)
|
|
power = 0.001f;
|
|
// float direction = UnityEngine.Random.Range(-Mathf.PI/8, Mathf.PI/8);
|
|
// float power = UnityEngine.Random.Range(1f, 1f);
|
|
if (ClipInput > 0f)
|
|
{
|
|
power *= ClipInput;
|
|
}
|
|
TargetMovementVector = new Vector2(Mathf.Cos(direction), Mathf.Sin(direction));
|
|
TargetMovementVector *= power;
|
|
TargetMovementMagnatude = TargetMovementVector.magnitude;
|
|
Jump = ChooseJump();
|
|
_delayUntilNextAction = 1f + (UnityEngine.Random.value * 5f);
|
|
}
|
|
bool ChooseBackflip()
|
|
{
|
|
if (NoJumpsInMockMode)
|
|
return false;
|
|
var rnd = UnityEngine.Random.Range(0, 10);
|
|
return rnd == 0;
|
|
}
|
|
bool ChooseJump()
|
|
{
|
|
if (NoJumpsInMockMode)
|
|
return false;
|
|
var rnd = UnityEngine.Random.Range(0, 5);
|
|
return rnd == 0;
|
|
}
|
|
void SetRandomHorizontalDirection()
|
|
{
|
|
float direction = UnityEngine.Random.Range(0f, 360f);
|
|
var movementVector = new Vector2(Mathf.Cos(direction), Mathf.Sin(direction));
|
|
HorizontalDirection = new Vector3(movementVector.normalized.x, 0f, movementVector.normalized.y);
|
|
movementVector /= float.MinValue;
|
|
TargetMovementVector = new Vector2(movementVector.x, movementVector.y);
|
|
TargetMovementMagnatude = TargetMovementVector.magnitude;
|
|
}
|
|
|
|
}
|
|
|