Пример #1
0
        StringBuilder DumpBaseJoint(Joint joint)
        {
            var msg = new StringBuilder();

            msg.Append("name: ").Append(joint.name).AppendLine();
            msg.Append("ownerBody: ")
            .Append(DebugEx.ObjectToString(joint.gameObject.GetComponent <Rigidbody>()))
            .AppendLine();
            msg.Append("connectedBody: ")
            .Append(DebugEx.ObjectToString(joint.connectedBody))
            .AppendLine();
            // Collider setup.
            msg.Append("enableCollision: ").Append(joint.enableCollision).AppendLine();
            // Optimization.
            msg.Append("enablePreprocessing: ").Append(joint.enablePreprocessing).AppendLine();
            // Break forces.
            msg.Append("breakForce: ").Append(joint.breakForce).AppendLine();
            msg.Append("breakTorque: ").Append(joint.breakTorque).AppendLine();
            // Geometry.
            msg.Append("anchor: ").Append(DbgFormatter.Vector(joint.anchor)).AppendLine();
            msg.Append("connectedAnchor: ")
            .Append(DbgFormatter.Vector(joint.connectedAnchor))
            .AppendLine();
            msg.Append("axis: ").Append(DbgFormatter.Vector(joint.axis)).AppendLine();
            return(msg);
        }
Пример #2
0
        public void TestMachine()
        {
            var sm = new SimpleStateMachine <State>(strict: false);

            sm.AddStateHandlers(
                State.One,
                enterHandler: oldState => Debug.Log("Now in state ONE"),
                leaveHandler: newState => Debug.LogFormat("Going into state: {0}", newState));
            sm.onAfterTransition += (from, to) => Debug.LogFormat(
                "Move from {0} to {1}", DbgFormatter.Nullable(from), DbgFormatter.Nullable(to));

            sm.currentState = State.One; // Start the machine.
            // Logs:
            // Now in state ONE
            // Move from NULL to One

            sm.currentState = State.Two;
            // Logs:
            // Going into state: Two
            // Move from One to Two

            sm.currentState = State.Three;
            // Logs: Move from Two to Three

            sm.currentState = null; // Stop the machine.
            // Logs: Move Three to NULL
        }
Пример #3
0
        /// <inheritdoc/>
        public virtual bool CheckCanLinkTo(ILinkTarget target,
                                           bool checkStates = true,
                                           bool reportToGui = false, bool reportToLog = true)
        {
            var errors = new List <string>()
                         .Concat(CheckBasicLinkConditions(target, checkStates))
                         .Concat(linkRenderer.CheckColliderHits(nodeTransform, target.nodeTransform))
                         .Concat(linkJoint.CheckConstraints(this, target))
                         .ToArray();

            if (errors.Length > 0)
            {
                if (reportToGui || reportToLog)
                {
                    HostedDebugLog.Warning(
                        this, "Cannot link a part of type={0} with: part={1}, type={2}, errors={3}",
                        cfgLinkType, target.part, target.cfgLinkType, DbgFormatter.C2S(errors));
                }
                if (reportToGui)
                {
                    ShowStatusMessage(DbgFormatter.C2S(errors, separator: "\n"), isError: true);
                }
            }
            return(errors.Length == 0);
        }
Пример #4
0
 /// <summary>Disables/enables all the colliders between the parts.</summary>
 /// <remarks>The ignore state is reset to <c>false</c> on every scene load.</remarks>
 /// <param name="part1">Source part.</param>
 /// <param name="part2">Target part.</param>
 /// <param name="ignore">
 /// If <c>true</c> then the collisions between the parts will be ignored. Otherwise, the
 /// collisions will be handled.
 /// </param>
 /// <seealso href="https://docs.unity3d.com/ScriptReference/Collider.html">
 /// Unity3D: Collider</seealso>
 /// <seealso href="https://docs.unity3d.com/ScriptReference/Physics.IgnoreCollision.html">
 /// Unity3D: Physics.IgnoreCollision</seealso>
 public static void SetCollisionIgnores(Part part1, Part part2, bool ignore)
 {
     Debug.LogFormat("Set collision ignores between {0} and {1} to {2}",
                     DbgFormatter.PartId(part1), DbgFormatter.PartId(part2), ignore);
     SetCollisionIgnores(
         Hierarchy.GetPartModelTransform(part1), Hierarchy.GetPartModelTransform(part2), ignore);
 }
Пример #5
0
 /// <inheritdoc/>
 public override void OnDebugAdjustablesUpdated()
 {
     base.OnDebugAdjustablesUpdated();
     if (isLinked)
     {
         var checks = CheckConstraints(linkSource, linkTarget);
         if (checks.Length == 0)
         {
             // Given all checks are green, we can simply recreate the joint to update it.
             HostedDebugLog.Warning(
                 this, "New settings fit the current link. Refreshing the joint...");
             DropJoint();
             CreateJoint(dbgLinkSource, dbgLinkTarget);
         }
         else
         {
             // STOP! The joint, once broken, won't re-establish with the new settings.
             HostedDebugLog.Warning(this, "New settings DON'T fit the current link:\n{0}"
                                    + "\n\nNot refershing the joint, re-link manually to update.",
                                    DbgFormatter.C2S(checks, separator: "\n"));
         }
     }
     else
     {
         // No joint, not update. However, it makes sense to note it.
         HostedDebugLog.Warning(
             this, "No link esatblished, only update the module settings");
     }
 }
Пример #6
0
        /// <summary>Adds default items to the pod's seats.</summary>
        /// <remarks>Items are only added to a part created in the editor. Thus, reacting on the editor
        /// event.</remarks>
        /// <param name="type">Unused.</param>
        /// <param name="p">A target part.</param>
        void OnEditPartCreate(ConstructionEventType type, Part p)
        {
            if (type != ConstructionEventType.PartCreated && type != ConstructionEventType.PartCopied)
            {
                return;
            }
            var inventories = p.GetComponents <ModuleKISInventory>();

            foreach (var inventory in inventories)
            {
                if (inventory.podSeat == 0 && ModuleKISInventory.defaultItemsForTheFirstSeat.Count > 0)
                {
                    Debug.LogFormat("Adding default item(s) into the first seat of part {0}: {1}",
                                    p.name, DbgFormatter.C2S(ModuleKISInventory.defaultItemsForTheFirstSeat));
                    AddItems(inventory, ModuleKISInventory.defaultItemsForTheFirstSeat);
                }
                if (inventory.podSeat != -1 && ModuleKISInventory.defaultItemsForAllSeats.Count > 0)
                {
                    Debug.LogFormat(
                        "Adding default item(s) into seat's {0} inventory of part {1}: {2}",
                        inventory.podSeat, p.name,
                        DbgFormatter.C2S(ModuleKISInventory.defaultItemsForAllSeats));
                    AddItems(inventory, ModuleKISInventory.defaultItemsForAllSeats);
                }
            }
        }
Пример #7
0
 void LogObjectChildren(Transform objTransform)
 {
     Debug.Log(DbgFormatter.TranformPath(objTransform));
     for (var i = 0; i < objTransform.transform.childCount; i++)
     {
         LogObjectChildren(objTransform.transform.GetChild(i));
     }
 }
Пример #8
0
 /// <summary>Throws if enum value is not in the expected set.</summary>
 /// <typeparam name="T">Type of value to check.</typeparam>
 /// <param name="arg">The value to check.</param>
 /// <param name="message">An optional message to present in the error.</param>
 /// <param name="context">The optional "owner" object.</param>
 /// <param name="values">The acceptable values of the enum.</param>
 /// <exception cref="InvalidOperationException">If condition fails.</exception>
 public static void OneOf <T>(T arg, T[] values, string message = null, object context = null)
 {
     if (!values.Contains(arg))
     {
         throw new InvalidOperationException(
                   Preconditions.MakeContextError(
                       context, "Not one of: {1}. {2}", DbgFormatter.C2S(values), message));
     }
 }
Пример #9
0
 /// <summary>Throws if enum value is not in the expected set.</summary>
 /// <typeparam name="T">Type of value to check.</typeparam>
 /// <param name="arg">The argument value to check.</param>
 /// <param name="argName">The argument name.</param>
 /// <param name="values">The acceptable values of the enum.</param>
 /// <param name="message">An optional message to present in the error.</param>
 /// <param name="context">The optional "owner" object.</param>
 /// <exception cref="ArgumentOutOfRangeException">
 /// If the argument is not one of the specified.
 /// </exception>
 public static void OneOf <T>(T arg, string argName, T[] values,
                              string message = null, object context = null)
 {
     if (!values.Contains(arg))
     {
         throw new ArgumentOutOfRangeException(
                   argName, arg,
                   Preconditions.MakeContextError(
                       context, "Not one of: {1}. {2}", DbgFormatter.C2S(values), message));
     }
 }
