예제 #1
0
        bool Validate(SerializedProperty property)
        {
            if (attribute.validator == null)
            {
                return(true);
            }

            SerializedProperty prop = property.serializedObject.FindProperty(attribute.propertyPath);

            if (prop == null)
            {
                return(true);
            }

            bool valid = true;

            try
            {
                valid = attribute.validator(prop);
            }
            catch (Exception)
            {
                Dbg.LogErrorOnce(
                    Dbg.Context(attribute),
                    "ValueRestrictAttribute validator for {0}.{1} threw. This message will only log once",
                    property.serializedObject, property.propertyPath
                    );
            }

            return(valid);
        }
예제 #2
0
    // Steps a routine and returns what should happen
    // to it next
    StepResult Step(ref Routine routine)
    {
        object current = routine.enumerator.Current;

        // Handle nested coroutines
        if (current is CoroutineHandle)
        {
            if (IsRunning((CoroutineHandle)current))
            {
                return(StepResult.Requeue);
            }
        }
        else if (current is YieldInstruction)
        {
            if (current is AsyncOperation)
            {
                var asOp = (AsyncOperation)current;
                if (!asOp.isDone)
                {
                    return(StepResult.Requeue);
                }
            }
            else if (runningInterops.ContainsKey(routine.id))
            {
                return(StepResult.Requeue);
            }
        }
        else if (current is CustomYieldInstruction)
        {
            // NOTE: Does not precisely mimic Unity's behavior
            //       since current is not queried start of update
            //       and end of update
            var asYieldInstr = (CustomYieldInstruction)current;
            if (asYieldInstr.keepWaiting)
            {
                return(StepResult.Requeue);
            }
        }
        else if (current is CustomWaitForSeconds)
        {
            if (routine.delay > 0.0f)
            {
                routine.delay -= Time.deltaTime;
                return(StepResult.Requeue);
            }
        }

        if (!routine.enumerator.MoveNext())
        {
            return(StepResult.Stopped);
        }

        current = routine.enumerator.Current;

        // Make sure that if a CustomWaitForSeconds was returned
        // that it is immediately used to free the instance up
        if (current is CustomWaitForSeconds)
        {
            var asWait = (CustomWaitForSeconds)current;

            routine.delay = asWait.duration;
            asWait.inUse  = false;
        }
        else if (current is YieldInstruction)
        {
            if (current is WaitForFixedUpdate)
            {
                return(StepResult.RequeueFixed);
            }
            else if (current is WaitForEndOfFrame)
            {
                return(StepResult.RequeuePostRender);
            }
            else
            {
                Dbg.LogWarnOnce(
                    Dbg.Context(current.GetType(), this),
                    "Unsupported YieldInstruction type {0}. It will be started using Unity's normal coroutines and have some additional performance overhead. This message will only log once.",
                    current.GetType()
                    );

                runningInterops[routine.id] = StartCoroutine(
                    InteropRoutine(routine.id, (YieldInstruction)current)
                    );
            }
        }
        else if (current is IEnumerator)
        {
            throw new Exception("Returning an IEnumerator is not supported. Start a separate coroutine instead.");
        }

        return(StepResult.Requeue);
    }
