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

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;
}
}