Пример #10
0
        /// <summary>Returns an anchor for the physical joint at the target part.</summary>
        /// <remarks>
        /// The anchor will be calculated in the source's part scale, and the target's model scale will
        /// be ignored.
        /// </remarks>
        /// <param name="source">The source of the link.</param>
        /// <param name="target">The target of the link.</param>
        /// <returns>The position in the world coordinates.</returns>
        protected Vector3 GetTargetPhysicalAnchor(ILinkSource source, ILinkTarget target)
        {
            var scale = source.nodeTransform.lossyScale;

            if (Mathf.Abs(scale.x - scale.y) > 1e-05 || Mathf.Abs(scale.x - scale.z) > 1e-05)
            {
                HostedDebugLog.Error(this, "Uneven scale on the source part is not supported: {0}",
                                     DbgFormatter.Vector(scale));
            }
            return(target.nodeTransform.position
                   + target.nodeTransform.rotation * (anchorAtTarget * scale.x));
        }
Пример #11
0
        /// <summary>Finds a transform in the hirerachy by the provided path.</summary>
        /// <remarks>
        /// Every element of the path may specify an exact transform name or a partial match pattern:
        /// <list type="bullet">
        /// <item>
        /// <c>*</c> - any name matches. Such patterns can be nested to specify the desired level of
        /// nesting. E.g. <c>*/*/a</c> will look for name <c>a</c> in the grandchildren.
        /// </item>
        /// <item>
        /// <c>*</c> as a prefix - the name is matched by suffix. E.g. <c>*a</c> matches any name that
        /// ends with <c>a</c>.
        /// </item>
        /// <item>
        /// <c>*</c> as a suffix - the name is matched by prefix. E.g. <c>a*</c> matches any name that
        /// starts with <c>a</c>.
        /// </item>
        /// <item>
        /// <c>**</c> - any <i>path</i> matches. What will eventually be found depends on the pattern to
        /// the right of <c>**</c>. The path match pattern does a "breadth-first" search, i.e. it tries to
        /// find the shortest path possible. E.g. <c>**/a/b</c> will go through all the nodes starting
        /// from the parent until path <c>a/b</c> is found. Be careful with this pattern since in case of
        /// not matching anything it will walk thought the <i>whole</i> hirerachy.
        /// </item>
        /// </list>
        /// <para>
        /// All patterns except <c>**</c> may have a matching index. It can be used to resolve matches
        /// when there are multiple objects found with the same name and at the <i>same level</i>. E.g. if
        /// there are two objects with name "a" at the root level then the first one can be accessed by
        /// pattern <c>a:0</c>, and the second one by pattern <c>a:1</c>.
        /// </para>
        /// <para>
        /// Path search is <i>slow</i> since it needs walking though the hierarchy nodes. In the worst
        /// case all the nodes will be visited. Don't use this method in the performance demanding
        /// methods.
        /// </para>
        /// </remarks>
        /// <param name="parent">The transfrom to start looking from.</param>
        /// <param name="path">The path elements. All the special symbols must be unescaped.</param>
        /// <param name="defValue">
        /// An object to return if the path is not found. This situation will be treated as a danger, and
        /// a warning log record will be made.
        /// </param>
        /// <returns>Transform or <c>null</c> if nothing found.</returns>
        /// <example>
        /// Given the following hierarchy:
        /// <code lang="c++"><![CDATA[
        /// // a
        /// // + b
        /// // | + c
        /// // | | + c1
        /// // | | + d
        /// // | + c
        /// // |   + d
        /// // |     + e
        /// // |       + e1
        /// // + abc
        /// ]]></code>
        /// <para>The following pattern/output will be possible:</para>
        /// <code><![CDATA[
        /// // a/b/c/d/e/e1 => node "e1"
        /// // a/b/*/d/e/e1 => node "e1"
        /// // a/b/*/*/e/e1 => node "e1"
        /// // a/b/c/c1 => node "с1"
        /// // a/b/*:0 => branch "a/b/c/c1", node "c"
        /// // a/b/*:1 => branch "a/b/c/d/e/e1", node "c"
        /// // a/b/c:1/d => branch "a/b/c/d/e/e1", node "d"
        /// // **/e1 => node "e1"
        /// // **/c1 => node "c1"
        /// // **/c/d => AMBIGUITY! The first found branch will be taken
        /// // a/**/e1 => node "e1"
        /// // *bc => node "abc"
        /// // ab* => node "abc"
        /// // *b* => node "abc"
        /// ]]></code>
        /// </example>
        /// <seealso cref="UnescapeName"/>
        /// <include file="Unity3D_HelpIndex.xml" path="//item[@name='T:UnityEngine.Transform']/*"/>
        public static Transform FindTransformByPath(Transform parent, string[] path,
                                                    Transform defValue = null)
        {
            var obj = FindTransformByPathInternal(parent, path);

            if (obj == null && defValue != null)
            {
                HostedDebugLog.Warning(parent, "Cannot find path: {0}. Using a fallback: {1}",
                                       MakePath(path), DbgFormatter.TranformPath(defValue));
                return(defValue);
            }
            return(obj);
        }
Пример #12
0
 /// <summary>Updates data in all the open part menus.</summary>
 public static void LocalizePartMenus()
 {
     // The editor's tooltip caches the data, and we cannot update it. So just reset it.
     if (HighLogic.LoadedSceneIsEditor)
     {
         UIMasterController.Instance.DestroyCurrentTooltip();
     }
     UnityEngine.Object.FindObjectsOfType(typeof(UIPartActionWindow))
     .OfType <UIPartActionWindow>()
     .ToList()
     .ForEach(m => {
         Debug.LogFormat("Localize menu for part {0}", DbgFormatter.PartId(m.part));
         m.titleText.text = m.part.partInfo.title;
     });
 }
Пример #13
0
 /// <inheritdoc/>
 public virtual bool CreateJoint(ILinkSource source, ILinkTarget target)
 {
     if (isLinked)
     {
         HostedDebugLog.Error(
             this, "Cannot link the joint which is already linked to: {0}", linkTarget);
         return(false);
     }
     if (!CheckCoupled(source, target))
     {
         var errors = CheckConstraints(source, target);
         if (errors.Length > 0)
         {
             HostedDebugLog.Error(this, "Cannot create joint:\n{0}", DbgFormatter.C2S(errors));
             return(false);
         }
     }
     else
     {
         HostedDebugLog.Fine(this, "The parts are coupled. Skip the constraints check");
     }
     linkSource = source;
     linkTarget = target;
     if (!originalLength.HasValue)
     {
         SetOrigianlLength(Vector3.Distance(
                               GetSourcePhysicalAnchor(source), GetTargetPhysicalAnchor(source, target)));
     }
     isLinked = true;
     // If the parts are already coupled at this moment, then the mode must be set as such.
     coupleOnLinkMode |= isCoupled;
     // Ensure the coupling can be done.
     coupleOnLinkMode &= linkSource.coupleNode != null && linkTarget.coupleNode != null;
     if (coupleOnLinkMode)
     {
         CoupleParts();
     }
     else
     {
         AttachParts();
     }
     return(true);
 }
Пример #14
0
        /// <summary>Creates a debug dialog for the parts.</summary>
        /// <remarks>
        /// Implement a code that would react on user interactions and invoke this method to show a debug
        /// dialog. The dialog can be bound to a specific part, in which case it only showns for that
        /// part, or the dialog may allow interactively selecting a part from the scene.
        /// </remarks>
        /// <param name="title">The titile of the dialog.</param>
        /// <param name="dialogWidth">
        /// The width of the dialog. If omitted, then the code will decide.
        /// </param>
        /// <param name="valueColumnWidth">
        /// The width of the value changing controls. If omitted, then the code will decide.
        /// </param>
        /// <param name="group">
        /// The group of the controls to present. If empty, then all the controls are shown.
        /// </param>
        /// <param name="bindToPart">
        /// The part to attach the dialog to. If set, then the dialog won't allow changing the part via
        /// GUI. Otherwise, there will be controls in the dialog that allow selection a part from the
        /// scene.
        /// </param>
        /// <returns>The created dialog.</returns>
        /// <seealso cref="DestroyPartDebugDialog"/>
        /// <seealso cref="DebugAdjustableAttribute"/>
        public static PartDebugAdjustmentDialog MakePartDebugDialog(
            string title,
            float?dialogWidth = null, float?valueColumnWidth = null, string group = "",
            Part bindToPart   = null)
        {
            if (bindToPart != null)
            {
                title += " : " + DbgFormatter.PartId(bindToPart);
            }
            var dlg = dialogsRoot.AddComponent <PartDebugAdjustmentDialog>();

            dlg.dialogTitle     = title;
            dlg.dialogWidth     = dialogWidth ?? dlg.dialogWidth;
            dlg.dialogValueSize = valueColumnWidth ?? dlg.dialogValueSize;
            dlg.controlsGroup   = group;
            if (bindToPart != null)
            {
                dlg.lockToPart = true;
                dlg.SetPart(bindToPart);
            }
            DebugEx.Info("Created debug dialog: {0}", title);
            return(dlg);
        }
        public void TestMachine()
        {
            var sm = new SimpleStateMachine <State>(strict: false);

            sm.AddStateHandlers(
                State.One,
                enterHandler: oldState => Debug.Log("Now in state ONE"),
                leaveHandler: newState => Debug.LogFormat("Going into state: {0}", newState));
            sm.onBeforeTransition += (from, to) => Debug.LogFormat(
                "Before move: current={0}, new={1}",
                DbgFormatter.Nullable(sm.currentState), DbgFormatter.Nullable(to));
            sm.onAfterTransition += (from, to) => Debug.LogFormat(
                "After move: old={0}, current={1}",
                DbgFormatter.Nullable(from), DbgFormatter.Nullable(sm.currentState));

            sm.currentState = State.One; // Start the machine.
            // Logs:
            // Now in state ONE
            // Before move: current=NULL, new=One
            // After move: old=NULL, current=One

            sm.currentState = State.Two;
            // Logs:
            // Going into state: Two
            // Before move: current=One, new=Two
            // After move: old=One, current=Two

            sm.currentState = State.Three;
            // Logs:
            // Before move: current=Two, new=Three
            // After move: old=Two, current=Three

            sm.currentState = null; // Stop the machine.
            // Logs:
            // Before move: current=Three, new=NULL
            // After move: old=Three, current=NULL
        }
Пример #16
0
        void WaitAndApplyTweaks()
        {
            var roots = UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects();

            foreach (var root in roots)
            {
                if (logAllObjects)
                {
                    LogObjectChildren(root.transform);
                }
                foreach (var tweak in modelTweaks)
                {
                    var names        = tweak.modelNamePattern.Split('/');
                    var reducedNames = names.Skip(1).ToArray();
                    // Try first name part separately since the scene objects don't have a single root.
                    if (names[0] == "**")
                    {
                        reducedNames = names; // Try all children in the root.
                    }
                    else if (!Hierarchy.PatternMatch(names[0], root.transform.name))
                    {
                        continue;
                    }
                    var objTransform = Hierarchy.FindTransformByPath(root.transform, reducedNames);
                    if (objTransform != null)
                    {
                        Debug.LogFormat("Tweak '{0}' matched kerbal model: {1}",
                                        tweak.tweakName, DbgFormatter.TranformPath(objTransform));
                        tweak.itemNames.ToList().ForEach(x => {
                            var item = new TweakEquippableItem(x, tweak.matchMeshesBySuffix);
                            item.ApplyTweak(objTransform.gameObject);
                            sceneTweaks.Add(item);
                        });
                    }
                }
            }
        }
