Add config drive controller. Single agent for both recording and training.
This commit is contained in:
Родитель
bfebf91b35
Коммит
6e5fb6577e
Двоичный файл не отображается.
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 24e83aea37bed45529b03860c4d72ffd
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 7bd65ce151aaa4a41a45312543c56be1, type: 3}
|
Двоичный файл не отображается.
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d10d7ee1f589242e2960bf2658bdec93
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 7bd65ce151aaa4a41a45312543c56be1, type: 3}
|
Двоичный файл не отображается.
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 5d27792c403d74622b43b77e59f53dc5
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 7bd65ce151aaa4a41a45312543c56be1, type: 3}
|
Двоичный файл не отображается.
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7d4484eee5cd8444cb3f7a6f5c4654f2
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 7bd65ce151aaa4a41a45312543c56be1, type: 3}
|
Двоичный файл не отображается.
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d62b3558b65b1472598c4561ea30afc1
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 7bd65ce151aaa4a41a45312543c56be1, type: 3}
|
Двоичный файл не отображается.
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 79eba9672f24c473c859d9f6e1ab7a58
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 7bd65ce151aaa4a41a45312543c56be1, type: 3}
|
Двоичный файл не отображается.
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1bbff1433082c4721a3c893450c4ecf9
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 7bd65ce151aaa4a41a45312543c56be1, type: 3}
|
Двоичный файл не отображается.
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: c450a6a249cbc40daa9492d00b26f0a6
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 7bd65ce151aaa4a41a45312543c56be1, type: 3}
|
Двоичный файл не отображается.
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 05ddcac22763744c8a1f346e14fa8455
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 7bd65ce151aaa4a41a45312543c56be1, type: 3}
|
Двоичный файл не отображается.
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0693b5247cb7845e1b085c6db82958bb
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 7bd65ce151aaa4a41a45312543c56be1, type: 3}
|
Двоичный файл не отображается.
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e7cd07d9d1da34e6680d25aaf7915459
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 7bd65ce151aaa4a41a45312543c56be1, type: 3}
|
Двоичный файл не отображается.
|
@ -1,10 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f1be46dd9c3db4e25801d54ef693fde0
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData: ' (Unity.MLAgents.Demonstrations.DemonstrationSummary)'
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 7bd65ce151aaa4a41a45312543c56be1, type: 3}
|
|
@ -236,7 +236,7 @@ ModelImporter:
|
|||
value: {x: 0, y: 0, z: 0}
|
||||
length: 0
|
||||
modified: 0
|
||||
- boneName: chest
|
||||
- boneName: spine1
|
||||
humanName: Chest
|
||||
limit:
|
||||
min: {x: 0, y: 0, z: 0}
|
||||
|
@ -284,6 +284,14 @@ ModelImporter:
|
|||
value: {x: 0, y: 0, z: 0}
|
||||
length: 0
|
||||
modified: 0
|
||||
- boneName: chest
|
||||
humanName: UpperChest
|
||||
limit:
|
||||
min: {x: 0, y: 0, z: 0}
|
||||
max: {x: 0, y: 0, z: 0}
|
||||
value: {x: 0, y: 0, z: 0}
|
||||
length: 0
|
||||
modified: 0
|
||||
skeleton:
|
||||
- name: Walker(Clone)
|
||||
parentName:
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,7 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4ab79b31fae4b4f62aec86188b2c0d02
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,296 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.MLAgents;
|
||||
using Unity.MLAgents.Actuators;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
[Serializable]
|
||||
public struct CJControlSettings
|
||||
{
|
||||
public string name;
|
||||
public Vector3 target;
|
||||
public Range3D range;
|
||||
public Vector3 originalPosition;
|
||||
public Quaternion originalRotation;
|
||||
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Range3D
|
||||
{
|
||||
public Range xRange;
|
||||
public Range yRange;
|
||||
public Range zRange;
|
||||
|
||||
public Range3D(float xLow, float xHigh, float yLow, float yHigh, float zLow, float zHigh)
|
||||
{
|
||||
xRange = new Range(xLow, xHigh);
|
||||
yRange = new Range(xLow, xHigh);
|
||||
zRange = new Range(xLow, xHigh);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Range
|
||||
{
|
||||
public float low;
|
||||
public float high;
|
||||
|
||||
public Range(float low, float high)
|
||||
{
|
||||
this.low = low;
|
||||
this.high = high;
|
||||
}
|
||||
|
||||
public float Scale(float input)
|
||||
{
|
||||
var t = (1.0f + input) / 2.0f;
|
||||
return Mathf.Round(Mathf.Lerp(low, high, t));
|
||||
|
||||
// if (input >= 0f)
|
||||
// {
|
||||
// return Mathf.RoundToInt(Mathf.Lerp(0f, m_High, input));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return Mathf.RoundToInt(Mathf.Lerp(m_Low, 0f, 1.0f + input));
|
||||
// }
|
||||
}
|
||||
|
||||
public float InverseScale(float input)
|
||||
{
|
||||
var t = Mathf.InverseLerp(low, high, input);
|
||||
return 2.0f * t - 1.0f;
|
||||
|
||||
// if (input >= 0f)
|
||||
// {
|
||||
// return Mathf.InverseLerp(0f, m_High, input);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return Mathf.InverseLerp(m_Low, 0f, input) - 1.0f;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
public class ConfigurableJointController : MonoBehaviour
|
||||
{
|
||||
public float spring = 1000;
|
||||
public float damping = 250;
|
||||
public float forceLimit = 500;
|
||||
public bool kinematicRoot;
|
||||
public float totalMass;
|
||||
|
||||
[SerializeField]
|
||||
public CJControlSettings[] cjControlSettings;
|
||||
|
||||
[Header("Body Parts")]
|
||||
public Transform hips;
|
||||
public Transform spine;
|
||||
public Transform head;
|
||||
public Transform thighL;
|
||||
public Transform shinL;
|
||||
public Transform footL;
|
||||
public Transform thighR;
|
||||
public Transform shinR;
|
||||
public Transform footR;
|
||||
public Transform armL;
|
||||
public Transform forearmL;
|
||||
public Transform handL;
|
||||
public Transform armR;
|
||||
public Transform forearmR;
|
||||
public Transform handR;
|
||||
|
||||
ConfigurableJoint[] m_ConfigurableJointChain;
|
||||
Rigidbody[] m_RigidbodyChain;
|
||||
Agent m_Agent;
|
||||
bool m_IsAgentNull;
|
||||
Vector3 m_RootOriginalPosition;
|
||||
Quaternion m_RootOriginalRotation;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
m_Agent = GetComponent<Agent>();
|
||||
m_IsAgentNull = m_Agent == null;
|
||||
PopulateParameters();
|
||||
m_ConfigurableJointChain[0].GetComponent<Rigidbody>().isKinematic = kinematicRoot;
|
||||
m_RootOriginalPosition = hips.position;
|
||||
m_RootOriginalRotation = hips.rotation;
|
||||
StartCoroutine(ResetCJointTargetsAndPositions());
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void FixedUpdate()
|
||||
{
|
||||
if (m_IsAgentNull)
|
||||
{
|
||||
SetCJointTargets();
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
void OnValidate()
|
||||
{
|
||||
PopulateParameters();
|
||||
}
|
||||
#endif
|
||||
void PopulateParameters(bool force = false)
|
||||
{
|
||||
if (m_ConfigurableJointChain == null || m_ConfigurableJointChain.Length == 0 || force)
|
||||
{
|
||||
m_ConfigurableJointChain = new[]
|
||||
{
|
||||
hips.GetComponent<ConfigurableJoint>(),
|
||||
spine.GetComponent<ConfigurableJoint>(),
|
||||
head.GetComponent<ConfigurableJoint>(),
|
||||
thighL.GetComponent<ConfigurableJoint>(),
|
||||
shinL.GetComponent<ConfigurableJoint>(),
|
||||
footL.GetComponent<ConfigurableJoint>(),
|
||||
thighR.GetComponent<ConfigurableJoint>(),
|
||||
shinR.GetComponent<ConfigurableJoint>(),
|
||||
footR.GetComponent<ConfigurableJoint>(),
|
||||
armL.GetComponent<ConfigurableJoint>(),
|
||||
forearmL.GetComponent<ConfigurableJoint>(),
|
||||
handL.GetComponent<ConfigurableJoint>(),
|
||||
armR.GetComponent<ConfigurableJoint>(),
|
||||
forearmR.GetComponent<ConfigurableJoint>(),
|
||||
handR.GetComponent<ConfigurableJoint>(),
|
||||
};
|
||||
}
|
||||
|
||||
if (m_RigidbodyChain == null || m_RigidbodyChain.Length == 0 || force)
|
||||
{
|
||||
m_RigidbodyChain = new[]
|
||||
{
|
||||
hips.GetComponent<Rigidbody>(),
|
||||
spine.GetComponent<Rigidbody>(),
|
||||
head.GetComponent<Rigidbody>(),
|
||||
thighL.GetComponent<Rigidbody>(),
|
||||
shinL.GetComponent<Rigidbody>(),
|
||||
footL.GetComponent<Rigidbody>(),
|
||||
thighR.GetComponent<Rigidbody>(),
|
||||
shinR.GetComponent<Rigidbody>(),
|
||||
footR.GetComponent<Rigidbody>(),
|
||||
armL.GetComponent<Rigidbody>(),
|
||||
forearmL.GetComponent<Rigidbody>(),
|
||||
handL.GetComponent<Rigidbody>(),
|
||||
armR.GetComponent<Rigidbody>(),
|
||||
forearmR.GetComponent<Rigidbody>(),
|
||||
handR.GetComponent<Rigidbody>(),
|
||||
};
|
||||
}
|
||||
if (cjControlSettings == null || cjControlSettings.Length == 0 || force)
|
||||
{
|
||||
cjControlSettings = new CJControlSettings[m_ConfigurableJointChain.Length - 1];
|
||||
for (int i = 0; i < cjControlSettings.Length; i++)
|
||||
{
|
||||
cjControlSettings[i].name = m_ConfigurableJointChain[i + 1].name;
|
||||
cjControlSettings[i].target = m_ConfigurableJointChain[i + 1].targetRotation.eulerAngles;
|
||||
cjControlSettings[i].range = new Range3D(
|
||||
m_ConfigurableJointChain[i + 1].lowAngularXLimit.limit,
|
||||
m_ConfigurableJointChain[i + 1].highAngularXLimit.limit,
|
||||
-m_ConfigurableJointChain[i + 1].angularYLimit.limit,
|
||||
m_ConfigurableJointChain[i + 1].angularYLimit.limit,
|
||||
-m_ConfigurableJointChain[i + 1].angularZLimit.limit,
|
||||
m_ConfigurableJointChain[i + 1].angularZLimit.limit
|
||||
);
|
||||
cjControlSettings[i].originalPosition = m_ConfigurableJointChain[i].transform.position;
|
||||
cjControlSettings[i].originalRotation = m_ConfigurableJointChain[i].transform.rotation;
|
||||
}
|
||||
}
|
||||
if (totalMass == 0)
|
||||
{
|
||||
foreach (var rb in m_RigidbodyChain)
|
||||
{
|
||||
totalMass += rb.mass;
|
||||
}
|
||||
}
|
||||
}
|
||||
public void SetCJointTargets(ActionSegment<float> angles)
|
||||
{
|
||||
for (int i = 0; i < cjControlSettings.Length; i++)
|
||||
{
|
||||
var subindex = 3 * i;
|
||||
var xAngle = cjControlSettings[i].range.xRange.Scale(angles[subindex]);
|
||||
var yAngle = cjControlSettings[i].range.yRange.Scale(angles[++subindex]);
|
||||
var zAngle = cjControlSettings[i].range.zRange.Scale(angles[++subindex]);
|
||||
var targetRotation = new Vector3(xAngle, yAngle, zAngle);
|
||||
SetCJointTarget(m_ConfigurableJointChain[i + 1], targetRotation);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCJointTargets()
|
||||
{
|
||||
for (int i = 0; i < cjControlSettings.Length; i++)
|
||||
{
|
||||
SetCJointTarget(m_ConfigurableJointChain[i + 1], cjControlSettings[i].target);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCJointTarget(ConfigurableJoint joint, Vector3 target)
|
||||
{
|
||||
joint.targetRotation = Quaternion.Euler(target);
|
||||
}
|
||||
|
||||
public void SetCJointPositionsAndRotations()
|
||||
{
|
||||
for (int i = 0; i < cjControlSettings.Length; i++)
|
||||
{
|
||||
m_RigidbodyChain[i + 1].transform.position = cjControlSettings[i].originalPosition;
|
||||
m_RigidbodyChain[i + 1].transform.rotation = cjControlSettings[i].originalRotation;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator ResetCJointTargetsAndPositions()
|
||||
{
|
||||
m_ConfigurableJointChain[0].GetComponent<Rigidbody>().isKinematic = true;
|
||||
ZeroCJointPhysics();
|
||||
ZeroCJointPhysicsSettings();
|
||||
// yield return new WaitForSeconds(1.0f / 50);
|
||||
SetCJointPositionsAndRotations();
|
||||
SetCJointTargets();
|
||||
SetCJointPhysicsSettings();
|
||||
yield return new WaitForSeconds(1.0f / 50);
|
||||
m_ConfigurableJointChain[0].GetComponent<Rigidbody>().isKinematic = kinematicRoot;
|
||||
}
|
||||
void SetCJointPhysicsSettings()
|
||||
{
|
||||
for (int i = 1; i < m_ConfigurableJointChain.Length; i++)
|
||||
{
|
||||
m_ConfigurableJointChain[i].rotationDriveMode = RotationDriveMode.Slerp;
|
||||
var drive = m_ConfigurableJointChain[i].slerpDrive;
|
||||
drive.positionSpring = spring;
|
||||
drive.positionDamper = damping;
|
||||
drive.maximumForce = forceLimit;
|
||||
m_ConfigurableJointChain[i].slerpDrive = drive;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void ZeroCJointPhysics()
|
||||
{
|
||||
foreach (var rb in m_RigidbodyChain)
|
||||
{
|
||||
rb.velocity = Vector3.zero;
|
||||
rb.angularVelocity = Vector3.zero;
|
||||
rb.Sleep();
|
||||
}
|
||||
}
|
||||
|
||||
public void ZeroCJointPhysicsSettings()
|
||||
{
|
||||
for (int i = 1; i < m_ConfigurableJointChain.Length; i++)
|
||||
{
|
||||
m_ConfigurableJointChain[i].rotationDriveMode = RotationDriveMode.Slerp;
|
||||
var drive = m_ConfigurableJointChain[i].slerpDrive;
|
||||
drive.positionSpring = 0f;
|
||||
drive.positionDamper = 0f;
|
||||
drive.maximumForce = forceLimit;
|
||||
m_ConfigurableJointChain[i].slerpDrive = drive;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2079264ed7d4b4902a80b2cf7b282c16
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -1,12 +1,14 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using RootMotion.Dynamics;
|
||||
using Unity.MLAgents;
|
||||
using Unity.MLAgents.Actuators;
|
||||
using Unity.MLAgents.Sensors;
|
||||
using UnityEngine;
|
||||
|
||||
public class WalkerASEAgent : Agent
|
||||
{
|
||||
public bool RecordingMode;
|
||||
public bool recordingMode;
|
||||
|
||||
public Transform root;
|
||||
public Rigidbody rootRB;
|
||||
|
@ -14,15 +16,33 @@ public class WalkerASEAgent : Agent
|
|||
Vector3 m_OriginalPosition;
|
||||
Quaternion m_OriginalRotation;
|
||||
|
||||
ConfigurableJointController m_Controller;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
m_OriginalPosition = root.position;
|
||||
m_OriginalRotation = root.rotation;
|
||||
m_Controller = GetComponent<ConfigurableJointController>();
|
||||
if (!recordingMode)
|
||||
{
|
||||
var puppetMaster = GetComponentInChildren<PuppetMaster>();
|
||||
var animator = GetComponentInChildren<Animator>();
|
||||
Destroy(puppetMaster);
|
||||
Destroy(animator.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnEpisodeBegin()
|
||||
{
|
||||
ResetAgent();
|
||||
if (recordingMode)
|
||||
{
|
||||
ResetAnimation();
|
||||
}
|
||||
}
|
||||
void ResetAnimation()
|
||||
{
|
||||
// TODO reset animation on an episode reset (nice to have)
|
||||
}
|
||||
|
||||
void ResetAgent()
|
||||
|
@ -46,7 +66,29 @@ public class WalkerASEAgent : Agent
|
|||
|
||||
}
|
||||
|
||||
public float GetRootHeightFromGround()
|
||||
public override void OnActionReceived(ActionBuffers actionBuffers)
|
||||
{
|
||||
|
||||
var continuousActions = actionBuffers.ContinuousActions;
|
||||
m_Controller.SetCJointTargets(continuousActions);
|
||||
}
|
||||
|
||||
public override void Heuristic(in ActionBuffers actionsOut)
|
||||
{
|
||||
var continuousActionsOut = actionsOut.ContinuousActions;
|
||||
// add control from editor component
|
||||
for (int i = 0; i < m_Controller.cjControlSettings.Length; i++)
|
||||
{
|
||||
var target = m_Controller.cjControlSettings[i].target;
|
||||
var subIndex = 3 * i;
|
||||
continuousActionsOut[subIndex] = m_Controller.cjControlSettings[i].range.xRange.InverseScale(target.x);
|
||||
continuousActionsOut[++subIndex] = m_Controller.cjControlSettings[i].range.yRange.InverseScale(target.y);
|
||||
continuousActionsOut[++subIndex] = m_Controller.cjControlSettings[i].range.zRange.InverseScale(target.z);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float GetRootHeightFromGround()
|
||||
{
|
||||
int layerMask = 1 << 3;
|
||||
layerMask = ~layerMask;
|
||||
|
@ -54,18 +96,18 @@ public class WalkerASEAgent : Agent
|
|||
return raycastHit.distance;
|
||||
}
|
||||
|
||||
public float GetRootBalance()
|
||||
float GetRootBalance()
|
||||
{
|
||||
var agentUp = root.transform.TransformDirection(Vector3.up);
|
||||
return Vector3.Dot(agentUp, Vector3.up);
|
||||
}
|
||||
|
||||
public Vector3 GetVelocity()
|
||||
Vector3 GetVelocity()
|
||||
{
|
||||
return rootRB.velocity;
|
||||
}
|
||||
|
||||
public Vector3 GetAngularVelocity()
|
||||
Vector3 GetAngularVelocity()
|
||||
{
|
||||
return rootRB.angularVelocity;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче