fileFormatVersion: 2 | |||||
guid: 8cbcc68bb8cc7e649b1f5bf601d24fec | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
%YAML 1.1 | |||||
%TAG !u! tag:unity3d.com,2011: | |||||
--- !u!114 &11400000 | |||||
MonoBehaviour: | |||||
m_ObjectHideFlags: 0 | |||||
m_CorrespondingSourceObject: {fileID: 0} | |||||
m_PrefabInstance: {fileID: 0} | |||||
m_PrefabAsset: {fileID: 0} | |||||
m_GameObject: {fileID: 0} | |||||
m_Enabled: 1 | |||||
m_EditorHideFlags: 0 | |||||
m_Script: {fileID: 11500000, guid: 8b23992c8eb17439887f5e944bf04a40, type: 3} | |||||
m_Name: CozmoLearning | |||||
m_EditorClassIdentifier: | |||||
brainParameters: | |||||
vectorObservationSize: 0 | |||||
numStackedVectorObservations: 1 | |||||
vectorActionSize: 01000000 | |||||
cameraResolutions: | |||||
- width: 84 | |||||
height: 84 | |||||
blackAndWhite: 1 | |||||
vectorActionDescriptions: | |||||
- | |||||
vectorActionSpaceType: 0 | |||||
model: {fileID: 0} | |||||
inferenceDevice: 0 |
fileFormatVersion: 2 | |||||
guid: 94e62c225e4fe8148a7543c5fd1acfd4 | |||||
NativeFormatImporter: | |||||
externalObjects: {} | |||||
mainObjectFileID: 11400000 | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: c5dd104aa5d6bff4d972bb36ad0340ab | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: 64f5b1a0bb6688d498ff44bbae7b57a5 | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using UnityEngine; | |||||
using System.Collections; | |||||
public class CurvedLinePoint : MonoBehaviour | |||||
{ | |||||
[HideInInspector] public bool showGizmo = true; | |||||
[HideInInspector] public float gizmoSize = 0.1f; | |||||
[HideInInspector] public Color gizmoColor = new Color(1,0,0,0.5f); | |||||
void OnDrawGizmos() | |||||
{ | |||||
if( showGizmo == true ) | |||||
{ | |||||
Gizmos.color = gizmoColor; | |||||
Gizmos.DrawSphere( this.transform.position, gizmoSize ); | |||||
} | |||||
} | |||||
//update parent line when this point moved | |||||
void OnDrawGizmosSelected() | |||||
{ | |||||
CurvedLineRenderer curvedLine = this.transform.parent.GetComponent<CurvedLineRenderer>(); | |||||
if( curvedLine != null ) | |||||
{ | |||||
curvedLine.Update(); | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: 4efb4faa31cad924994c5bc6ba7329d7 | |||||
timeCreated: 1457753586 | |||||
licenseType: Free | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using UnityEngine; | |||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
[RequireComponent( typeof(LineRenderer) )] | |||||
public class CurvedLineRenderer : MonoBehaviour | |||||
{ | |||||
//PUBLIC | |||||
public float lineSegmentSize = 0.15f; | |||||
public float lineWidth = 0.1f; | |||||
[Header("Gizmos")] | |||||
public bool showGizmos = true; | |||||
public float gizmoSize = 0.1f; | |||||
public Color gizmoColor = new Color(1,0,0,0.5f); | |||||
//PRIVATE | |||||
private CurvedLinePoint[] linePoints = new CurvedLinePoint[0]; | |||||
private Vector3[] linePositions = new Vector3[0]; | |||||
private Vector3[] linePositionsOld = new Vector3[0]; | |||||
// Update is called once per frame | |||||
public void Update () | |||||
{ | |||||
GetPoints(); | |||||
SetPointsToLine(); | |||||
} | |||||
void GetPoints() | |||||
{ | |||||
//find curved points in children | |||||
linePoints = this.GetComponentsInChildren<CurvedLinePoint>(); | |||||
//add positions | |||||
linePositions = new Vector3[linePoints.Length]; | |||||
for( int i = 0; i < linePoints.Length; i++ ) | |||||
{ | |||||
linePositions[i] = linePoints[i].transform.position; | |||||
} | |||||
} | |||||
void SetPointsToLine() | |||||
{ | |||||
//create old positions if they dont match | |||||
if( linePositionsOld.Length != linePositions.Length ) | |||||
{ | |||||
linePositionsOld = new Vector3[linePositions.Length]; | |||||
} | |||||
//check if line points have moved | |||||
bool moved = false; | |||||
for( int i = 0; i < linePositions.Length; i++ ) | |||||
{ | |||||
//compare | |||||
if( linePositions[i] != linePositionsOld[i] ) | |||||
{ | |||||
moved = true; | |||||
} | |||||
} | |||||
//update if moved | |||||
if( moved == true ) | |||||
{ | |||||
LineRenderer line = this.GetComponent<LineRenderer>(); | |||||
//get smoothed values | |||||
Vector3[] smoothedPoints = LineSmoother.SmoothLine( linePositions, lineSegmentSize ); | |||||
//set line settings | |||||
line.SetVertexCount( smoothedPoints.Length ); | |||||
line.SetPositions( smoothedPoints ); | |||||
line.SetWidth( lineWidth, lineWidth ); | |||||
} | |||||
} | |||||
void OnDrawGizmosSelected() | |||||
{ | |||||
Update(); | |||||
} | |||||
void OnDrawGizmos() | |||||
{ | |||||
if( linePoints.Length == 0 ) | |||||
{ | |||||
GetPoints(); | |||||
} | |||||
//settings for gizmos | |||||
foreach( CurvedLinePoint linePoint in linePoints ) | |||||
{ | |||||
linePoint.showGizmo = showGizmos; | |||||
linePoint.gizmoSize = gizmoSize; | |||||
linePoint.gizmoColor = gizmoColor; | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: f886d860c5994de44bda0d51d3182bee | |||||
timeCreated: 1457752249 | |||||
licenseType: Free | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: ac901715280af9641bef97a88e0a3522 | |||||
timeCreated: 1457750910 | |||||
licenseType: Free | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: ba19bde9a20962f488a50be7f354bc2e | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: 7910d69941406d04294f7eb428513ad0 | |||||
timeCreated: 1457754790 | |||||
licenseType: Free | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: c1b4e62fb04f0734d84710b9fbdd8c85 | |||||
timeCreated: 1457756473 | |||||
licenseType: Free | |||||
NativeFormatImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: 7dc1ce4b31c63e34da34775dd888c0dc | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: 239a923e346c7564eab507004b9293df | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: 48abdf8d850ee0b4890625559ec6f520 | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: fbee1fddc738f410ea0b37fe6301d7c0 | |||||
TextureImporter: | |||||
fileIDToRecycleName: {} | |||||
externalObjects: {} | |||||
serializedVersion: 4 | |||||
mipmaps: | |||||
mipMapMode: 0 | |||||
enableMipMap: 1 | |||||
sRGBTexture: 1 | |||||
linearTexture: 0 | |||||
fadeOut: 0 | |||||
borderMipMap: 0 | |||||
mipMapsPreserveCoverage: 0 | |||||
alphaTestReferenceValue: 0.5 | |||||
mipMapFadeDistanceStart: 1 | |||||
mipMapFadeDistanceEnd: 3 | |||||
bumpmap: | |||||
convertToNormalMap: 0 | |||||
externalNormalMap: 0 | |||||
heightScale: 0.25 | |||||
normalMapFilter: 0 | |||||
isReadable: 0 | |||||
grayScaleToAlpha: 0 | |||||
generateCubemap: 6 | |||||
cubemapConvolution: 0 | |||||
seamlessCubemap: 0 | |||||
textureFormat: 1 | |||||
maxTextureSize: 2048 | |||||
textureSettings: | |||||
serializedVersion: 2 | |||||
filterMode: -1 | |||||
aniso: -1 | |||||
mipBias: -1 | |||||
wrapU: -1 | |||||
wrapV: -1 | |||||
wrapW: -1 | |||||
nPOTScale: 1 | |||||
lightmap: 0 | |||||
compressionQuality: 50 | |||||
spriteMode: 0 | |||||
spriteExtrude: 1 | |||||
spriteMeshType: 1 | |||||
alignment: 0 | |||||
spritePivot: {x: 0.5, y: 0.5} | |||||
spritePixelsToUnits: 100 | |||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||||
spriteGenerateFallbackPhysicsShape: 1 | |||||
alphaUsage: 1 | |||||
alphaIsTransparency: 0 | |||||
spriteTessellationDetail: -1 | |||||
textureType: 0 | |||||
textureShape: 1 | |||||
maxTextureSizeSet: 0 | |||||
compressionQualitySet: 0 | |||||
textureFormatSet: 0 | |||||
platformSettings: | |||||
- buildTarget: DefaultTexturePlatform | |||||
maxTextureSize: 2048 | |||||
resizeAlgorithm: 0 | |||||
textureFormat: -1 | |||||
textureCompression: 1 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
androidETC2FallbackOverride: 0 | |||||
spriteSheet: | |||||
serializedVersion: 2 | |||||
sprites: [] | |||||
outline: [] | |||||
physicsShape: [] | |||||
spritePackingTag: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: aff60a06d6c704801a2d09a8e72cbefc | |||||
TextureImporter: | |||||
fileIDToRecycleName: {} | |||||
externalObjects: {} | |||||
serializedVersion: 4 | |||||
mipmaps: | |||||
mipMapMode: 0 | |||||
enableMipMap: 1 | |||||
sRGBTexture: 1 | |||||
linearTexture: 0 | |||||
fadeOut: 0 | |||||
borderMipMap: 0 | |||||
mipMapsPreserveCoverage: 0 | |||||
alphaTestReferenceValue: 0.5 | |||||
mipMapFadeDistanceStart: 1 | |||||
mipMapFadeDistanceEnd: 3 | |||||
bumpmap: | |||||
convertToNormalMap: 0 | |||||
externalNormalMap: 0 | |||||
heightScale: 0.25 | |||||
normalMapFilter: 0 | |||||
isReadable: 0 | |||||
grayScaleToAlpha: 0 | |||||
generateCubemap: 6 | |||||
cubemapConvolution: 0 | |||||
seamlessCubemap: 0 | |||||
textureFormat: 1 | |||||
maxTextureSize: 2048 | |||||
textureSettings: | |||||
serializedVersion: 2 | |||||
filterMode: -1 | |||||
aniso: -1 | |||||
mipBias: -1 | |||||
wrapU: -1 | |||||
wrapV: -1 | |||||
wrapW: -1 | |||||
nPOTScale: 1 | |||||
lightmap: 0 | |||||
compressionQuality: 50 | |||||
spriteMode: 0 | |||||
spriteExtrude: 1 | |||||
spriteMeshType: 1 | |||||
alignment: 0 | |||||
spritePivot: {x: 0.5, y: 0.5} | |||||
spritePixelsToUnits: 100 | |||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||||
spriteGenerateFallbackPhysicsShape: 1 | |||||
alphaUsage: 1 | |||||
alphaIsTransparency: 0 | |||||
spriteTessellationDetail: -1 | |||||
textureType: 0 | |||||
textureShape: 1 | |||||
maxTextureSizeSet: 0 | |||||
compressionQualitySet: 0 | |||||
textureFormatSet: 0 | |||||
platformSettings: | |||||
- buildTarget: DefaultTexturePlatform | |||||
maxTextureSize: 2048 | |||||
resizeAlgorithm: 0 | |||||
textureFormat: -1 | |||||
textureCompression: 1 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
androidETC2FallbackOverride: 0 | |||||
spriteSheet: | |||||
serializedVersion: 2 | |||||
sprites: [] | |||||
outline: [] | |||||
physicsShape: [] | |||||
spritePackingTag: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: 224cd0666bb7b4477b0806fd29cf5966 | |||||
TextureImporter: | |||||
fileIDToRecycleName: {} | |||||
externalObjects: {} | |||||
serializedVersion: 4 | |||||
mipmaps: | |||||
mipMapMode: 0 | |||||
enableMipMap: 1 | |||||
sRGBTexture: 1 | |||||
linearTexture: 0 | |||||
fadeOut: 0 | |||||
borderMipMap: 0 | |||||
mipMapsPreserveCoverage: 0 | |||||
alphaTestReferenceValue: 0.5 | |||||
mipMapFadeDistanceStart: 1 | |||||
mipMapFadeDistanceEnd: 3 | |||||
bumpmap: | |||||
convertToNormalMap: 0 | |||||
externalNormalMap: 0 | |||||
heightScale: 0.25 | |||||
normalMapFilter: 0 | |||||
isReadable: 0 | |||||
grayScaleToAlpha: 0 | |||||
generateCubemap: 6 | |||||
cubemapConvolution: 0 | |||||
seamlessCubemap: 0 | |||||
textureFormat: 1 | |||||
maxTextureSize: 2048 | |||||
textureSettings: | |||||
serializedVersion: 2 | |||||
filterMode: -1 | |||||
aniso: -1 | |||||
mipBias: -1 | |||||
wrapU: -1 | |||||
wrapV: -1 | |||||
wrapW: -1 | |||||
nPOTScale: 1 | |||||
lightmap: 0 | |||||
compressionQuality: 50 | |||||
spriteMode: 0 | |||||
spriteExtrude: 1 | |||||
spriteMeshType: 1 | |||||
alignment: 0 | |||||
spritePivot: {x: 0.5, y: 0.5} | |||||
spritePixelsToUnits: 100 | |||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||||
spriteGenerateFallbackPhysicsShape: 1 | |||||
alphaUsage: 1 | |||||
alphaIsTransparency: 0 | |||||
spriteTessellationDetail: -1 | |||||
textureType: 0 | |||||
textureShape: 1 | |||||
maxTextureSizeSet: 0 | |||||
compressionQualitySet: 0 | |||||
textureFormatSet: 0 | |||||
platformSettings: | |||||
- buildTarget: DefaultTexturePlatform | |||||
maxTextureSize: 2048 | |||||
resizeAlgorithm: 0 | |||||
textureFormat: -1 | |||||
textureCompression: 1 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
androidETC2FallbackOverride: 0 | |||||
spriteSheet: | |||||
serializedVersion: 2 | |||||
sprites: [] | |||||
outline: [] | |||||
physicsShape: [] | |||||
spritePackingTag: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: 11630fa83cc8b4194b94352e3e6cdb9d | |||||
folderAsset: yes | |||||
timeCreated: 1504127524 | |||||
licenseType: Pro | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: 67b4fb0b937cc471eae742addf6bda86 | |||||
folderAsset: yes | |||||
timeCreated: 1503177274 | |||||
licenseType: Free | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using UnityEngine; | |||||
using UnityEditor; | |||||
namespace MLAgents | |||||
{ | |||||
/* | |||||
This code is meant to modify the behavior of the inspector on Brain Components. | |||||
Depending on the type of brain that is used, the available fields will be modified in the inspector accordingly. | |||||
*/ | |||||
[CustomEditor(typeof(Agent), true)] | |||||
[CanEditMultipleObjects] | |||||
public class AgentEditor : Editor | |||||
{ | |||||
public override void OnInspectorGUI() | |||||
{ | |||||
SerializedObject serializedAgent = serializedObject; | |||||
serializedAgent.Update(); | |||||
SerializedProperty brain = serializedAgent.FindProperty("brain"); | |||||
SerializedProperty actionsPerDecision = serializedAgent.FindProperty( | |||||
"agentParameters.numberOfActionsBetweenDecisions"); | |||||
SerializedProperty maxSteps = serializedAgent.FindProperty( | |||||
"agentParameters.maxStep"); | |||||
SerializedProperty isResetOnDone = serializedAgent.FindProperty( | |||||
"agentParameters.resetOnDone"); | |||||
SerializedProperty isODD = serializedAgent.FindProperty( | |||||
"agentParameters.onDemandDecision"); | |||||
SerializedProperty cameras = serializedAgent.FindProperty( | |||||
"agentParameters.agentCameras"); | |||||
EditorGUILayout.PropertyField(brain); | |||||
EditorGUILayout.LabelField("Agent Cameras"); | |||||
for (int i = 0; i < cameras.arraySize; i++) | |||||
{ | |||||
EditorGUILayout.PropertyField( | |||||
cameras.GetArrayElementAtIndex(i), | |||||
new GUIContent("Camera " + (i + 1).ToString() + ": ")); | |||||
} | |||||
EditorGUILayout.BeginHorizontal(); | |||||
if (GUILayout.Button("Add Camera", EditorStyles.miniButton)) | |||||
{ | |||||
cameras.arraySize++; | |||||
} | |||||
if (GUILayout.Button("Remove Camera", EditorStyles.miniButton)) | |||||
{ | |||||
cameras.arraySize--; | |||||
} | |||||
EditorGUILayout.EndHorizontal(); | |||||
EditorGUILayout.PropertyField( | |||||
maxSteps, | |||||
new GUIContent( | |||||
"Max Step", "The per-agent maximum number of steps.")); | |||||
EditorGUILayout.PropertyField( | |||||
isResetOnDone, | |||||
new GUIContent( | |||||
"Reset On Done", | |||||
"If checked, the agent will reset on done. Else, AgentOnDone() will be called.")); | |||||
EditorGUILayout.PropertyField( | |||||
isODD, | |||||
new GUIContent( | |||||
"On Demand Decisions", | |||||
"If checked, you must manually request decisions.")); | |||||
if (!isODD.boolValue) | |||||
{ | |||||
EditorGUILayout.PropertyField( | |||||
actionsPerDecision, | |||||
new GUIContent( | |||||
"Decision Interval", | |||||
"The agent will automatically request a decision every X" + | |||||
" steps and perform an action at every step.")); | |||||
actionsPerDecision.intValue = Mathf.Max(1, actionsPerDecision.intValue); | |||||
} | |||||
serializedAgent.ApplyModifiedProperties(); | |||||
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); | |||||
base.OnInspectorGUI(); | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: c3b291e1cd0c64781861652b579d0ac1 | |||||
timeCreated: 1503270350 | |||||
licenseType: Free | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using UnityEngine; | |||||
using UnityEditor; | |||||
namespace MLAgents | |||||
{ | |||||
/// <summary> | |||||
/// CustomEditor for the Brain base class. Defines the default Inspector view for a Brain. | |||||
/// Shows the BrainParameters of the Brain and expose a tool to deep copy BrainParameters | |||||
/// between brains. | |||||
/// </summary> | |||||
[CustomEditor(typeof(Brain))] | |||||
public class BrainEditor : Editor | |||||
{ | |||||
public override void OnInspectorGUI() | |||||
{ | |||||
var brain = (Brain) target; | |||||
var brainToCopy = EditorGUILayout.ObjectField( | |||||
"Copy Brain Parameters from : ", null, typeof(Brain), false) as Brain; | |||||
if (brainToCopy != null) | |||||
{ | |||||
brain.brainParameters = brainToCopy.brainParameters.Clone(); | |||||
EditorUtility.SetDirty(brain); | |||||
AssetDatabase.SaveAssets(); | |||||
return; | |||||
} | |||||
var serializedBrain = serializedObject; | |||||
serializedBrain.Update(); | |||||
EditorGUILayout.PropertyField(serializedBrain.FindProperty("brainParameters"), true); | |||||
serializedBrain.ApplyModifiedProperties(); | |||||
// Draws a horizontal thick line | |||||
EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: 7b07bebd03994ed08559c725da882b62 | |||||
timeCreated: 1537834304 |
using UnityEngine; | |||||
using UnityEditor; | |||||
namespace MLAgents | |||||
{ | |||||
/// <summary> | |||||
/// PropertyDrawer for BrainParameters. Defines how BrainParameters are displayed in the | |||||
/// Inspector. | |||||
/// </summary> | |||||
[CustomPropertyDrawer(typeof(BrainParameters))] | |||||
public class BrainParametersDrawer : PropertyDrawer | |||||
{ | |||||
// The height of a line in the Unity Inspectors | |||||
private const float LineHeight = 17f; | |||||
private const int VecObsNumLine = 3; | |||||
private const string CamResPropName = "cameraResolutions"; | |||||
private const string ActionSizePropName = "vectorActionSize"; | |||||
private const string ActionTypePropName = "vectorActionSpaceType"; | |||||
private const string ActionDescriptionPropName = "vectorActionDescriptions"; | |||||
private const string VecObsPropName = "vectorObservationSize"; | |||||
private const string NumVecObsPropName ="numStackedVectorObservations"; | |||||
private const string CamWidthPropName = "width"; | |||||
private const string CamHeightPropName = "height"; | |||||
private const string CamGrayPropName = "blackAndWhite"; | |||||
private const int DefaultCameraWidth = 84; | |||||
private const int DefaultCameraHeight = 84; | |||||
private const bool DefaultCameraGray = false; | |||||
/// <inheritdoc /> | |||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) | |||||
{ | |||||
if (property.isExpanded) | |||||
{ | |||||
return LineHeight + | |||||
GetHeightDrawVectorObservation() + | |||||
GetHeightDrawVisualObservation(property) + | |||||
GetHeightDrawVectorAction(property) + | |||||
GetHeightDrawVectorActionDescriptions(property); | |||||
} | |||||
return LineHeight; | |||||
} | |||||
/// <inheritdoc /> | |||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | |||||
{ | |||||
var indent = EditorGUI.indentLevel; | |||||
EditorGUI.indentLevel = 0; | |||||
position.height = LineHeight; | |||||
property.isExpanded = EditorGUI.Foldout(position, property.isExpanded, label); | |||||
position.y += LineHeight; | |||||
if (property.isExpanded) | |||||
{ | |||||
EditorGUI.BeginProperty(position, label, property); | |||||
EditorGUI.indentLevel++; | |||||
// Vector Observations | |||||
DrawVectorObservation(position, property); | |||||
position.y += GetHeightDrawVectorObservation(); | |||||
//Visual Observations | |||||
DrawVisualObservations(position, property); | |||||
position.y += GetHeightDrawVisualObservation(property); | |||||
// Vector Action | |||||
DrawVectorAction(position, property); | |||||
position.y += GetHeightDrawVectorAction(property); | |||||
// Vector Action Descriptions | |||||
DrawVectorActionDescriptions(position, property); | |||||
position.y += GetHeightDrawVectorActionDescriptions(property); | |||||
EditorGUI.EndProperty(); | |||||
} | |||||
EditorGUI.indentLevel = indent; | |||||
} | |||||
/// <summary> | |||||
/// Draws the Vector Observations for the Brain Parameters | |||||
/// </summary> | |||||
/// <param name="position">Rectangle on the screen to use for the property GUI.</param> | |||||
/// <param name="property">The SerializedProperty of the BrainParameters | |||||
/// to make the custom GUI for.</param> | |||||
private static void DrawVectorObservation(Rect position, SerializedProperty property) | |||||
{ | |||||
EditorGUI.LabelField(position, "Vector Observation"); | |||||
position.y += LineHeight; | |||||
EditorGUI.indentLevel++; | |||||
EditorGUI.PropertyField(position, | |||||
property.FindPropertyRelative(VecObsPropName), | |||||
new GUIContent("Space Size", | |||||
"Length of state " + | |||||
"vector for brain (In Continuous state space)." + | |||||
"Or number of possible values (in Discrete state space).")); | |||||
position.y += LineHeight; | |||||
EditorGUI.PropertyField(position, | |||||
property.FindPropertyRelative(NumVecObsPropName), | |||||
new GUIContent("Stacked Vectors", | |||||
"Number of states that will be stacked before " + | |||||
"beeing fed to the neural network.")); | |||||
position.y += LineHeight; | |||||
EditorGUI.indentLevel--; | |||||
} | |||||
/// <summary> | |||||
/// The Height required to draw the Vector Observations paramaters | |||||
/// </summary> | |||||
/// <returns>The height of the drawer of the Vector Observations </returns> | |||||
private static float GetHeightDrawVectorObservation() | |||||
{ | |||||
return VecObsNumLine * LineHeight; | |||||
} | |||||
/// <summary> | |||||
/// Draws the Visual Observations parameters for the Brain Parameters | |||||
/// </summary> | |||||
/// <param name="position">Rectangle on the screen to use for the property GUI.</param> | |||||
/// <param name="property">The SerializedProperty of the BrainParameters | |||||
/// to make the custom GUI for.</param> | |||||
private static void DrawVisualObservations(Rect position, SerializedProperty property) | |||||
{ | |||||
EditorGUI.LabelField(position, "Visual Observations"); | |||||
position.y += LineHeight; | |||||
var quarter = position.width / 4; | |||||
var resolutions = property.FindPropertyRelative(CamResPropName); | |||||
DrawVisualObsButtons(position, resolutions); | |||||
position.y += LineHeight; | |||||
// Display the labels for the columns : Index, Width, Height and Gray | |||||
var indexRect = new Rect(position.x, position.y, quarter, position.height); | |||||
var widthRect = new Rect(position.x + quarter, position.y, quarter, position.height); | |||||
var heightRect = new Rect(position.x + 2*quarter, position.y, quarter, position.height); | |||||
var bwRect = new Rect(position.x + 3*quarter, position.y, quarter, position.height); | |||||
EditorGUI.indentLevel++; | |||||
if (resolutions.arraySize > 0) | |||||
{ | |||||
EditorGUI.LabelField(indexRect, "Index"); | |||||
indexRect.y += LineHeight; | |||||
EditorGUI.LabelField(widthRect, "Width"); | |||||
widthRect.y += LineHeight; | |||||
EditorGUI.LabelField(heightRect, "Height"); | |||||
heightRect.y += LineHeight; | |||||
EditorGUI.LabelField(bwRect, "Gray"); | |||||
bwRect.y += LineHeight; | |||||
} | |||||
// Iterate over the resolutions | |||||
for (var i = 0; i < resolutions.arraySize; i++) | |||||
{ | |||||
EditorGUI.LabelField(indexRect, "Obs " + i); | |||||
indexRect.y += LineHeight; | |||||
var res = resolutions.GetArrayElementAtIndex(i); | |||||
var w = res.FindPropertyRelative("width"); | |||||
w.intValue = EditorGUI.IntField(widthRect, w.intValue); | |||||
widthRect.y += LineHeight; | |||||
var h = res.FindPropertyRelative("height"); | |||||
h.intValue = EditorGUI.IntField(heightRect, h.intValue); | |||||
heightRect.y += LineHeight; | |||||
var bw = res.FindPropertyRelative("blackAndWhite"); | |||||
bw.boolValue = EditorGUI.Toggle(bwRect, bw.boolValue); | |||||
bwRect.y += LineHeight; | |||||
} | |||||
EditorGUI.indentLevel--; | |||||
} | |||||
/// <summary> | |||||
/// Draws the buttons to add and remove the visual observations parameters | |||||
/// </summary> | |||||
/// <param name="position">Rectangle on the screen to use for the property GUI.</param> | |||||
/// <param name="resolutions">The SerializedProperty of the resolution array | |||||
/// to make the custom GUI for.</param> | |||||
private static void DrawVisualObsButtons(Rect position, SerializedProperty resolutions) | |||||
{ | |||||
var widthEighth = position.width / 8; | |||||
var addButtonRect = new Rect(position.x + widthEighth, position.y, | |||||
3 * widthEighth, position.height); | |||||
var removeButtonRect = new Rect(position.x + 4 * widthEighth, position.y, | |||||
3 * widthEighth, position.height); | |||||
if (resolutions.arraySize == 0) | |||||
{ | |||||
addButtonRect.width *= 2; | |||||
} | |||||
// Display the buttons | |||||
if (GUI.Button(addButtonRect, "Add New", EditorStyles.miniButton)) | |||||
{ | |||||
resolutions.arraySize += 1; | |||||
var newRes = resolutions.GetArrayElementAtIndex(resolutions.arraySize - 1); | |||||
newRes.FindPropertyRelative(CamWidthPropName).intValue = DefaultCameraWidth; | |||||
newRes.FindPropertyRelative(CamHeightPropName).intValue = DefaultCameraHeight; | |||||
newRes.FindPropertyRelative(CamGrayPropName).boolValue = DefaultCameraGray; | |||||
} | |||||
if (resolutions.arraySize > 0) | |||||
{ | |||||
if (GUI.Button(removeButtonRect, "Remove Last", EditorStyles.miniButton)) | |||||
{ | |||||
resolutions.arraySize -= 1; | |||||
} | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// The Height required to draw the Visual Observations parameters | |||||
/// </summary> | |||||
/// <returns>The height of the drawer of the Visual Observations </returns> | |||||
private static float GetHeightDrawVisualObservation(SerializedProperty property) | |||||
{ | |||||
var visObsSize = property.FindPropertyRelative(CamResPropName).arraySize + 2; | |||||
if (property.FindPropertyRelative(CamResPropName).arraySize > 0) | |||||
{ | |||||
visObsSize += 1; | |||||
} | |||||
return LineHeight * visObsSize; | |||||
} | |||||
/// <summary> | |||||
/// Draws the Vector Actions parameters for the Brain Parameters | |||||
/// </summary> | |||||
/// <param name="position">Rectangle on the screen to use for the property GUI.</param> | |||||
/// <param name="property">The SerializedProperty of the BrainParameters | |||||
/// to make the custom GUI for.</param> | |||||
private static void DrawVectorAction(Rect position, SerializedProperty property) | |||||
{ | |||||
EditorGUI.LabelField(position, "Vector Action"); | |||||
position.y += LineHeight; | |||||
EditorGUI.indentLevel++; | |||||
var bpVectorActionType = property.FindPropertyRelative(ActionTypePropName); | |||||
EditorGUI.PropertyField( | |||||
position, | |||||
bpVectorActionType, | |||||
new GUIContent("Space Type", | |||||
"Corresponds to whether state vector contains a single integer (Discrete) " + | |||||
"or a series of real-valued floats (Continuous).")); | |||||
position.y += LineHeight; | |||||
if (bpVectorActionType.enumValueIndex == 1) | |||||
{ | |||||
DrawContinuousVectorAction(position, property); | |||||
} | |||||
else | |||||
{ | |||||
DrawDiscreteVectorAction(position, property); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Draws the Continuous Vector Actions parameters for the Brain Parameters | |||||
/// </summary> | |||||
/// <param name="position">Rectangle on the screen to use for the property GUI.</param> | |||||
/// <param name="property">The SerializedProperty of the BrainParameters | |||||
/// to make the custom GUI for.</param> | |||||
private static void DrawContinuousVectorAction(Rect position, SerializedProperty property) | |||||
{ | |||||
var vecActionSize = property.FindPropertyRelative(ActionSizePropName); | |||||
vecActionSize.arraySize = 1; | |||||
SerializedProperty continuousActionSize = | |||||
vecActionSize.GetArrayElementAtIndex(0); | |||||
EditorGUI.PropertyField( | |||||
position, | |||||
continuousActionSize, | |||||
new GUIContent("Space Size", "Length of continuous action vector.")); | |||||
} | |||||
/// <summary> | |||||
/// Draws the Discrete Vector Actions parameters for the Brain Parameters | |||||
/// </summary> | |||||
/// <param name="position">Rectangle on the screen to use for the property GUI.</param> | |||||
/// <param name="property">The SerializedProperty of the BrainParameters | |||||
/// to make the custom GUI for.</param> | |||||
private static void DrawDiscreteVectorAction(Rect position, SerializedProperty property) | |||||
{ | |||||
var vecActionSize = property.FindPropertyRelative(ActionSizePropName); | |||||
vecActionSize.arraySize = EditorGUI.IntField( | |||||
position, "Branches Size", vecActionSize.arraySize); | |||||
position.y += LineHeight; | |||||
position.x += 20; | |||||
position.width -= 20; | |||||
for (var branchIndex = 0; | |||||
branchIndex < vecActionSize.arraySize; | |||||
branchIndex++) | |||||
{ | |||||
SerializedProperty branchActionSize = | |||||
vecActionSize.GetArrayElementAtIndex(branchIndex); | |||||
EditorGUI.PropertyField( | |||||
position, | |||||
branchActionSize, | |||||
new GUIContent("Branch " + branchIndex + " Size", | |||||
"Number of possible actions for the branch number " + branchIndex + ".")); | |||||
position.y += LineHeight; | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// The Height required to draw the Vector Action parameters | |||||
/// </summary> | |||||
/// <returns>The height of the drawer of the Vector Action </returns> | |||||
private static float GetHeightDrawVectorAction(SerializedProperty property) | |||||
{ | |||||
var actionSize = 2 + property.FindPropertyRelative(ActionSizePropName).arraySize; | |||||
if (property.FindPropertyRelative(ActionTypePropName).enumValueIndex == 0) | |||||
{ | |||||
actionSize += 1; | |||||
} | |||||
return actionSize * LineHeight; | |||||
} | |||||
/// <summary> | |||||
/// Draws the Vector Actions descriptions for the Brain Parameters | |||||
/// </summary> | |||||
/// <param name="position">Rectangle on the screen to use for the property GUI.</param> | |||||
/// <param name="property">The SerializedProperty of the BrainParameters | |||||
/// to make the custom GUI for.</param> | |||||
private static void DrawVectorActionDescriptions(Rect position, SerializedProperty property) | |||||
{ | |||||
var bpVectorActionType = property.FindPropertyRelative(ActionTypePropName); | |||||
var vecActionSize = property.FindPropertyRelative(ActionSizePropName); | |||||
var numberOfDescriptions = 0; | |||||
if (bpVectorActionType.enumValueIndex == 1) | |||||
{ | |||||
numberOfDescriptions = vecActionSize.GetArrayElementAtIndex(0).intValue; | |||||
} | |||||
else | |||||
{ | |||||
numberOfDescriptions = vecActionSize.arraySize; | |||||
} | |||||
EditorGUI.indentLevel++; | |||||
var vecActionDescriptions = | |||||
property.FindPropertyRelative(ActionDescriptionPropName); | |||||
vecActionDescriptions.arraySize = numberOfDescriptions; | |||||
if (bpVectorActionType.enumValueIndex == 1) | |||||
{ | |||||
//Continuous case : | |||||
EditorGUI.PropertyField( | |||||
position, | |||||
vecActionDescriptions, | |||||
new GUIContent("Action Descriptions", | |||||
"A list of strings used to name the available actionsm for the Brain."), | |||||
true); | |||||
position.y += LineHeight; | |||||
} | |||||
else | |||||
{ | |||||
// Discrete case : | |||||
EditorGUI.PropertyField( | |||||
position, | |||||
vecActionDescriptions, | |||||
new GUIContent("Branch Descriptions", | |||||
"A list of strings used to name the available branches for the Brain."), | |||||
true); | |||||
position.y += LineHeight; | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// The Height required to draw the Action Descriptions | |||||
/// </summary> | |||||
/// <returns>The height of the drawer of the Action Descriptions </returns> | |||||
private static float GetHeightDrawVectorActionDescriptions(SerializedProperty property) | |||||
{ | |||||
var descriptionSize = 1; | |||||
if (property.FindPropertyRelative(ActionDescriptionPropName).isExpanded) | |||||
{ | |||||
var descriptions = property.FindPropertyRelative(ActionDescriptionPropName); | |||||
descriptionSize += descriptions.arraySize + 1; | |||||
} | |||||
return descriptionSize * LineHeight; | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: b060ae8e687cf49bcae88b24db17bfa6 | |||||
timeCreated: 1517291065 | |||||
licenseType: Free | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using UnityEngine; | |||||
using UnityEditor; | |||||
using System; | |||||
using System.Linq; | |||||
using UnityEditor.SceneManagement; | |||||
namespace MLAgents | |||||
{ | |||||
/// <summary> | |||||
/// PropertyDrawer for BroadcastHub. Used to display the BroadcastHub in the Inspector. | |||||
/// </summary> | |||||
[CustomPropertyDrawer(typeof(BroadcastHub))] | |||||
public class BroadcastHubDrawer : PropertyDrawer | |||||
{ | |||||
private BroadcastHub _hub; | |||||
// The height of a line in the Unity Inspectors | |||||
private const float LineHeight = 17f; | |||||
// The vertical space left below the BroadcastHub UI. | |||||
private const float ExtraSpaceBelow = 10f; | |||||
// The horizontal size of the Control checkbox | |||||
private const int ControlSize = 80; | |||||
/// <summary> | |||||
/// Computes the height of the Drawer depending on the property it is showing | |||||
/// </summary> | |||||
/// <param name="property">The property that is being drawn.</param> | |||||
/// <param name="label">The label of the property being drawn.</param> | |||||
/// <returns>The vertical space needed to draw the property.</returns> | |||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) | |||||
{ | |||||
LazyInitializeHub(property, label); | |||||
var numLines = _hub.Count + 2 + (_hub.Count > 0 ? 1 : 0); | |||||
return (numLines) * LineHeight + ExtraSpaceBelow; | |||||
} | |||||
/// <inheritdoc /> | |||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | |||||
{ | |||||
LazyInitializeHub(property, label); | |||||
position.height = LineHeight; | |||||
EditorGUI.LabelField(position, new GUIContent(label.text, | |||||
"The Broadcast Hub helps you define which Brains you want to expose to " + | |||||
"the external process")); | |||||
position.y += LineHeight; | |||||
EditorGUI.BeginProperty(position, label, property); | |||||
EditorGUI.indentLevel++; | |||||
DrawAddRemoveButtons(position); | |||||
position.y += LineHeight; | |||||
// This is the labels for each columns | |||||
var brainWidth = position.width - ControlSize; | |||||
var brainRect = new Rect( | |||||
position.x, position.y, brainWidth, position.height); | |||||
var controlRect = new Rect( | |||||
position.x + brainWidth, position.y, ControlSize, position.height); | |||||
if (_hub.Count > 0) | |||||
{ | |||||
EditorGUI.LabelField(brainRect, "Brains"); | |||||
brainRect.y += LineHeight; | |||||
EditorGUI.LabelField(controlRect, "Control"); | |||||
controlRect.y += LineHeight; | |||||
controlRect.x += 15; | |||||
} | |||||
DrawBrains(brainRect, controlRect); | |||||
EditorGUI.indentLevel--; | |||||
EditorGUI.EndProperty(); | |||||
} | |||||
/// <summary> | |||||
/// Draws the Add and Remove buttons. | |||||
/// </summary> | |||||
/// <param name="position">The position at which to draw.</param> | |||||
private void DrawAddRemoveButtons(Rect position) | |||||
{ | |||||
// This is the rectangle for the Add button | |||||
var addButtonRect = position; | |||||
addButtonRect.x += 20; | |||||
if (_hub.Count > 0) | |||||
{ | |||||
addButtonRect.width /= 2; | |||||
addButtonRect.width -= 24; | |||||
var buttonContent = new GUIContent( | |||||
"Add New", "Add a new Brain to the Broadcast Hub"); | |||||
if (GUI.Button(addButtonRect, buttonContent, EditorStyles.miniButton)) | |||||
{ | |||||
MarkSceneAsDirty(); | |||||
AddBrain(); | |||||
} | |||||
// This is the rectangle for the Remove button | |||||
var removeButtonRect = position; | |||||
removeButtonRect.x = position.width / 2 + 15; | |||||
removeButtonRect.width = addButtonRect.width - 18; | |||||
buttonContent = new GUIContent( | |||||
"Remove Last", "Remove the last Brain from the Broadcast Hub"); | |||||
if (GUI.Button(removeButtonRect, buttonContent, EditorStyles.miniButton)) | |||||
{ | |||||
MarkSceneAsDirty(); | |||||
RemoveLastBrain(); | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
addButtonRect.width -= 50; | |||||
var buttonContent = new GUIContent( | |||||
"Add Brain to Broadcast Hub", "Add a new Brain to the Broadcast Hub"); | |||||
if (GUI.Button(addButtonRect, buttonContent, EditorStyles.miniButton)) | |||||
{ | |||||
MarkSceneAsDirty(); | |||||
AddBrain(); | |||||
} | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Draws the Brain and Control checkbox for the brains contained in the BroadCastHub. | |||||
/// </summary> | |||||
/// <param name="brainRect">The Rect to draw the Brains.</param> | |||||
/// <param name="controlRect">The Rect to draw the control checkbox.</param> | |||||
private void DrawBrains(Rect brainRect, Rect controlRect) | |||||
{ | |||||
for (var index = 0; index < _hub.Count; index++) | |||||
{ | |||||
var exposedBrains = _hub.broadcastingBrains; | |||||
var brain = exposedBrains[index]; | |||||
// This is the rectangle for the brain | |||||
EditorGUI.BeginChangeCheck(); | |||||
var newBrain = EditorGUI.ObjectField( | |||||
brainRect, brain, typeof(Brain), true) as Brain; | |||||
brainRect.y += LineHeight; | |||||
if (EditorGUI.EndChangeCheck()) | |||||
{ | |||||
MarkSceneAsDirty(); | |||||
_hub.broadcastingBrains.RemoveAt(index); | |||||
var brainToInsert = exposedBrains.Contains(newBrain) ? null : newBrain; | |||||
exposedBrains.Insert(index, brainToInsert); | |||||
break; | |||||
} | |||||
// This is the Rectangle for the control checkbox | |||||
EditorGUI.BeginChangeCheck(); | |||||
if (brain is LearningBrain) | |||||
{ | |||||
var isTraining = _hub.IsControlled(brain); | |||||
isTraining = EditorGUI.Toggle(controlRect, isTraining); | |||||
_hub.SetControlled(brain, isTraining); | |||||
} | |||||
controlRect.y += LineHeight; | |||||
if (EditorGUI.EndChangeCheck()) | |||||
{ | |||||
MarkSceneAsDirty(); | |||||
} | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Lazy initializes the Drawer with the property to be drawn. | |||||
/// </summary> | |||||
/// <param name="property">The SerializedProperty of the BroadcastHub | |||||
/// to make the custom GUI for.</param> | |||||
/// <param name="label">The label of this property.</param> | |||||
private void LazyInitializeHub(SerializedProperty property, GUIContent label) | |||||
{ | |||||
if (_hub != null) | |||||
{ | |||||
return; | |||||
} | |||||
var target = property.serializedObject.targetObject; | |||||
_hub = fieldInfo.GetValue(target) as BroadcastHub; | |||||
if (_hub == null) | |||||
{ | |||||
_hub = new BroadcastHub(); | |||||
fieldInfo.SetValue(target, _hub); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Signals that the property has been modified and requires the scene to be saved for | |||||
/// the changes to persist. Only works when the Editor is not playing. | |||||
/// </summary> | |||||
private static void MarkSceneAsDirty() | |||||
{ | |||||
if (!EditorApplication.isPlaying) | |||||
{ | |||||
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Removes the last Brain from the BroadcastHub | |||||
/// </summary> | |||||
private void RemoveLastBrain() | |||||
{ | |||||
if (_hub.Count > 0) | |||||
{ | |||||
_hub.broadcastingBrains.RemoveAt(_hub.broadcastingBrains.Count - 1); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Adds a new Brain to the BroadcastHub. The value of this brain will not be initialized. | |||||
/// </summary> | |||||
private void AddBrain() | |||||
{ | |||||
_hub.broadcastingBrains.Add(null); | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: aa1bef9e5833447ab7251fc6f7a3a609 | |||||
timeCreated: 1536852419 |
using System.Text; | |||||
using MLAgents; | |||||
using UnityEditor; | |||||
/// <summary> | |||||
/// Renders a custom UI for Demonstration Scriptable Object. | |||||
/// </summary> | |||||
[CustomEditor(typeof(Demonstration))] | |||||
[CanEditMultipleObjects] | |||||
public class DemonstrationEditor : Editor | |||||
{ | |||||
SerializedProperty brainParameters; | |||||
SerializedProperty demoMetaData; | |||||
void OnEnable() | |||||
{ | |||||
brainParameters = serializedObject.FindProperty("brainParameters"); | |||||
demoMetaData = serializedObject.FindProperty("metaData"); | |||||
} | |||||
/// <summary> | |||||
/// Renders Inspector UI for Demonstration metadata. | |||||
/// </summary> | |||||
void MakeMetaDataProperty(SerializedProperty property) | |||||
{ | |||||
var nameProp = property.FindPropertyRelative("demonstrationName"); | |||||
var expProp = property.FindPropertyRelative("numberExperiences"); | |||||
var epiProp = property.FindPropertyRelative("numberEpisodes"); | |||||
var rewProp = property.FindPropertyRelative("meanReward"); | |||||
var nameLabel = nameProp.displayName + ": " + nameProp.stringValue; | |||||
var expLabel = expProp.displayName + ": " + expProp.intValue; | |||||
var epiLabel = epiProp.displayName + ": " + epiProp.intValue; | |||||
var rewLabel = rewProp.displayName + ": " + rewProp.floatValue; | |||||
EditorGUILayout.LabelField(nameLabel); | |||||
EditorGUILayout.LabelField(expLabel); | |||||
EditorGUILayout.LabelField(epiLabel); | |||||
EditorGUILayout.LabelField(rewLabel); | |||||
} | |||||
/// <summary> | |||||
/// Constructs label for action size array. | |||||
/// </summary> | |||||
static string BuildActionArrayLabel(SerializedProperty actionSizeProperty) | |||||
{ | |||||
var actionSize = actionSizeProperty.arraySize; | |||||
StringBuilder actionLabel = new StringBuilder("[ "); | |||||
for (int i = 0; i < actionSize; i++) | |||||
{ | |||||
actionLabel.Append(actionSizeProperty.GetArrayElementAtIndex(i).intValue); | |||||
if (i < actionSize - 1) | |||||
{ | |||||
actionLabel.Append(", "); | |||||
} | |||||
} | |||||
actionLabel.Append(" ]"); | |||||
return actionLabel.ToString(); | |||||
} | |||||
/// <summary> | |||||
/// Renders Inspector UI for Brain Parameters of Demonstration. | |||||
/// </summary> | |||||
void MakeBrainParametersProperty(SerializedProperty property) | |||||
{ | |||||
var vecObsSizeProp = property.FindPropertyRelative("vectorObservationSize"); | |||||
var numStackedProp = property.FindPropertyRelative("numStackedVectorObservations"); | |||||
var actSizeProperty = property.FindPropertyRelative("vectorActionSize"); | |||||
var camResProp = property.FindPropertyRelative("cameraResolutions"); | |||||
var actSpaceTypeProp = property.FindPropertyRelative("vectorActionSpaceType"); | |||||
var vecObsSizeLabel = vecObsSizeProp.displayName + ": " + vecObsSizeProp.intValue; | |||||
var numStackedLabel = numStackedProp.displayName + ": " + numStackedProp.intValue; | |||||
var vecActSizeLabel = actSizeProperty.displayName + ": " + BuildActionArrayLabel(actSizeProperty); | |||||
var camResLabel = camResProp.displayName + ": " + camResProp.arraySize; | |||||
var actSpaceTypeLabel = actSpaceTypeProp.displayName + ": " + (SpaceType) actSpaceTypeProp.enumValueIndex; | |||||
EditorGUILayout.LabelField(vecObsSizeLabel); | |||||
EditorGUILayout.LabelField(numStackedLabel); | |||||
EditorGUILayout.LabelField(vecActSizeLabel); | |||||
EditorGUILayout.LabelField(camResLabel); | |||||
EditorGUILayout.LabelField(actSpaceTypeLabel); | |||||
} | |||||
public override void OnInspectorGUI() | |||||
{ | |||||
serializedObject.Update(); | |||||
EditorGUILayout.LabelField("Meta Data", EditorStyles.boldLabel); | |||||
MakeMetaDataProperty(demoMetaData); | |||||
EditorGUILayout.LabelField("Brain Parameters", EditorStyles.boldLabel); | |||||
MakeBrainParametersProperty(brainParameters); | |||||
serializedObject.ApplyModifiedProperties(); | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: 84f9cd83f56c74790a51444a6cfe4945 | |||||
MonoImporter: | |||||
externalObjects: {} | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using System; | |||||
using System.IO; | |||||
using MLAgents.CommunicatorObjects; | |||||
using UnityEditor; | |||||
using UnityEngine; | |||||
using UnityEditor.Experimental.AssetImporters; | |||||
namespace MLAgents | |||||
{ | |||||
/// <summary> | |||||
/// Asset Importer used to parse demonstration files. | |||||
/// </summary> | |||||
[ScriptedImporter(1, new[] {"demo"})] | |||||
public class DemonstrationImporter : ScriptedImporter | |||||
{ | |||||
private const string IconPath = "Assets/ML-Agents/Resources/DemoIcon.png"; | |||||
public override void OnImportAsset(AssetImportContext ctx) | |||||
{ | |||||
var inputType = Path.GetExtension(ctx.assetPath); | |||||
if (inputType == null) | |||||
{ | |||||
throw new Exception("Demonstration import error."); | |||||
} | |||||
try | |||||
{ | |||||
// Read first two proto objects containing metadata and brain parameters. | |||||
Stream reader = File.OpenRead(ctx.assetPath); | |||||
var metaDataProto = DemonstrationMetaProto.Parser.ParseDelimitedFrom(reader); | |||||
var metaData = new DemonstrationMetaData(metaDataProto); | |||||
reader.Seek(DemonstrationStore.MetaDataBytes + 1, 0); | |||||
var brainParamsProto = BrainParametersProto.Parser.ParseDelimitedFrom(reader); | |||||
var brainParameters = new BrainParameters(brainParamsProto); | |||||
reader.Close(); | |||||
var demonstration = ScriptableObject.CreateInstance<Demonstration>(); | |||||
demonstration.Initialize(brainParameters, metaData); | |||||
userData = demonstration.ToString(); | |||||
Texture2D texture = (Texture2D) | |||||
AssetDatabase.LoadAssetAtPath(IconPath, typeof(Texture2D)); | |||||
#if UNITY_2017_3_OR_NEWER | |||||
ctx.AddObjectToAsset(ctx.assetPath, demonstration, texture); | |||||
ctx.SetMainObject(demonstration); | |||||
#else | |||||
ctx.SetMainAsset(ctx.assetPath, model); | |||||
#endif | |||||
} | |||||
catch | |||||
{ | |||||
return; | |||||
} | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: 7bd65ce151aaa4a41a45312543c56be1 | |||||
MonoImporter: | |||||
externalObjects: {} | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using UnityEngine; | |||||
using UnityEditor; | |||||
namespace MLAgents | |||||
{ | |||||
/// <summary> | |||||
/// CustomEditor for the Heuristic Brain class. Defines the default Inspector view for a | |||||
/// HeuristicBrain. | |||||
/// Shows the BrainParameters of the Brain and expose a tool to deep copy BrainParameters | |||||
/// between brains. Provides a drag box for a Decision Monoscript that will be used by | |||||
/// the Heuristic Brain. | |||||
/// </summary> | |||||
[CustomEditor(typeof(HeuristicBrain))] | |||||
public class HeuristicBrainEditor : BrainEditor | |||||
{ | |||||
public override void OnInspectorGUI() | |||||
{ | |||||
EditorGUILayout.LabelField("Heuristic Brain", EditorStyles.boldLabel); | |||||
var brain = (HeuristicBrain) target; | |||||
base.OnInspectorGUI(); | |||||
// Expose the Heuristic Brain's Monoscript for decision in a drag and drop box. | |||||
brain.decisionScript = EditorGUILayout.ObjectField( | |||||
"Decision Script", brain.decisionScript, typeof(MonoScript), true) as MonoScript; | |||||
CheckIsDecision(brain); | |||||
// Draw an error box if the Decision is not set. | |||||
if (brain.decisionScript == null) | |||||
{ | |||||
EditorGUILayout.HelpBox("You need to add a 'Decision' component to this Object", | |||||
MessageType.Error); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Ensures tht the Monoscript for the decision of the HeuristicBrain is either null or | |||||
/// an implementation of Decision. If the Monoscript is not an implementation of | |||||
/// Decision, it will be set to null. | |||||
/// </summary> | |||||
/// <param name="brain">The HeuristicBrain with the decision script attached</param> | |||||
private static void CheckIsDecision(HeuristicBrain brain) | |||||
{ | |||||
if (brain.decisionScript != null) | |||||
{ | |||||
var decisionInstance = (CreateInstance(brain.decisionScript.name) as Decision); | |||||
if (decisionInstance == null) | |||||
{ | |||||
Debug.LogError( | |||||
"Instance of " + brain.decisionScript.name + " couldn't be created. " + | |||||
"The the script class needs to derive from Decision."); | |||||
brain.decisionScript = null; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: c3347a9ad704411896dd4898423c6515 | |||||
timeCreated: 1536852553 |
using UnityEngine; | |||||
using UnityEditor; | |||||
namespace MLAgents | |||||
{ | |||||
/// <summary> | |||||
/// CustomEditor for the LearningBrain class. Defines the default Inspector view for a | |||||
/// LearningBrain. | |||||
/// Shows the BrainParameters of the Brain and expose a tool to deep copy BrainParameters | |||||
/// between brains. Also exposes a drag box for the Model that will be used by the | |||||
/// LearningBrain. | |||||
/// </summary> | |||||
[CustomEditor(typeof(LearningBrain))] | |||||
public class LearningBrainEditor : BrainEditor | |||||
{ | |||||
private const string ModelPropName = "model"; | |||||
private const string InferenceDevicePropName = "inferenceDevice"; | |||||
private const float TimeBetweenModelReloads = 2f; | |||||
// Time since the last reload of the model | |||||
private float _timeSinceModelReload; | |||||
// Whether or not the model needs to be reloaded | |||||
private bool _requireReload; | |||||
/// <summary> | |||||
/// Called when the user opens the Inspector for the LearningBrain | |||||
/// </summary> | |||||
public void OnEnable() | |||||
{ | |||||
_requireReload = true; | |||||
EditorApplication.update += IncreaseTimeSinceLastModelReload; | |||||
} | |||||
/// <summary> | |||||
/// Called when the user leaves the Inspector for the LearningBrain | |||||
/// </summary> | |||||
public void OnDisable() | |||||
{ | |||||
EditorApplication.update -= IncreaseTimeSinceLastModelReload; | |||||
} | |||||
public override void OnInspectorGUI() | |||||
{ | |||||
EditorGUILayout.LabelField("Learning Brain", EditorStyles.boldLabel); | |||||
var brain = (LearningBrain) target; | |||||
var serializedBrain = serializedObject; | |||||
EditorGUI.BeginChangeCheck(); | |||||
base.OnInspectorGUI(); | |||||
serializedBrain.Update(); | |||||
var tfGraphModel = serializedBrain.FindProperty(ModelPropName); | |||||
EditorGUILayout.ObjectField(tfGraphModel); | |||||
var inferenceDevice = serializedBrain.FindProperty(InferenceDevicePropName); | |||||
EditorGUILayout.PropertyField(inferenceDevice); | |||||
serializedBrain.ApplyModifiedProperties(); | |||||
if (EditorGUI.EndChangeCheck()) | |||||
{ | |||||
_requireReload = true; | |||||
} | |||||
if (_requireReload && _timeSinceModelReload > TimeBetweenModelReloads) | |||||
{ | |||||
brain.ReloadModel(); | |||||
_requireReload = false; | |||||
_timeSinceModelReload = 0; | |||||
} | |||||
// Display all failed checks | |||||
var failedChecks = brain.GetModelFailedChecks(); | |||||
foreach (var check in failedChecks) | |||||
{ | |||||
if (check != null) | |||||
{ | |||||
EditorGUILayout.HelpBox(check, MessageType.Warning); | |||||
} | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Increases the time since last model reload by the deltaTime since the last Update call | |||||
/// from the UnityEditor | |||||
/// </summary> | |||||
private void IncreaseTimeSinceLastModelReload() | |||||
{ | |||||
_timeSinceModelReload += Time.deltaTime; | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: b538d92cc78b4a62a596822eca31423e | |||||
timeCreated: 1536970736 |
using System.IO; | |||||
using UnityEditor; | |||||
using UnityEngine; | |||||
using UnityEditor.Experimental.AssetImporters; | |||||
using MLAgents.InferenceBrain; | |||||
namespace MLAgents | |||||
{ | |||||
/// <summary> | |||||
/// Asset Importer of barracuda models. | |||||
/// </summary> | |||||
[ScriptedImporter(1, new[] {"nn"})] | |||||
public class NNModelImporter : ScriptedImporter { | |||||
private const string IconPath = "Assets/ML-Agents/Resources/NNModelIcon.png"; | |||||
public override void OnImportAsset(AssetImportContext ctx) | |||||
{ | |||||
var model = File.ReadAllBytes(ctx.assetPath); | |||||
var asset = ScriptableObject.CreateInstance<NNModel>(); | |||||
asset.Value = model; | |||||
Texture2D texture = (Texture2D) | |||||
AssetDatabase.LoadAssetAtPath(IconPath, typeof(Texture2D)); | |||||
ctx.AddObjectToAsset(ctx.assetPath, asset, texture); | |||||
ctx.SetMainObject(asset); | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: 83221ad3db87f4b3b91b041047cb2bc5 | |||||
MonoImporter: | |||||
externalObjects: {} | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using System.Collections; | |||||
using System.Collections.Generic; | |||||
using UnityEngine; | |||||
using UnityEditor; | |||||
using System.Linq; | |||||
namespace MLAgents | |||||
{ | |||||
/// <summary> | |||||
/// CustomEditor for the PlayerBrain class. Defines the default Inspector view for a | |||||
/// PlayerBrain. | |||||
/// Shows the BrainParameters of the Brain and expose a tool to deep copy BrainParameters | |||||
/// between brains. Also exposes the key mappings for either continuous or discrete control | |||||
/// depending on the Vector Action Space Type of the Brain Parameter. These mappings are the | |||||
/// ones that will be used by the PlayerBrain. | |||||
/// </summary> | |||||
[CustomEditor(typeof(PlayerBrain))] | |||||
public class PlayerBrainEditor : BrainEditor | |||||
{ | |||||
private const string KeyContinuousPropName = "keyContinuousPlayerActions"; | |||||
private const string KeyDiscretePropName = "discretePlayerActions"; | |||||
private const string AxisContinuousPropName = "axisContinuousPlayerActions"; | |||||
public override void OnInspectorGUI() | |||||
{ | |||||
EditorGUILayout.LabelField("Player Brain", EditorStyles.boldLabel); | |||||
var brain = (PlayerBrain) target; | |||||
var serializedBrain = serializedObject; | |||||
base.OnInspectorGUI(); | |||||
serializedBrain.Update(); | |||||
if (brain.brainParameters.vectorActionSpaceType == SpaceType.continuous) | |||||
{ | |||||
DrawContinuousKeyMapping(serializedBrain, brain); | |||||
} | |||||
else | |||||
{ | |||||
DrawDiscreteKeyMapping(serializedBrain); | |||||
} | |||||
serializedBrain.ApplyModifiedProperties(); | |||||
} | |||||
/// <summary> | |||||
/// Draws the UI for continuous control key mapping to actions. | |||||
/// </summary> | |||||
/// <param name="serializedBrain"> The SerializedObject corresponding to the brain. </param> | |||||
/// <param name="brain"> The Brain of which properties are displayed. </param> | |||||
private static void DrawContinuousKeyMapping( | |||||
SerializedObject serializedBrain, PlayerBrain brain) | |||||
{ | |||||
GUILayout.Label("Edit the continuous inputs for your actions", EditorStyles.boldLabel); | |||||
var keyActionsProp = serializedBrain.FindProperty(KeyContinuousPropName); | |||||
var axisActionsProp = serializedBrain.FindProperty(AxisContinuousPropName); | |||||
EditorGUILayout.PropertyField(keyActionsProp , true); | |||||
EditorGUILayout.PropertyField(axisActionsProp, true); | |||||
var keyContinuous = brain.keyContinuousPlayerActions; | |||||
var axisContinuous = brain.axisContinuousPlayerActions; | |||||
var brainParams = brain.brainParameters; | |||||
if (keyContinuous == null) | |||||
{ | |||||
keyContinuous = new PlayerBrain.KeyContinuousPlayerAction[0]; | |||||
} | |||||
if (axisContinuous == null) | |||||
{ | |||||
axisContinuous = new PlayerBrain.AxisContinuousPlayerAction[0]; | |||||
} | |||||
foreach (var action in keyContinuous) | |||||
{ | |||||
if (action.index >= brainParams.vectorActionSize[0]) | |||||
{ | |||||
EditorGUILayout.HelpBox( | |||||
$"Key {action.key.ToString()} is assigned to index " + | |||||
$"{action.index.ToString()} but the action size is only of size " + | |||||
$"{brainParams.vectorActionSize.ToString()}", | |||||
MessageType.Error); | |||||
} | |||||
} | |||||
foreach (var action in axisContinuous) | |||||
{ | |||||
if (action.index >= brainParams.vectorActionSize[0]) | |||||
{ | |||||
EditorGUILayout.HelpBox( | |||||
$"Axis {action.axis} is assigned to index {action.index.ToString()} " + | |||||
$"but the action size is only of size {brainParams.vectorActionSize}", | |||||
MessageType.Error); | |||||
} | |||||
} | |||||
GUILayout.Label("You can change axis settings from Edit->Project Settings->Input", | |||||
EditorStyles.helpBox ); | |||||
} | |||||
/// <summary> | |||||
/// Draws the UI for discrete control key mapping to actions. | |||||
/// </summary> | |||||
/// <param name="serializedBrain"> The SerializedObject corresponding to the brain. </param> | |||||
private static void DrawDiscreteKeyMapping(SerializedObject serializedBrain) | |||||
{ | |||||
GUILayout.Label("Edit the discrete inputs for your actions", | |||||
EditorStyles.boldLabel); | |||||
var dhas = serializedBrain.FindProperty(KeyDiscretePropName); | |||||
serializedBrain.Update(); | |||||
EditorGUILayout.PropertyField(dhas, true); | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: 0d99e43f78e54b4f96a346219e2ca2d2 | |||||
timeCreated: 1536851993 |
using UnityEngine; | |||||
using UnityEditor; | |||||
using System; | |||||
using System.Linq; | |||||
using UnityEditor.SceneManagement; | |||||
namespace MLAgents | |||||
{ | |||||
/// <summary> | |||||
/// PropertyDrawer for ResetParameters. Defines how ResetParameters are displayed in the | |||||
/// Inspector. | |||||
/// </summary> | |||||
[CustomPropertyDrawer(typeof(ResetParameters))] | |||||
public class ResetParameterDrawer : PropertyDrawer | |||||
{ | |||||
private ResetParameters _parameters; | |||||
// The height of a line in the Unity Inspectors | |||||
private const float LineHeight = 17f; | |||||
// This is the prefix for the key when you add a reset parameter | |||||
private const string NewKeyPrefix = "Param-"; | |||||
/// <summary> | |||||
/// Computes the height of the Drawer depending on the property it is showing | |||||
/// </summary> | |||||
/// <param name="property">The property that is being drawn.</param> | |||||
/// <param name="label">The label of the property being drawn.</param> | |||||
/// <returns>The vertical space needed to draw the property.</returns> | |||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) | |||||
{ | |||||
LazyInitializeParameters(property, label); | |||||
return (_parameters.Count + 2) * LineHeight; | |||||
} | |||||
/// <inheritdoc /> | |||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) | |||||
{ | |||||
LazyInitializeParameters(property, label); | |||||
position.height = LineHeight; | |||||
EditorGUI.LabelField(position, label); | |||||
position.y += LineHeight; | |||||
var width = position.width / 2 - 24; | |||||
var keyRect = new Rect(position.x + 20, position.y, width, position.height); | |||||
var valueRect = new Rect(position.x + width + 30, position.y, width, position.height); | |||||
DrawAddRemoveButtons(keyRect, valueRect); | |||||
EditorGUI.BeginProperty(position, label, property); | |||||
foreach (var parameter in _parameters) | |||||
{ | |||||
var key = parameter.Key; | |||||
var value = parameter.Value; | |||||
keyRect.y += LineHeight; | |||||
valueRect.y += LineHeight; | |||||
EditorGUI.BeginChangeCheck(); | |||||
var newKey = EditorGUI.TextField(keyRect, key); | |||||
if (EditorGUI.EndChangeCheck()) | |||||
{ | |||||
MarkSceneAsDirty(); | |||||
try | |||||
{ | |||||
_parameters.Remove(key); | |||||
_parameters.Add(newKey, value); | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
Debug.Log(e.Message); | |||||
} | |||||
break; | |||||
} | |||||
EditorGUI.BeginChangeCheck(); | |||||
value = EditorGUI.FloatField(valueRect, value); | |||||
if (EditorGUI.EndChangeCheck()) | |||||
{ | |||||
MarkSceneAsDirty(); | |||||
_parameters[key] = value; | |||||
break; | |||||
} | |||||
} | |||||
EditorGUI.EndProperty(); | |||||
} | |||||
/// <summary> | |||||
/// Draws the Add and Remove buttons. | |||||
/// </summary> | |||||
/// <param name="addRect">The rectangle for the Add New button.</param> | |||||
/// <param name="removeRect">The rectangle for the Remove Last button.</param> | |||||
private void DrawAddRemoveButtons(Rect addRect, Rect removeRect) | |||||
{ | |||||
// This is the Add button | |||||
if (_parameters.Count == 0) | |||||
{ | |||||
addRect.width *= 2; | |||||
} | |||||
if (GUI.Button(addRect, | |||||
new GUIContent("Add New", "Add a new item to the default reset parameters"), | |||||
EditorStyles.miniButton)) | |||||
{ | |||||
MarkSceneAsDirty(); | |||||
AddParameter(); | |||||
} | |||||
// If there are no items in the ResetParameters, Hide the Remove button | |||||
if (_parameters.Count == 0) | |||||
{ | |||||
return; | |||||
} | |||||
// This is the Remove button | |||||
if (GUI.Button(removeRect, | |||||
new GUIContent( | |||||
"Remove Last", "Remove the last item from the default reset parameters"), | |||||
EditorStyles.miniButton)) | |||||
{ | |||||
MarkSceneAsDirty(); | |||||
RemoveLastParameter(); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Signals that the property has been modified and requires the scene to be saved for | |||||
/// the changes to persist. Only works when the Editor is not playing. | |||||
/// </summary> | |||||
private static void MarkSceneAsDirty() | |||||
{ | |||||
if (!EditorApplication.isPlaying) | |||||
{ | |||||
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Ensures that the state of the Drawer is synchronized with the property. | |||||
/// </summary> | |||||
/// <param name="property">The SerializedProperty of the ResetParameters | |||||
/// to make the custom GUI for.</param> | |||||
/// <param name="label">The label of this property.</param> | |||||
private void LazyInitializeParameters(SerializedProperty property, GUIContent label) | |||||
{ | |||||
if (_parameters != null) | |||||
{ | |||||
return; | |||||
} | |||||
var target = property.serializedObject.targetObject; | |||||
_parameters = fieldInfo.GetValue(target) as ResetParameters; | |||||
if (_parameters == null) | |||||
{ | |||||
_parameters = new ResetParameters(); | |||||
fieldInfo.SetValue(target, _parameters); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Removes the last ResetParameter from the ResetParameters | |||||
/// </summary> | |||||
private void RemoveLastParameter() | |||||
{ | |||||
if (_parameters.Count > 0) | |||||
{ | |||||
string key = _parameters.Keys.ToList()[_parameters.Count - 1]; | |||||
_parameters.Remove(key); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// Adds a new ResetParameter to the ResetParameters with a default name. | |||||
/// </summary> | |||||
private void AddParameter() | |||||
{ | |||||
string key = NewKeyPrefix + _parameters.Count; | |||||
var value = default(float); | |||||
try | |||||
{ | |||||
_parameters.Add(key, value); | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
Debug.Log(e.Message); | |||||
} | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: 740b9a60fe38f476ab020dcf91f3f94a | |||||
timeCreated: 1517291065 | |||||
licenseType: Free | |||||
MonoImporter: | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: 172fcc71d343247a9a91d5b54dd21cd6 | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using System.Collections.Generic; | |||||
using NUnit.Framework; | |||||
using UnityEngine; | |||||
using System.IO.Abstractions.TestingHelpers; | |||||
namespace MLAgents.Tests | |||||
{ | |||||
public class DemonstrationTests : MonoBehaviour | |||||
{ | |||||
private const string DemoDirecory = "Assets/Demonstrations/"; | |||||
private const string ExtensionType = ".demo"; | |||||
private const string DemoName = "Test"; | |||||
[Test] | |||||
public void TestSanitization() | |||||
{ | |||||
const string dirtyString = "abc123&!@"; | |||||
const string knownCleanString = "abc123"; | |||||
var cleanString = DemonstrationRecorder.SanitizeName(dirtyString); | |||||
Assert.AreNotEqual(dirtyString, cleanString); | |||||
Assert.AreEqual(cleanString, knownCleanString); | |||||
} | |||||
[Test] | |||||
public void TestStoreInitalize() | |||||
{ | |||||
var fileSystem = new MockFileSystem(); | |||||
var demoStore = new DemonstrationStore(fileSystem); | |||||
Assert.IsFalse(fileSystem.Directory.Exists(DemoDirecory)); | |||||
var brainParameters = new BrainParameters | |||||
{ | |||||
vectorObservationSize = 3, | |||||
numStackedVectorObservations = 2, | |||||
cameraResolutions = new [] {new Resolution()}, | |||||
vectorActionDescriptions = new [] {"TestActionA", "TestActionB"}, | |||||
vectorActionSize = new [] {2, 2}, | |||||
vectorActionSpaceType = SpaceType.discrete | |||||
}; | |||||
demoStore.Initialize(DemoName, brainParameters, "TestBrain"); | |||||
Assert.IsTrue(fileSystem.Directory.Exists(DemoDirecory)); | |||||
Assert.IsTrue(fileSystem.FileExists(DemoDirecory + DemoName + ExtensionType)); | |||||
var agentInfo = new AgentInfo | |||||
{ | |||||
reward = 1f, | |||||
visualObservations = new List<Texture2D>(), | |||||
actionMasks = new []{false, true}, | |||||
done = true, | |||||
id = 5, | |||||
maxStepReached = true, | |||||
memories = new List<float>(), | |||||
stackedVectorObservation = new List<float>() {1f, 1f, 1f}, | |||||
storedTextActions = "TestAction", | |||||
storedVectorActions = new [] {0f, 1f}, | |||||
textObservation = "TestAction", | |||||
}; | |||||
demoStore.Record(agentInfo); | |||||
demoStore.Close(); | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: 4c5a970f5b6be4b57b3bd7a5f84c3623 | |||||
MonoImporter: | |||||
externalObjects: {} | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using NUnit.Framework; | |||||
namespace MLAgents.Tests | |||||
{ | |||||
public class EditModeTestActionMasker | |||||
{ | |||||
[Test] | |||||
public void Contruction() | |||||
{ | |||||
var bp = new BrainParameters(); | |||||
var masker = new ActionMasker(bp); | |||||
Assert.IsNotNull(masker); | |||||
} | |||||
[Test] | |||||
public void FailsWithContinuous() | |||||
{ | |||||
var bp = new BrainParameters(); | |||||
bp.vectorActionSpaceType = SpaceType.continuous; | |||||
bp.vectorActionSize = new int[1] {4}; | |||||
var masker = new ActionMasker(bp); | |||||
masker.SetActionMask(0, new int[1] {0}); | |||||
Assert.Catch<UnityAgentsException>(() => masker.GetMask()); | |||||
} | |||||
[Test] | |||||
public void NullMask() | |||||
{ | |||||
var bp = new BrainParameters(); | |||||
bp.vectorActionSpaceType = SpaceType.discrete; | |||||
var masker = new ActionMasker(bp); | |||||
var mask = masker.GetMask(); | |||||
Assert.IsNull(mask); | |||||
} | |||||
[Test] | |||||
public void FirstBranchMask() | |||||
{ | |||||
var bp = new BrainParameters(); | |||||
bp.vectorActionSpaceType = SpaceType.discrete; | |||||
bp.vectorActionSize = new int[3] {4, 5, 6}; | |||||
var masker = new ActionMasker(bp); | |||||
var mask = masker.GetMask(); | |||||
Assert.IsNull(mask); | |||||
masker.SetActionMask(0, new int[]{1,2,3}); | |||||
mask = masker.GetMask(); | |||||
Assert.IsFalse(mask[0]); | |||||
Assert.IsTrue(mask[1]); | |||||
Assert.IsTrue(mask[2]); | |||||
Assert.IsTrue(mask[3]); | |||||
Assert.IsFalse(mask[4]); | |||||
Assert.AreEqual(mask.Length, 15); | |||||
} | |||||
[Test] | |||||
public void SecondBranchMask() | |||||
{ | |||||
var bp = new BrainParameters(); | |||||
bp.vectorActionSpaceType = SpaceType.discrete; | |||||
bp.vectorActionSize = new int[3] {4, 5, 6}; | |||||
var masker = new ActionMasker(bp); | |||||
bool[] mask = masker.GetMask(); | |||||
masker.SetActionMask(1, new int[]{1,2,3}); | |||||
mask = masker.GetMask(); | |||||
Assert.IsFalse(mask[0]); | |||||
Assert.IsFalse(mask[4]); | |||||
Assert.IsTrue(mask[5]); | |||||
Assert.IsTrue(mask[6]); | |||||
Assert.IsTrue(mask[7]); | |||||
Assert.IsFalse(mask[8]); | |||||
Assert.IsFalse(mask[9]); | |||||
} | |||||
[Test] | |||||
public void MaskReset() | |||||
{ | |||||
var bp = new BrainParameters(); | |||||
bp.vectorActionSpaceType = SpaceType.discrete; | |||||
bp.vectorActionSize = new int[3] {4, 5, 6}; | |||||
var masker = new ActionMasker(bp); | |||||
var mask = masker.GetMask(); | |||||
masker.SetActionMask(1, new int[3]{1,2,3}); | |||||
mask = masker.GetMask(); | |||||
masker.ResetMask(); | |||||
mask = masker.GetMask(); | |||||
for (var i = 0; i < 15; i++) | |||||
{ | |||||
Assert.IsFalse(mask[i]); | |||||
} | |||||
} | |||||
[Test] | |||||
public void ThrowsError() | |||||
{ | |||||
var bp = new BrainParameters(); | |||||
bp.vectorActionSpaceType = SpaceType.discrete; | |||||
bp.vectorActionSize = new int[3] {4, 5, 6}; | |||||
var masker = new ActionMasker(bp); | |||||
Assert.Catch<UnityAgentsException>( | |||||
() => masker.SetActionMask(0, new int[1]{5})); | |||||
Assert.Catch<UnityAgentsException>( | |||||
() => masker.SetActionMask(1, new int[1]{5})); | |||||
masker.SetActionMask(2, new int[1] {5}); | |||||
Assert.Catch<UnityAgentsException>( | |||||
() => masker.SetActionMask(3, new int[1]{1})); | |||||
masker.GetMask(); | |||||
masker.ResetMask(); | |||||
masker.SetActionMask(0, new int[4] {0, 1, 2, 3}); | |||||
Assert.Catch<UnityAgentsException>( | |||||
() => masker.GetMask()); | |||||
} | |||||
[Test] | |||||
public void MultipleMaskEdit() | |||||
{ | |||||
var bp = new BrainParameters(); | |||||
bp.vectorActionSpaceType = SpaceType.discrete; | |||||
bp.vectorActionSize = new int[3] {4, 5, 6}; | |||||
var masker = new ActionMasker(bp); | |||||
masker.SetActionMask(0, new int[2] {0, 1}); | |||||
masker.SetActionMask(0, new int[1] {3}); | |||||
masker.SetActionMask(2, new int[1] {1}); | |||||
var mask = masker.GetMask(); | |||||
for (var i = 0; i < 15; i++) | |||||
{ | |||||
if ((i == 0) || (i == 1) || (i == 3)|| (i == 10)) | |||||
{ | |||||
Assert.IsTrue(mask[i]); | |||||
} | |||||
else | |||||
{ | |||||
Assert.IsFalse(mask[i]); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: 2e2810ee6c8c64fb39abdf04b5d17f50 | |||||
MonoImporter: | |||||
externalObjects: {} | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using NUnit.Framework; | |||||
using UnityEngine; | |||||
using System.Reflection; | |||||
using MLAgents.InferenceBrain; | |||||
namespace MLAgents.Tests | |||||
{ | |||||
public class EditModeTestInternalBrainTensorApplier | |||||
{ | |||||
private class TestAgent : Agent | |||||
{ | |||||
public AgentAction GetAction() | |||||
{ | |||||
FieldInfo f = typeof(Agent).GetField( | |||||
"action", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
return (AgentAction) f.GetValue(this); | |||||
} | |||||
} | |||||
private Dictionary<Agent, AgentInfo> GetFakeAgentInfos() | |||||
{ | |||||
var goA = new GameObject("goA"); | |||||
var agentA = goA.AddComponent<TestAgent>(); | |||||
var infoA = new AgentInfo(); | |||||
var goB = new GameObject("goB"); | |||||
var agentB = goB.AddComponent<TestAgent>(); | |||||
var infoB = new AgentInfo(); | |||||
return new Dictionary<Agent, AgentInfo>(){{agentA, infoA},{agentB, infoB}}; | |||||
} | |||||
[Test] | |||||
public void Contruction() | |||||
{ | |||||
var bp = new BrainParameters(); | |||||
var tensorGenerator = new TensorApplier(bp, 0); | |||||
Assert.IsNotNull(tensorGenerator); | |||||
} | |||||
[Test] | |||||
public void ApplyContinuousActionOutput() | |||||
{ | |||||
var inputTensor = new Tensor() | |||||
{ | |||||
Shape = new long[] {2, 3}, | |||||
Data = new float[,] {{1, 2, 3}, {4, 5, 6}} | |||||
}; | |||||
var agentInfos = GetFakeAgentInfos(); | |||||
var applier = new ContinuousActionOutputApplier(); | |||||
applier.Apply(inputTensor, agentInfos); | |||||
var agents = agentInfos.Keys.ToList(); | |||||
var agent = agents[0] as TestAgent; | |||||
var action = agent.GetAction(); | |||||
Assert.AreEqual(action.vectorActions[0], 1); | |||||
Assert.AreEqual(action.vectorActions[1], 2); | |||||
Assert.AreEqual(action.vectorActions[2], 3); | |||||
agent = agents[1] as TestAgent; | |||||
action = agent.GetAction(); | |||||
Assert.AreEqual(action.vectorActions[0], 4); | |||||
Assert.AreEqual(action.vectorActions[1], 5); | |||||
Assert.AreEqual(action.vectorActions[2], 6); | |||||
} | |||||
[Test] | |||||
public void ApplyDiscreteActionOutput() | |||||
{ | |||||
var inputTensor = new Tensor() | |||||
{ | |||||
Shape = new long[] {2, 5}, | |||||
Data = new float[,] {{0.5f, 22.5f, 0.1f, 5f, 1f}, | |||||
{4f, 5f, 6f, 7f, 8f}} | |||||
}; | |||||
var agentInfos = GetFakeAgentInfos(); | |||||
var applier = new DiscreteActionOutputApplier(new int[]{2, 3}, 0); | |||||
applier.Apply(inputTensor, agentInfos); | |||||
var agents = agentInfos.Keys.ToList(); | |||||
var agent = agents[0] as TestAgent; | |||||
var action = agent.GetAction(); | |||||
Assert.AreEqual(action.vectorActions[0], 1); | |||||
Assert.AreEqual(action.vectorActions[1], 1); | |||||
agent = agents[1] as TestAgent; | |||||
action = agent.GetAction(); | |||||
Assert.AreEqual(action.vectorActions[0], 1); | |||||
Assert.AreEqual(action.vectorActions[1], 2); | |||||
} | |||||
[Test] | |||||
public void ApplyMemoryOutput() | |||||
{ | |||||
var inputTensor = new Tensor() | |||||
{ | |||||
Shape = new long[] {2, 5}, | |||||
Data = new float[,] {{0.5f, 22.5f, 0.1f, 5f, 1f}, | |||||
{4f, 5f, 6f, 7f, 8f}} | |||||
}; | |||||
var agentInfos = GetFakeAgentInfos(); | |||||
var applier = new MemoryOutputApplier(); | |||||
applier.Apply(inputTensor, agentInfos); | |||||
var agents = agentInfos.Keys.ToList(); | |||||
var agent = agents[0] as TestAgent; | |||||
var action = agent.GetAction(); | |||||
Assert.AreEqual(action.memories[0], 0.5f); | |||||
Assert.AreEqual(action.memories[1], 22.5f); | |||||
agent = agents[1] as TestAgent; | |||||
action = agent.GetAction(); | |||||
Assert.AreEqual(action.memories[2], 6); | |||||
Assert.AreEqual(action.memories[3], 7); | |||||
} | |||||
[Test] | |||||
public void ApplyValueEstimate() | |||||
{ | |||||
var inputTensor = new Tensor() | |||||
{ | |||||
Shape = new long[] {2, 1}, | |||||
Data = new float[,] {{0.5f}, {8f}} | |||||
}; | |||||
var agentInfos = GetFakeAgentInfos(); | |||||
var applier = new ValueEstimateApplier(); | |||||
applier.Apply(inputTensor, agentInfos); | |||||
var agents = agentInfos.Keys.ToList(); | |||||
var agent = agents[0] as TestAgent; | |||||
var action = agent.GetAction(); | |||||
Assert.AreEqual(action.value, 0.5f); | |||||
agent = agents[1] as TestAgent; | |||||
action = agent.GetAction(); | |||||
Assert.AreEqual(action.value, 8); | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: be419f7ed5c24b24a6f2636d3b107535 | |||||
timeCreated: 1537915674 |
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using NUnit.Framework; | |||||
using UnityEngine; | |||||
using MLAgents.InferenceBrain; | |||||
namespace MLAgents.Tests | |||||
{ | |||||
public class EditModeTestInternalBrainTensorGenerator | |||||
{ | |||||
private class TestAgent : Agent | |||||
{ | |||||
} | |||||
private Dictionary<Agent, AgentInfo> GetFakeAgentInfos() | |||||
{ | |||||
var goA = new GameObject("goA"); | |||||
var agentA = goA.AddComponent<TestAgent>(); | |||||
var infoA = new AgentInfo() | |||||
{ | |||||
stackedVectorObservation = (new float[] {1f, 2f, 3f}).ToList(), | |||||
memories = null, | |||||
storedVectorActions = new float[] {1, 2}, | |||||
actionMasks = null, | |||||
}; | |||||
var goB = new GameObject("goB"); | |||||
var agentB = goB.AddComponent<TestAgent>(); | |||||
var infoB = new AgentInfo() | |||||
{ | |||||
stackedVectorObservation = (new float[] {4f, 5f, 6f}).ToList(), | |||||
memories = (new float[] {1f, 1f, 1f}).ToList(), | |||||
storedVectorActions = new float[] {3, 4}, | |||||
actionMasks = new bool[] {true, false, false, false, false}, | |||||
}; | |||||
return new Dictionary<Agent, AgentInfo>(){{agentA, infoA},{agentB, infoB}}; | |||||
} | |||||
[Test] | |||||
public void Contruction() | |||||
{ | |||||
var bp = new BrainParameters(); | |||||
var tensorGenerator = new TensorGenerator(bp, 0); | |||||
Assert.IsNotNull(tensorGenerator); | |||||
} | |||||
[Test] | |||||
public void GenerateBatchSize() | |||||
{ | |||||
var inputTensor = new Tensor(); | |||||
var batchSize = 4; | |||||
var generator = new BatchSizeGenerator(); | |||||
generator.Generate(inputTensor, batchSize, null); | |||||
Assert.IsNotNull(inputTensor.Data as int[]); | |||||
Assert.AreEqual((inputTensor.Data as int[])[0], batchSize); | |||||
} | |||||
[Test] | |||||
public void GenerateSequenceLength() | |||||
{ | |||||
var inputTensor = new Tensor(); | |||||
var batchSize = 4; | |||||
var generator = new SequenceLengthGenerator(); | |||||
generator.Generate(inputTensor, batchSize, null); | |||||
Assert.IsNotNull(inputTensor.Data as int[]); | |||||
Assert.AreEqual((inputTensor.Data as int[])[0], 1); | |||||
} | |||||
[Test] | |||||
public void GenerateVectorObservation() | |||||
{ | |||||
var inputTensor = new Tensor() | |||||
{ | |||||
Shape = new long[] {2, 3} | |||||
}; | |||||
var batchSize = 4; | |||||
var agentInfos = GetFakeAgentInfos(); | |||||
var generator = new VectorObservationGenerator(); | |||||
generator.Generate(inputTensor, batchSize, agentInfos); | |||||
Assert.IsNotNull(inputTensor.Data as float[,]); | |||||
Assert.AreEqual((inputTensor.Data as float[,])[0, 0], 1); | |||||
Assert.AreEqual((inputTensor.Data as float[,])[0, 2], 3); | |||||
Assert.AreEqual((inputTensor.Data as float[,])[1, 0], 4); | |||||
Assert.AreEqual((inputTensor.Data as float[,])[1, 2], 6); | |||||
} | |||||
[Test] | |||||
public void GenerateRecurrentInput() | |||||
{ | |||||
var inputTensor = new Tensor() | |||||
{ | |||||
Shape = new long[] {2, 5} | |||||
}; | |||||
var batchSize = 4; | |||||
var agentInfos = GetFakeAgentInfos(); | |||||
var generator = new RecurrentInputGenerator(); | |||||
generator.Generate(inputTensor, batchSize, agentInfos); | |||||
Assert.IsNotNull(inputTensor.Data as float[,]); | |||||
Assert.AreEqual((inputTensor.Data as float[,])[0, 0], 0); | |||||
Assert.AreEqual((inputTensor.Data as float[,])[0, 4], 0); | |||||
Assert.AreEqual((inputTensor.Data as float[,])[1, 0], 1); | |||||
Assert.AreEqual((inputTensor.Data as float[,])[1, 4], 0); | |||||
} | |||||
[Test] | |||||
public void GeneratePreviousActionInput() | |||||
{ | |||||
var inputTensor = new Tensor() | |||||
{ | |||||
Shape = new long[] {2, 2}, | |||||
ValueType = Tensor.TensorType.Integer | |||||
}; | |||||
var batchSize = 4; | |||||
var agentInfos = GetFakeAgentInfos(); | |||||
var generator = new PreviousActionInputGenerator(); | |||||
generator.Generate(inputTensor, batchSize, agentInfos); | |||||
Assert.IsNotNull(inputTensor.Data as int[,]); | |||||
Assert.AreEqual((inputTensor.Data as int[,])[0, 0], 1); | |||||
Assert.AreEqual((inputTensor.Data as int[,])[0, 1], 2); | |||||
Assert.AreEqual((inputTensor.Data as int[,])[1, 0], 3); | |||||
Assert.AreEqual((inputTensor.Data as int[,])[1, 1], 4); | |||||
} | |||||
[Test] | |||||
public void GenerateActionMaskInput() | |||||
{ | |||||
var inputTensor = new Tensor() | |||||
{ | |||||
Shape = new long[] {2, 5}, | |||||
ValueType = Tensor.TensorType.FloatingPoint | |||||
}; | |||||
var batchSize = 4; | |||||
var agentInfos = GetFakeAgentInfos(); | |||||
var generator = new ActionMaskInputGenerator(); | |||||
generator.Generate(inputTensor, batchSize, agentInfos); | |||||
Assert.IsNotNull(inputTensor.Data as float[,]); | |||||
Assert.AreEqual((inputTensor.Data as float[,])[0, 0], 1); | |||||
Assert.AreEqual((inputTensor.Data as float[,])[0, 4], 1); | |||||
Assert.AreEqual((inputTensor.Data as float[,])[1, 0], 0); | |||||
Assert.AreEqual((inputTensor.Data as float[,])[1, 4], 1); | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: d2d2076c51c414ac7a91f8fbf15d4f7c | |||||
MonoImporter: | |||||
externalObjects: {} | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using UnityEngine; | |||||
using NUnit.Framework; | |||||
using System.Reflection; | |||||
namespace MLAgents.Tests | |||||
{ | |||||
public class TestAcademy : Academy | |||||
{ | |||||
public int initializeAcademyCalls; | |||||
public int academyResetCalls; | |||||
public int AcademyStepCalls; | |||||
public override void InitializeAcademy() | |||||
{ | |||||
initializeAcademyCalls += 1; | |||||
} | |||||
public override void AcademyReset() | |||||
{ | |||||
academyResetCalls += 1; | |||||
} | |||||
public override void AcademyStep() | |||||
{ | |||||
AcademyStepCalls += 1; | |||||
} | |||||
} | |||||
public class TestAgent : Agent | |||||
{ | |||||
public int initializeAgentCalls; | |||||
public int collectObservationsCalls; | |||||
public int agentActionCalls; | |||||
public int agentResetCalls; | |||||
public int agentOnDoneCalls; | |||||
public override void InitializeAgent() | |||||
{ | |||||
initializeAgentCalls += 1; | |||||
} | |||||
public override void CollectObservations() | |||||
{ | |||||
collectObservationsCalls += 1; | |||||
} | |||||
public override void AgentAction(float[] vectorAction, string textAction) | |||||
{ | |||||
agentActionCalls += 1; | |||||
AddReward(0.1f); | |||||
} | |||||
public override void AgentReset() | |||||
{ | |||||
agentResetCalls += 1; | |||||
} | |||||
public override void AgentOnDone() | |||||
{ | |||||
agentOnDoneCalls += 1; | |||||
} | |||||
} | |||||
// This is an empty class for testing the behavior of agents and academy | |||||
// It is left empty because we are not testing any brain behavior | |||||
public class TestBrain : Brain | |||||
{ | |||||
public int numberOfCallsToInitialize = 0; | |||||
public int numberOfCallsToDecideAction = 0; | |||||
public static TestBrain Instantiate() | |||||
{ | |||||
return CreateInstance<TestBrain>(); | |||||
} | |||||
protected override void Initialize() | |||||
{ | |||||
numberOfCallsToInitialize++; | |||||
} | |||||
protected override void DecideAction() | |||||
{ | |||||
numberOfCallsToDecideAction++; | |||||
agentInfos.Clear(); | |||||
} | |||||
} | |||||
public class EditModeTestGeneration | |||||
{ | |||||
[Test] | |||||
public void TestAcademy() | |||||
{ | |||||
// Use the Assert class to test conditions. | |||||
GameObject acaGO = new GameObject("TestAcademy"); | |||||
acaGO.AddComponent<TestAcademy>(); | |||||
TestAcademy aca = acaGO.GetComponent<TestAcademy>(); | |||||
Assert.AreNotEqual(null, aca); | |||||
Assert.AreEqual(0, aca.initializeAcademyCalls); | |||||
Assert.AreEqual(0, aca.GetEpisodeCount()); | |||||
Assert.AreEqual(0, aca.GetStepCount()); | |||||
} | |||||
[Test] | |||||
public void TestAgent() | |||||
{ | |||||
GameObject agentGO = new GameObject("TestAgent"); | |||||
agentGO.AddComponent<TestAgent>(); | |||||
TestAgent agent = agentGO.GetComponent<TestAgent>(); | |||||
Assert.AreNotEqual(null, agent); | |||||
Assert.AreEqual(0, agent.initializeAgentCalls); | |||||
} | |||||
} | |||||
public class EditModeTestInitialization | |||||
{ | |||||
private Brain GenerateTestBrain() | |||||
{ | |||||
return ScriptableObject.CreateInstance<TestBrain>(); | |||||
} | |||||
[Test] | |||||
public void TestAcademy() | |||||
{ | |||||
GameObject acaGO = new GameObject("TestAcademy"); | |||||
acaGO.AddComponent<TestAcademy>(); | |||||
TestAcademy aca = acaGO.GetComponent<TestAcademy>(); | |||||
Assert.AreEqual(0, aca.initializeAcademyCalls); | |||||
Assert.AreEqual(0, aca.GetStepCount()); | |||||
Assert.AreEqual(0, aca.GetEpisodeCount()); | |||||
Assert.AreEqual(false, aca.IsDone()); | |||||
//This will call the method even though it is private | |||||
MethodInfo AcademyInitializeMethod = typeof(Academy).GetMethod("InitializeEnvironment", | |||||
BindingFlags.Instance | BindingFlags.NonPublic); | |||||
AcademyInitializeMethod.Invoke(aca, new object[] { }); | |||||
Assert.AreEqual(1, aca.initializeAcademyCalls); | |||||
Assert.AreEqual(0, aca.GetEpisodeCount()); | |||||
Assert.AreEqual(0, aca.GetStepCount()); | |||||
Assert.AreEqual(false, aca.IsDone()); | |||||
Assert.AreEqual(0, aca.academyResetCalls); | |||||
Assert.AreEqual(0, aca.AcademyStepCalls); | |||||
} | |||||
[Test] | |||||
public void TestAgent() | |||||
{ | |||||
GameObject agentGO1 = new GameObject("TestAgent"); | |||||
agentGO1.AddComponent<TestAgent>(); | |||||
TestAgent agent1 = agentGO1.GetComponent<TestAgent>(); | |||||
GameObject agentGO2 = new GameObject("TestAgent"); | |||||
agentGO2.AddComponent<TestAgent>(); | |||||
TestAgent agent2 = agentGO2.GetComponent<TestAgent>(); | |||||
GameObject acaGO = new GameObject("TestAcademy"); | |||||
acaGO.AddComponent<TestAcademy>(); | |||||
TestAcademy aca = acaGO.GetComponent<TestAcademy>(); | |||||
TestBrain brain = TestBrain.Instantiate(); | |||||
brain.brainParameters = new BrainParameters(); | |||||
brain.brainParameters.vectorObservationSize = 0; | |||||
agent1.GiveBrain(brain); | |||||
agent2.GiveBrain(brain); | |||||
Assert.AreEqual(false, agent1.IsDone()); | |||||
Assert.AreEqual(false, agent2.IsDone()); | |||||
Assert.AreEqual(0, agent1.agentResetCalls); | |||||
Assert.AreEqual(0, agent2.agentResetCalls); | |||||
Assert.AreEqual(0, agent1.initializeAgentCalls); | |||||
Assert.AreEqual(0, agent2.initializeAgentCalls); | |||||
Assert.AreEqual(0, agent1.agentActionCalls); | |||||
Assert.AreEqual(0, agent2.agentActionCalls); | |||||
MethodInfo AgentEnableMethod = typeof(Agent).GetMethod("OnEnableHelper", | |||||
BindingFlags.Instance | BindingFlags.NonPublic); | |||||
MethodInfo AcademyInitializeMethod = typeof(Academy).GetMethod("InitializeEnvironment", | |||||
BindingFlags.Instance | BindingFlags.NonPublic); | |||||
AgentEnableMethod.Invoke(agent2, new object[] { aca }); | |||||
AcademyInitializeMethod.Invoke(aca, new object[] { }); | |||||
AgentEnableMethod.Invoke(agent1, new object[] { aca }); | |||||
Assert.AreEqual(false, agent1.IsDone()); | |||||
Assert.AreEqual(false, agent2.IsDone()); | |||||
// agent1 was not enabled when the academy started | |||||
// The agents have been initialized | |||||
Assert.AreEqual(0, agent1.agentResetCalls); | |||||
Assert.AreEqual(0, agent2.agentResetCalls); | |||||
Assert.AreEqual(1, agent1.initializeAgentCalls); | |||||
Assert.AreEqual(1, agent2.initializeAgentCalls); | |||||
Assert.AreEqual(0, agent1.agentActionCalls); | |||||
Assert.AreEqual(0, agent2.agentActionCalls); | |||||
} | |||||
} | |||||
public class EditModeTestStep | |||||
{ | |||||
[Test] | |||||
public void TestAcademy() | |||||
{ | |||||
GameObject acaGO = new GameObject("TestAcademy"); | |||||
acaGO.AddComponent<TestAcademy>(); | |||||
TestAcademy aca = acaGO.GetComponent<TestAcademy>(); | |||||
MethodInfo AcademyInitializeMethod = typeof(Academy).GetMethod("InitializeEnvironment", | |||||
BindingFlags.Instance | BindingFlags.NonPublic); | |||||
AcademyInitializeMethod.Invoke(aca, new object[] { }); | |||||
MethodInfo AcademyStepMethod = typeof(Academy).GetMethod("EnvironmentStep", | |||||
BindingFlags.Instance | BindingFlags.NonPublic); | |||||
int numberReset = 0; | |||||
for (int i = 0; i < 10; i++) | |||||
{ | |||||
Assert.AreEqual(1, aca.initializeAcademyCalls); | |||||
Assert.AreEqual(numberReset, aca.GetEpisodeCount()); | |||||
Assert.AreEqual(i, aca.GetStepCount()); | |||||
Assert.AreEqual(false, aca.IsDone()); | |||||
Assert.AreEqual(numberReset, aca.academyResetCalls); | |||||
Assert.AreEqual(i, aca.AcademyStepCalls); | |||||
// The reset happens at the begining of the first step | |||||
if (i == 0) | |||||
{ | |||||
numberReset += 1; | |||||
} | |||||
AcademyStepMethod.Invoke((object)aca, new object[] { }); | |||||
} | |||||
} | |||||
[Test] | |||||
public void TestAgent() | |||||
{ | |||||
GameObject agentGO1 = new GameObject("TestAgent"); | |||||
agentGO1.AddComponent<TestAgent>(); | |||||
TestAgent agent1 = agentGO1.GetComponent<TestAgent>(); | |||||
GameObject agentGO2 = new GameObject("TestAgent"); | |||||
agentGO2.AddComponent<TestAgent>(); | |||||
TestAgent agent2 = agentGO2.GetComponent<TestAgent>(); | |||||
GameObject acaGO = new GameObject("TestAcademy"); | |||||
acaGO.AddComponent<TestAcademy>(); | |||||
TestAcademy aca = acaGO.GetComponent<TestAcademy>(); | |||||
TestBrain brain = TestBrain.Instantiate(); | |||||
MethodInfo AgentEnableMethod = typeof(Agent).GetMethod( | |||||
"OnEnableHelper", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
MethodInfo AcademyInitializeMethod = typeof(Academy).GetMethod( | |||||
"InitializeEnvironment", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
agent1.agentParameters = new AgentParameters(); | |||||
agent2.agentParameters = new AgentParameters(); | |||||
brain.brainParameters = new BrainParameters(); | |||||
// We use event based so the agent will now try to send anything to the brain | |||||
agent1.agentParameters.onDemandDecision = false; | |||||
agent1.agentParameters.numberOfActionsBetweenDecisions = 2; | |||||
// agent1 will take an action at every step and request a decision every 2 steps | |||||
agent2.agentParameters.onDemandDecision = true; | |||||
// agent2 will request decisions only when RequestDecision is called | |||||
brain.brainParameters.vectorObservationSize = 0; | |||||
brain.brainParameters.cameraResolutions = new Resolution[0]; | |||||
agent1.GiveBrain(brain); | |||||
agent2.GiveBrain(brain); | |||||
AgentEnableMethod.Invoke(agent1, new object[] { aca }); | |||||
AcademyInitializeMethod.Invoke(aca, new object[] { }); | |||||
MethodInfo AcademyStepMethod = typeof(Academy).GetMethod( | |||||
"EnvironmentStep", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
int numberAgent1Reset = 0; | |||||
int numberAgent2Initialization = 0; | |||||
int requestDecision = 0; | |||||
int requestAction = 0; | |||||
for (int i = 0; i < 50; i++) | |||||
{ | |||||
Assert.AreEqual(numberAgent1Reset, agent1.agentResetCalls); | |||||
// Agent2 is never reset since intialized after academy | |||||
Assert.AreEqual(0, agent2.agentResetCalls); | |||||
Assert.AreEqual(1, agent1.initializeAgentCalls); | |||||
Assert.AreEqual(numberAgent2Initialization, agent2.initializeAgentCalls); | |||||
Assert.AreEqual(i, agent1.agentActionCalls); | |||||
Assert.AreEqual(requestAction, agent2.agentActionCalls); | |||||
Assert.AreEqual((i + 1) / 2, agent1.collectObservationsCalls); | |||||
Assert.AreEqual(requestDecision, agent2.collectObservationsCalls); | |||||
// Agent 1 resets at the first step | |||||
if (i == 0) | |||||
{ | |||||
numberAgent1Reset += 1; | |||||
} | |||||
//Agent 2 is only initialized at step 2 | |||||
if (i == 2) | |||||
{ | |||||
AgentEnableMethod.Invoke(agent2, new object[] { aca }); | |||||
numberAgent2Initialization += 1; | |||||
} | |||||
// We are testing request decision and request actions when called | |||||
// at different intervals | |||||
if ((i % 3 == 0) && (i > 2)) | |||||
{ | |||||
//Every 3 steps after agent 2 is initialized, request decision | |||||
requestDecision += 1; | |||||
requestAction += 1; | |||||
agent2.RequestDecision(); | |||||
} | |||||
else if ((i % 5 == 0) && (i > 2)) | |||||
{ | |||||
// Every 5 steps after agent 2 is initialized, request action | |||||
requestAction += 1; | |||||
agent2.RequestAction(); | |||||
} | |||||
AcademyStepMethod.Invoke(aca, new object[] { }); | |||||
} | |||||
} | |||||
} | |||||
public class EditModeTestReset | |||||
{ | |||||
[Test] | |||||
public void TestAcademy() | |||||
{ | |||||
GameObject acaGO = new GameObject("TestAcademy"); | |||||
acaGO.AddComponent<TestAcademy>(); | |||||
TestAcademy aca = acaGO.GetComponent<TestAcademy>(); | |||||
MethodInfo AcademyInitializeMethod = typeof(Academy).GetMethod( | |||||
"InitializeEnvironment", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
AcademyInitializeMethod.Invoke(aca, new object[] { }); | |||||
MethodInfo AcademyStepMethod = typeof(Academy).GetMethod( | |||||
"EnvironmentStep", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
int numberReset = 0; | |||||
int stepsSinceReset = 0; | |||||
for (int i = 0; i < 50; i++) | |||||
{ | |||||
Assert.AreEqual(stepsSinceReset, aca.GetStepCount()); | |||||
Assert.AreEqual(1, aca.initializeAcademyCalls); | |||||
Assert.AreEqual(numberReset, aca.GetEpisodeCount()); | |||||
Assert.AreEqual(false, aca.IsDone()); | |||||
Assert.AreEqual(numberReset, aca.academyResetCalls); | |||||
Assert.AreEqual(i, aca.AcademyStepCalls); | |||||
// Academy resets at the first step | |||||
if (i == 0) | |||||
{ | |||||
numberReset += 1; | |||||
} | |||||
stepsSinceReset += 1; | |||||
// Regularly set the academy to done to check behavior | |||||
if (i % 5 == 3) | |||||
{ | |||||
aca.Done(); | |||||
numberReset += 1; | |||||
stepsSinceReset = 1; | |||||
Assert.AreEqual(true, aca.IsDone()); | |||||
} | |||||
AcademyStepMethod.Invoke((object)aca, new object[] { }); | |||||
} | |||||
} | |||||
[Test] | |||||
public void TestAgent() | |||||
{ | |||||
GameObject agentGO1 = new GameObject("TestAgent"); | |||||
agentGO1.AddComponent<TestAgent>(); | |||||
TestAgent agent1 = agentGO1.GetComponent<TestAgent>(); | |||||
GameObject agentGO2 = new GameObject("TestAgent"); | |||||
agentGO2.AddComponent<TestAgent>(); | |||||
TestAgent agent2 = agentGO2.GetComponent<TestAgent>(); | |||||
GameObject acaGO = new GameObject("TestAcademy"); | |||||
acaGO.AddComponent<TestAcademy>(); | |||||
TestAcademy aca = acaGO.GetComponent<TestAcademy>(); | |||||
TestBrain brain = TestBrain.Instantiate(); | |||||
MethodInfo AgentEnableMethod = typeof(Agent).GetMethod( | |||||
"OnEnableHelper", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
MethodInfo AcademyInitializeMethod = typeof(Academy).GetMethod( | |||||
"InitializeEnvironment", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
MethodInfo AcademyStepMethod = typeof(Academy).GetMethod( | |||||
"EnvironmentStep", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
agent1.agentParameters = new AgentParameters(); | |||||
agent2.agentParameters = new AgentParameters(); | |||||
brain.brainParameters = new BrainParameters(); | |||||
// We use event based so the agent will now try to send anything to the brain | |||||
agent1.agentParameters.onDemandDecision = false; | |||||
agent1.agentParameters.numberOfActionsBetweenDecisions = 2; | |||||
// agent1 will take an action at every step and request a decision every 2 steps | |||||
agent2.agentParameters.onDemandDecision = true; | |||||
// agent2 will request decisions only when RequestDecision is called | |||||
brain.brainParameters.vectorObservationSize = 0; | |||||
brain.brainParameters.cameraResolutions = new Resolution[0]; | |||||
agent1.GiveBrain(brain); | |||||
agent2.GiveBrain(brain); | |||||
AgentEnableMethod.Invoke(agent2, new object[] { aca }); | |||||
AcademyInitializeMethod.Invoke(aca, new object[] { }); | |||||
int numberAgent1Reset = 0; | |||||
int numberAgent2Reset = 0; | |||||
int numberAcaReset = 0; | |||||
int acaStepsSinceReset = 0; | |||||
int agent1StepSinceReset = 0; | |||||
int agent2StepSinceReset = 0; | |||||
int requestDecision = 0; | |||||
int requestAction = 0; | |||||
for (int i = 0; i < 5000; i++) | |||||
{ | |||||
Assert.AreEqual(acaStepsSinceReset, aca.GetStepCount()); | |||||
Assert.AreEqual(1, aca.initializeAcademyCalls); | |||||
Assert.AreEqual(numberAcaReset, aca.GetEpisodeCount()); | |||||
Assert.AreEqual(false, aca.IsDone()); | |||||
Assert.AreEqual(numberAcaReset, aca.academyResetCalls); | |||||
Assert.AreEqual(i, aca.AcademyStepCalls); | |||||
Assert.AreEqual(agent2StepSinceReset, agent2.GetStepCount()); | |||||
Assert.AreEqual(numberAgent1Reset, agent1.agentResetCalls); | |||||
Assert.AreEqual(numberAgent2Reset, agent2.agentResetCalls); | |||||
// Agent 2 and academy reset at the first step | |||||
if (i == 0) | |||||
{ | |||||
numberAcaReset += 1; | |||||
numberAgent2Reset += 1; | |||||
} | |||||
//Agent 1 is only initialized at step 2 | |||||
if (i == 2) | |||||
{ | |||||
AgentEnableMethod.Invoke(agent1, new object[] { aca }); | |||||
} | |||||
// Reset Academy every 100 steps | |||||
if (i % 100 == 3) | |||||
{ | |||||
aca.Done(); | |||||
numberAcaReset += 1; | |||||
acaStepsSinceReset = 0; | |||||
} | |||||
// Set agent 1 to done every 11 steps to test behavior | |||||
if (i % 11 == 5) | |||||
{ | |||||
agent1.Done(); | |||||
} | |||||
// Reseting agent 2 regularly | |||||
if (i % 13 == 3) | |||||
{ | |||||
if (!(agent2.IsDone() || aca.IsDone())) | |||||
{ | |||||
// If the agent was already reset before the request decision | |||||
// We should not reset again | |||||
agent2.Done(); | |||||
numberAgent2Reset += 1; | |||||
agent2StepSinceReset = 0; | |||||
} | |||||
} | |||||
// Request a decision for agent 2 regularly | |||||
if (i % 3 == 2) | |||||
{ | |||||
requestDecision += 1; | |||||
requestAction += 1; | |||||
agent2.RequestDecision(); | |||||
} | |||||
else if (i % 5 == 1) | |||||
{ | |||||
// Request an action without decision regularly | |||||
requestAction += 1; | |||||
agent2.RequestAction(); | |||||
} | |||||
if (agent1.IsDone() && (((acaStepsSinceReset) % agent1.agentParameters.numberOfActionsBetweenDecisions == 0)) || aca.IsDone()) | |||||
{ | |||||
numberAgent1Reset += 1; | |||||
agent1StepSinceReset = 0; | |||||
} | |||||
if (aca.IsDone()) | |||||
{ | |||||
numberAgent2Reset += 1; | |||||
agent2StepSinceReset = 0; | |||||
} | |||||
acaStepsSinceReset += 1; | |||||
agent1StepSinceReset += 1; | |||||
agent2StepSinceReset += 1; | |||||
//Agent 1 is only initialized at step 2 | |||||
if (i < 2) | |||||
{ | |||||
agent1StepSinceReset = 0; | |||||
} | |||||
AcademyStepMethod.Invoke((object)aca, new object[] { }); | |||||
} | |||||
} | |||||
} | |||||
public class EditModeTestMaxStep | |||||
{ | |||||
[Test] | |||||
public void TestAcademy() | |||||
{ | |||||
GameObject acaGO = new GameObject("TestAcademy"); | |||||
acaGO.AddComponent<TestAcademy>(); | |||||
TestAcademy aca = acaGO.GetComponent<TestAcademy>(); | |||||
MethodInfo AcademyInitializeMethod = typeof(Academy).GetMethod( | |||||
"InitializeEnvironment", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
AcademyInitializeMethod.Invoke(aca, new object[] { }); | |||||
MethodInfo AcademyStepMethod = typeof(Academy).GetMethod( | |||||
"EnvironmentStep", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
FieldInfo maxStep = typeof(Academy).GetField( | |||||
"maxSteps", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
maxStep.SetValue((object)aca, 20); | |||||
int numberReset = 0; | |||||
int stepsSinceReset = 0; | |||||
for (int i = 0; i < 50; i++) | |||||
{ | |||||
Assert.AreEqual(stepsSinceReset, aca.GetStepCount()); | |||||
Assert.AreEqual(1, aca.initializeAcademyCalls); | |||||
Assert.AreEqual(false, aca.IsDone()); | |||||
Assert.AreEqual(i, aca.AcademyStepCalls); | |||||
Assert.AreEqual(numberReset, aca.GetEpisodeCount()); | |||||
Assert.AreEqual(numberReset, aca.academyResetCalls); | |||||
stepsSinceReset += 1; | |||||
// Make sure max step is reached every 20 steps | |||||
if (i % 20 == 0) | |||||
{ | |||||
numberReset += 1; | |||||
stepsSinceReset = 1; | |||||
} | |||||
AcademyStepMethod.Invoke((object)aca, new object[] { }); | |||||
} | |||||
} | |||||
[Test] | |||||
public void TestAgent() | |||||
{ | |||||
GameObject agentGO1 = new GameObject("TestAgent"); | |||||
agentGO1.AddComponent<TestAgent>(); | |||||
TestAgent agent1 = agentGO1.GetComponent<TestAgent>(); | |||||
GameObject agentGO2 = new GameObject("TestAgent"); | |||||
agentGO2.AddComponent<TestAgent>(); | |||||
TestAgent agent2 = agentGO2.GetComponent<TestAgent>(); | |||||
GameObject acaGO = new GameObject("TestAcademy"); | |||||
acaGO.AddComponent<TestAcademy>(); | |||||
TestAcademy aca = acaGO.GetComponent<TestAcademy>(); | |||||
TestBrain brain = TestBrain.Instantiate(); | |||||
MethodInfo AgentEnableMethod = typeof(Agent).GetMethod( | |||||
"OnEnableHelper", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
MethodInfo AcademyInitializeMethod = typeof(Academy).GetMethod( | |||||
"InitializeEnvironment", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
MethodInfo AcademyStepMethod = typeof(Academy).GetMethod( | |||||
"EnvironmentStep", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
FieldInfo maxStep = typeof(Academy).GetField( | |||||
"maxSteps", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
maxStep.SetValue((object)aca, 100); | |||||
agent1.agentParameters = new AgentParameters(); | |||||
agent2.agentParameters = new AgentParameters(); | |||||
brain.brainParameters = new BrainParameters(); | |||||
// We use event based so the agent will now try to send anything to the brain | |||||
agent1.agentParameters.onDemandDecision = false; | |||||
agent1.agentParameters.numberOfActionsBetweenDecisions = 1; | |||||
// agent1 will take an action at every step and request a decision every 2 steps | |||||
agent2.agentParameters.onDemandDecision = true; | |||||
// agent2 will request decisions only when RequestDecision is called | |||||
agent1.agentParameters.maxStep = 20; | |||||
agent2.agentParameters.maxStep = 30; | |||||
brain.brainParameters.vectorObservationSize = 0; | |||||
brain.brainParameters.cameraResolutions = new Resolution[0]; | |||||
agent1.GiveBrain(brain); | |||||
agent2.GiveBrain(brain); | |||||
AgentEnableMethod.Invoke(agent2, new object[] { aca }); | |||||
AcademyInitializeMethod.Invoke(aca, new object[] { }); | |||||
int numberAgent1Reset = 0; | |||||
int numberAgent2Reset = 0; | |||||
int numberAcaReset = 0; | |||||
int acaStepsSinceReset = 0; | |||||
int agent1StepSinceReset = 0; | |||||
int agent2StepSinceReset = 0; | |||||
for (int i = 0; i < 500; i++) | |||||
{ | |||||
Assert.AreEqual(acaStepsSinceReset, aca.GetStepCount()); | |||||
Assert.AreEqual(1, aca.initializeAcademyCalls); | |||||
Assert.AreEqual(i, aca.AcademyStepCalls); | |||||
Assert.AreEqual(agent1StepSinceReset, agent1.GetStepCount()); | |||||
Assert.AreEqual(agent2StepSinceReset, agent2.GetStepCount()); | |||||
Assert.AreEqual(numberAcaReset, aca.GetEpisodeCount()); | |||||
Assert.AreEqual(numberAcaReset, aca.academyResetCalls); | |||||
Assert.AreEqual(numberAgent1Reset, agent1.agentResetCalls); | |||||
Assert.AreEqual(numberAgent2Reset, agent2.agentResetCalls); | |||||
//At the first step, Academy and agent 2 reset | |||||
if (i == 0) | |||||
{ | |||||
numberAcaReset += 1; | |||||
numberAgent2Reset += 1; | |||||
} | |||||
//Agent 1 is only initialized at step 2 | |||||
if (i == 2) | |||||
{ | |||||
AgentEnableMethod.Invoke(agent1, new object[] { aca }); | |||||
} | |||||
// we request a decision at each step | |||||
agent2.RequestDecision(); | |||||
if (i > 3) | |||||
{ | |||||
// Make sure the academy max steps at 100 | |||||
if (i % 100 == 0) | |||||
{ | |||||
acaStepsSinceReset = 0; | |||||
agent1StepSinceReset = 0; | |||||
agent2StepSinceReset = 0; | |||||
numberAcaReset += 1; | |||||
numberAgent1Reset += 1; | |||||
numberAgent2Reset += 1; | |||||
} | |||||
else | |||||
{ | |||||
//Make sure the agents reset when their max steps is reached | |||||
if (agent1StepSinceReset % 21 == 0) | |||||
{ | |||||
agent1StepSinceReset = 0; | |||||
numberAgent1Reset += 1; | |||||
} | |||||
if (agent2StepSinceReset % 31 == 0) | |||||
{ | |||||
agent2StepSinceReset = 0; | |||||
numberAgent2Reset += 1; | |||||
} | |||||
} | |||||
} | |||||
acaStepsSinceReset += 1; | |||||
agent1StepSinceReset += 1; | |||||
agent2StepSinceReset += 1; | |||||
//Agent 1 is only initialized at step 2 | |||||
if (i < 2) | |||||
{ | |||||
agent1StepSinceReset = 0; | |||||
} | |||||
AcademyStepMethod.Invoke((object)aca, new object[] { }); | |||||
} | |||||
} | |||||
} | |||||
public class EditModeTestMiscellaneous | |||||
{ | |||||
[Test] | |||||
public void TestResetOnDone() | |||||
{ | |||||
GameObject agentGO1 = new GameObject("TestAgent"); | |||||
agentGO1.AddComponent<TestAgent>(); | |||||
TestAgent agent1 = agentGO1.GetComponent<TestAgent>(); | |||||
GameObject agentGO2 = new GameObject("TestAgent"); | |||||
agentGO2.AddComponent<TestAgent>(); | |||||
TestAgent agent2 = agentGO2.GetComponent<TestAgent>(); | |||||
GameObject acaGO = new GameObject("TestAcademy"); | |||||
acaGO.AddComponent<TestAcademy>(); | |||||
TestAcademy aca = acaGO.GetComponent<TestAcademy>(); | |||||
TestBrain brain = TestBrain.Instantiate(); | |||||
MethodInfo AgentEnableMethod = typeof(Agent).GetMethod( | |||||
"OnEnableHelper", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
MethodInfo AcademyInitializeMethod = typeof(Academy).GetMethod( | |||||
"InitializeEnvironment", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
MethodInfo AcademyStepMethod = typeof(Academy).GetMethod( | |||||
"EnvironmentStep", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
agent1.agentParameters = new AgentParameters(); | |||||
agent2.agentParameters = new AgentParameters(); | |||||
brain.brainParameters = new BrainParameters(); | |||||
// We use event based so the agent will now try to send anything to the brain | |||||
agent1.agentParameters.onDemandDecision = false; | |||||
// agent1 will take an action at every step and request a decision every steps | |||||
agent1.agentParameters.numberOfActionsBetweenDecisions = 1; | |||||
// agent2 will request decisions only when RequestDecision is called | |||||
agent2.agentParameters.onDemandDecision = true; | |||||
agent1.agentParameters.maxStep = 20; | |||||
//Here we specify that the agent does not reset when done | |||||
agent1.agentParameters.resetOnDone = false; | |||||
agent2.agentParameters.resetOnDone = false; | |||||
brain.brainParameters.vectorObservationSize = 0; | |||||
brain.brainParameters.cameraResolutions = new Resolution[0]; | |||||
agent1.GiveBrain(brain); | |||||
agent2.GiveBrain(brain); | |||||
AgentEnableMethod.Invoke(agent2, new object[] { aca }); | |||||
AcademyInitializeMethod.Invoke(aca, new object[] { }); | |||||
AgentEnableMethod.Invoke(agent1, new object[] { aca }); | |||||
int agent1ResetOnDone = 0; | |||||
int agent2ResetOnDone = 0; | |||||
int acaStepsSinceReset = 0; | |||||
int agent1StepSinceReset = 0; | |||||
int agent2StepSinceReset = 0; | |||||
for (int i = 0; i < 50; i++) | |||||
{ | |||||
Assert.AreEqual(i, aca.AcademyStepCalls); | |||||
Assert.AreEqual(agent1StepSinceReset, agent1.GetStepCount()); | |||||
Assert.AreEqual(agent2StepSinceReset, agent2.GetStepCount()); | |||||
Assert.AreEqual(agent1ResetOnDone, agent1.agentOnDoneCalls); | |||||
Assert.AreEqual(agent2ResetOnDone, agent2.agentOnDoneCalls); | |||||
// we request a decision at each step | |||||
agent2.RequestDecision(); | |||||
acaStepsSinceReset += 1; | |||||
if (agent1ResetOnDone == 0) | |||||
agent1StepSinceReset += 1; | |||||
if (agent2ResetOnDone == 0) | |||||
agent2StepSinceReset += 1; | |||||
if ((i > 2) && (i % 21 == 0)) | |||||
{ | |||||
agent1ResetOnDone = 1; | |||||
} | |||||
if (i == 31) | |||||
{ | |||||
agent2ResetOnDone = 1; | |||||
agent2.Done(); | |||||
} | |||||
AcademyStepMethod.Invoke((object)aca, new object[] { }); | |||||
} | |||||
} | |||||
[Test] | |||||
public void TestCumulativeReward() | |||||
{ | |||||
GameObject agentGO1 = new GameObject("TestAgent"); | |||||
agentGO1.AddComponent<TestAgent>(); | |||||
TestAgent agent1 = agentGO1.GetComponent<TestAgent>(); | |||||
GameObject agentGO2 = new GameObject("TestAgent"); | |||||
agentGO2.AddComponent<TestAgent>(); | |||||
TestAgent agent2 = agentGO2.GetComponent<TestAgent>(); | |||||
GameObject acaGO = new GameObject("TestAcademy"); | |||||
acaGO.AddComponent<TestAcademy>(); | |||||
TestAcademy aca = acaGO.GetComponent<TestAcademy>(); | |||||
TestBrain brain = TestBrain.Instantiate(); | |||||
MethodInfo AgentEnableMethod = typeof(Agent).GetMethod( | |||||
"OnEnableHelper", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
MethodInfo AcademyInitializeMethod = typeof(Academy).GetMethod( | |||||
"InitializeEnvironment", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
MethodInfo AcademyStepMethod = typeof(Academy).GetMethod( | |||||
"EnvironmentStep", BindingFlags.Instance | BindingFlags.NonPublic); | |||||
agent1.agentParameters = new AgentParameters(); | |||||
agent2.agentParameters = new AgentParameters(); | |||||
brain.brainParameters = new BrainParameters(); | |||||
// We use event based so the agent will now try to send anything to the brain | |||||
agent1.agentParameters.onDemandDecision = false; | |||||
agent1.agentParameters.numberOfActionsBetweenDecisions = 3; | |||||
// agent1 will take an action at every step and request a decision every 2 steps | |||||
agent2.agentParameters.onDemandDecision = true; | |||||
// agent2 will request decisions only when RequestDecision is called | |||||
agent1.agentParameters.maxStep = 20; | |||||
brain.brainParameters.vectorObservationSize = 0; | |||||
brain.brainParameters.cameraResolutions = new Resolution[0]; | |||||
agent1.GiveBrain(brain); | |||||
agent2.GiveBrain(brain); | |||||
AgentEnableMethod.Invoke(agent2, new object[] { aca }); | |||||
AcademyInitializeMethod.Invoke(aca, new object[] { }); | |||||
AgentEnableMethod.Invoke(agent1, new object[] { aca }); | |||||
int j = 0; | |||||
for (int i = 0; i < 500; i++) | |||||
{ | |||||
agent2.RequestAction(); | |||||
Assert.LessOrEqual(Mathf.Abs(j * 0.1f + j * 10f - agent1.GetCumulativeReward()), 0.05f); | |||||
Assert.LessOrEqual(Mathf.Abs(i * 0.1f - agent2.GetCumulativeReward()), 0.05f); | |||||
AcademyStepMethod.Invoke((object)aca, new object[] { }); | |||||
agent1.AddReward(10f); | |||||
if ((i % 21 == 0) && (i > 0)) | |||||
{ | |||||
j = 0; | |||||
} | |||||
j++; | |||||
} | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: 3170fcbfa5f4d4a8ca82c50c750e9083 | |||||
MonoImporter: | |||||
externalObjects: {} | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using System; | |||||
using NUnit.Framework; | |||||
using UnityEngine; | |||||
using MLAgents.InferenceBrain; | |||||
using MLAgents.InferenceBrain.Utils; | |||||
namespace MLAgents.Tests | |||||
{ | |||||
public class MultinomialTest | |||||
{ | |||||
[Test] | |||||
public void TestEvalP() | |||||
{ | |||||
Multinomial m = new Multinomial(2018); | |||||
Tensor src = new Tensor | |||||
{ | |||||
Data = new float[1, 3] {{0.1f, 0.2f, 0.7f}}, | |||||
ValueType = Tensor.TensorType.FloatingPoint | |||||
}; | |||||
Tensor dst = new Tensor | |||||
{ | |||||
Data = new float[1, 3], | |||||
ValueType = Tensor.TensorType.FloatingPoint | |||||
}; | |||||
m.Eval(src, dst); | |||||
float[] reference = {2, 2, 1}; | |||||
int i = 0; | |||||
foreach (var f in dst.Data) | |||||
{ | |||||
Assert.AreEqual(reference[i], f); | |||||
++i; | |||||
} | |||||
} | |||||
[Test] | |||||
public void TestEvalLogits() | |||||
{ | |||||
Multinomial m = new Multinomial(2018); | |||||
Tensor src = new Tensor | |||||
{ | |||||
Data = new float[1, 3] {{Mathf.Log(0.1f) - 50, Mathf.Log(0.2f) - 50, Mathf.Log(0.7f) - 50}}, | |||||
ValueType = Tensor.TensorType.FloatingPoint | |||||
}; | |||||
Tensor dst = new Tensor | |||||
{ | |||||
Data = new float[1, 3], | |||||
ValueType = Tensor.TensorType.FloatingPoint | |||||
}; | |||||
m.Eval(src, dst); | |||||
float[] reference = {2, 2, 2}; | |||||
int i = 0; | |||||
foreach (var f in dst.Data) | |||||
{ | |||||
Assert.AreEqual(reference[i], f); | |||||
++i; | |||||
} | |||||
} | |||||
[Test] | |||||
public void TestEvalBatching() | |||||
{ | |||||
Multinomial m = new Multinomial(2018); | |||||
Tensor src = new Tensor | |||||
{ | |||||
Data = new float[2, 3] | |||||
{ | |||||
{Mathf.Log(0.1f) - 50, Mathf.Log(0.2f) - 50, Mathf.Log(0.7f) - 50}, | |||||
{Mathf.Log(0.3f) - 25, Mathf.Log(0.4f) - 25, Mathf.Log(0.3f) - 25}, | |||||
}, | |||||
ValueType = Tensor.TensorType.FloatingPoint | |||||
}; | |||||
Tensor dst = new Tensor | |||||
{ | |||||
Data = new float[2, 3], | |||||
ValueType = Tensor.TensorType.FloatingPoint | |||||
}; | |||||
m.Eval(src, dst); | |||||
float[] reference = {2, 2, 2, 0, 1, 0}; | |||||
int i = 0; | |||||
foreach (var f in dst.Data) | |||||
{ | |||||
Assert.AreEqual(reference[i], f); | |||||
++i; | |||||
} | |||||
} | |||||
[Test] | |||||
public void TestSrcInt() | |||||
{ | |||||
Multinomial m = new Multinomial(2018); | |||||
Tensor src = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.Integer | |||||
}; | |||||
Assert.Throws<NotImplementedException>(() => m.Eval(src, null)); | |||||
} | |||||
[Test] | |||||
public void TestDstInt() | |||||
{ | |||||
Multinomial m = new Multinomial(2018); | |||||
Tensor src = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.FloatingPoint | |||||
}; | |||||
Tensor dst = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.Integer | |||||
}; | |||||
Assert.Throws<ArgumentException>(() => m.Eval(src, dst)); | |||||
} | |||||
[Test] | |||||
public void TestSrcDataNull() | |||||
{ | |||||
Multinomial m = new Multinomial(2018); | |||||
Tensor src = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.FloatingPoint | |||||
}; | |||||
Tensor dst = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.FloatingPoint | |||||
}; | |||||
Assert.Throws<ArgumentNullException>(() => m.Eval(src, dst)); | |||||
} | |||||
[Test] | |||||
public void TestDstDataNull() | |||||
{ | |||||
Multinomial m = new Multinomial(2018); | |||||
Tensor src = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.FloatingPoint, | |||||
Data = new float[1] | |||||
}; | |||||
Tensor dst = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.FloatingPoint | |||||
}; | |||||
Assert.Throws<ArgumentNullException>(() => m.Eval(src, dst)); | |||||
} | |||||
[Test] | |||||
public void TestSrcWrongShape() | |||||
{ | |||||
Multinomial m = new Multinomial(2018); | |||||
Tensor src = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.FloatingPoint, | |||||
Data = new float[1] | |||||
}; | |||||
Tensor dst = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.FloatingPoint, | |||||
Data = new float[1] | |||||
}; | |||||
Assert.Throws<ArgumentException>(() => m.Eval(src, dst)); | |||||
} | |||||
[Test] | |||||
public void TestDstWrongShape() | |||||
{ | |||||
Multinomial m = new Multinomial(2018); | |||||
Tensor src = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.FloatingPoint, | |||||
Data = new float[1, 1] | |||||
}; | |||||
Tensor dst = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.FloatingPoint, | |||||
Data = new float[1] | |||||
}; | |||||
Assert.Throws<ArgumentException>(() => m.Eval(src, dst)); | |||||
} | |||||
[Test] | |||||
public void TestUnequalBatchSize() | |||||
{ | |||||
Multinomial m = new Multinomial(2018); | |||||
Tensor src = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.FloatingPoint, | |||||
Data = new float[1, 1] | |||||
}; | |||||
Tensor dst = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.FloatingPoint, | |||||
Data = new float[2, 1] | |||||
}; | |||||
Assert.Throws<ArgumentException>(() => m.Eval(src, dst)); | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: 668f4ac2d83814df5a8883722633e4e5 | |||||
MonoImporter: | |||||
externalObjects: {} | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using System; | |||||
using NUnit.Framework; | |||||
using MLAgents.InferenceBrain; | |||||
using MLAgents.InferenceBrain.Utils; | |||||
namespace MLAgents.Tests | |||||
{ | |||||
public class RandomNormalTest | |||||
{ | |||||
[Test] | |||||
public void RandomNormalTestTwoDouble() | |||||
{ | |||||
RandomNormal rn = new RandomNormal(2018); | |||||
Assert.AreEqual(-0.46666, rn.NextDouble(), 0.0001); | |||||
Assert.AreEqual(-0.37989, rn.NextDouble(), 0.0001); | |||||
} | |||||
[Test] | |||||
public void RandomNormalTestWithMean() | |||||
{ | |||||
RandomNormal rn = new RandomNormal(2018, 5.0f); | |||||
Assert.AreEqual(4.53333, rn.NextDouble(), 0.0001); | |||||
Assert.AreEqual(4.6201, rn.NextDouble(), 0.0001); | |||||
} | |||||
[Test] | |||||
public void RandomNormalTestWithStddev() | |||||
{ | |||||
RandomNormal rn = new RandomNormal(2018, 1.0f, 4.2f); | |||||
Assert.AreEqual(-0.9599, rn.NextDouble(), 0.0001); | |||||
Assert.AreEqual(-0.5955, rn.NextDouble(), 0.0001); | |||||
} | |||||
[Test] | |||||
public void RandomNormalTestWithMeanStddev() | |||||
{ | |||||
RandomNormal rn = new RandomNormal(2018, -3.2f, 2.2f); | |||||
Assert.AreEqual(-4.2266, rn.NextDouble(), 0.0001); | |||||
Assert.AreEqual(-4.0357, rn.NextDouble(), 0.0001); | |||||
} | |||||
[Test] | |||||
public void RandomNormalTestTensorInt() | |||||
{ | |||||
RandomNormal rn = new RandomNormal(1982); | |||||
Tensor t = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.Integer | |||||
}; | |||||
Assert.Throws<NotImplementedException>(() => rn.FillTensor(t)); | |||||
} | |||||
[Test] | |||||
public void RandomNormalTestDataNull() | |||||
{ | |||||
RandomNormal rn = new RandomNormal(1982); | |||||
Tensor t = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.FloatingPoint | |||||
}; | |||||
Assert.Throws<ArgumentNullException>(() => rn.FillTensor(t)); | |||||
} | |||||
[Test] | |||||
public void RandomNormalTestTensor() | |||||
{ | |||||
RandomNormal rn = new RandomNormal(1982); | |||||
Tensor t = new Tensor | |||||
{ | |||||
ValueType = Tensor.TensorType.FloatingPoint, | |||||
Data = Array.CreateInstance(typeof(float), new long[3] {3, 4, 2}) | |||||
}; | |||||
rn.FillTensor(t); | |||||
float[] reference = new float[] | |||||
{ | |||||
-0.2139822f, | |||||
0.5051259f, | |||||
-0.5640336f, | |||||
-0.3357787f, | |||||
-0.2055894f, | |||||
-0.09432302f, | |||||
-0.01419199f, | |||||
0.53621f, | |||||
-0.5507085f, | |||||
-0.2651141f, | |||||
0.09315512f, | |||||
-0.04918706f, | |||||
-0.179625f, | |||||
0.2280539f, | |||||
0.1883962f, | |||||
0.4047216f, | |||||
0.1704049f, | |||||
0.5050544f, | |||||
-0.3365685f, | |||||
0.3542781f, | |||||
0.5951571f, | |||||
0.03460682f, | |||||
-0.5537263f, | |||||
-0.4378373f, | |||||
}; | |||||
int i = 0; | |||||
foreach (float f in t.Data) | |||||
{ | |||||
Assert.AreEqual(f, reference[i], 0.0001); | |||||
++i; | |||||
} | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: 518c8e6e10fd94059a064ffbe65557af | |||||
MonoImporter: | |||||
externalObjects: {} | |||||
serializedVersion: 2 | |||||
defaultReferences: [] | |||||
executionOrder: 0 | |||||
icon: {instanceID: 0} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
using NUnit.Framework; | |||||
using UnityEngine; | |||||
namespace MLAgents.Tests | |||||
{ | |||||
public class UtilitiesTests | |||||
{ | |||||
[Test] | |||||
public void TestCumSum() | |||||
{ | |||||
var output = Utilities.CumSum(new int[]{1, 2, 3, 10}); | |||||
CollectionAssert.AreEqual(output, new int[] {0, 1, 3, 6, 16}); | |||||
output = Utilities.CumSum(new int[0]); | |||||
CollectionAssert.AreEqual(output, new int[]{0}); | |||||
output = Utilities.CumSum(new int[]{100}); | |||||
CollectionAssert.AreEqual(output, new int[]{0, 100}); | |||||
output = Utilities.CumSum(new int[]{-1, 10}); | |||||
CollectionAssert.AreEqual(output, new int[]{0, -1, 9}); | |||||
} | |||||
} | |||||
} |
fileFormatVersion: 2 | |||||
guid: 45ab7fc6851444d8ba622b4f63b8290b | |||||
timeCreated: 1538775063 |
fileFormatVersion: 2 | |||||
guid: 6584f096f53dc43eeb32803b91f36c5c | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: f8097eaa1623c4a8ab4eff559e20fedb | |||||
folderAsset: yes | |||||
timeCreated: 1504127718 | |||||
licenseType: Pro | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: 70626ce713f4a428e9b72ab06365ec0d | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
%YAML 1.1 | |||||
%TAG !u! tag:unity3d.com,2011: | |||||
--- !u!114 &11400000 | |||||
MonoBehaviour: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_GameObject: {fileID: 0} | |||||
m_Enabled: 1 | |||||
m_EditorHideFlags: 0 | |||||
m_Script: {fileID: 11500000, guid: 8b23992c8eb17439887f5e944bf04a40, type: 3} | |||||
m_Name: 3DBallHardLearning | |||||
m_EditorClassIdentifier: | |||||
brainParameters: | |||||
vectorObservationSize: 5 | |||||
numStackedVectorObservations: 9 | |||||
vectorActionSize: 02000000 | |||||
cameraResolutions: [] | |||||
vectorActionDescriptions: | |||||
- | |||||
- | |||||
vectorActionSpaceType: 1 | |||||
model: {fileID: 11400000, guid: 8be33caeca04d43498913448b5364f2b, type: 3} |
fileFormatVersion: 2 | |||||
guid: 4f74e089fbb75455ebf6f0495e30be6e | |||||
NativeFormatImporter: | |||||
externalObjects: {} | |||||
mainObjectFileID: 11400000 | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
%YAML 1.1 | |||||
%TAG !u! tag:unity3d.com,2011: | |||||
--- !u!114 &11400000 | |||||
MonoBehaviour: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_GameObject: {fileID: 0} | |||||
m_Enabled: 1 | |||||
m_EditorHideFlags: 0 | |||||
m_Script: {fileID: 11500000, guid: 41e9bda8f3cf1492fa74926a530f6f70, type: 3} | |||||
m_Name: 3DBallHardPlayer | |||||
m_EditorClassIdentifier: | |||||
brainParameters: | |||||
vectorObservationSize: 5 | |||||
numStackedVectorObservations: 9 | |||||
vectorActionSize: 02000000 | |||||
cameraResolutions: [] | |||||
vectorActionDescriptions: | |||||
- | |||||
- | |||||
vectorActionSpaceType: 1 | |||||
keyContinuousPlayerActions: [] | |||||
axisContinuousPlayerActions: | |||||
- axis: Horizontal | |||||
index: 0 | |||||
scale: -1 | |||||
- axis: Vertical | |||||
index: 1 | |||||
scale: 1 | |||||
discretePlayerActions: [] |
fileFormatVersion: 2 | |||||
guid: 55f48be32ac184c6ab67cf647100bac4 | |||||
NativeFormatImporter: | |||||
externalObjects: {} | |||||
mainObjectFileID: 11400000 | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
%YAML 1.1 | |||||
%TAG !u! tag:unity3d.com,2011: | |||||
--- !u!114 &11400000 | |||||
MonoBehaviour: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_GameObject: {fileID: 0} | |||||
m_Enabled: 1 | |||||
m_EditorHideFlags: 0 | |||||
m_Script: {fileID: 11500000, guid: 943466ab374444748a364f9d6c3e2fe2, type: 3} | |||||
m_Name: 3DBallHeuristic | |||||
m_EditorClassIdentifier: | |||||
brainParameters: | |||||
vectorObservationSize: 8 | |||||
numStackedVectorObservations: 1 | |||||
vectorActionSize: 02000000 | |||||
cameraResolutions: [] | |||||
vectorActionDescriptions: | |||||
- | |||||
- | |||||
vectorActionSpaceType: 1 | |||||
isExternal: 0 | |||||
decision: {fileID: 0} | |||||
decisionScript: {fileID: 11500000, guid: 67264e06e07fb40d8939b0860ebee773, type: 3} | |||||
c_decision: RandomDecision |
fileFormatVersion: 2 | |||||
guid: 3a0cd58e7f0764eea8952cb416295fd0 | |||||
NativeFormatImporter: | |||||
externalObjects: {} | |||||
mainObjectFileID: 11400000 | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
%YAML 1.1 | |||||
%TAG !u! tag:unity3d.com,2011: | |||||
--- !u!114 &11400000 | |||||
MonoBehaviour: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_GameObject: {fileID: 0} | |||||
m_Enabled: 1 | |||||
m_EditorHideFlags: 0 | |||||
m_Script: {fileID: 11500000, guid: 8b23992c8eb17439887f5e944bf04a40, type: 3} | |||||
m_Name: 3DBallLearning | |||||
m_EditorClassIdentifier: | |||||
brainParameters: | |||||
vectorObservationSize: 8 | |||||
numStackedVectorObservations: 1 | |||||
vectorActionSize: 02000000 | |||||
cameraResolutions: [] | |||||
vectorActionDescriptions: | |||||
- | |||||
- | |||||
vectorActionSpaceType: 1 | |||||
model: {fileID: 11400000, guid: c282d4bbc4c8f4e78b2bb29eccd17557, type: 3} |
fileFormatVersion: 2 | |||||
guid: 383c589e8bb76464eadc2525b5b0f2c1 | |||||
NativeFormatImporter: | |||||
externalObjects: {} | |||||
mainObjectFileID: 11400000 | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
%YAML 1.1 | |||||
%TAG !u! tag:unity3d.com,2011: | |||||
--- !u!114 &11400000 | |||||
MonoBehaviour: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_GameObject: {fileID: 0} | |||||
m_Enabled: 1 | |||||
m_EditorHideFlags: 0 | |||||
m_Script: {fileID: 11500000, guid: 41e9bda8f3cf1492fa74926a530f6f70, type: 3} | |||||
m_Name: 3DBallPlayer | |||||
m_EditorClassIdentifier: | |||||
brainParameters: | |||||
vectorObservationSize: 8 | |||||
numStackedVectorObservations: 1 | |||||
vectorActionSize: 02000000 | |||||
cameraResolutions: [] | |||||
vectorActionDescriptions: | |||||
- | |||||
- | |||||
vectorActionSpaceType: 1 | |||||
isExternal: 0 | |||||
keyContinuousPlayerActions: [] | |||||
axisContinuousPlayerActions: | |||||
- axis: Horizontal | |||||
index: 0 | |||||
scale: 1 | |||||
- axis: Vertical | |||||
index: 1 | |||||
scale: 1 | |||||
discretePlayerActions: | |||||
- key: 12 | |||||
branchIndex: 4 | |||||
value: 0 | |||||
- key: 0 | |||||
branchIndex: 4 | |||||
value: 0 | |||||
- key: 0 | |||||
branchIndex: 0 | |||||
value: 0 | |||||
- key: 0 | |||||
branchIndex: 0 | |||||
value: 0 |
fileFormatVersion: 2 | |||||
guid: 97d8f9d40dc8c452f932f7caa9549c7d | |||||
NativeFormatImporter: | |||||
externalObjects: {} | |||||
mainObjectFileID: 11400000 | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: f480b7a50f9974756b821ca885514018 | |||||
folderAsset: yes | |||||
timeCreated: 1497125575 | |||||
licenseType: Pro | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: c1d20401220d74fef901ca46558766ea | |||||
folderAsset: yes | |||||
timeCreated: 1501267188 | |||||
licenseType: Pro | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
%YAML 1.1 | |||||
%TAG !u! tag:unity3d.com,2011: | |||||
--- !u!21 &2100000 | |||||
Material: | |||||
serializedVersion: 6 | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_Name: logo1 | |||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} | |||||
m_ShaderKeywords: _ALPHAPREMULTIPLY_ON | |||||
m_LightmapFlags: 4 | |||||
m_EnableInstancingVariants: 0 | |||||
m_DoubleSidedGI: 0 | |||||
m_CustomRenderQueue: 3000 | |||||
stringTagMap: | |||||
RenderType: Transparent | |||||
disabledShaderPasses: [] | |||||
m_SavedProperties: | |||||
serializedVersion: 3 | |||||
m_TexEnvs: | |||||
- _BumpMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _DetailAlbedoMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _DetailMask: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _DetailNormalMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _EmissionMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _MainTex: | |||||
m_Texture: {fileID: 2800000, guid: 0d342588c0383439e92173c7356b6e4c, type: 3} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _MetallicGlossMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _OcclusionMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _ParallaxMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
m_Floats: | |||||
- _BumpScale: 1 | |||||
- _Cutoff: 0.5 | |||||
- _DetailNormalMapScale: 1 | |||||
- _DstBlend: 10 | |||||
- _GlossMapScale: 1 | |||||
- _Glossiness: 1 | |||||
- _GlossyReflections: 1 | |||||
- _Metallic: 0 | |||||
- _Mode: 3 | |||||
- _OcclusionStrength: 1 | |||||
- _Parallax: 0.02 | |||||
- _SmoothnessTextureChannel: 0 | |||||
- _SpecularHighlights: 1 | |||||
- _SrcBlend: 1 | |||||
- _UVSec: 0 | |||||
- _ZWrite: 0 | |||||
m_Colors: | |||||
- _Color: {r: 1, g: 1, b: 1, a: 1} | |||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} |
fileFormatVersion: 2 | |||||
guid: e35c6159207d7448e988c8cf0c137ab6 | |||||
timeCreated: 1501267793 | |||||
licenseType: Pro | |||||
NativeFormatImporter: | |||||
mainObjectFileID: 2100000 | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
%YAML 1.1 | |||||
%TAG !u! tag:unity3d.com,2011: | |||||
--- !u!21 &2100000 | |||||
Material: | |||||
serializedVersion: 6 | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_Name: logo2 | |||||
m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} | |||||
m_ShaderKeywords: | |||||
m_LightmapFlags: 4 | |||||
m_EnableInstancingVariants: 0 | |||||
m_DoubleSidedGI: 0 | |||||
m_CustomRenderQueue: -1 | |||||
stringTagMap: {} | |||||
disabledShaderPasses: [] | |||||
m_SavedProperties: | |||||
serializedVersion: 3 | |||||
m_TexEnvs: | |||||
- _BumpMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _DetailAlbedoMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _DetailMask: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _DetailNormalMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _EmissionMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _MainTex: | |||||
m_Texture: {fileID: 2800000, guid: 0d342588c0383439e92173c7356b6e4c, type: 3} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _MetallicGlossMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _OcclusionMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _ParallaxMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
m_Floats: | |||||
- _BumpScale: 1 | |||||
- _Cutoff: 0.5 | |||||
- _DetailNormalMapScale: 1 | |||||
- _DstBlend: 0 | |||||
- _GlossMapScale: 1 | |||||
- _Glossiness: 0.5 | |||||
- _GlossyReflections: 1 | |||||
- _Metallic: 0 | |||||
- _Mode: 0 | |||||
- _OcclusionStrength: 1 | |||||
- _Parallax: 0.02 | |||||
- _SmoothnessTextureChannel: 0 | |||||
- _SpecularHighlights: 1 | |||||
- _SrcBlend: 1 | |||||
- _UVSec: 0 | |||||
- _ZWrite: 1 | |||||
m_Colors: | |||||
- _Color: {r: 1, g: 1, b: 1, a: 1} | |||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} |
fileFormatVersion: 2 | |||||
guid: 4efff3f0f46984b78ae6161ef6558291 | |||||
timeCreated: 1501706173 | |||||
licenseType: Free | |||||
NativeFormatImporter: | |||||
mainObjectFileID: 2100000 | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
%YAML 1.1 | |||||
%TAG !u! tag:unity3d.com,2011: | |||||
--- !u!21 &2100000 | |||||
Material: | |||||
serializedVersion: 6 | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 0} | |||||
m_Name: Text | |||||
m_Shader: {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} | |||||
m_ShaderKeywords: | |||||
m_LightmapFlags: 4 | |||||
m_EnableInstancingVariants: 0 | |||||
m_DoubleSidedGI: 0 | |||||
m_CustomRenderQueue: -1 | |||||
stringTagMap: {} | |||||
disabledShaderPasses: [] | |||||
m_SavedProperties: | |||||
serializedVersion: 3 | |||||
m_TexEnvs: | |||||
- _BumpMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _DetailAlbedoMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _DetailMask: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _DetailNormalMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _EmissionMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _MainTex: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _MetallicGlossMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _OcclusionMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
- _ParallaxMap: | |||||
m_Texture: {fileID: 0} | |||||
m_Scale: {x: 1, y: 1} | |||||
m_Offset: {x: 0, y: 0} | |||||
m_Floats: | |||||
- _BumpScale: 1 | |||||
- _ColorMask: 15 | |||||
- _Cutoff: 0.5 | |||||
- _DetailNormalMapScale: 1 | |||||
- _DstBlend: 0 | |||||
- _GlossMapScale: 1 | |||||
- _Glossiness: 0.5 | |||||
- _GlossyReflections: 1 | |||||
- _Metallic: 0 | |||||
- _Mode: 0 | |||||
- _OcclusionStrength: 1 | |||||
- _Parallax: 0.02 | |||||
- _SmoothnessTextureChannel: 0 | |||||
- _SpecularHighlights: 1 | |||||
- _SrcBlend: 1 | |||||
- _Stencil: 0 | |||||
- _StencilComp: 8 | |||||
- _StencilOp: 0 | |||||
- _StencilReadMask: 255 | |||||
- _StencilWriteMask: 255 | |||||
- _UVSec: 0 | |||||
- _UseUIAlphaClip: 0 | |||||
- _ZWrite: 1 | |||||
m_Colors: | |||||
- _Color: {r: 1, g: 1, b: 1, a: 1} | |||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1} |
fileFormatVersion: 2 | |||||
guid: 58e2b2715aaee4686a912897f823f8f5 | |||||
timeCreated: 1501268164 | |||||
licenseType: Pro | |||||
NativeFormatImporter: | |||||
mainObjectFileID: 2100000 | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: 0d342588c0383439e92173c7356b6e4c | |||||
timeCreated: 1501268935 | |||||
licenseType: Pro | |||||
TextureImporter: | |||||
fileIDToRecycleName: {} | |||||
serializedVersion: 4 | |||||
mipmaps: | |||||
mipMapMode: 0 | |||||
enableMipMap: 1 | |||||
sRGBTexture: 1 | |||||
linearTexture: 0 | |||||
fadeOut: 0 | |||||
borderMipMap: 0 | |||||
mipMapsPreserveCoverage: 0 | |||||
alphaTestReferenceValue: 0.5 | |||||
mipMapFadeDistanceStart: 1 | |||||
mipMapFadeDistanceEnd: 3 | |||||
bumpmap: | |||||
convertToNormalMap: 0 | |||||
externalNormalMap: 0 | |||||
heightScale: 0.25 | |||||
normalMapFilter: 0 | |||||
isReadable: 0 | |||||
grayScaleToAlpha: 0 | |||||
generateCubemap: 6 | |||||
cubemapConvolution: 0 | |||||
seamlessCubemap: 0 | |||||
textureFormat: 1 | |||||
maxTextureSize: 2048 | |||||
textureSettings: | |||||
serializedVersion: 2 | |||||
filterMode: -1 | |||||
aniso: -1 | |||||
mipBias: -1 | |||||
wrapU: 0 | |||||
wrapV: 0 | |||||
wrapW: 0 | |||||
nPOTScale: 0 | |||||
lightmap: 0 | |||||
compressionQuality: 50 | |||||
spriteMode: 1 | |||||
spriteExtrude: 1 | |||||
spriteMeshType: 1 | |||||
alignment: 0 | |||||
spritePivot: {x: 0.5, y: 0.5} | |||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} | |||||
spritePixelsToUnits: 100 | |||||
alphaUsage: 1 | |||||
alphaIsTransparency: 1 | |||||
spriteTessellationDetail: -1 | |||||
textureType: 0 | |||||
textureShape: 1 | |||||
maxTextureSizeSet: 0 | |||||
compressionQualitySet: 0 | |||||
textureFormatSet: 0 | |||||
platformSettings: | |||||
- buildTarget: DefaultTexturePlatform | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 1 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
- buildTarget: Standalone | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 1 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
- buildTarget: WebGL | |||||
maxTextureSize: 2048 | |||||
textureFormat: -1 | |||||
textureCompression: 1 | |||||
compressionQuality: 50 | |||||
crunchedCompression: 0 | |||||
allowsAlphaSplitting: 0 | |||||
overridden: 0 | |||||
spriteSheet: | |||||
serializedVersion: 2 | |||||
sprites: [] | |||||
outline: [] | |||||
physicsShape: [] | |||||
spritePackingTag: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: 7f76e451b3030e54eac0f7c5488d22e9 | |||||
folderAsset: yes | |||||
timeCreated: 1506066534 | |||||
licenseType: Free | |||||
DefaultImporter: | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
%YAML 1.1 | |||||
%TAG !u! tag:unity3d.com,2011: | |||||
--- !u!1001 &100100000 | |||||
Prefab: | |||||
m_ObjectHideFlags: 1 | |||||
serializedVersion: 2 | |||||
m_Modification: | |||||
m_TransformParent: {fileID: 0} | |||||
m_Modifications: [] | |||||
m_RemovedComponents: [] | |||||
m_ParentPrefab: {fileID: 0} | |||||
m_RootGameObject: {fileID: 1665577603478558} | |||||
m_IsPrefabParent: 1 | |||||
--- !u!1 &1536511242562482 | |||||
GameObject: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
serializedVersion: 5 | |||||
m_Component: | |||||
- component: {fileID: 4095153324598508} | |||||
- component: {fileID: 33624138613246242} | |||||
- component: {fileID: 135537954369514846} | |||||
- component: {fileID: 23926879167055144} | |||||
- component: {fileID: 54606488393645454} | |||||
m_Layer: 0 | |||||
m_Name: Ball | |||||
m_TagString: Untagged | |||||
m_Icon: {fileID: 0} | |||||
m_NavMeshLayer: 0 | |||||
m_StaticEditorFlags: 0 | |||||
m_IsActive: 1 | |||||
--- !u!1 &1665577603478558 | |||||
GameObject: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
serializedVersion: 5 | |||||
m_Component: | |||||
- component: {fileID: 4162486845013972} | |||||
m_Layer: 0 | |||||
m_Name: Game | |||||
m_TagString: Untagged | |||||
m_Icon: {fileID: 0} | |||||
m_NavMeshLayer: 0 | |||||
m_StaticEditorFlags: 0 | |||||
m_IsActive: 1 | |||||
--- !u!1 &1796982831911906 | |||||
GameObject: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
serializedVersion: 5 | |||||
m_Component: | |||||
- component: {fileID: 4426913383042176} | |||||
- component: {fileID: 33771194379694972} | |||||
- component: {fileID: 64845544452232838} | |||||
- component: {fileID: 23074177913792258} | |||||
m_Layer: 0 | |||||
m_Name: Plane (1) | |||||
m_TagString: Untagged | |||||
m_Icon: {fileID: 0} | |||||
m_NavMeshLayer: 0 | |||||
m_StaticEditorFlags: 0 | |||||
m_IsActive: 1 | |||||
--- !u!1 &1914042422505674 | |||||
GameObject: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
serializedVersion: 5 | |||||
m_Component: | |||||
- component: {fileID: 4014323973652284} | |||||
- component: {fileID: 33653230733766482} | |||||
- component: {fileID: 65551894134645910} | |||||
- component: {fileID: 23487775825466554} | |||||
- component: {fileID: 114980646877373948} | |||||
m_Layer: 0 | |||||
m_Name: Platform | |||||
m_TagString: Untagged | |||||
m_Icon: {fileID: 0} | |||||
m_NavMeshLayer: 0 | |||||
m_StaticEditorFlags: 0 | |||||
m_IsActive: 1 | |||||
--- !u!4 &4014323973652284 | |||||
Transform: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1914042422505674} | |||||
m_LocalRotation: {x: -0.069583125, y: 0.0049145464, z: 0.0702813, w: 0.99508524} | |||||
m_LocalPosition: {x: 0, y: 2.22, z: -5} | |||||
m_LocalScale: {x: 5, y: 0.19999997, z: 5} | |||||
m_Children: | |||||
- {fileID: 4426913383042176} | |||||
m_Father: {fileID: 4162486845013972} | |||||
m_RootOrder: 0 | |||||
m_LocalEulerAnglesHint: {x: -8, y: 0, z: 8.08} | |||||
--- !u!4 &4095153324598508 | |||||
Transform: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1536511242562482} | |||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} | |||||
m_LocalPosition: {x: 0, y: 6.2200003, z: -5} | |||||
m_LocalScale: {x: 1, y: 1, z: 1} | |||||
m_Children: [] | |||||
m_Father: {fileID: 4162486845013972} | |||||
m_RootOrder: 1 | |||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} | |||||
--- !u!4 &4162486845013972 | |||||
Transform: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1665577603478558} | |||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} | |||||
m_LocalPosition: {x: -10.3, y: 9, z: 5} | |||||
m_LocalScale: {x: 1, y: 1, z: 1} | |||||
m_Children: | |||||
- {fileID: 4014323973652284} | |||||
- {fileID: 4095153324598508} | |||||
m_Father: {fileID: 0} | |||||
m_RootOrder: 0 | |||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} | |||||
--- !u!4 &4426913383042176 | |||||
Transform: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1796982831911906} | |||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} | |||||
m_LocalPosition: {x: 0, y: 0.51, z: 0} | |||||
m_LocalScale: {x: 0.1, y: 0.1, z: 0.1} | |||||
m_Children: [] | |||||
m_Father: {fileID: 4014323973652284} | |||||
m_RootOrder: 0 | |||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} | |||||
--- !u!23 &23074177913792258 | |||||
MeshRenderer: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1796982831911906} | |||||
m_Enabled: 1 | |||||
m_CastShadows: 0 | |||||
m_ReceiveShadows: 0 | |||||
m_DynamicOccludee: 1 | |||||
m_MotionVectors: 1 | |||||
m_LightProbeUsage: 1 | |||||
m_ReflectionProbeUsage: 1 | |||||
m_Materials: | |||||
- {fileID: 2100000, guid: e35c6159207d7448e988c8cf0c137ab6, type: 2} | |||||
m_StaticBatchInfo: | |||||
firstSubMesh: 0 | |||||
subMeshCount: 0 | |||||
m_StaticBatchRoot: {fileID: 0} | |||||
m_ProbeAnchor: {fileID: 0} | |||||
m_LightProbeVolumeOverride: {fileID: 0} | |||||
m_ScaleInLightmap: 1 | |||||
m_PreserveUVs: 1 | |||||
m_IgnoreNormalsForChartDetection: 0 | |||||
m_ImportantGI: 0 | |||||
m_StitchLightmapSeams: 0 | |||||
m_SelectedEditorRenderState: 3 | |||||
m_MinimumChartSize: 4 | |||||
m_AutoUVMaxDistance: 0.5 | |||||
m_AutoUVMaxAngle: 89 | |||||
m_LightmapParameters: {fileID: 0} | |||||
m_SortingLayerID: 0 | |||||
m_SortingLayer: 0 | |||||
m_SortingOrder: 0 | |||||
--- !u!23 &23487775825466554 | |||||
MeshRenderer: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1914042422505674} | |||||
m_Enabled: 1 | |||||
m_CastShadows: 1 | |||||
m_ReceiveShadows: 1 | |||||
m_DynamicOccludee: 1 | |||||
m_MotionVectors: 1 | |||||
m_LightProbeUsage: 1 | |||||
m_ReflectionProbeUsage: 1 | |||||
m_Materials: | |||||
- {fileID: 2100000, guid: 00d852aac9443402984416f9dbcd22ea, type: 2} | |||||
m_StaticBatchInfo: | |||||
firstSubMesh: 0 | |||||
subMeshCount: 0 | |||||
m_StaticBatchRoot: {fileID: 0} | |||||
m_ProbeAnchor: {fileID: 0} | |||||
m_LightProbeVolumeOverride: {fileID: 0} | |||||
m_ScaleInLightmap: 1 | |||||
m_PreserveUVs: 1 | |||||
m_IgnoreNormalsForChartDetection: 0 | |||||
m_ImportantGI: 0 | |||||
m_StitchLightmapSeams: 0 | |||||
m_SelectedEditorRenderState: 3 | |||||
m_MinimumChartSize: 4 | |||||
m_AutoUVMaxDistance: 0.5 | |||||
m_AutoUVMaxAngle: 89 | |||||
m_LightmapParameters: {fileID: 0} | |||||
m_SortingLayerID: 0 | |||||
m_SortingLayer: 0 | |||||
m_SortingOrder: 0 | |||||
--- !u!23 &23926879167055144 | |||||
MeshRenderer: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1536511242562482} | |||||
m_Enabled: 1 | |||||
m_CastShadows: 1 | |||||
m_ReceiveShadows: 1 | |||||
m_DynamicOccludee: 1 | |||||
m_MotionVectors: 1 | |||||
m_LightProbeUsage: 1 | |||||
m_ReflectionProbeUsage: 1 | |||||
m_Materials: | |||||
- {fileID: 2100000, guid: edd958d75ed1448138de86f3335ea4fa, type: 2} | |||||
m_StaticBatchInfo: | |||||
firstSubMesh: 0 | |||||
subMeshCount: 0 | |||||
m_StaticBatchRoot: {fileID: 0} | |||||
m_ProbeAnchor: {fileID: 0} | |||||
m_LightProbeVolumeOverride: {fileID: 0} | |||||
m_ScaleInLightmap: 1 | |||||
m_PreserveUVs: 1 | |||||
m_IgnoreNormalsForChartDetection: 0 | |||||
m_ImportantGI: 0 | |||||
m_StitchLightmapSeams: 0 | |||||
m_SelectedEditorRenderState: 3 | |||||
m_MinimumChartSize: 4 | |||||
m_AutoUVMaxDistance: 0.5 | |||||
m_AutoUVMaxAngle: 89 | |||||
m_LightmapParameters: {fileID: 0} | |||||
m_SortingLayerID: 0 | |||||
m_SortingLayer: 0 | |||||
m_SortingOrder: 0 | |||||
--- !u!33 &33624138613246242 | |||||
MeshFilter: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1536511242562482} | |||||
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} | |||||
--- !u!33 &33653230733766482 | |||||
MeshFilter: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1914042422505674} | |||||
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} | |||||
--- !u!33 &33771194379694972 | |||||
MeshFilter: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1796982831911906} | |||||
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} | |||||
--- !u!54 &54606488393645454 | |||||
Rigidbody: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1536511242562482} | |||||
serializedVersion: 2 | |||||
m_Mass: 1 | |||||
m_Drag: 0 | |||||
m_AngularDrag: 0.01 | |||||
m_UseGravity: 1 | |||||
m_IsKinematic: 0 | |||||
m_Interpolate: 0 | |||||
m_Constraints: 0 | |||||
m_CollisionDetection: 0 | |||||
--- !u!64 &64845544452232838 | |||||
MeshCollider: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1796982831911906} | |||||
m_Material: {fileID: 0} | |||||
m_IsTrigger: 0 | |||||
m_Enabled: 0 | |||||
serializedVersion: 3 | |||||
m_Convex: 0 | |||||
m_CookingOptions: 14 | |||||
m_SkinWidth: 0.01 | |||||
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} | |||||
--- !u!65 &65551894134645910 | |||||
BoxCollider: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1914042422505674} | |||||
m_Material: {fileID: 0} | |||||
m_IsTrigger: 0 | |||||
m_Enabled: 1 | |||||
serializedVersion: 2 | |||||
m_Size: {x: 1, y: 1, z: 1} | |||||
m_Center: {x: 0, y: 0, z: 0} | |||||
--- !u!114 &114980646877373948 | |||||
MonoBehaviour: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1914042422505674} | |||||
m_Enabled: 1 | |||||
m_EditorHideFlags: 0 | |||||
m_Script: {fileID: 11500000, guid: aaba48bf82bee4751aa7b89569e57f73, type: 3} | |||||
m_Name: | |||||
m_EditorClassIdentifier: | |||||
brain: {fileID: 11400000, guid: 383c589e8bb76464eadc2525b5b0f2c1, type: 2} | |||||
agentParameters: | |||||
agentCameras: [] | |||||
maxStep: 5000 | |||||
resetOnDone: 1 | |||||
onDemandDecision: 0 | |||||
numberOfActionsBetweenDecisions: 5 | |||||
ball: {fileID: 1536511242562482} | |||||
--- !u!135 &135537954369514846 | |||||
SphereCollider: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1536511242562482} | |||||
m_Material: {fileID: 13400000, guid: 56162663048874fd4b10e065f9cf78b7, type: 2} | |||||
m_IsTrigger: 0 | |||||
m_Enabled: 1 | |||||
serializedVersion: 2 | |||||
m_Radius: 0.5 | |||||
m_Center: {x: 0, y: 0, z: 0} |
fileFormatVersion: 2 | |||||
guid: ff026d63a00abdc48ad6ddcff89aba04 | |||||
timeCreated: 1506066551 | |||||
licenseType: Free | |||||
NativeFormatImporter: | |||||
mainObjectFileID: 100100000 | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
%YAML 1.1 | |||||
%TAG !u! tag:unity3d.com,2011: | |||||
--- !u!1001 &100100000 | |||||
Prefab: | |||||
m_ObjectHideFlags: 1 | |||||
serializedVersion: 2 | |||||
m_Modification: | |||||
m_TransformParent: {fileID: 0} | |||||
m_Modifications: [] | |||||
m_RemovedComponents: [] | |||||
m_ParentPrefab: {fileID: 0} | |||||
m_RootGameObject: {fileID: 1236545525418104} | |||||
m_IsPrefabParent: 1 | |||||
--- !u!1 &1236545525418104 | |||||
GameObject: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
serializedVersion: 5 | |||||
m_Component: | |||||
- component: {fileID: 4128795324062154} | |||||
m_Layer: 0 | |||||
m_Name: GameHard | |||||
m_TagString: Untagged | |||||
m_Icon: {fileID: 0} | |||||
m_NavMeshLayer: 0 | |||||
m_StaticEditorFlags: 0 | |||||
m_IsActive: 1 | |||||
--- !u!1 &1334091176806954 | |||||
GameObject: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
serializedVersion: 5 | |||||
m_Component: | |||||
- component: {fileID: 4891208142487102} | |||||
- component: {fileID: 33018876700343880} | |||||
- component: {fileID: 64837101465786842} | |||||
- component: {fileID: 23262352428609250} | |||||
m_Layer: 0 | |||||
m_Name: Plane (1) | |||||
m_TagString: Untagged | |||||
m_Icon: {fileID: 0} | |||||
m_NavMeshLayer: 0 | |||||
m_StaticEditorFlags: 0 | |||||
m_IsActive: 1 | |||||
--- !u!1 &1836508099280124 | |||||
GameObject: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
serializedVersion: 5 | |||||
m_Component: | |||||
- component: {fileID: 4261594809067724} | |||||
- component: {fileID: 33000258395075262} | |||||
- component: {fileID: 65716795579935884} | |||||
- component: {fileID: 23004681142288168} | |||||
- component: {fileID: 114716278740392856} | |||||
m_Layer: 0 | |||||
m_Name: Platform | |||||
m_TagString: Untagged | |||||
m_Icon: {fileID: 0} | |||||
m_NavMeshLayer: 0 | |||||
m_StaticEditorFlags: 0 | |||||
m_IsActive: 1 | |||||
--- !u!1 &1943673078433006 | |||||
GameObject: | |||||
m_ObjectHideFlags: 0 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
serializedVersion: 5 | |||||
m_Component: | |||||
- component: {fileID: 4898959047766504} | |||||
- component: {fileID: 33853974925079708} | |||||
- component: {fileID: 135765715237510820} | |||||
- component: {fileID: 23914679743685510} | |||||
- component: {fileID: 54430881130472984} | |||||
m_Layer: 0 | |||||
m_Name: Ball | |||||
m_TagString: Untagged | |||||
m_Icon: {fileID: 0} | |||||
m_NavMeshLayer: 0 | |||||
m_StaticEditorFlags: 0 | |||||
m_IsActive: 1 | |||||
--- !u!4 &4128795324062154 | |||||
Transform: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1236545525418104} | |||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} | |||||
m_LocalPosition: {x: -9, y: -2, z: 5} | |||||
m_LocalScale: {x: 1, y: 1, z: 1} | |||||
m_Children: | |||||
- {fileID: 4261594809067724} | |||||
- {fileID: 4898959047766504} | |||||
m_Father: {fileID: 0} | |||||
m_RootOrder: 0 | |||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} | |||||
--- !u!4 &4261594809067724 | |||||
Transform: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1836508099280124} | |||||
m_LocalRotation: {x: -0.069583125, y: 0.0049145464, z: 0.0702813, w: 0.99508524} | |||||
m_LocalPosition: {x: 0, y: 2.22, z: -5} | |||||
m_LocalScale: {x: 5, y: 0.19999997, z: 5} | |||||
m_Children: | |||||
- {fileID: 4891208142487102} | |||||
m_Father: {fileID: 4128795324062154} | |||||
m_RootOrder: 0 | |||||
m_LocalEulerAnglesHint: {x: -8, y: 0, z: 8.08} | |||||
--- !u!4 &4891208142487102 | |||||
Transform: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1334091176806954} | |||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} | |||||
m_LocalPosition: {x: 0, y: 0.51, z: 0} | |||||
m_LocalScale: {x: 0.1, y: 0.1, z: 0.1} | |||||
m_Children: [] | |||||
m_Father: {fileID: 4261594809067724} | |||||
m_RootOrder: 0 | |||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} | |||||
--- !u!4 &4898959047766504 | |||||
Transform: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1943673078433006} | |||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} | |||||
m_LocalPosition: {x: 0, y: 6.2200003, z: -5} | |||||
m_LocalScale: {x: 1, y: 1, z: 1} | |||||
m_Children: [] | |||||
m_Father: {fileID: 4128795324062154} | |||||
m_RootOrder: 1 | |||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} | |||||
--- !u!23 &23004681142288168 | |||||
MeshRenderer: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1836508099280124} | |||||
m_Enabled: 1 | |||||
m_CastShadows: 1 | |||||
m_ReceiveShadows: 1 | |||||
m_DynamicOccludee: 1 | |||||
m_MotionVectors: 1 | |||||
m_LightProbeUsage: 1 | |||||
m_ReflectionProbeUsage: 1 | |||||
m_Materials: | |||||
- {fileID: 2100000, guid: 776dd8b57653342839c3fb5f46ce664e, type: 2} | |||||
m_StaticBatchInfo: | |||||
firstSubMesh: 0 | |||||
subMeshCount: 0 | |||||
m_StaticBatchRoot: {fileID: 0} | |||||
m_ProbeAnchor: {fileID: 0} | |||||
m_LightProbeVolumeOverride: {fileID: 0} | |||||
m_ScaleInLightmap: 1 | |||||
m_PreserveUVs: 1 | |||||
m_IgnoreNormalsForChartDetection: 0 | |||||
m_ImportantGI: 0 | |||||
m_StitchLightmapSeams: 0 | |||||
m_SelectedEditorRenderState: 3 | |||||
m_MinimumChartSize: 4 | |||||
m_AutoUVMaxDistance: 0.5 | |||||
m_AutoUVMaxAngle: 89 | |||||
m_LightmapParameters: {fileID: 0} | |||||
m_SortingLayerID: 0 | |||||
m_SortingLayer: 0 | |||||
m_SortingOrder: 0 | |||||
--- !u!23 &23262352428609250 | |||||
MeshRenderer: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1334091176806954} | |||||
m_Enabled: 1 | |||||
m_CastShadows: 0 | |||||
m_ReceiveShadows: 0 | |||||
m_DynamicOccludee: 1 | |||||
m_MotionVectors: 1 | |||||
m_LightProbeUsage: 1 | |||||
m_ReflectionProbeUsage: 1 | |||||
m_Materials: | |||||
- {fileID: 2100000, guid: e35c6159207d7448e988c8cf0c137ab6, type: 2} | |||||
m_StaticBatchInfo: | |||||
firstSubMesh: 0 | |||||
subMeshCount: 0 | |||||
m_StaticBatchRoot: {fileID: 0} | |||||
m_ProbeAnchor: {fileID: 0} | |||||
m_LightProbeVolumeOverride: {fileID: 0} | |||||
m_ScaleInLightmap: 1 | |||||
m_PreserveUVs: 1 | |||||
m_IgnoreNormalsForChartDetection: 0 | |||||
m_ImportantGI: 0 | |||||
m_StitchLightmapSeams: 0 | |||||
m_SelectedEditorRenderState: 3 | |||||
m_MinimumChartSize: 4 | |||||
m_AutoUVMaxDistance: 0.5 | |||||
m_AutoUVMaxAngle: 89 | |||||
m_LightmapParameters: {fileID: 0} | |||||
m_SortingLayerID: 0 | |||||
m_SortingLayer: 0 | |||||
m_SortingOrder: 0 | |||||
--- !u!23 &23914679743685510 | |||||
MeshRenderer: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1943673078433006} | |||||
m_Enabled: 1 | |||||
m_CastShadows: 1 | |||||
m_ReceiveShadows: 1 | |||||
m_DynamicOccludee: 1 | |||||
m_MotionVectors: 1 | |||||
m_LightProbeUsage: 1 | |||||
m_ReflectionProbeUsage: 1 | |||||
m_Materials: | |||||
- {fileID: 2100000, guid: edd958d75ed1448138de86f3335ea4fa, type: 2} | |||||
m_StaticBatchInfo: | |||||
firstSubMesh: 0 | |||||
subMeshCount: 0 | |||||
m_StaticBatchRoot: {fileID: 0} | |||||
m_ProbeAnchor: {fileID: 0} | |||||
m_LightProbeVolumeOverride: {fileID: 0} | |||||
m_ScaleInLightmap: 1 | |||||
m_PreserveUVs: 1 | |||||
m_IgnoreNormalsForChartDetection: 0 | |||||
m_ImportantGI: 0 | |||||
m_StitchLightmapSeams: 0 | |||||
m_SelectedEditorRenderState: 3 | |||||
m_MinimumChartSize: 4 | |||||
m_AutoUVMaxDistance: 0.5 | |||||
m_AutoUVMaxAngle: 89 | |||||
m_LightmapParameters: {fileID: 0} | |||||
m_SortingLayerID: 0 | |||||
m_SortingLayer: 0 | |||||
m_SortingOrder: 0 | |||||
--- !u!33 &33000258395075262 | |||||
MeshFilter: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1836508099280124} | |||||
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} | |||||
--- !u!33 &33018876700343880 | |||||
MeshFilter: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1334091176806954} | |||||
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} | |||||
--- !u!33 &33853974925079708 | |||||
MeshFilter: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1943673078433006} | |||||
m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} | |||||
--- !u!54 &54430881130472984 | |||||
Rigidbody: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1943673078433006} | |||||
serializedVersion: 2 | |||||
m_Mass: 1 | |||||
m_Drag: 0 | |||||
m_AngularDrag: 0.01 | |||||
m_UseGravity: 1 | |||||
m_IsKinematic: 0 | |||||
m_Interpolate: 0 | |||||
m_Constraints: 0 | |||||
m_CollisionDetection: 0 | |||||
--- !u!64 &64837101465786842 | |||||
MeshCollider: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1334091176806954} | |||||
m_Material: {fileID: 0} | |||||
m_IsTrigger: 0 | |||||
m_Enabled: 0 | |||||
serializedVersion: 3 | |||||
m_Convex: 0 | |||||
m_CookingOptions: 14 | |||||
m_SkinWidth: 0.01 | |||||
m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} | |||||
--- !u!65 &65716795579935884 | |||||
BoxCollider: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1836508099280124} | |||||
m_Material: {fileID: 0} | |||||
m_IsTrigger: 0 | |||||
m_Enabled: 1 | |||||
serializedVersion: 2 | |||||
m_Size: {x: 1, y: 1, z: 1} | |||||
m_Center: {x: 0, y: 0, z: 0} | |||||
--- !u!114 &114716278740392856 | |||||
MonoBehaviour: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1836508099280124} | |||||
m_Enabled: 1 | |||||
m_EditorHideFlags: 0 | |||||
m_Script: {fileID: 11500000, guid: edf26e11cf4ed42eaa3ffb7b91bb4676, type: 3} | |||||
m_Name: | |||||
m_EditorClassIdentifier: | |||||
brain: {fileID: 11400000, guid: 4f74e089fbb75455ebf6f0495e30be6e, type: 2} | |||||
agentParameters: | |||||
agentCameras: [] | |||||
maxStep: 5000 | |||||
resetOnDone: 1 | |||||
onDemandDecision: 0 | |||||
numberOfActionsBetweenDecisions: 5 | |||||
ball: {fileID: 1943673078433006} | |||||
--- !u!135 &135765715237510820 | |||||
SphereCollider: | |||||
m_ObjectHideFlags: 1 | |||||
m_PrefabParentObject: {fileID: 0} | |||||
m_PrefabInternal: {fileID: 100100000} | |||||
m_GameObject: {fileID: 1943673078433006} | |||||
m_Material: {fileID: 13400000, guid: 56162663048874fd4b10e065f9cf78b7, type: 2} | |||||
m_IsTrigger: 0 | |||||
m_Enabled: 1 | |||||
serializedVersion: 2 | |||||
m_Radius: 0.5 | |||||
m_Center: {x: 0, y: 0, z: 0} |
fileFormatVersion: 2 | |||||
guid: 50eec9166a3e043dd8102d117835dee6 | |||||
timeCreated: 1515351281 | |||||
licenseType: Pro | |||||
NativeFormatImporter: | |||||
externalObjects: {} | |||||
mainObjectFileID: 100100000 | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: f4933f3f3e4b741de85835dd811541ff | |||||
folderAsset: yes | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: 6f62a2ccb3830437ea4e85a617e856b3 | |||||
timeCreated: 1513216032 | |||||
licenseType: Pro | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |
fileFormatVersion: 2 | |||||
guid: 35c41099ceec44889bdbe95ed86c97ac | |||||
timeCreated: 1513216032 | |||||
licenseType: Pro | |||||
DefaultImporter: | |||||
externalObjects: {} | |||||
userData: | |||||
assetBundleName: | |||||
assetBundleVariant: |