Пример #17
0
        /// <inheritdoc/>
        public string DumpJoint(ConfigurableJoint joint)
        {
            if (joint == null)
            {
                return("<NULL JOINT>");
            }
            var msg = DumpBaseJoint(joint);

            // Geometry.
            msg.Append("secondaryAxis: ").Append(DbgFormatter.Vector(joint.secondaryAxis)).AppendLine();
            // X axis settings.
            msg.Append("xDrive: ").Append(Dump(joint.xDrive)).AppendLine();
            msg.Append("xMotion: ").Append(joint.xMotion).AppendLine();
            msg.Append("angularXMotion: ").Append(joint.angularXMotion).AppendLine();
            msg.Append("angularXLimitSpring: ").Append(Dump(joint.angularXLimitSpring)).AppendLine();
            msg.Append("angularXDrive: ").Append(Dump(joint.angularXDrive)).AppendLine();
            msg.Append("lowAngularXLimit: ").Append(Dump(joint.lowAngularXLimit)).AppendLine();
            msg.Append("highAngularXLimit: ").Append(Dump(joint.highAngularXLimit)).AppendLine();
            // Y axis settings.
            msg.Append("yDrive: ").Append(Dump(joint.yDrive)).AppendLine();
            msg.Append("yMotion: ").Append(joint.yMotion).AppendLine();
            msg.Append("angularYMotion: ").Append(joint.angularYMotion).AppendLine();
            msg.Append("angularYLimit: ").Append(Dump(joint.angularYLimit)).AppendLine();
            // Z axis settings.
            msg.Append("zDrive: ").Append(Dump(joint.zDrive)).AppendLine();
            msg.Append("zMotion: ").Append(joint.zMotion).AppendLine();
            msg.Append("angularZMotion: ").Append(joint.angularZMotion).AppendLine();
            msg.Append("angularZLimit: ").Append(Dump(joint.angularZLimit)).AppendLine();
            // Multiple axis settings.
            msg.Append("linearLimit: ").Append(Dump(joint.linearLimit)).AppendLine();
            msg.Append("linearLimitSpring: ").Append(Dump(joint.linearLimitSpring)).AppendLine();
            msg.Append("angularYZDrive: ").Append(Dump(joint.angularYZDrive)).AppendLine();
            msg.Append("angularYZLimitSpring: ").Append(Dump(joint.angularYZLimitSpring)).AppendLine();

            return(msg.ToString());
        }
Пример #18
0
        /// <summary>Invokes a callback with the original value of an attribute argument.</summary>
        /// <param name="member">The attributed member.</param>
        /// <param name="attrType">The type of the attribute.</param>
        /// <param name="argName">The name of the attribute argument.</param>
        /// <param name="setupFn">
        /// The callback that is called if the specified argument in the attribute is found.
        /// </param>
        static void SetupArgumentFromAttribute(
            MemberInfo member, Type attrType, string argName, Action <string> setupFn)
        {
            var fieldAttr = member.CustomAttributes.FirstOrDefault(x => x.AttributeType == attrType);

            if (fieldAttr == null)
            {
                DebugEx.Error("Attribute not found: attrType={0}, member={1}.{2}",
                              attrType, member.DeclaringType, member.Name);
                return;
            }
            var namedArgument = fieldAttr.NamedArguments?
                                .FirstOrDefault(x => x.MemberName == argName);

            if (namedArgument == null)
            {
                DebugEx.Error("Cannot fetch named argument: attrType={0}, member={1}.{2}, argName={3}",
                              attrType, member.DeclaringType, member.Name, argName);
                DebugEx.Warning("Available arguments for attribute {0}: {1}",
                                DbgFormatter.C2S(fieldAttr.NamedArguments, predicate: x => x.MemberName));
                return;
            }
            setupFn((string)namedArgument.Value.TypedValue.Value);
        }
