예제 #1
0
    public override void OnInspectorGUI()
    {
        GUI.changed = false;
        GravityEngine gravityEngine = (GravityEngine)target;
        float         massScale     = gravityEngine.massScale;
        float         timeScale     = gravityEngine.timeScale;
        float         lengthScale   = gravityEngine.lengthScale;

        float physToWorldFactor = gravityEngine.physToWorldFactor;

        bool optimizeMassless = gravityEngine.optimizeMassless;
        bool detectNbodies    = gravityEngine.detectNbodies;
        bool evolveAtStart    = gravityEngine.evolveAtStart;
        bool scaling          = gravityEngine.editorShowScale;
        bool showAdvanced     = gravityEngine.editorShowAdvanced;
        bool showTrajectory   = gravityEngine.editorShowTrajectory;
        bool cmFoldout        = gravityEngine.editorCMfoldout;
        bool mapToScene       = gravityEngine.mapToScene;

        bool       trajectoryPrediction = gravityEngine.trajectoryPrediction;
        float      trajectoryTime       = gravityEngine.trajectoryTime;
        GameObject trajCanvas           = gravityEngine.trajectoryCanvas;
        GameObject markerParent         = gravityEngine.markerParent;
        float      computeFactor        = gravityEngine.trajectoryComputeFactor;

        int stepsPerFrame         = gravityEngine.stepsPerFrame;
        int particleStepsPerFrame = gravityEngine.particleStepsPerFrame;

        GravityEngine.Algorithm algorithm = GravityEngine.Algorithm.LEAPFROG;
        ForceChooser.Forces     force     = ForceChooser.Forces.Gravity;
        GravityScaler.Units     units     = GravityScaler.Units.DIMENSIONLESS;

        EditorGUIUtility.labelWidth = 200;

        mapToScene = EditorGUILayout.Toggle(new GUIContent("Use Transform to Reposition", mapTip), mapToScene);

        EditorGUIUtility.labelWidth = 150;

        // SCALING
        scaling = EditorGUILayout.Foldout(scaling, "Scaling");
        if (scaling)
        {
            units =
                (GravityScaler.Units)EditorGUILayout.EnumPopup(new GUIContent("Units", unitsTip), gravityEngine.units);
            EditorGUILayout.LabelField("Scaling values change when <ENTER> ispressed.");

            switch (units)
            {
            case GravityScaler.Units.DIMENSIONLESS:
                // only have mass scale in DL case
                EditorGUILayout.LabelField("Use mass scale to control scene speed.");
                EditorGUILayout.LabelField("(More massive = faster)");
                massScale = EditorGUILayout.DelayedFloatField(new GUIContent("Mass Scale", mTip), gravityEngine.massScale);
                break;

            case GravityScaler.Units.SI:
                // no mass scale is controlled by time exclusivly
                EditorGUILayout.LabelField("m/kg/sec.");
                // meters per Unity unit in the case of meters
                lengthScale = EditorGUILayout.DelayedFloatField(new GUIContent("Unity unit per m", timeTip), gravityEngine.lengthScale);
                timeScale   = EditorGUILayout.DelayedFloatField(new GUIContent("Game sec. per sec.", timeTip), gravityEngine.timeScale);
                break;

            case GravityScaler.Units.ORBITAL:
                EditorGUILayout.LabelField("km/1E24 kg/hr");
                // Express in km per Unity unit km/U
                lengthScale = EditorGUILayout.DelayedFloatField(new GUIContent("Unity unit per km", timeTip), gravityEngine.lengthScale);
                timeScale   = EditorGUILayout.DelayedFloatField(new GUIContent("Game sec. per hour", timeTip), gravityEngine.timeScale);
                break;

            case GravityScaler.Units.SOLAR:
                EditorGUILayout.LabelField("AU/1E24 kg/year");
                lengthScale = EditorGUILayout.DelayedFloatField(new GUIContent("Unity unit per AU", timeTip), gravityEngine.lengthScale);
                timeScale   = EditorGUILayout.DelayedFloatField(new GUIContent("Game Sec per year", timeTip), gravityEngine.timeScale);
                break;
            }
        }

        // TRAJECTORY PREDICTION
        showTrajectory = EditorGUILayout.Foldout(showTrajectory, "Trajectory Prediction");
        if (showTrajectory)
        {
            trajectoryPrediction = EditorGUILayout.Toggle(new GUIContent("Trajectory Prediction", trajTip), trajectoryPrediction);
            trajectoryTime       = EditorGUILayout.FloatField(new GUIContent("Trajectory Time", trajTimeTip), trajectoryTime);
            computeFactor        = EditorGUILayout.FloatField(new GUIContent("Re-computes per frame)", trajResetTip), computeFactor);
            trajCanvas           = (GameObject)EditorGUILayout.ObjectField(new GUIContent("Canvas for Text (optional)", trajCanvasTip),
                                                                           trajCanvas, typeof(GameObject), true);
            markerParent = (GameObject)EditorGUILayout.ObjectField(new GUIContent("Time Marker Parent (optional)", markerTip),
                                                                   markerParent, typeof(GameObject), true);
        }

        // ADVANCED
        showAdvanced = EditorGUILayout.Foldout(showAdvanced, "Advanced");
        if (showAdvanced)
        {
            algorithm =
                (GravityEngine.Algorithm)EditorGUILayout.EnumPopup(new GUIContent("Algorithm", algoTip), gravityEngine.algorithm);

            // Force selection is tangled with choice of integrator and scale - so needs to be here
            force =
                (ForceChooser.Forces)EditorGUILayout.EnumPopup(new GUIContent("Force", forceTip), gravityEngine.force);
            if (force == ForceChooser.Forces.Custom)
            {
                IForceDelegate force_delegate = gravityEngine.GetComponent <IForceDelegate>();
                if (force_delegate == null)
                {
                    EditorGUILayout.LabelField("  Attach a Force Delegate to this object.", EditorStyles.boldLabel);
                }
                else
                {
                    EditorGUILayout.LabelField("  Force delegate: " + force_delegate.GetType());
                }
            }
            if (force != ForceChooser.Forces.Gravity)
            {
                EditorGUILayout.LabelField("    Note: Orbit predictors assume Newtonian gravity");
                EditorGUILayout.LabelField("    They are not accurate for other forces.");
            }

            optimizeMassless = EditorGUILayout.Toggle(new GUIContent("Optimize Massless Bodies", mlessTip),
                                                      gravityEngine.optimizeMassless);
            detectNbodies     = EditorGUILayout.Toggle(new GUIContent("Automatically Add NBody objects", autoAddTip), gravityEngine.detectNbodies);
            evolveAtStart     = EditorGUILayout.Toggle(new GUIContent("Evolve at Start", autoStartTip), gravityEngine.evolveAtStart);
            physToWorldFactor = EditorGUILayout.FloatField(new GUIContent("Physics to World Scale", phyWTip), gravityEngine.physToWorldFactor);

            EditorGUILayout.LabelField("Steps per frame:");
            stepsPerFrame         = EditorGUILayout.IntField(new GUIContent("  Massive Bodies", stepTip), stepsPerFrame);
            particleStepsPerFrame = EditorGUILayout.IntField(new GUIContent("  Particles", pstepTip), particleStepsPerFrame);
        }
        // Switch bodies list on/off based on option
        if (!gravityEngine.detectNbodies)
        {
            // use native Inspector look & feel for bodies object
            EditorGUILayout.LabelField("Control Nbody in following gameObjects (and children)", EditorStyles.boldLabel);
            SerializedProperty bodiesProp = serializedObject.FindProperty("bodies");
            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(bodiesProp, true);
            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();
            }
        }
        else
        {
            EditorGUILayout.LabelField("NBody objects will be detected automatically", EditorStyles.boldLabel);
        }
        // Show the CM and the velocity of the CM
        cmFoldout = EditorGUILayout.Foldout(cmFoldout, "Center of Mass Info");
        if (cmFoldout)
        {
            EditorGUILayout.LabelField("Center of Mass:" + gravityEngine.GetWorldCenterOfMass());
            EditorGUILayout.LabelField("CM Velocity:" + gravityEngine.GetWorldCenterOfMassVelocity());
        }


        // Checking the Event type lets us update after Undo and Redo commands.
        // A redo updates _lengthScale but does not run the setter
        if (Event.current.type == EventType.ExecuteCommand &&
            Event.current.commandName == "UndoRedoPerformed")
        {
            // explicitly re-set so setter code will run.
            gravityEngine.lengthScale = lengthScale;
        }

        if (GUI.changed)
        {
            Undo.RecordObject(gravityEngine, "GE Change");
            gravityEngine.mapToScene = mapToScene;

            gravityEngine.timeScale = timeScale;
            gravityEngine.massScale = massScale;
            // This runs a setter in GE that will do a rescale of the scene if necessary
            gravityEngine.lengthScale       = lengthScale;
            gravityEngine.units             = units;
            gravityEngine.physToWorldFactor = physToWorldFactor;
            gravityEngine.optimizeMassless  = optimizeMassless;
            gravityEngine.detectNbodies     = detectNbodies;

            gravityEngine.editorShowTrajectory    = showTrajectory;
            gravityEngine.trajectoryPrediction    = trajectoryPrediction;
            gravityEngine.trajectoryTime          = trajectoryTime;
            gravityEngine.trajectoryCanvas        = trajCanvas;
            gravityEngine.markerParent            = markerParent;
            gravityEngine.trajectoryComputeFactor = computeFactor;

            gravityEngine.algorithm             = algorithm;
            gravityEngine.force                 = force;
            gravityEngine.evolveAtStart         = evolveAtStart;
            gravityEngine.editorShowScale       = scaling;
            gravityEngine.editorShowAdvanced    = showAdvanced;
            gravityEngine.editorCMfoldout       = cmFoldout;
            gravityEngine.stepsPerFrame         = stepsPerFrame;
            gravityEngine.particleStepsPerFrame = particleStepsPerFrame;
            EditorUtility.SetDirty(gravityEngine);
        }
    }