I'd like to create a simple object that I can access like this:
myobject.floatValue1 = 1.0;
myobject.floatValue2 = 2.0;
It shouldn't have anymore than the two properties. Is it possible to create an enum or typedef with such a simple structure. Or must I create a class?
Sure, just make a C structure:
struct myStruct
{
float floatValue1;
float floatValue2;
};
typedef struct myStruct myType;
Then use it like this:
myType myVariable = {0.0, 0.0}; // optional initialization
myVariable.floatValue1 = 1.0;
myVariable.floatValue2 = 2.0;
Take a look at using a struct, e.g.:
struct MyObjectType {
float floatValue1;
float floatValue2;
};
...
MyObjectType myobject;
myobject.floatValue1 = 1.0;
myobject.floatValue2 = 2.0;
Related
I have this Class called ToggledFloat. It wraps a float but also adds a bool telling if it is enabled or not.
[System.Serializable]
public class ToggledFloat
{
public float value;
public bool enabled = false;
}
[System.Serializable]
public class ClassWIthNestedProp
{
public ToggledFloat aTogFloat;
}
public class Test : MonoBehaviour
{
public ClassWIthNestedProp eCA;
public ToggledFloat tF;
}
I can easily make a Custom Property Drawer for this, and it looks right, when the editor draws this property at indentation level "0". However when I look at ToggledFloat properties nested inside another property they look wrong.
My propertyDrawer looks like this:
[CustomPropertyDrawer(typeof(ToggledFloat))]
public class ToggledPropertyEditor : PropertyDrawer
{
public override float GetPropertyHeight (SerializedProperty property, GUIContent label)
{
var propVal = property.FindPropertyRelative("value");
float contentUnfoldedHeight = EditorGUI.GetPropertyHeight (propVal, label);
return contentUnfoldedHeight;
}
// Draw the property inside the given rect
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
int iL = EditorGUI.indentLevel;
//EditorGUI.indentLevel = 0; //- Set this to "0" to make thing work but non-indented
SerializedProperty valueProp = property.FindPropertyRelative("value");
SerializedProperty enabledProp = property.FindPropertyRelative("enabled");
//Label left of checkbox
float labelWidth = GUI.skin.label.CalcSize(label).x;
Rect labelRect = new Rect(0/*position.x*/, position.y, labelWidth, 16);
EditorGUI.LabelField(labelRect, label, GUIContent.none);
EditorGUI.DrawRect(labelRect, new Color(0,0,1,.1f));
//Checkbox
Rect enableRect = new Rect();
enableRect.xMin = labelRect.xMax;
enableRect.yMin = labelRect.yMin;
enableRect.width = 16;
enableRect.height = 16;
EditorGUI.PropertyField(enableRect, enabledProp, GUIContent.none);
EditorGUI.DrawRect(enableRect, new Color(0,1,0,.1f));
//Value
Rect valueRect = new Rect();
valueRect.xMin = enableRect.xMax;
valueRect.yMin = enableRect.yMin;
valueRect.xMax = position.xMax;
valueRect.yMax = position.yMax;
EditorGUI.DrawRect(valueRect, new Color(1,0,0,.1f));
bool enabled = GUI.enabled;
GUI.enabled = enabledProp.boolValue;
EditorGUI.PropertyField(valueRect, valueProp, new GUIContent(""), true);
GUI.enabled = enabled;
EditorGUI.indentLevel = iL;
}
}
When the inspector draws an instance of class Test, it looks like this:
The Colored rects are only there for allowing me to debug where those rects actually are. The weird thing is that the text-labels are offset from the coloured rects, even though they get the same rect as argument. This is of course only a problem if I want coloured rects in my inspector - but the real problem is that it seems that this offset problem causes nested checkboxes to not work. I cannot click checkboxes on a nested property.
If I then explicitly set EditorGUI.IndenLevel = 0, then the coloured rects and the labels coincide and the toggle buttons work properly - but I then loose the automatic indentation, that I would really like to use.
Can someone tell me what I am overlooking
The DrawRect method doesn't consider the indent level. You have to adjust rect yourself to draw indented rectangle. Fortunately, There is a function to get the intented rect.
From UnityCsReference EditorGUI
static void DrawIndentedRect(Rect rect, Color color)
{
EditorGUI.DrawRect(EditorGUI.IndentedRect(rect), color);
}
Captured Inspector IndentedRect
However it doesn't work properly.
From the implementation of IndentedRect, it reduces the width of rect.
static void DrawIndentedRect(Rect rect, Color color)
{
// Indent per level is 15
rect.x += EditorGUI.indentLevel * 15;
EditorGUI.DrawRect(rect, color);
}
or
static void DrawIndentedRect(Rect rect, Color color)
{
var indentedRect = EditorGUI.IndentedRect(rect);
indentedRect.width = rect.width;
EditorGUI.DrawRect(indentedRect, color);
}
Captured Inspector DrawIndentedRect
I want to enable two SKSpriteNodes to pass through one another. From my understanding the following code should do the trick:
beam?.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: beam!.size.width - 40, height: beam!.size.height/4));
beam?.physicsBody?.categoryBitMask = ColliderType.BEAM;
beam?.physicsBody?.contactTestBitMask = ColliderType.ENEMY;
beam?.physicsBody?.collisionBitMask = 0;
beam?.physicsBody?.affectedByGravity = false;
beam?.physicsBody?.allowsRotation = false;
item?.physicsBody?.categoryBitMask = ColliderType.CRATES;
item?.physicsBody?.contactTestBitMask = ColliderType.PLAYER;
item?.physicsBody?.collisionBitMask = ColliderType.GROUND;
item?.physicsBody?.affectedByGravity = true;
item?.physicsBody?.allowsRotation = false;
As neither should be picked up by the by the other's collider type. I have tried many different methods already including setting their collision bit masks to 0.
When the two nodes collide the item moves below the beam. Then when the beam disappears the item moves back into its original place. The item must remain dynamic to other nodes, but advice on this topic is greatly appreciated. Thanks.
struct ColliderType {
static let PLAYER: UInt32 = 0;
static let GROUND: UInt32 = 1;
static let CRATES: UInt32 = 2;
static let BULLET: UInt32 = 3;
static let ENEMY: UInt32 = 4;
static let EXPLOSION: UInt32 = 5;
static let UFO: UInt32 = 6;
static let UFOBOMB: UInt32 = 7;
static let SHIELD: UInt32 = 8;
static let BEAM: UInt32 = 9;
}
After CGPointMake let me down I found out that we can initalise a static const CGPoint like this instead:
static const CGPoint p = { 0.f, 0.f };
It works but what is the curly bracket notation actually doing?
CGPoint is a struct:
struct CGPoint {
CGFloat x;
CGFloat y;
};
It's a valid method to initialize a struct in C. See Struct initialization of the C/C++ programming language?.
I am designing a Padding struct as follows:
/* Padding. */
struct CGPadding {
CGFloat left;
CGFloat top;
CGFloat right;
CGFloat bottom;
};
typedef struct CGPadding CGPadding;
CG_INLINE CGPadding CGPaddingMake(CGFloat left, CGFloat top, CGFloat right, CGFloat bottom) { CGPadding p; p.left = left; p.top = top; p.right = right; p.bottom = bottom; return p; }
This all works perfectly well, the problem is how can I create a const CGPadding CGPaddingZero? If I do like this:
const CGPadding CGPaddingZero = (CGPadding){0.0, 0.0, 0.0, 0.0};
It doesnt work. So what am I doing wrong?
I find this very interesting because I do it all the time on the iPhone and it works fine. May it have something to do with the typedef afterward to the same name? What if you get rid of the typedef and define your struct like this?
typedef struct CGPadding {
CGFloat left;
CGFloat top;
CGFloat right;
CGFloat bottom;
} CGPadding;
Does it work then? Also, since all 0's is zero for a float as well and you're zero-ing out the whole thing, you could just say
const CGPadding CGPaddingZero = {0};
I do this stuff all the time on the iPhone so I'd be quite surprised if it doesn't work for you.
i have a struct HLRange with two CGFloat's
struct HOLRange
{
CGFloat min;
CGFloat max;
};
typedef struct HOLRange HOLRange;
but how do i make a function like HLRangeMake(1,2); .. like CGRectMake?
--EDIT--
my header file
#import <Foundation/Foundation.h>
struct HOLRange
{
CGFloat min;
CGFloat max;
};
typedef struct HOLRange HOLRange;
HOLRange HOLRangeMake(CGFloat min, CGFloat max) {
HOLRange range;
range.min = min;
range.max = max;
return range;
}
#interface Structs : NSObject {
}
#end
error message: ld: duplicate symbol _HOLRangeMake in /Users/Documents/projects/iphone/test/catalog/base1/build/base1.build/Debug-iphoneos/base1.build/Objects-normal/armv6/base1AppDelegate.o and /Users/Documents/projects/iphone/test/catalog/base1/build/base1.build/Debug-iphoneos/base1.build/Objects-normal/armv6/main.o
HOLRange HLRangeMake(CGFloat min, CGFloat max) {
HOLRange range;
range.min = min;
range.max = max;
return range;
}
You can see CGRectMake source in CGGeometry.h so you can do the same:
CG_INLINE CGRect
CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
{
CGRect rect;
rect.origin.x = x; rect.origin.y = y;
rect.size.width = width; rect.size.height = height;
return rect;
}
Edit: You must either define your function as inline or move its implementation to .m file. You're getting linker errors as you function becomes defined in every compile unit that imports HoleRange.h (?) header.
Old post. However, I'd like to share my method of resolving this problem for future viewers.
typdef struct _HOLRange {
CGFloat min;
CGFloat max;
} HOLRange;
static inline HOLRange(CGFloat min, CGFloat max) {
return (HOLRange) {min, max};
}
You can define your stuct and Make function like this. Short and quick.
I like the format of this better. It makes more sense visually and seems more "correct."
typedef struct {
CGFloat min;
CGFloat max;
} HOLRange;
static inline HOLRange HOLRangeMake(CGFloat min, CGFloat max) {
HOLRange range;
range.min = min;
range.max = max;
return range;
}