Пример #19
0
        /// <summary>Shows a window that displays the winch controls.</summary>
        /// <param name="windowId">Window ID.</param>
        void ConsoleWindowFunc(int windowId)
        {
            MakeGuiStyles();

            if (guiActions.ExecutePendingGuiActions())
            {
                if (parentPartTracking)
                {
                    SetPart(Mouse.HoveredPart);
                }
                if (parentPartTracking && Input.GetMouseButtonDown(0))
                {
                    parentPartTracking = false;
                }
            }

            using (new GUILayout.VerticalScope(GUI.skin.box)) {
                using (new GuiEnabledStateScope(!parentPartTracking)) {
                    if (GUILayout.Button("Set part"))
                    {
                        guiActions.Add(() => parentPartTracking = true);
                    }
                }
                using (new GuiEnabledStateScope(parentPartTracking)) {
                    if (GUILayout.Button("Cancel set mode..."))
                    {
                        guiActions.Add(() => parentPartTracking = false);
                    }
                }
                var parentPartName =
                    "Part: " + (parentPart != null ? DbgFormatter.PartId(parentPart) : "NONE");
                GUILayout.Label(parentPartName, guiNoWrapStyle);
            }

            if (parentPart != null && itemModule != null &&
                (itemModule.equipable || itemModule.carriable))
            {
                GUILayout.Label("KIS Item detected:");
                using (new GUILayout.VerticalScope(GUI.skin.box)) {
                    using (new GUILayout.HorizontalScope(GUI.skin.box)) {
                        GUILayout.Label("Equip pos (metres):", guiCaptionStyle);
                        GUILayout.FlexibleSpace();
                        itemModule.equipPos = itemPosition.UpdateFrame(
                            itemModule.equipPos, guiValueStyle, new[] { GUILayout.Width(100) });
                    }
                    using (new GUILayout.HorizontalScope(GUI.skin.box)) {
                        GUILayout.Label("Equip dir (euler degrees):", guiCaptionStyle);
                        GUILayout.FlexibleSpace();
                        itemModule.equipDir = itemDirection.UpdateFrame(
                            itemModule.equipDir, guiValueStyle, new[] { GUILayout.Width(100) });
                    }
                }
            }

            if (GUILayout.Button("Close", GUILayout.ExpandWidth(false)))
            {
                guiActions.Add(() => isGUIOpen = false);
            }

            // Allow the window to be dragged by its title bar.
            GuiWindow.DragWindow(ref windowRect, titleBarRect);
        }
        /// <summary>Shows a window that displays the winch controls.</summary>
        /// <param name="windowId">Window ID.</param>
        void ConsoleWindowFunc(int windowId)
        {
            if (guiActions.ExecutePendingGuiActions())
            {
                if (parentPartTracking && Input.GetMouseButtonDown(0) &&
                    !windowRect.Contains(Mouse.screenPos))
                {
                    SetPart(Mouse.HoveredPart);
                    parentPartTracking = false;
                }
            }

            string parentPartName = parentPart != null?DbgFormatter.PartId(parentPart) : "NONE";

            if (!lockToPart)
            {
                if (GUILayout.Button(!parentPartTracking ? "Set part" : "Cancel set mode..."))
                {
                    guiActions.Add(() => { parentPartTracking = !parentPartTracking; });
                }
                if (parentPartTracking && Mouse.HoveredPart != null)
                {
                    parentPartName = "Select: " + DbgFormatter.PartId(Mouse.HoveredPart);
                }
                GUILayout.Label(parentPartName, new GUIStyle(GUI.skin.box)
                {
                    wordWrap = true
                });
            }

            // Render the adjustable fields.
            if (parentPart != null && adjustableModules != null)
            {
                if (adjustableModules.Length > 0)
                {
                    mainScrollView.BeginView(GUI.skin.box, Screen.height - 200);
                    for (var i = 0; i < adjustableModules.Length; i++)
                    {
                        var isSelected    = selectedModule == i;
                        var module        = adjustableModules[i];
                        var toggleCaption = (isSelected ? "\u25b2 " : "\u25bc ") + "Module: " + module.Key;
                        if (GUILayout.Button(toggleCaption))
                        {
                            var selectedModuleSnapshot = selectedModule == i ? -1 : i; // Make a copy for lambda!
                            guiActions.Add(() => selectedModule = selectedModuleSnapshot);
                        }
                        if (isSelected)
                        {
                            foreach (var control in module.Value)
                            {
                                control.RenderControl(
                                    guiActions, GUI.skin.label, new[] { GUILayout.Width(dialogValueSize) });
                            }
                        }
                    }
                    mainScrollView.EndView();
                }
                else
                {
                    GUILayout.Box("No adjustable members found");
                }
            }

            if (GUILayout.Button("Close", GUILayout.ExpandWidth(false)))
            {
                guiActions.Add(() => DebugGui.DestroyPartDebugDialog(this));
            }

            // Allow the window to be dragged by its title bar.
            GuiWindow.DragWindow(ref windowRect, titleBarRect);
        }
Пример #21
0
 /// <summary>Shows a human readable representation.</summary>
 /// <returns>String value.</returns>
 public override string ToString()
 {
     return(string.Format(
                "[PosAndRot Pos={0}, Euler={1}]", DbgFormatter.Vector(pos), DbgFormatter.Vector(euler)));
 }
 void LogFromTo(State?from, State?to)
 {
     Debug.LogFormat(
         "Move from {0} to {1}", DbgFormatter.Nullable(from), DbgFormatter.Nullable(to));
 }