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); }
// 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); }
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(); } } }