예제 #3
0
        public static void Draw(SerializedProperty fieldProperty, GUIContent label, Transform self)
        {
            if (fieldProperty.hasMultipleDifferentValues)
            {
                return;
            }

            if (editingProperty != null && !IsEditingProperty(fieldProperty))
            {
                return;
            }

            var kindProp           = fieldProperty.FindPropertyRelative("kind");
            var parentProp         = fieldProperty.FindPropertyRelative("parent");
            var childNameProp      = fieldProperty.FindPropertyRelative("childName");
            var findInactiveProp   = fieldProperty.FindPropertyRelative("findInactive");
            var findInChildrenProp = fieldProperty.FindPropertyRelative("findInChildren");
            var directCompProp     = fieldProperty.FindPropertyRelative("directComponent");
            var localOffsetProp    = fieldProperty.FindPropertyRelative("_localOffset");
            var localRotProp       = fieldProperty.FindPropertyRelative("_localRotation");

            bool anyNull =
                kindProp == null ||
                parentProp == null ||
                childNameProp == null ||
                findInactiveProp == null ||
                findInChildrenProp == null ||
                directCompProp == null ||
                localOffsetProp == null ||
                localRotProp == null;

            if (anyNull)
            {
                Dbg.LogWarnOnceRelease(
                    Dbg.Context(fieldProperty.propertyPath),
                    "Property with path {0} lacked a field. Are you sure it's a LocalOffsetField?",
                    fieldProperty.propertyPath
                    );
                return;
            }

            Transform bone = FindCompField <Transform> .Get(
                kindProp.EnumValue <FindCompKind>(),
                (Transform)parentProp.objectReferenceValue,
                self,
                childNameProp.stringValue,
                findInChildrenProp.boolValue,
                findInactiveProp.boolValue,
                (Transform)directCompProp.objectReferenceValue
                );

            if (bone == null)
            {
                return;
            }

            var localOffset   = localOffsetProp.vector3Value;
            var localRotation = Quaternion.Euler(localRotProp.vector3Value);

            EditorHelper.RegisterUndo("Transformed Effect",
                                      fieldProperty.serializedObject.targetObject,
                                      undoHelper
                                      );

            Vector3 worldPos = bone.TransformPoint(localOffset);

            bool clicked = false;

            HandlesHelper.Scope(() =>
            {
                if (IsEditingProperty(fieldProperty))
                {
                    Handles.color = Color.green;
                }

                if (editingProperty == null)
                {
                    clicked = Handles.Button(
                        worldPos,
                        Quaternion.identity,
                        size: 0.05f,
                        pickSize: 0.05f,
                        capFunction: Handles.SphereHandleCap
                        );
                }
                else
                {
                    Handles.SphereHandleCap(
                        controlID: 0,
                        position: worldPos,
                        rotation: Quaternion.identity,
                        size: 0.05f,
                        eventType: EventType.Repaint
                        );
                }
            });

            if (clicked)
            {
                undoHelper.worldSpaceRot = Quaternion.identity;
                editingProperty          = fieldProperty;
                if (Tools.current != Tool.Move && Tools.current != Tool.Rotate)
                {
                    Tools.current = Tool.Move;
                }
            }

            GUIStyle style = EditorStyles.toolbarTextField;

            style.CalcSize(label);
            Handles.Label(worldPos, label, style);

            if (!IsEditingProperty(fieldProperty))
            {
                return;
            }

            fieldProperty.serializedObject.Update();

            HandlesHelper.Scope(() =>
            {
                if (Tools.current == Tool.Rotate)
                {
                    if (Tools.pivotRotation == PivotRotation.Local)
                    {
                        Handles.matrix = bone.localToWorldMatrix;
                    }
                    else
                    {
                        Handles.matrix = Matrix4x4.TRS(
                            bone.TransformPoint(localOffset),
                            Quaternion.identity,
                            bone.localScale
                            );
                    }

                    DrawArrowCap(localOffset, localRotation, bone);

                    Quaternion newLocalRot = localRotation;

                    if (Tools.pivotRotation == PivotRotation.Global)
                    {
                        var newWorldSpaceRot = Handles.RotationHandle(undoHelper.worldSpaceRot, Vector3.zero);

                        // Difference between the the new and the old world space rotation
                        var diff = Quaternion.Inverse(undoHelper.worldSpaceRot) * newWorldSpaceRot;

                        if (diff != Quaternion.identity)
                        {
                            // Convert local rot to world
                            Quaternion rotInWorld = bone.rotation * localRotation;
                            // Apply world difference
                            rotInWorld = diff * rotInWorld;
                            // Convert back to local space
                            newLocalRot = Quaternion.Inverse(bone.rotation) * rotInWorld;

                            undoHelper.worldSpaceRot = newWorldSpaceRot;
                        }
                    }
                    else
                    {
                        newLocalRot = Handles.RotationHandle(localRotation, localOffset);
                    }

                    if (localRotation != newLocalRot)
                    {
                        localRotProp.vector3Value = newLocalRot.eulerAngles;
                    }
                }
                else if (Tools.current == Tool.Move)
                {
                    Handles.matrix = bone.localToWorldMatrix;

                    var rot = localRotation;
                    if (Tools.pivotRotation == PivotRotation.Global)
                    {
                        rot = Quaternion.LookRotation(
                            bone.InverseTransformDirection(Vector3.forward),
                            bone.InverseTransformDirection(Vector3.up)
                            );
                    }
                    var pos = Handles.PositionHandle(localOffset, rot);
                    if (localOffset != pos)
                    {
                        localOffsetProp.vector3Value = pos;
                    }
                }
            });

            fieldProperty.serializedObject.ApplyModifiedProperties();

            DrawEditingWarning();

            Event e = Event.current;

            if (e.type == EventType.keyUp)
            {
                if (e.keyCode == KeyCode.Escape)
                {
                    StopEditing();
                }
            }
        }