This commit is contained in:
2025-05-13 03:30:23 +03:00
parent 224cfc8cf6
commit 5c489bb6ee
554 changed files with 1114771 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
using UnityEngine;
using System.Collections;
public class AccumulatorAlarm : MonoBehaviour
{
// Use this for initialization
void Start ()
{
// var val = voltage.ToString("0.00");
}
// Update is called once per frame
void Update () {
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0429b6da746ae534daab4982b75de5dc
timeCreated: 1452356245
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+64
View File
@@ -0,0 +1,64 @@
using UnityEngine;
using System.Collections;
public static class AdvancedGizmo {
public enum CircleCloseType{
None,
Direct,
ToCenter
}
public static void Circle(float radius, float angle = 360.0f, int tesselation = 12, CircleCloseType close = CircleCloseType.None, Matrix4x4? transform = null){
var matrixBackup = Gizmos.matrix;
Gizmos.matrix = transform.HasValue ? transform.Value : Matrix4x4.identity;
for (int i = 0; i < tesselation; ++i) {
float angle0 = i * (angle * Mathf.Deg2Rad / tesselation);
float angle1 = (i + 1) * (angle * Mathf.Deg2Rad / tesselation);
var p0 = new Vector3(Mathf.Sin(angle0) * radius, 0, Mathf.Cos(angle0) * radius);
var p1 = new Vector3(Mathf.Sin(angle1) * radius, 0, Mathf.Cos(angle1) * radius);
Gizmos.DrawLine(p0, p1);
}
if (close != CircleCloseType.None) {
float angle1 = angle * Mathf.Deg2Rad;
var p0 = new Vector3(Mathf.Sin(0) * radius, 0, Mathf.Cos(0) * radius);
var p1 = new Vector3(Mathf.Sin(angle1) * radius, 0, Mathf.Cos(angle1) * radius);
if(close == CircleCloseType.Direct){
Gizmos.DrawLine(p0, p1);
}else{
Gizmos.DrawLine(p0, Vector3.zero);
Gizmos.DrawLine(p1, Vector3.zero);
}
}
Gizmos.matrix = matrixBackup;
}
public static void CircleArrow(float radius, float angle = 360.0f, int tesselation = 12, CircleCloseType close = CircleCloseType.None, Matrix4x4? transform = null){
Circle(radius, angle, tesselation, close, transform);
float len = 0.03f;
float wid = 0.01f;
float angleOffset = 2.0f * Mathf.Asin (len / (2.0f * radius)) * Mathf.Sign(angle);
var matrixBackup = Gizmos.matrix;
Gizmos.matrix = transform.HasValue ? transform.Value : Matrix4x4.identity;
var radiusVector = new Vector3(Mathf.Sin(0), 0, Mathf.Cos(0));
var p1 = new Vector3(Mathf.Sin(angleOffset), 0, Mathf.Cos(angleOffset)) * radius;
var p0 = radiusVector * radius;
var dir = (p1 - p0).normalized;
var dir2 = Vector3.Cross (dir, Vector3.up).normalized;
Gizmos.DrawLine(p0, p1 + dir2 * wid);
Gizmos.DrawLine(p0, p1 - dir2 * wid);
Gizmos.DrawLine(p1 + dir2 * wid, p1 - dir2 * wid);
Gizmos.matrix = matrixBackup;
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 10ff9e1069ff610488e0106f7baa9503
timeCreated: 1423391656
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+26
View File
@@ -0,0 +1,26 @@
using UnityEngine;
using System.Collections;
public static class AdvancedPhysics {
public static void AddTorqueAtPosition(this Rigidbody body, Vector3 torque, Vector3 position, ref Vector3 force, ref Vector3 ortho){
Vector3 torqueAxis = torque.normalized;
ortho = new Vector3(1,0,0);
if ( (torqueAxis-ortho).sqrMagnitude < 0.01f ) {
ortho = new Vector3(0,1,0);
}
Vector3.OrthoNormalize(ref torqueAxis, ref ortho);
force = Vector3.Cross(0.5f * torque, ortho);
body.AddForceAtPosition (force, position + ortho);
body.AddForceAtPosition (-force, position - ortho);
}
public static void AddTorqueAtPosition(this Rigidbody body, Vector3 torque, Vector3 position){
Vector3 force = new Vector3 ();
Vector3 ortho = new Vector3 ();
AddTorqueAtPosition (body, torque, position, ref force, ref ortho);
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: af667e3c43d9f2a418ed51318ecc1a3b
timeCreated: 1423542666
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+6
View File
@@ -0,0 +1,6 @@
using UnityEngine;
using System.Collections;
public abstract class Altimeter : Device {
public abstract float GetHeight();
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 68169fe171afc8c4da28278f090c7b84
timeCreated: 1423550689
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+172
View File
@@ -0,0 +1,172 @@
using UnityEngine;
using System.Collections;
using System;
public enum BiquadFilterType {
Lowpass = 0,
Highpass,
Bandpass,
Notch,
Peak,
Lowshelf,
Highshelf
};
[Serializable]
public class BiquadFilter {
//new Biquad(bq_type_peak, 200.0 / sampleRate, 1.0, -3.0);
protected BiquadFilterType filterType;
protected double a0, a1, a2, b1, b2;
public double Fc, Q, peakGain;
protected double z1, z2;
public BiquadFilter() {
filterType = BiquadFilterType.Lowpass;
a0 = 1.0f;
a1 = a2 = b1 = b2 = 0.0f;
Fc = 0.50f;
Q = 0.707f;
peakGain = 0.0f;
z1 = z2 = 0.0f;
}
public BiquadFilter(BiquadFilterType _filterType, double _Fc, double _Q, double _peakGainD) {
SetBiquad(_filterType, _Fc, _Q, _peakGainD);
z1 = z2 = 0.0f;
}
public void SetBiquad(BiquadFilterType _filterType, double _Fc, double _Q, double _peakGainDB) {
filterType = _filterType;
Q = _Q;
Fc = _Fc;
SetPeakGain(_peakGainDB);
}
public void SetType(BiquadFilterType _filterType) {
filterType = _filterType;
CalcBiquad();
}
public void SetQ(double _Q) {
Q = _Q;
CalcBiquad();
}
public void SetFc(double _Fc) {
Fc = _Fc;
CalcBiquad();
}
public void SetPeakGain(double _peakGainDB) {
peakGain = _peakGainDB;
CalcBiquad();
}
public void CalcBiquad() {
double norm;
double V = System.Math.Pow(10.0, System.Math.Abs(peakGain) / 20.0);
double K = System.Math.Tan(3.14159265358979 * Fc);
switch (filterType) {
case BiquadFilterType.Lowpass:
norm = 1 / (1 + K / Q + K * K);
a0 = K * K * norm;
a1 = 2 * a0;
a2 = a0;
b1 = 2 * (K * K - 1) * norm;
b2 = (1 - K / Q + K * K) * norm;
break;
case BiquadFilterType.Highpass:
norm = 1 / (1 + K / Q + K * K);
a0 = 1 * norm;
a1 = -2 * a0;
a2 = a0;
b1 = 2 * (K * K - 1) * norm;
b2 = (1 - K / Q + K * K) * norm;
break;
case BiquadFilterType.Bandpass:
norm = 1 / (1 + K / Q + K * K);
a0 = K / Q * norm;
a1 = 0;
a2 = -a0;
b1 = 2 * (K * K - 1) * norm;
b2 = (1 - K / Q + K * K) * norm;
break;
case BiquadFilterType.Notch:
norm = 1 / (1 + K / Q + K * K);
a0 = (1 + K * K) * norm;
a1 = 2 * (K * K - 1) * norm;
a2 = a0;
b1 = a1;
b2 = (1 - K / Q + K * K) * norm;
break;
case BiquadFilterType.Peak:
if (peakGain >= 0) { // boost
norm = 1 / (1 + 1/Q * K + K * K);
a0 = (1 + V/Q * K + K * K) * norm;
a1 = 2 * (K * K - 1) * norm;
a2 = (1 - V/Q * K + K * K) * norm;
b1 = a1;
b2 = (1 - 1/Q * K + K * K) * norm;
}
else { // cut
norm = 1 / (1 + V/Q * K + K * K);
a0 = (1 + 1/Q * K + K * K) * norm;
a1 = 2 * (K * K - 1) * norm;
a2 = (1 - 1/Q * K + K * K) * norm;
b1 = a1;
b2 = (1 - V/Q * K + K * K) * norm;
}
break;
case BiquadFilterType.Lowshelf:
if (peakGain >= 0) { // boost
norm = 1 / (1 + System.Math.Sqrt(2) * K + K * K);
a0 = (1 + System.Math.Sqrt(2*V) * K + V * K * K) * norm;
a1 = 2 * (V * K * K - 1) * norm;
a2 = (1 - System.Math.Sqrt(2*V) * K + V * K * K) * norm;
b1 = 2 * (K * K - 1) * norm;
b2 = (1 - System.Math.Sqrt(2) * K + K * K) * norm;
}
else { // cut
norm = 1 / (1 + System.Math.Sqrt(2*V) * K + V * K * K);
a0 = (1 + System.Math.Sqrt(2) * K + K * K) * norm;
a1 = 2 * (K * K - 1) * norm;
a2 = (1 - System.Math.Sqrt(2) * K + K * K) * norm;
b1 = 2 * (V * K * K - 1) * norm;
b2 = (1 - System.Math.Sqrt(2*V) * K + V * K * K) * norm;
}
break;
case BiquadFilterType.Highshelf:
if (peakGain >= 0) { // boost
norm = 1 / (1 + System.Math.Sqrt(2) * K + K * K);
a0 = (V + System.Math.Sqrt(2*V) * K + K * K) * norm;
a1 = 2 * (K * K - V) * norm;
a2 = (V - System.Math.Sqrt(2*V) * K + K * K) * norm;
b1 = 2 * (K * K - 1) * norm;
b2 = (1 - System.Math.Sqrt(2) * K + K * K) * norm;
}
else { // cut
norm = 1 / (V + System.Math.Sqrt(2*V) * K + K * K);
a0 = (1 + System.Math.Sqrt(2) * K + K * K) * norm;
a1 = 2 * (K * K - 1) * norm;
a2 = (1 - System.Math.Sqrt(2) * K + K * K) * norm;
b1 = 2 * (K * K - V) * norm;
b2 = (V - System.Math.Sqrt(2*V) * K + K * K) * norm;
}
break;
}
return;
}
public double Process(double input) {
double output = input * a0 + z1;
z1 = input * a1 + z2 - b1 * output;
z2 = input * a2 - b2 * output;
return output;
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f6464d43440f27d438b7a694cc926299
timeCreated: 1425818051
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+77
View File
@@ -0,0 +1,77 @@
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class CameraController : MonoBehaviour {
public bool Active = false;
public float sensitivity = 2F;
float rotationY = 0F;
Vector3 Speed = new Vector3();
public float MaxSpeed = 10f;
public float AccelerationTime = 1f;
public float BrakingTime = 0.5f;
void Start ()
{
rotationY = -transform.localEulerAngles.x;
}
void Update ()
{
if(Input.GetKeyDown("mouse 1")){
Active = !Active;
}
Screen.lockCursor = Active;
if (!Active) return;
float rotationX = transform.localEulerAngles.y + Input.GetAxis("Mouse X") * sensitivity;
rotationY += Input.GetAxis("Mouse Y") * sensitivity;
rotationY = Mathf.Clamp (rotationY, -90, 90);
transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
Vector3 AccelerationForce = new Vector3(
((Input.GetKey("d")? 1f:0f)-(Input.GetKey("a")? 1f:0f)),
((Input.GetKey("space")? 1f:0f)-(Input.GetKey("left ctrl")? 1f:0f)),
((Input.GetKey("w")? 1f:0f)-(Input.GetKey("s")? 1f:0f))
);
AccelerationForce *= (Time.deltaTime/AccelerationTime);
Speed += AccelerationForce;
Vector3 BrakingForce = new Vector3(
(Input.GetKey("d")|Input.GetKey("a"))? 0f:1f,
(Input.GetKey("space")|Input.GetKey("left ctrl"))? 0f:1f,
(Input.GetKey("w")|Input.GetKey("s"))? 0f:1f
);
BrakingForce *= (Time.deltaTime/BrakingTime);
Speed.Set(
Speed.x-(Mathf.Sign(Speed.x)*Mathf.Min(BrakingForce.x,Mathf.Abs(Speed.x))),
Speed.y-(Mathf.Sign(Speed.y)*Mathf.Min(BrakingForce.y,Mathf.Abs(Speed.y))),
Speed.z-(Mathf.Sign(Speed.z)*Mathf.Min(BrakingForce.z,Mathf.Abs(Speed.z))));
Speed.Set(
Mathf.Clamp(Speed.x,-1f,1f),
Mathf.Clamp(Speed.y,-1f,1f),
Mathf.Clamp(Speed.z,-1f,1f));
transform.Translate(Time.deltaTime*Speed*MaxSpeed,Space.Self);
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: cc5ee2ad9517a694cb75ffbb0484358f
timeCreated: 1423679043
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,25 @@
using UnityEngine;
using System.Collections;
public class CameraFollowController : MonoBehaviour {
public Transform target;
public float distance = 1.0f;
public float height = 1.0f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (target != null) {
var forward = target.transform.forward;
forward.y = 0;
forward.Normalize();
transform.position = target.transform.position - forward * distance + Vector3.up * height;
transform.LookAt(target.transform);
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0bd8f3cbef6afba4db1d564a22882f54
timeCreated: 1424010338
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+7
View File
@@ -0,0 +1,7 @@
using UnityEngine;
using System.Collections;
public class Device : MonoBehaviour {
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4a4ccac7b93309e47aefca780f9ba0a3
timeCreated: 1423550428
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 5284d4a98c08d4e44aacf3bda118844e
folderAsset: yes
timeCreated: 1423910038
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
using UnityEngine;
using UnityEditor;
[InitializeOnLoad]
public class AutosaveOnRun
{
static AutosaveOnRun()
{
EditorApplication.playmodeStateChanged = () =>
{
if(EditorApplication.isPlayingOrWillChangePlaymode && !EditorApplication.isPlaying)
{
Debug.Log("Auto-Saving scene before entering Play mode: " + EditorApplication.currentScene);
EditorApplication.SaveScene();
EditorApplication.SaveAssets();
}
};
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b9a811bc67f439d42af246b9e870de83
timeCreated: 1451992256
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,75 @@
using UnityEditor;
using UnityEngine;
class InputEditor : EditorWindow {
[MenuItem ("L/InputEditor")]
static void ShowWindow () {
EditorWindow.GetWindow (typeof(InputEditor));
}
public enum AxisType{
KeyOrMouseButton = 0,
MouseMovement = 1,
JoystickAxis = 2
}
private bool _renameAxis;
void OnGUI () {
_renameAxis = GUILayout.Toggle (_renameAxis, "Rename axis");
if (GUILayout.Button ("Reset input axes")) {
var serializedObject = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/InputManager.asset")[0]);
int axisId = 0;
while(true){
var axesProperty = serializedObject.FindProperty("m_Axes");
axesProperty.Next(true);
axesProperty.Next(true);
axesProperty.Next(true);
bool fail = false;
for(int i = 0; i < axisId; ++i){
if(!axesProperty.Next(false)){
fail = true;
break;
}
}
if(fail){
break;
}
int propId = 0;
//go deeper - into axis properties
axesProperty.Next(true);
do{
switch(propId){
case 0:
if(_renameAxis){
axesProperty.stringValue = "Axis" + axisId;
}
break;
case 9: //sensitivity
axesProperty.floatValue = 1.0f;
break;
case 10: //snap
case 11: //invert
break;
case 12: //type
axesProperty.enumValueIndex = (int)AxisType.JoystickAxis;
break;
case 13: //axis
axesProperty.intValue = axisId;
break;
}
propId++;
}while(axesProperty.Next(false) && propId < 15);
axisId++;
}
serializedObject.ApplyModifiedProperties();
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1583d288f90da744085ad61412896bb2
timeCreated: 1423910048
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,23 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
[CustomEditor(typeof(MotorPlot))]
public class MotorEditor : Editor {
public override void OnInspectorGUI() {
base.OnInspectorGUI();
if (GUILayout.Button("Update unbound plots")) {
(target as MotorPlot).DrawUnboundPlots();
}
if (GUILayout.Button("Update plots")) {
(target as MotorPlot).IntegratePlotsVisual();
}
if (GUILayout.Button("Optimize")) {
(target as MotorPlot).Optimize();
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 074d4210038f618409b1f613122e619f
timeCreated: 1452020381
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,22 @@
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(Transform))]
public class TransformEditor : Editor {
public override void OnInspectorGUI (){
base.OnInspectorGUI ();
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button ("Reset rotaton")) {
(target as Transform).rotation = Quaternion.identity;
}
if (GUILayout.Button ("R +90")) {
(target as Transform).Rotate(0, 90, 0);
}
if (GUILayout.Button ("R -90")) {
(target as Transform).Rotate(0, -90, 0);
}
EditorGUILayout.EndHorizontal();
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 72c86113d776a354397477e591e59d48
timeCreated: 1425919706
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,59 @@
using UnityEngine;
using UnityEditor;
using System.Linq;
using System;
public class UnityResourcesEditor : EditorWindow {
public string resourcesAssetPath = @"Assets/unity editor resources.asset";
public GUISkin LightSkin;
public GUISkin DarkSkin;
[MenuItem ("L/UnityResourcesEditor")]
static void Init () {
UnityResourcesEditor window = (UnityResourcesEditor)EditorWindow.GetWindow (typeof (UnityResourcesEditor));
window.Show();
}
void CopyProperties<T>(T from, T to, string[] exclude = null){
var props = typeof(T).GetProperties ().Where(v=>v.CanWrite && v.CanWrite).ToArray();
foreach (var p in props) {
Debug.Log(p.Name);
if(exclude != null && exclude.Any(v => v == p.Name)){
Debug.Log("Skin property: " + p.Name);
continue;
}
p.SetValue(to, p.GetValue(from, null), null);
}
}
void CopyGuiSkin(GUISkin from, GUISkin to){
Debug.Log ("Copy skins");
CopyProperties (from, to, new []{"name"});
CopyProperties (from.settings, to.settings);
}
void OnGUI () {
GUILayout.Label ("Asset path", EditorStyles.boldLabel);
resourcesAssetPath = GUILayout.TextField (resourcesAssetPath);
if (GUILayout.Button ("Load resources")) {
var resources = AssetDatabase.LoadAllAssetsAtPath (resourcesAssetPath);
var skins = resources.Where(v=>v is GUISkin).Cast<GUISkin>().ToArray();
var lightSkin = skins.First(v=>v.name.ToLower() == "LightSkin".ToLower());
var darkSkin = skins.First(v=>v.name.ToLower() == "DarkSkin".ToLower());
CopyGuiSkin(darkSkin, lightSkin);
Debug.Log("Light skin name: " + lightSkin.name);
Debug.Log("Dark skin name: " + darkSkin.name);
AssetDatabase.SaveAssets();
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7a576cb8317355048a2b1652b6df62a2
timeCreated: 1425716261
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,31 @@
using UnityEngine;
using System.Collections;
public class ElectronicSpeedController : MonoBehaviour {
public Motor motor;
public bool inverseDirection;
[Range(0, 1)]
public float inputSpeed;
// Use this for initialization
void Start () {
}
void OnDrawGizmos(){
AdvancedGizmo.CircleArrow (0.1f, inverseDirection ? -270 : 270, 37, AdvancedGizmo.CircleCloseType.None, motor.transform.localToWorldMatrix);
}
// Update is called once per frame
void Update () {
inputSpeed = Mathf.Clamp01 (inputSpeed);
if (motor != null) {
motor.speed = motor.maxRpm * inputSpeed * (inverseDirection ? -1.0f : 1.0f);
var rps = motor.speed / 60.0f;
var rotateAngle = rps * 360.0f * Time.deltaTime;
motor.rotor.transform.Rotate(0, 0, rotateAngle);
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ecbaaf54d5305d04db5720bb7624cea1
timeCreated: 1423328533
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
using UnityEngine;
using System.Collections;
public class FlightController : Device {
public Quaternion targetOrientation = Quaternion.identity;
public float targetThrolle;
public OrientationSensor orientationSensor;
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 86fc4779855f897408768cb72207114b
timeCreated: 1423552125
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
using UnityEngine;
using System.Collections;
public class IdealAltimeter : Altimeter {
public override float GetHeight (){
return transform.position.y;
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: dc6c39b608ed5e347a44373f193265d6
timeCreated: 1423551172
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+32
View File
@@ -0,0 +1,32 @@
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(RectTransform))]
public class Joystick : MonoBehaviour {
public JoystickViewController view;
public string XAxis = "Yaw";
public string YAxis = "Throlle";
private Vector2 _state;
public Vector2 State{
get{ return _state;}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
_state.x = Input.GetAxis (XAxis);
_state.y = Input.GetAxis (YAxis);
view.SetAxis (_state.x, _state.y);
}
void OnGUI(){
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: dbb9dd3ef7d4b28499544535a3be7fcb
timeCreated: 1423866951
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+74
View File
@@ -0,0 +1,74 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
public class JoystickView : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnGUI(){
DoGui ();
}
public static List<string> GetInputAxis()
{
var allAxis = new List<string>();
var serializedObject = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/InputManager.asset")[0]);
var axesProperty = serializedObject.FindProperty("m_Axes");
axesProperty.Next(true);
axesProperty.Next(true);
while (axesProperty.Next(false))
{
SerializedProperty axis = axesProperty.Copy();
axis.Next(true);
allAxis.Add(axis.stringValue);
}
return allAxis;
}
void DoGui(){
var joysticks = Input.GetJoystickNames ();
#if UNITY_EDITOR
Handles.BeginGUI ();
#endif
var axes = GetInputAxis ();
float height = 20;
for (int i = 0; i < axes.Count; ++i) {
GUI.Label(new Rect(10,i * height + 10, 300,height), string.Format("Axis {0}: {1}", axes[i], Input.GetAxis(axes[i])));
}
for (int i = 0; i < 20; ++i) {
GUI.Label(new Rect(410,i * height + 10, 300,height), string.Format("Button {0}: {1}", i, Input.GetKey (KeyCode.Joystick1Button0 + i)));
}
/*foreach(var j in joysticks){
//EditorGUILayout.TextField(j);
}*/
#if UNITY_EDITOR
Handles.EndGUI ();
#endif
}
void OnDrawGizmos(){
DoGui ();
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 16d4b57de1550a940ab33fd142eeb0de
timeCreated: 1423907729
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,39 @@
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class JoystickViewController : MonoBehaviour {
private Vector2 _axisValue;
public RectTransform axisView;
public RectTransform axisViewParent;
public void SetAxis(float x, float y){
_axisValue.x = Mathf.Clamp(x, -1.0f, 1.0f);
_axisValue.y = Mathf.Clamp(y, -1.0f, 1.0f);
if (_axisValue.sqrMagnitude > 1.0f) {
_axisValue.Normalize ();
}
float parentWidth = axisViewParent.rect.width;
float parentHeight = axisViewParent.rect.height;
var pos = axisView.localPosition;
pos.x = _axisValue.x * (parentWidth * 0.5f);
pos.y = _axisValue.y * (parentHeight * 0.5f);
axisView.localPosition = pos;
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 70459ef9cfb07c64b8a545219e0ba3b0
timeCreated: 1423904821
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+51
View File
@@ -0,0 +1,51 @@
using UnityEngine;
using System.Collections;
public class Motor : MonoBehaviour {
public GameObject rotor;
public float maxRpm = 3000;
public float speed;
public float minPitch = 0.8f;
public float maxPitch = 1.2f;
public AudioSource soundSource;
private float[] speedHistory;
int historyId = 0;
void Start(){
speedHistory = new float[15];
for (int i = 0; i < speedHistory.Length; ++i) {
speedHistory[i] = 0;
}
}
void Update(){
if (soundSource != null) {
speedHistory[historyId] = speed;
historyId = (historyId + 1) % speedHistory.Length;
float smoothSpeed = 0;
for (int i = 0; i < speedHistory.Length; ++i) {
smoothSpeed += speedHistory[i];
}
smoothSpeed = smoothSpeed / (float)speedHistory.Length;
float pitch = (smoothSpeed / maxRpm) * (maxPitch - minPitch) + minPitch;
soundSource.pitch = pitch;
if(soundSource.isPlaying && speed < 5){
soundSource.Stop();
}
if(!soundSource.isPlaying && speed >=5){
soundSource.Play();
}
}
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0b1922fe0093758438859302e80d5f1f
timeCreated: 1423314461
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+264
View File
@@ -0,0 +1,264 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using System.Linq;
using System;
public class MotorPlot : MonoBehaviour {
private Vector3[] plot_current;
private Vector3[] plot_rps;
private Vector3[] plot_power;
private Vector3[] plot_in_power;
private Vector3[] plot_eff;
public Motor motor;
const float plotHeight = 10.0f;
const float plotWidth = plotHeight * 1.25f;
Vector3[] CreatePlot(Plot plot) {
Vector3[] result = new Vector3[plot.Samples.Count];
for (int i = 0; i < plot.Samples.Count; ++i) {
float x = (plotWidth / plot.Samples.Count) * i;
result[i] = new Vector3(x, 0, (float)(plot.Samples[i] * plotHeight * plot.NormalizeValue));
}
return result;
}
public class Plot {
public Plot(double _NormalizeValue) {
NormalizeValue = _NormalizeValue;
}
public double NormalizeValue;
public List<double> Samples = new List<double>();
public double GetMin() {
return Samples.Min();
}
public double GetMinNormalized() {
return Samples.Min() * NormalizeValue;
}
public double GetMaxNormalized() {
return Samples.Max() * NormalizeValue;
}
public double GetMax() {
return Samples.Max();
}
}
public class Plots {
public Plot current = new Plot(1000.0 / 200.0);
public Plot rpm = new Plot(1.0 / 24000.0);
public Plot power = new Plot((1.0 * 1000.0f / 150.0));
public Plot in_power = new Plot((1.0 * 1000.0f / 150.0));
public Plot eff = new Plot(100.0 / 54.0);
}
private double k_torque_backup;
private double k_friction_backup;
private double k_backemf_backup;
public int maxOptimizationIterations = 10000;
public int integrationIterations = 1000;
private static void fvec(double[] arg, double[] fi, object obj) {
//errors: eff_max, pow_max, rpm_max, cur_min, cur_max
//k_Friction, k_Torque, k_BackEMF, rotorInertia
var m = (MotorPlot)obj;
m.motor.k_Friction = m.k_friction_backup + arg[0];
m.motor.k_Torque = m.k_torque_backup + arg[1];
m.motor.k_BackEMF = m.k_backemf_backup + arg[2];
var plots = m.IntegratePlots();
var eff_max_norm = plots.eff.GetMaxNormalized();
var pow_max_norm = plots.power.GetMaxNormalized();
var cur_max_norm = plots.current.GetMaxNormalized();
var target_eff_max_norm = (52.0 / 100.0) * plots.eff.NormalizeValue;
var target_pow_max_norm = (120.3 / 1000.0) * plots.power.NormalizeValue;
var target_rpm_max_norm = 23050.0 * plots.rpm.NormalizeValue;
var target_cur_min_norm = (17.0 / 1000.0) * plots.current.NormalizeValue;
var target_cur_max_norm = (180.0 / 1000.0) * plots.current.NormalizeValue;
var target_rpm_derivative = (0 - target_rpm_max_norm) / plotWidth;
var iter_rpm_derivative = (plots.rpm.GetMinNormalized() - (plots.rpm.Samples[plots.rpm.Samples.Count / 2] * plots.rpm.NormalizeValue)) / (plotWidth / 2);
var target_cur_derivative = (target_cur_max_norm - target_cur_min_norm) / plotWidth;
var iter_cur_derivative = (plots.current.GetMaxNormalized() - (plots.current.Samples[plots.current.Samples.Count / 2] * plots.current.NormalizeValue)) / (plotWidth / 2);
var err_eff = target_eff_max_norm - eff_max_norm;
var err_pow = target_pow_max_norm - pow_max_norm;
var err_rpm_deriv = target_rpm_derivative - iter_rpm_derivative;
var err_cur = target_cur_derivative - iter_cur_derivative;
var err_cur_max = target_cur_max_norm - cur_max_norm;
fi[0] = err_pow * err_pow;
fi[1] = err_rpm_deriv * err_rpm_deriv;
fi[2] = err_cur * err_cur;
fi[3] = err_cur_max * err_cur_max;
fi[4] = err_eff * err_eff;
}
public void Optimize() {
const double optStep = 0.0000001;
k_torque_backup = motor.k_Torque;
k_friction_backup = motor.k_Friction;
k_backemf_backup = motor.k_BackEMF;
double[] Params = new double[3] { 0, 0, 0 };
alglib.minlmstate state;
alglib.minlmreport rep;
try {
//params count, errors count, params
alglib.minlmcreatev(Params.Length, 6, Params, optStep, out state);
} catch (Exception ex) {
Debug.Log("Failed to optimize, bad params! " + ex.Message);
return;
}
alglib.minlmsetcond(state, 0.00000000001, 0.00000000001, 0.00000000001, maxOptimizationIterations);
//alglib.minlmsetbc(state, FunctionParametersMin, FunctionParametersMax);
alglib.minlmoptimize(state, fvec, null, this);
alglib.minlmresults(state, out Params, out rep);
motor.k_Friction = k_friction_backup + Params[0];
motor.k_Torque = k_torque_backup + Params[1];
motor.k_BackEMF = k_backemf_backup + Params[2];
Debug.Log(rep.iterationscount);
IntegratePlotsVisual();
}
public void DrawUnboundPlots() {
Plots result = new Plots();
motor.ResetState();
plot_eff = null;
plot_in_power = null;
plot_power = null;
plot_rps = null;
plot_current = null;
var oldVoltage = motor.Vin;
for (int i = 0; i < integrationIterations; ++i) {
if (i > (integrationIterations / 2)) {
motor.Vin = 0;
}
result.current.Samples.Add(motor.current);
result.rpm.Samples.Add(motor.angularSpeedRPM);
motor.Integrate(motor.integrationStep);
}
motor.Vin = oldVoltage;
plot_rps = CreatePlot(result.rpm);
plot_current = CreatePlot(result.current);
SceneView.RepaintAll();
}
public Plots IntegratePlots() {
Plots result = new Plots();
motor.ResetState();
motor.LoadTorque = 0;
double loadStep = 0.04185 * motor.integrationStep;
//warm up
for (int i = 0; i < (int)(1.0f / motor.integrationStep) * 100; ++i) {
motor.Integrate(motor.integrationStep);
}
int iteration = 0;
//add load torque until motor stall
while (motor.angularSpeedRPM > 0.0) {
++iteration;
motor.LoadTorque = loadStep * iteration;
// double power = (k_BackEMF / k_Torque) * angularSpeedRPS * (torque - torqueOffset);
double power = motor.angularSpeedRPS * motor.LoadTorque / 1000.0;
double inPower = motor.current * motor.Vin;
double eff = power / inPower;
result.current.Samples.Add(motor.current);
result.rpm.Samples.Add(motor.angularSpeedRPM);
result.eff.Samples.Add(eff);
result.power.Samples.Add(power);
result.in_power.Samples.Add(inPower);
for (int m = 0; m < 10; ++m) {
motor.Integrate(motor.integrationStep);
}
}
Debug.Log("Load torque = " + motor.LoadTorque);
return result;
}
public void IntegratePlotsVisual() {
var plots = IntegratePlots();
//convert values to plots
plot_current = CreatePlot(plots.current);
plot_rps = CreatePlot(plots.rpm);
plot_power = CreatePlot(plots.power);
plot_in_power = CreatePlot(plots.in_power);
plot_eff = CreatePlot(plots.eff);
SceneView.RepaintAll();
}
void OnDrawGizmos() {
Handles.matrix = Matrix4x4.identity;
Handles.color = Color.red;
if (plot_current != null) {
Handles.DrawPolyLine(plot_current);
}
Handles.color = Color.blue;
if (plot_rps != null) {
Handles.DrawPolyLine(plot_rps);
}
Handles.color = Color.yellow;
if (plot_power != null) {
Handles.DrawPolyLine(plot_power);
}
Handles.color = Color.green;
if (plot_eff != null) {
Handles.DrawPolyLine(plot_eff);
}
Handles.color = Color.gray;
if (plot_in_power != null) {
Handles.DrawPolyLine(plot_in_power);
}
Handles.color = Color.black;
//draw borders
Vector3 upOffset = Vector3.forward * plotHeight;
Vector3 rightOffset = Vector3.right * plotWidth;
Handles.DrawLine(Vector3.zero, upOffset);
Handles.DrawLine(Vector3.zero, rightOffset);
Handles.DrawLine(upOffset, upOffset + rightOffset);
Handles.DrawLine(rightOffset, upOffset + rightOffset);
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3ad79268f57596f4da62ff8db17ffc6c
timeCreated: 1452189955
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+9
View File
@@ -0,0 +1,9 @@
using UnityEngine;
using System.Collections;
public class NewtonIntegrator : MonoBehaviour {
// public delegate void DerivativeFunc()
//public void
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 27465a0c48a740742b56587f1299cc79
timeCreated: 1452188047
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+22
View File
@@ -0,0 +1,22 @@
using UnityEngine;
using System.Collections;
public class OrientationSensor : MonoBehaviour {
public Quaternion orientation = Quaternion.identity;
public Vector3 right = Vector3.right;
public Vector3 up = Vector3.right;
public Vector3 forward = Vector3.right;
// Use this for initialization
void Start () {
}
// Update is called once per frame
public void FixedUpdate () {
orientation = transform.rotation;
right = orientation * Vector3.right;
up = orientation * Vector3.up;
forward = orientation * Vector3.forward;
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8f9e446d96d8cb246904fcd464bce598
timeCreated: 1423770347
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+219
View File
@@ -0,0 +1,219 @@
using UnityEngine;
using System.Collections;
using System;
[Serializable]
public class OscilloscopeChannel{
public bool sample = true;
public bool draw = true;
public Color color = Color.green;
public float cellTime = 0.2f;
public float cellValue = 0.2f;
public OscilloscopeSampler sampler;
private float[] sampleValueBuffer;
public float[] SampleValueBuffer {
get {
return sampleValueBuffer;
}
}
private float[] sampleTimeBuffer;
public float[] SampleTimeBuffer {
get {
return sampleTimeBuffer;
}
}
private int sampleBufferPosition;
public int SampleBufferPosition {
get {
return sampleBufferPosition;
}
}
public void Reset(int cellCount, int sampleRate){
float totalTime = cellCount * cellTime;
int maxSampleCount = Mathf.CeilToInt (totalTime * sampleRate);
sampleTimeBuffer = new float[maxSampleCount];
sampleValueBuffer = new float[maxSampleCount];
}
public void Sample(){
sampleBufferPosition = (sampleBufferPosition + 1) % sampleValueBuffer.Length;
float val = sampler == null ? 0 : sampler();
sampleTimeBuffer[sampleBufferPosition] = Time.time;
sampleValueBuffer[sampleBufferPosition] = val;
}
}
public delegate float OscilloscopeSampler();
[ExecuteInEditMode]
public class Oscilloscope : MonoBehaviour {
public Vector2 pos = new Vector2(10,10);
public Vector2 size;
public OscilloscopeChannel[] channels;
private Vector3[] screenCorners;
private const float cellSize = 40.0f;
private const int hCellCountHalf = 6;
private const int vCellCountHalf = 4;
public int sampleRate = 50;
private float lastSampleTime;
public bool showInEditor = true;
public int xMatrixOffset = 0;
public int yMatrixOffset = 0;
private GUIStyle richLabelStyle;
// Use this for initialization
void Start () {
size = new Vector2 (hCellCountHalf * 2 * cellSize, vCellCountHalf * 2 * cellSize);
screenCorners = new []{
new Vector3(pos.x, pos.y, 0.5f),
new Vector3(pos.x + size.x, pos.y, 0.5f),
new Vector3(pos.x + size.x, pos.y + size.y, 0.5f),
new Vector3(pos.x, pos.y + size.y, 0.5f)
};
foreach (var c in channels) {
c.Reset(hCellCountHalf * 2, sampleRate);
}
}
void UpdateSamples(){
float currentTime = Time.time;
float timeElapsed = currentTime - lastSampleTime;
if(timeElapsed >= (1.0f / sampleRate)){
if(channels != null){
foreach( var c in channels){
if(c.sample)
c.Sample();
}
}
lastSampleTime = currentTime;
}
}
Vector2[] GenerateLineDividers(Vector2 from, Vector2 to, float step, int count, float leftSize, float rightSize){
Vector2[] result = new Vector2[count * 2];
Vector2 dir = (to - from).normalized;
Vector2 right = new Vector2 (dir.y, -dir.x);
Vector2 leftOffset = right * -leftSize;
Vector2 rightOffset = right * rightSize;
for (int i = 0; i < count; ++i) {
var p = from + dir * step * i;
result[i * 2 + 0] = p + leftOffset;
result[i * 2 + 1] = p + rightOffset;
}
return result;
}
void DrawLinesArray(Vector2[] lines){
for (int i = 0; i < lines.Length / 2; ++i) {
var p0 = lines[i * 2 + 0];
var p1 = lines[i * 2 + 1];
GL.Vertex(new Vector3(p0.x, p0.y, 0.4f));
GL.Vertex(new Vector3(p1.x, p1.y, 0.4f));
}
}
void OnValidate(){
}
void DrawDisplay(){
size = new Vector2 (hCellCountHalf * 2 * cellSize, vCellCountHalf * 2 * cellSize);
screenCorners = new []{
new Vector3(pos.x, pos.y, 0.5f),
new Vector3(pos.x + size.x, pos.y, 0.5f),
new Vector3(pos.x + size.x, pos.y + size.y, 0.5f),
new Vector3(pos.x, pos.y + size.y, 0.5f)
};
UpdateSamples ();
return;
}
void DrawHandles(){
/*Rect bottomRect = new Rect (pos.x, pos.y + size.y, size.x, 20);
int digitWidth = 20;
int labelWidth = 60;
int channelInfoLength = digitWidth + labelWidth;
if (channels != null) {
int channelId = 0;
foreach(var c in channels){
if(c != null){
float offsetX = channelInfoLength * channelId + bottomRect.x;
Rect digitRect = new Rect(offsetX, bottomRect.y, digitWidth, bottomRect.height);
Rect labelRect = new Rect(offsetX + digitWidth, bottomRect.y, labelWidth, bottomRect.height);
GUI.Label(digitRect, string.Format("<color=green>{0}</color>", channelId.ToString()),richLabelStyle);
GUI.Label(labelRect, string.Format("<color=white>{0}</color>", c.cellValue.ToString()),richLabelStyle);
int colorLineHeight = 3;
Rect colorLineRect = new Rect(offsetX, labelRect.yMax - colorLineHeight, channelInfoLength / 3, colorLineHeight);
DrawRect(colorLineRect, c.color, 0.3f);
channelId++;
}
}
}*/
}
void OnWillRenderObject() {
Debug.Log ("On will render");
}
void Draw(){
if (!enabled) {
return;
}
if (richLabelStyle == null) {
richLabelStyle = new GUIStyle ();
richLabelStyle.richText = true;
}
GL.PushMatrix();
GL.LoadPixelMatrix (0, Screen.width + xMatrixOffset, Screen.height + yMatrixOffset, 0);
DrawDisplay ();
//DrawHandles ();
GL.PopMatrix();
}
void OnPostRender(){
Draw ();
}
void OnDrawGizmos(){
//if (showInEditor) {
Draw ();
//}
}
// Update is called once per frame
void Update () {
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d44e2f9a2da50b242aab19dd970b8c3d
timeCreated: 1423678116
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+244
View File
@@ -0,0 +1,244 @@
using UnityEngine;
using System.Collections;
public class OscilloscopeDisplay : MonoBehaviour {
public Material displayMaterial;
private Texture2D diplayBackground;
public Oscilloscope oscilloscope;
public int halfXCellCount = 6;
public int halfYCellCount = 4;
public int cellSize = 50;
public int shortLineSize = 5;
public Vector2 position;
public Color backgroundColor = new Color(0,0,0,0.6f);
public Color linesColor = new Color(0.27f,0.57f,0.9f, 1.0f);
static Material lineMaterial;
static void CreateLineMaterial() {
if( !lineMaterial ) {
lineMaterial = new Material( " Shader \"Lines/Colored Blended\" {" +
" SubShader { Pass { " +
" Blend SrcAlpha OneMinusSrcAlpha " +
" ZWrite Off Cull Off ZTest Off Fog { Mode Off } " +
" BindChannels {" +
" Bind \"vertex\", vertex Bind \"color\", color }" +
"} } }" );
lineMaterial.hideFlags = HideFlags.HideAndDontSave;
lineMaterial.shader.hideFlags = HideFlags.HideAndDontSave;
}
}
// Use this for initialization
void Start () {
}
void GenerateBackground(Texture2D tex){
if (tex == null) {
return;
}
Debug.Log ("GenerateBackground");
Color[] pixels = new Color[tex.width * tex.height];
//fill background
for (int i = 0; i < pixels.Length; ++i) {
pixels[i] = backgroundColor;
}
//draw grid
//-horizontal lines
for (int i = 0; i <= halfYCellCount * 2; ++i) {
int y = i * cellSize;
for(int x = 0; x < tex.width; ++x){
if(y != 0 && y != tex.height - 1){
if((x % 2) == 1){
continue;
}
}
int id = y * tex.width + x;
pixels[id] = linesColor;
}
}
//-vertical lines
for (int i = 0; i <= halfXCellCount * 2; ++i) {
int x = i * cellSize;
for(int y = 0; y < tex.height; ++y){
if(x != 0 && x != tex.width - 1){
if((y % 2) == 1){
continue;
}
}
int id = y * tex.width + x;
pixels[id] = linesColor;
}
}
//draw helper short lines
//-vertical
int[] cells = new int[]{0,halfXCellCount, halfXCellCount*2};
int[] offsets = new int[]{0, -shortLineSize / 2, -shortLineSize + 1 };
for (int i = 0; i < cells.Length; ++i) {
int x = cells[i] * cellSize + offsets[i];
for(int y = 0; y < tex.height; y += (cellSize / 5)){
for(int j = x; j < (x + shortLineSize); ++j){
pixels[ y * tex.width + j] = linesColor;
}
}
}
//horizontal
cells = new int[]{0, halfYCellCount, halfYCellCount*2};
for (int i = 0; i < cells.Length; ++i) {
int y = cells[i] * cellSize + offsets[i];
for(int x = 0; x < tex.width; x += (cellSize / 5)){
for(int j = y; j < (y + shortLineSize); ++j){
pixels[ j * tex.width + x] = linesColor;
}
}
}
tex.SetPixels (pixels);
tex.Apply ();
}
void OnValidate(){
int texWidth = cellSize * halfXCellCount * 2 + 1;
int texHeight = cellSize * halfYCellCount * 2 + 1;
if (diplayBackground == null || diplayBackground.width != texWidth || diplayBackground.height != texHeight) {
diplayBackground = new Texture2D(texWidth, texHeight, TextureFormat.ARGB32, false, true);
}
GenerateBackground (diplayBackground);
}
void OnDrawGizmos(){
GL.PushMatrix ();
//GL.LoadPixelMatrix ();
GL.LoadPixelMatrix (0, Camera.current.pixelWidth, Camera.current.pixelHeight, 0);
Graphics.DrawTexture (new Rect (position.x, position.y, diplayBackground.width, diplayBackground.height), diplayBackground);
if (oscilloscope != null) {
Vector2 size = new Vector2 (halfXCellCount * 2 * cellSize, halfYCellCount * 2 * cellSize);
CreateLineMaterial();
//func
lineMaterial.SetPass(0);
GL.Begin(GL.LINES);
lineMaterial.SetPass(0);
float verticalOffset = halfYCellCount * cellSize;
foreach (var channel in oscilloscope.channels) {
if(channel == null || !channel.draw){
continue;
}
GL.Color(channel.color);
var timeBuffer = channel.SampleTimeBuffer;
var valueBuffer = channel.SampleValueBuffer;
var bufferPos = channel.SampleBufferPosition;
if(timeBuffer == null || timeBuffer.Length == 0 || valueBuffer == null || valueBuffer.Length == 0){
continue;
}
float lastTime = timeBuffer[bufferPos];
float lastX = size.x;
float lastY = size.y - ((valueBuffer[bufferPos] / channel.cellValue) * cellSize + verticalOffset);
for(int i = 1; i < timeBuffer.Length; ++i){
if(bufferPos == 0){
bufferPos = valueBuffer.Length - 1;
}else{
bufferPos = bufferPos - 1;
}
float timeOffset = timeBuffer[bufferPos] - lastTime;
float curX = size.x + (timeOffset / channel.cellTime) * cellSize;
float curY = size.y - ((valueBuffer[bufferPos] / channel.cellValue) * cellSize + verticalOffset);
Vector2 curVector = Vector3.zero;
Vector2 lastVector = Vector3.zero;
if(ClipLine(lastX, lastY, curX, curY, ref curVector, ref lastVector, size)){
GL.Vertex(new Vector3(curVector.x + position.x, curVector.y + position.y, 0));
GL.Vertex(new Vector3(lastVector.x + position.x, lastVector.y + position.y, 0));
}
lastY = curY;
lastX = curX;
}
}
GL.End();
}
GL.PopMatrix ();
}
bool ClipLine(float lastX, float lastY, float curX, float curY, ref Vector2 L, ref Vector2 R, Vector2 size){
if (lastX < 0) {
return false;
}
L.x = curX;
L.y = curY;
R.x = lastX;
R.y = lastY;
if(R.x < 0){
float kx = (L.x / (L.x - R.x));
L.y = L.y + (R.y - L.y) * kx;
L.x = 0;
}
if (L.y > R.y) {
var tmp = R;
R = L;
L = tmp;
}
//L.y always smaller
if (R.y <= 0) {
return false;
}
if (L.y >= size.y) {
return false;
}
if (L.y < 0) { //top clamp
float kx = L.y / (L.y - R.y);
L.x = L.x + (R.x - L.x) * kx;
L.y = 0;
}
if (R.y > size.y){ //bottom clamp
float kx = (R.y - size.y) / (R.y - L.y);
R.x = R.x + (L.x - R.x) * kx;
R.y = size.y;
}
if (R.y > size.y || L.y > size.y) {
Debug.Log("Fail");
}
return true;
}
// Update is called once per frame
void Update () {
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 63f15ae69061bb24f95668f58a44f9fa
timeCreated: 1426016623
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+59
View File
@@ -0,0 +1,59 @@
using UnityEngine;
using System.Collections;
using System;
[Serializable]
public class PID {
public bool enabled = true;
public float kp = 1.0f;
public float ki = 1.0f;
public float kd = 1.0f;
public float outMin = -0.1f;
public float outMax = 0.1f;
private float _errorIntegral;
private float _lastError;
private float _setpoint;
public float LastError {get {return _lastError;}}
private float _p;
public float P {get {return _p;}}
private float _i;
public float I {get {return _i;}}
private float _d;
public float D {get {return _d;}}
public float Setpoint{
get{ return _setpoint; }
set{ _setpoint = value; }
}
public float Process(float dt, float pv){
if (!enabled) {
return 0;
}
float error = Setpoint - pv;
float derivative = (error - _lastError) / dt;
//derivative = Mathf.Clamp(derivative, outMin, outMax);
/*if (Mathf.Abs(integralChange) > 0.001f) {
integralChange = 0.001f * Mathf.Sign(integralChange);
}*/
_errorIntegral += error * dt;
//_errorIntegral = Mathf.Clamp(_errorIntegral, outMin, outMax);
_lastError = error;
_p = kp * error;
_i = ki * _errorIntegral;
_d = kd * derivative;
var output = _p + _i + _d;
return Mathf.Clamp(output, outMin, outMax);
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e7c34d969bf797248b749b29807d1aaf
timeCreated: 1423566544
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+58
View File
@@ -0,0 +1,58 @@
using UnityEngine;
using System.Collections;
public class PropellerForce : MonoBehaviour {
public Motor motor;
public float maxForce = 20;
public float maxTorque = 20;
private Vector3 forceVector;
private Rigidbody rb;
private Vector3 torque;
private Vector3 torqueForce;
private Vector3 torqueOrtho;
// Use this for initialization
void Start () {
rb = gameObject.GetComponentInParent<Rigidbody> ();
}
void FixedUpdate(){
if (rb == null) {
return;
}
float motorSpeedNormalized = (motor.speed / motor.maxRpm);
float force = Mathf.Abs(motorSpeedNormalized * maxForce);
forceVector = motor.transform.up * force;
rb.AddForceAtPosition(forceVector, motor.transform.position);
float torqueMagnitude = maxTorque * motorSpeedNormalized;
torque = -torqueMagnitude * motor.transform.up;
rb.AddTorqueAtPosition (torque, motor.transform.position, ref torqueForce, ref torqueOrtho);
}
void OnDrawGizmos(){
//return;
Gizmos.DrawLine (motor.transform.position, motor.transform.position + forceVector);
Gizmos.color = Color.green;
var pa = motor.transform.position;
var pb = motor.transform.position + torqueOrtho;
var pc = motor.transform.position + torqueOrtho + torqueForce;
var pd = motor.transform.position - torqueOrtho;
var pe = motor.transform.position - torqueOrtho - torqueForce;
Gizmos.DrawLine (pa, pb);
Gizmos.DrawLine (pb, pc);
Gizmos.DrawLine (pa, pd);
Gizmos.DrawLine (pd, pe);
}
// Update is called once per frame
void Update () {
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2c51ebb8487fe6844bb469c4bc187c35
timeCreated: 1423340351
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,34 @@
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class QuadcopterEditorOritentationController : MonoBehaviour {
public FlightController target;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnDrawGizmos(){
Gizmos.color = Color.red;
Gizmos.DrawLine (transform.position, transform.position + transform.right);
Gizmos.color = Color.green;
Gizmos.DrawLine (transform.position, transform.position + transform.up);
Gizmos.color = Color.blue;
Gizmos.DrawLine (transform.position, transform.position + transform.forward);
if (enabled) {
if(target != null){
target.targetOrientation = transform.rotation;
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 04a4bb44dcf9e8842903213ab500e4f5
timeCreated: 1425907563
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,246 @@
using UnityEngine;
using System.Collections;
public class QuadcopterFlightController : FlightController {
public ElectronicSpeedController[] esc;
private Vector2 tiltDirection;
private float tiltAmt;
private float yawError;
public PID yawPid;
public PID altitudePid;
public PID tiltPid;
private PID[] tiltPids;
public BiquadFilter[] motorTiltErrorFilters = new BiquadFilter[4];
public float targetAltitiude;
public Oscilloscope oscilloscope;
public class EngineStabilizationParameters{
public float tiltError;
}
private EngineStabilizationParameters[] stabilizationParameters = new EngineStabilizationParameters[4];
// Use this for initialization
void Start () {
stabilizationParameters = new EngineStabilizationParameters[esc.Length];
for (int i = 0; i < esc.Length; ++i) {
stabilizationParameters[i] = new EngineStabilizationParameters();
}
if (oscilloscope != null) {
oscilloscope.channels[0].sampler = SamplerP;
oscilloscope.channels[1].sampler = SamplerI;
oscilloscope.channels[2].sampler = SamplerD;
oscilloscope.channels[3].sampler = SamplerErr;
}
tiltPids = new PID[esc.Length];
for(int i = 0; i < tiltPids.Length; ++i){
tiltPids[i] = new PID();
tiltPids[i].Setpoint = 0;
}
}
float SamplerP(){
return tiltPids[0].P;
}
float SamplerI(){
return tiltPids[0].I;
}
float SamplerD(){
return tiltPids[0].D;
}
float SamplerErr(){
return tiltPids[0].LastError;
}
void UpdateTiltDirection(bool updateErrors){
if (stabilizationParameters == null) {
stabilizationParameters = new EngineStabilizationParameters[esc.Length];
}
for (int i = 0; i < esc.Length; ++i) {
if(stabilizationParameters[i] == null){
stabilizationParameters[i] = new EngineStabilizationParameters();
}
}
var qBody = orientationSensor.orientation;
var qDesired = targetOrientation;
var qBodyInv = Quaternion.Inverse (qBody);
var qError = qBodyInv * qDesired;
//decompose error
Vector3 qErrAxis;
float qErrAngle;
qError.ToAngleAxis (out qErrAngle, out qErrAxis);
var re = qErrAxis;
var rb = qBody * (qBodyInv * re);
var invQb = Quaternion.AngleAxis (qErrAngle, rb);
float q0 = invQb.w;
float q1 = invQb.x;
float q2 = invQb.z;
float q3 = invQb.y;
float aH = Mathf.Acos (1 - 2.0f * (q1*q1 + q2*q2));
float phi = 2.0f * Mathf.Atan2 (q3, q0);
yawError = phi;
if (yawError > Mathf.PI) {
yawError = yawError - Mathf.PI * 2.0f;
}else if(yawError < -Mathf.PI) {
yawError = yawError + Mathf.PI * 2.0f;
}
tiltAmt = Mathf.Abs(aH);
//Debug.LogFormat ("X{0}Y{1}Z{2}W{3} {4}", qBody.x, qBody.y, qBody.z, qBody.w, tiltAmt);
Vector2 tiltLocalVector;
if (tiltAmt <= 0.00001f) {
tiltDirection = Vector3.up;
tiltLocalVector = Vector2.zero;
} else {
float rx = (Mathf.Cos (phi / 2) * q1 - Mathf.Sin (phi / 2) * q2) / Mathf.Sin (aH / 2);
float ry = (Mathf.Sin (phi / 2) * q1 + Mathf.Cos (phi / 2) * q2) / Mathf.Sin (aH / 2);
float bH = Mathf.Atan2 (ry, rx);
float gH = Mathf.Atan2 (rx, -ry);
tiltDirection = new Vector2 (rx, ry);
tiltLocalVector = tiltDirection.RotateRadians(-phi);
tiltDirection = tiltLocalVector;
}
if (updateErrors) {
for(int i = 0; i < esc.Length; ++i) {
var c = esc[i];
var motorPos = c.motor.transform.position;
motorPos = transform.InverseTransformPoint(motorPos);
var motorDir = motorPos.normalized;
motorDir.y = 0;
var motorK = Vector3.Dot (motorDir, new Vector3(tiltLocalVector.y, 0, -tiltLocalVector.x));
float motorError = motorK * (tiltAmt / (float)esc.Length);
motorError = (float)motorTiltErrorFilters[i].Process((double)motorError);
//tiltAmt = orientationLopassFilter.DoFilter (tiltAmt, Time.fixedDeltaTime);
stabilizationParameters[i].tiltError = motorError;
}
}
}
void Stabilize(){
}
void FixedUpdate(){
UpdateTiltDirection (true);
foreach (var p in tiltPids) {
p.kp = tiltPid.kp;
p.kd = tiltPid.kd;
p.ki = tiltPid.ki;
p.outMin = tiltPid.outMin;
p.outMax = tiltPid.outMax;
}
yawPid.Setpoint = 0;
var yawK = yawPid.Process (Time.fixedDeltaTime, yawError);
altitudePid.Setpoint = targetAltitiude;
var altK = altitudePid.Process (Time.fixedDeltaTime, transform.position.y);
for(int i = 0; i < esc.Length; ++i) {
float tiltK = tiltPids[i].Process (Time.fixedDeltaTime, stabilizationParameters[i].tiltError);
var e = esc[i];
float sign = e.inverseDirection ? -1 : 1;
float yawPart = (yawK / esc.Length) * sign;
//Debug.LogFormat ("yawPart: {0}", yawPart);
e.inputSpeed = Mathf.Clamp01(targetThrolle) - tiltK +altK + yawPart;
/*if(i == 0){
Debug.Log ("Engine 0 speed: " + e.inputSpeed + "Err = " + stabilizationParameters[i].tiltError);
}else if(i == 3){
Debug.Log ("Engine 3 speed: " + e.inputSpeed + "Err = " + stabilizationParameters[i].tiltError);
}*/
}
//Debug.Log("D = " + tiltPids[0].D + "E=" + tiltPids[0].LastError);
}
// Update is called once per frame
void Update () {
}
void OnDrawGizmos(){
if (!Application.isPlaying) {
orientationSensor.FixedUpdate();
UpdateTiltDirection (true);
}
var up = targetOrientation * Vector3.up;
var right = targetOrientation * Vector3.right;
var forward = targetOrientation * Vector3.forward;
var p = transform.position;
//draw target plane
Gizmos.color = Color.red;
Gizmos.DrawLine (p, p + right);
Gizmos.color = Color.green;
Gizmos.DrawLine (p, p + up);
Gizmos.color = Color.blue;
Gizmos.DrawLine (p, p + forward);
//draw current frame
float cfOpacity = 0.2f;
Gizmos.color = new Color (1, 0, 0, cfOpacity);
Gizmos.DrawLine (p, p + orientationSensor.right);
Gizmos.color = new Color (0, 1, 0, cfOpacity);
Gizmos.DrawLine (p, p + orientationSensor.up);
Gizmos.color = new Color (0, 0, 1, cfOpacity);
Gizmos.DrawLine (p, p + orientationSensor.forward);
//draw tilt
Gizmos.color = Color.yellow;
Gizmos.DrawLine (p, p + orientationSensor.orientation * new Vector3(-tiltDirection.y, 0, tiltDirection.x));
if (stabilizationParameters != null) {
for(int i = 0; i < esc.Length; ++i) {
var c = esc[i];
var motorPos = c.motor.transform.position;
Gizmos.DrawLine (motorPos, motorPos + c.motor.transform.up * stabilizationParameters[i].tiltError * 50);
}
}
}
void OnGUI(){
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 86c32bb98f442ac478f3981bcd7b5011
timeCreated: 1423552181
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+48
View File
@@ -0,0 +1,48 @@
using UnityEngine;
using System.Collections;
public class RemoteController : MonoBehaviour {
public Joystick leftStick;
public Joystick rightStick;
public Vector4 yprtRate = new Vector4(35,35,35, 1);
public float yaw;
public float throlle = 0;
public Transform testTransform;
public Quaternion targetOrientation;
public FlightController targetController;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
throlle = Mathf.Clamp01 (leftStick.State.y);
yaw += leftStick.State.x * yprtRate.x * Time.deltaTime;
Vector2 tiltAxis = rightStick.State;
Quaternion rotation = Quaternion.identity;
if (tiltAxis.magnitude > 0.01f) {
Vector3 rotationAxis = Vector3.Cross(Vector3.up, new Vector3(tiltAxis.x * yprtRate.y, 0, tiltAxis.y * yprtRate.z));
rotation = Quaternion.AngleAxis(rotationAxis.magnitude, rotationAxis.normalized);
}
//add yaw
targetOrientation = Quaternion.AngleAxis (yaw, Vector3.up) * rotation;
if (testTransform != null) {
testTransform.rotation = targetOrientation;
}
if (targetController != null) {
targetController.targetOrientation = targetOrientation;
targetController.targetThrolle = Mathf.Pow (throlle, 1.0f/4.0f) * 0.4f ;
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 248b197a229f6b3479293f47fa5c40da
timeCreated: 1423935269
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+90
View File
@@ -0,0 +1,90 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class SegmentDisplay : MonoBehaviour{
public byte segments;
private Material segmentMaterial;
private int _mask;
private Dictionary<char, byte> char_map = new Dictionary<char, byte>() {
//digits
{'0', 0x3f },
{'1', 0x06 },
{'2', 0x5b },
{'3', 0x4f },
{'4', 0x66 },
{'5', 0x6d },
{'6', 0x7d },
{'7', 0x07 },
{'8', 0x7f },
{'9', 0x6f },
};
public void SetChar(char c)
{
byte val = char_map.ContainsKey(c) ? char_map[c] : (byte)0;
_mask = (_mask & (1 << 7)) | val;
UpdateShader();
}
Material mat
{
get
{
if (segmentMaterial == null)
{
segmentMaterial = gameObject.GetComponent<Renderer>().materials[1]; ;
}
return segmentMaterial;
}
}
private void UpdateShader()
{
mat.SetInt("segments", _mask);
}
public bool ShowDot
{
get { return (_mask & (1 << 7)) != 0; }
set {
_mask = (_mask & ~(1 << 7));
if (value){
_mask |= 1 << 7;
}
UpdateShader();
}
}
void Start ()
{
// StartCoroutine(UpdateDigit());
}
void Update (){
}
private int d = 0;
/*IEnumerator UpdateDigit() {
while (true) {
yield return new WaitForSeconds(1);
if (d >= 9)
{
d = 0;
}
else
{
d++;
}
}
}*/
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9937900fd7a6f6a49a5680226a2d99e6
timeCreated: 1452349197
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,35 @@
using UnityEngine;
using System.Collections;
public class SegmentDisplayString : MonoBehaviour {
public SegmentDisplay[] segments;
public void SetString(string val) {
int segmentId = 0;
for (int i = 0; i < val.Length; ++i) {
char v = val[i];
if (v == '.') {
segments[segmentId == 0 ? 0 : segmentId - 1].ShowDot = true;
} else {
segments[segmentId].ShowDot = false;
segments[segmentId].SetChar(v);
segmentId++;
if (segmentId >= segments.Length) {
break;
}
}
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: bee6484a74d2d5d49b80abdf2640d594
timeCreated: 1452362664
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
using UnityEngine;
using System.Collections;
using System;
[Serializable]
public class SimpleLowPassFilter {
public float old = 0.0f;
public float RC = 0.5f;
public float dtScale = 1.0f;
public float DoFilter(float val, float dt){
float a = dt / (RC + dt * dtScale);
float result = a * val + (1.0f - a) * old;
old = val;
return result;
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3d4441c1960b611449ce5b9a95ea640e
timeCreated: 1425815930
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,15 @@
using UnityEngine;
using System.Collections;
public class TestQuadcopterController : QuadcopterFlightController {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 65d8c0a0067702f4f99aca30e9ebdea1
timeCreated: 1423553200
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+14
View File
@@ -0,0 +1,14 @@
using UnityEngine;
using System.Collections;
public static class VectorEx {
public static Vector2 Rotate(this Vector2 v, float degrees){
return v.RotateRadians(degrees * Mathf.Deg2Rad);
}
public static Vector2 RotateRadians(this Vector2 v, float radians){
var ca = Mathf.Cos(radians);
var sa = Mathf.Sin(radians);
return new Vector2(ca*v.x - sa*v.y, sa*v.x + ca*v.y);
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d5ed7d4c9ef09044ebce072f7fb8f05d
timeCreated: 1425893756
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: