Select a line on window br clicking on it - c#

I want to make the If condition in the isAT to get the position of the line on the screen.Which mean when the mouse on the line and I click on the line I am able to select it.What I need is to able to select the Line when I click on it by the mouse.Thanks for help in advance.
public class MyLine : Shape
{
private float _endY, _endX;
public MyLine() : this(Color.Orange, 0 , 0, 0, 0)
{
}
public MyLine(Color clr, float starX, float starY, float endX, float endY ) : base(clr)
{
X = starX;
Y = starY;
this.endX = endX;
this.endY = endY;
}
public float endX
{
get { return _endX; }
set { _endX = value; }
}
public float endY
{
get { return _endY; }
set { _endY = value; }
}
public override bool IsAT(Point2D pt)
{
if (pt.X > X && pt.Y < Y && pt.X > endX && pt.Y > endY)
return true;
else
return false;
}
}

Related

Snake. Roll back the coordinates of the snake to impact

I can’t realize the possibility of continuing the game after a collision. The snake should stop and start moving after clicking on one of the arrow buttons.
In a collision, a window appears about the loss, I need to continue the game.
I press the button and the following happens:
I don’t understand how I can save the coordinates of the snake just before the collision.
In the moveTimer_Tick method, all elements move, i.e. new coordinates have already appeared at the head and body, then there is a check for collisions with the wall and body. If they are found, a window appears about the loss.
New snake coordinates are not displayed. But after clicking the "Continue" button, an update occurs and the snake climbs to the border.
The question is: how can I save the coordinates of the snake, before the collision, and after continuing to start with them.
namespace Snake{
public partial class MainWindow : Window
{
//The field on which the snake lives
Entity field;
// snake head
Head head;
// whole snake
List<PositionedEntity> snake;
// apple
Apple apple;
//number of points
int score;
// Is movement paused
bool paused;
//time
DispatcherTimer moveTimer;
//constructor form
public MainWindow()
{
InitializeComponent();
snake = new List<PositionedEntity>();
//create field 600x600pixels
field = new Entity(600, 600, "pack://application:,,,/Resources/snake.png");
//create a timer that runs every 300 ms
moveTimer = new DispatcherTimer();
moveTimer.Interval = new TimeSpan(0, 0, 0, 0, 300);
moveTimer.Tick += new EventHandler(moveTimer_Tick);
}
//redraw screen method
private void UpdateField()
{
//update the position of the elements of the snake
foreach (var p in snake)
{
Canvas.SetTop(p.image, p.y);
Canvas.SetLeft(p.image, p.x);
}
//update the position of apple
Canvas.SetTop(apple.image, apple.y);
Canvas.SetLeft(apple.image, apple.x);
//points update
lblScore.Content = String.Format("{0}000", score);
}
//timer tick handler. All movement takes place here.
void moveTimer_Tick(object sender, EventArgs e)
{
// Do not update if movement is paused
if(paused) {
return;
}
//in the reverse order we move all the elements of the snake
foreach (var p in Enumerable.Reverse(snake))
{
p.move();
}
//we check that the head of the snake did not crash into the body
foreach (var p in snake.Where(x => x != head))
{
if (p.x == head.x && p.y == head.y)
{
//we lose
moveTimer.Stop();
GameOver.Visibility = Visibility.Visible;
btnRestart.Visibility = Visibility.Visible;
tbScore.Text = String.Format("SCORE: {0}000", score);
return;
}
}
//check that the head of the snake did not go out of the field
if (head.x < 40 || head.x >= 540 || head.y < 40 || head.y >= 540)
{
//we lose
moveTimer.Stop();
GameOver.Visibility = Visibility.Visible;
btnRestart.Visibility = Visibility.Visible;
tbScore.Text = String.Format("SCORE: {0}000", score);
return;
}
//check that the head of the snake crashed into an apple
if (head.x == apple.x && head.y == apple.y)
{
//increase the score
score++;
//move the apple to a new place
apple.move();
var part = new BodyPart(snake.Last());
canvas1.Children.Add(part.image);
snake.Add(part);
}
UpdateField();
}
private void Window_KeyDown(object sender, KeyEventArgs e)
{
// Unpause movement when any key is pressed
if(paused) {
paused = false;
}
switch (e.Key)
{
case Key.Up:
head.direction = Head.Direction.UP;
break;
case Key.Down:
head.direction = Head.Direction.DOWN;
break;
case Key.Left:
head.direction = Head.Direction.LEFT;
break;
case Key.Right:
head.direction = Head.Direction.RIGHT;
break;
}
}
// "Start"
private void button1_Click(object sender, RoutedEventArgs e)
{
btnStart.Visibility = Visibility.Hidden;
btnRestart.Visibility = Visibility.Hidden;
tBNotEnoughPoints.Visibility = Visibility.Hidden;
score = 0;
snake.Clear();
canvas1.Children.Clear();
// "Game Over"
GameOver.Visibility = Visibility.Hidden;
canvas1.Children.Add(field.image);
apple = new Apple(snake);
canvas1.Children.Add(apple.image);
head = new Head();
snake.Add(head);
canvas1.Children.Add(head.image);
moveTimer.Start();
UpdateField();
}
private void btnContinue_Click(object sender, RoutedEventArgs e)
{
if (score >= 2)
{
GameOver.Visibility = Visibility.Hidden;
btnRestart.Visibility = Visibility.Hidden;
score -= 2;
// Pause movement
paused = true;
moveTimer.Start();
UpdateField();
}
else
{
tBNotEnoughPoints.Visibility = Visibility.Visible;
}
}
public class Entity
{
protected int m_width;
protected int m_height;
Image m_image;
public Entity(int w, int h, string image)
{
m_width = w;
m_height = h;
m_image = new Image();
m_image.Source = (new ImageSourceConverter()).ConvertFromString(image) as ImageSource;
m_image.Width = w;
m_image.Height = h;
}
public Image image
{
get
{
return m_image;
}
}
}
public class PositionedEntity : Entity
{
protected int m_x;
protected int m_y;
public PositionedEntity(int x, int y, int w, int h, string image)
: base(w, h, image)
{
m_x = x;
m_y = y;
}
public virtual void move() { }
public int x
{
get
{
return m_x;
}
set
{
m_x = value;
}
}
public int y
{
get
{
return m_y;
}
set
{
m_y = value;
}
}
}
public class Apple : PositionedEntity
{
List<PositionedEntity> m_snake;
public Apple(List<PositionedEntity> s)
: base(0, 0, 40, 40, "pack://application:,,,/Resources/fruit.png")
{
m_snake = s;
move();
}
public override void move()
{
Random rand = new Random();
do
{
x = rand.Next(13) * 40 + 40 ;
y = rand.Next(13) * 40 + 40 ;
bool overlap = false;
foreach (var p in m_snake)
{
if (p.x == x && p.y == y)
{
overlap = true;
break;
}
}
if (!overlap)
break;
} while (true);
}
}
public class Head : PositionedEntity
{
public enum Direction
{
RIGHT, DOWN, LEFT, UP, NONE
};
Direction m_direction;
public Direction direction {
set
{
m_direction = value;
RotateTransform rotateTransform = new RotateTransform(90 * (int)value);
image.RenderTransform = rotateTransform;
}
}
public Head()
: base(280, 280, 40, 40, "pack://application:,,,/Resources/head.png")
{
image.RenderTransformOrigin = new Point(0.5, 0.5);
m_direction = Direction.NONE;
}
public override void move()
{
switch (m_direction)
{
case Direction.DOWN:
y += 40;
break;
case Direction.UP:
y -= 40;
break;
case Direction.LEFT:
x -= 40;
break;
case Direction.RIGHT:
x += 40;
break;
}
}
}
public class BodyPart : PositionedEntity
{
PositionedEntity m_next;
public BodyPart(PositionedEntity next)
: base(next.x, next.y, 40, 40, "pack://application:,,,/Resources/body.png")
{
m_next = next;
}
public override void move()
{
x = m_next.x;
y = m_next.y;
}
}
}
}
There is something to say about the design of your code, but if you don't care and you want a fast (and ugly) solution you can modify your PositionEntity in order to store old coordinates:
public class PositionedEntity : Entity
{
protected int m_x;
protected int m_y;
protected int m_oldX;
protected int m_oldY;
public PositionedEntity(int x, int y, int w, int h, string image)
: base(w, h, image)
{
m_x = x;
m_y = y;
m_oldX = x;
m_oldY = y;
}
public virtual void move() { }
public virtual void RestorePrevious()
{
m_x = m_oldX;
m_y = m_oldY;
}
public int x
{
get
{
return m_x;
}
set
{
m_oldX = m_x;
m_x = value;
}
}
public int y
{
get
{
return m_y;
}
set
{
m_oldY = m_y;
m_y = value;
}
}
}
When you have a collision you should call the RestorePrevious() on the head and on all the rest of the snake

Check if text fits inside textview

I have a problem. I need to adjust the font size of a text, so it fits inside the TextView. But how can I get the size of the TextView and the size of the Text to compare with each other?
If android api is above 8 , you can do that easily in axml:
<TextView
android:id="#+id/text"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:autoSizeMaxTextSize="80dp" //code one
android:autoSizeMinTextSize="2dp" // code two
android:autoSizeTextType="uniform" // code three
android:background="#android:color/holo_red_light"
android:gravity="center"
android:maxLines="1" // be sure not return line
android:text="Here is auto size text"
android:textColor="#android:color/white"
android:textSize="80dp" />
else you can refer to the follow code to custom a TextView:
using Android.Content;
using Android.Runtime;
using Android.Widget;
using Android.Util;
using Android.Text;
using Java.Lang;
namespace My.Text
{
public class AutoResizeTextView : TextView
{
public const float MIN_TEXT_SIZE = 20;
public interface OnTextResizeListener
{
void OnTextResize(TextView textView, float oldSize, float newSize);
}
private const string mEllipsis = "...";
private OnTextResizeListener mTextResizeListener;
private bool mNeedsResize = false;
private float mTextSize;
private float mMaxTextSize = 0;
private float mMinTextSize = MIN_TEXT_SIZE;
private float mSpacingMult = 1.0f;
private float mSpacingAdd = 0.0f;
public bool AddEllipsis { get; set; } = true;
public AutoResizeTextView(Context context) : this(context, null) { }
public AutoResizeTextView(Context context, IAttributeSet attrs) : this(context, attrs, 0) { }
public AutoResizeTextView(Context context, IAttributeSet attrs, int defStyle): base(context, attrs, defStyle)
{
mTextSize = TextSize;
}
protected override void OnTextChanged(ICharSequence text, int start, int lengthBefore, int lengthAfter)
{
base.OnTextChanged(text, start, lengthBefore, lengthAfter);
mNeedsResize = true;
ResetTextSize();
}
protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
{
base.OnSizeChanged(w, h, oldw, oldh);
if (w != oldw || h != oldh)
mNeedsResize = true;
}
public void SetOnResizeListener(OnTextResizeListener listener)
{
mTextResizeListener = listener;
}
public override void SetTextSize([GeneratedEnum] ComplexUnitType unit, float size)
{
base.SetTextSize(unit, size);
mTextSize = TextSize;
}
public override void SetLineSpacing(float add, float mult)
{
base.SetLineSpacing(add, mult);
mSpacingMult = mult;
mSpacingAdd = add;
}
public void SetMaxTextSize(float maxTextSize)
{
mMaxTextSize = maxTextSize;
RequestLayout();
Invalidate();
}
public float GetMaxTextSize()
{
return mMaxTextSize;
}
public void SetMinTextSize(float minTextSize)
{
mMinTextSize = minTextSize;
RequestLayout();
Invalidate();
}
public float GetMinTextSize()
{
return mMinTextSize;
}
public void ResetTextSize()
{
if(mTextSize > 0)
{
base.SetTextSize(ComplexUnitType.Px, mTextSize);
mMaxTextSize = mTextSize;
}
}
protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
{
if(changed || mNeedsResize)
{
int widthLimit = (right - left) - CompoundPaddingLeft - CompoundPaddingRight;
int heightLimit = (bottom - top) - CompoundPaddingBottom - CompoundPaddingTop;
ResizeText(widthLimit, heightLimit);
}
base.OnLayout(changed, left, top, right, bottom);
base.OnLayout(changed, left, top, right, bottom);
}
public void ResizeText()
{
int heightLimit = Height - PaddingBottom - PaddingTop;
int widthLimit = Width - PaddingLeft - PaddingRight;
ResizeText(widthLimit, heightLimit);
}
public void ResizeText(int width, int height)
{
var text = TextFormatted;
if (text == null || text.Length() == 0 || height <= 0 || width <= 0 || mTextSize == 0)
return;
if (TransformationMethod != null)
text = TransformationMethod.GetTransformationFormatted(TextFormatted, this);
TextPaint textPaint = Paint;
float oldTextSize = textPaint.TextSize;
float targetTextSize = mMaxTextSize > 0 ? System.Math.Min(mTextSize, mMaxTextSize) : mTextSize;
int textHeight = GetTextHeight(text, textPaint, width, targetTextSize);
while(textHeight > height && targetTextSize > mMinTextSize)
{
targetTextSize = System.Math.Max(targetTextSize - 2, mMinTextSize);
textHeight = GetTextHeight(text, textPaint, width, targetTextSize);
}
if(AddEllipsis && targetTextSize == mMinTextSize && textHeight > height)
{
TextPaint paint = new TextPaint(textPaint);
StaticLayout layout = new StaticLayout(text, paint, width, Layout.Alignment.AlignNormal, mSpacingMult, mSpacingAdd, false);
if(layout.LineCount > 0)
{
int lastLine = layout.GetLineForVertical(height) - 1;
if (lastLine < 0)
SetText("", BufferType.Normal);
else
{
int start = layout.GetLineStart(lastLine);
int end = layout.GetLineEnd(lastLine);
float lineWidth = layout.GetLineWidth(lastLine);
float ellipseWidth = textPaint.MeasureText(mEllipsis);
while (width < lineWidth + ellipseWidth)
lineWidth = textPaint.MeasureText(text.SubSequence(start, --end + 1).ToString());
SetText(text.SubSequence(0, end) + mEllipsis, BufferType.Normal);
}
}
}
SetTextSize(ComplexUnitType.Px, targetTextSize);
SetLineSpacing(mSpacingAdd, mSpacingMult);
mTextResizeListener?.OnTextResize(this, oldTextSize, targetTextSize);
mNeedsResize = false;
}
private int GetTextHeight(ICharSequence source, TextPaint paint, int width, float textSize)
{
TextPaint paintCopy = new TextPaint(paint);
paintCopy.TextSize = textSize;
StaticLayout layout = new StaticLayout(source, paintCopy, width, Layout.Alignment.AlignNormal, mSpacingMult, mSpacingAdd, false);
return layout.Height;
}
}
}

Unity: Can't find UI Layout Element Max Size

In Unity UI, LayoutElement has a min, prefered and flxible size, but it do not have a max size property.
For example if I have a text1 and
layoutElement.flxibleWith = 1
layoutElement.minHeight = 19
text1 with one line txt:
But when I load text in text1 it continues spreading it height with no limits:
I have made a script:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
[ExecuteInEditMode]
[RequireComponent(typeof(LayoutElement))]
public class LayoutElementMaxSize : MonoBehaviour
{
private LayoutElement layoutElement;
private ContentSizeFitter contentSizeFitter;
private RectTransform rectransform;
public bool controllWidth;
public bool controllHeight;
public float maxHight;
public float maxWidth;
void Start()
{
layoutElement = GetComponent<LayoutElement>();
rectransform = GetComponent<RectTransform>();
}
public void Update()
{
if(rectransform.hasChanged)
{
rectransform.hasChanged = false;
if (controllHeight)
{
layoutElement.preferredHeight = -1;
layoutElement.CalculateLayoutInputHorizontal();
layoutElement.CalculateLayoutInputVertical();
if (rectransform.rect.height >= maxHight)
{
layoutElement.preferredHeight = maxHight;
}
}
if (controllWidth)
{
if (rectransform.rect.height >= maxWidth)
{
layoutElement.preferredWidth = maxWidth;
}
else
{
layoutElement.preferredWidth = -1;
}
}
}
}}
but it is not full filing my requirement plz take a look on it ..
I know this is an old question, but I was looking for something like this and I end up rewriting your class and it now works fine for me. Instead of just making another MonoBehaviour I override the LayoutElement, I also added an custom inspector to make it easy to edit it. Hope my solution could help you or anyone else that would like something like this.
using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
[RequireComponent(typeof(RectTransform))]
[System.Serializable]
public class LayoutMaxSize : LayoutElement
{
public float maxHeight = -1;
public float maxWidth = -1;
public override void CalculateLayoutInputHorizontal()
{
base.CalculateLayoutInputHorizontal();
UpdateMaxSizes();
}
public override void CalculateLayoutInputVertical()
{
base.CalculateLayoutInputVertical();
UpdateMaxSizes();
}
protected override void OnRectTransformDimensionsChange()
{
base.OnRectTransformDimensionsChange();
UpdateMaxSizes();
}
protected override void OnValidate()
{
base.OnValidate();
UpdateMaxSizes();
}
private void UpdateMaxSizes()
{
if (maxHeight != -1)
{
if (preferredHeight == -1 && maxHeight < GetComponent<RectTransform>().sizeDelta.y)
{
preferredHeight = maxHeight;
}
else if (preferredHeight != -1 && transform.childCount > 0)
{
bool first = true;
float biggestY = 0;
float lowestY = 0;
for (int i = 0; i < transform.childCount; i++)
{
var childrenTransform = transform.GetChild(i).GetComponent<RectTransform>();
if (childrenTransform == null) continue;
var childPos = childrenTransform.localPosition;
var childSize = childrenTransform.sizeDelta;
var childPivot = childrenTransform.pivot;
if(first)
{
biggestY = childPos.y + (childSize.y * (1f - childPivot.y));
lowestY = childPos.y - (childSize.y * childPivot.y);
}
else
{
biggestY = Mathf.Max(biggestY, childPos.y + (childSize.y * (1f - childPivot.y)));
lowestY = Mathf.Min(lowestY, childPos.y - (childSize.y * childPivot.y));
}
first = false;
}
if (first) return;
var childrenYSize = Mathf.Abs(biggestY - lowestY);
if(preferredHeight > childrenYSize)
{
preferredHeight = -1;
}
}
}
if (maxWidth != -1)
{
if (preferredWidth == -1 && maxWidth < GetComponent<RectTransform>().sizeDelta.x)
{
preferredWidth = maxWidth;
}
else if (preferredWidth != -1 && transform.childCount > 0)
{
bool first = true;
float biggestX = 0;
float lowestX = 0;
for (int i = 0; i < transform.childCount; i++)
{
var childrenTransform = transform.GetChild(i).GetComponent<RectTransform>();
if (childrenTransform == null) continue;
var childPos = childrenTransform.localPosition;
var childSize = childrenTransform.sizeDelta;
var childPivot = childrenTransform.pivot;
if (first)
{
biggestX = childPos.x + (childSize.x * (1f - childPivot.x));
lowestX = childPos.x - (childSize.x * childPivot.x);
}
else
{
biggestX = Mathf.Max(biggestX, childPos.x + (childSize.x * (1f - childPivot.x)));
lowestX = Mathf.Min(lowestX, childPos.x - (childSize.x * childPivot.x));
}
first = false;
}
if (first) return;
var childrenXSize = Mathf.Abs(biggestX - lowestX);
if (preferredWidth > childrenXSize)
{
preferredWidth = -1;
}
}
}
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(LayoutMaxSize))]
public class LayoutMaxSizeEditor : Editor
{
public override void OnInspectorGUI()
{
LayoutMaxSize layoutMax = target as LayoutMaxSize;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Ignore Layout");
layoutMax.ignoreLayout = EditorGUILayout.Toggle(layoutMax.ignoreLayout);
EditorGUILayout.EndHorizontal();
if (!layoutMax.ignoreLayout)
{
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Min Width");
var allowMinWidth = EditorGUILayout.Toggle(layoutMax.minWidth != -1);
if (allowMinWidth)
{
if (layoutMax.minWidth == -1) layoutMax.minWidth = 0;
layoutMax.minWidth = EditorGUILayout.FloatField(layoutMax.minWidth);
}
else if (layoutMax.minWidth != -1)
{
layoutMax.minWidth = -1;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Min Height");
var allowMinHeight = EditorGUILayout.Toggle(layoutMax.minHeight != -1);
if (allowMinHeight)
{
if (layoutMax.minHeight == -1) layoutMax.minHeight = 0;
layoutMax.minHeight = EditorGUILayout.FloatField(layoutMax.minHeight);
}
else if (layoutMax.minHeight != -1)
{
layoutMax.minHeight = -1;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Max Width");
var allowMaxWidth = EditorGUILayout.Toggle(layoutMax.maxWidth != -1);
if (allowMaxWidth)
{
if (layoutMax.maxWidth == -1) layoutMax.maxWidth = Mathf.Max(0, layoutMax.minWidth);
layoutMax.maxWidth = Mathf.Max(EditorGUILayout.FloatField(layoutMax.maxWidth), layoutMax.minWidth);
}
else if(layoutMax.maxWidth != -1)
{
layoutMax.maxWidth = -1;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Max Height");
var allowMaxHeight = EditorGUILayout.Toggle(layoutMax.maxHeight != -1);
if (allowMaxHeight)
{
if (layoutMax.maxHeight == -1) layoutMax.maxHeight = Mathf.Max(0, layoutMax.minHeight);
layoutMax.maxHeight = Mathf.Max(EditorGUILayout.FloatField(layoutMax.maxHeight), layoutMax.minHeight);
}
else if (layoutMax.maxHeight != -1)
{
layoutMax.maxHeight = -1;
}
EditorGUILayout.EndHorizontal();
}
}
}
#endif
I wrote a new script which includes maxheight and maxwidth field for layout element it is not fuly tested but if you want you can use it.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.UI;
#endif
[RequireComponent(typeof(RectTransform))]
[System.Serializable]
public class LayoutElementWithMaxValues : LayoutElement {
public float maxHeight;
public float maxWidth;
public bool useMaxWidth;
public bool useMaxHeight;
bool ignoreOnGettingPreferedSize;
public override int layoutPriority {
get => ignoreOnGettingPreferedSize ? -1 : base.layoutPriority;
set => base.layoutPriority = value; }
public override float preferredHeight {
get {
if (useMaxHeight) {
var defaultIgnoreValue = ignoreOnGettingPreferedSize;
ignoreOnGettingPreferedSize = true;
var baseValue = LayoutUtility.GetPreferredHeight(transform as RectTransform);
ignoreOnGettingPreferedSize = defaultIgnoreValue;
return baseValue > maxHeight ? maxHeight : baseValue;
}
else
return base.preferredHeight;
}
set => base.preferredHeight = value;
}
public override float preferredWidth {
get {
if (useMaxWidth) {
var defaultIgnoreValue = ignoreOnGettingPreferedSize;
ignoreOnGettingPreferedSize = true;
var baseValue = LayoutUtility.GetPreferredWidth(transform as RectTransform);
ignoreOnGettingPreferedSize = defaultIgnoreValue;
return baseValue > maxWidth ? maxWidth : baseValue;
}
else
return base.preferredWidth;
}
set => base.preferredWidth = value;
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(LayoutElementWithMaxValues), true)]
[CanEditMultipleObjects]
public class LayoutMaxSizeEditor : LayoutElementEditor {
LayoutElementWithMaxValues layoutMax;
SerializedProperty maxHeightProperty;
SerializedProperty maxWidthProperty;
SerializedProperty useMaxHeightProperty;
SerializedProperty useMaxWidthProperty;
RectTransform myRectTransform;
protected override void OnEnable() {
base.OnEnable();
layoutMax = target as LayoutElementWithMaxValues;
myRectTransform = layoutMax.transform as RectTransform;
maxHeightProperty = serializedObject.FindProperty(nameof(layoutMax.maxHeight));
maxWidthProperty = serializedObject.FindProperty(nameof(layoutMax.maxWidth));
useMaxHeightProperty = serializedObject.FindProperty(nameof(layoutMax.useMaxHeight));
useMaxWidthProperty = serializedObject.FindProperty(nameof(layoutMax.useMaxWidth));
}
public override void OnInspectorGUI() {
Draw(maxWidthProperty, useMaxWidthProperty);
Draw(maxHeightProperty, useMaxHeightProperty);
serializedObject.ApplyModifiedProperties();
EditorGUILayout.Space();
base.OnInspectorGUI();
}
void Draw(SerializedProperty property, SerializedProperty useProperty) {
Rect position = EditorGUILayout.GetControlRect();
GUIContent label = EditorGUI.BeginProperty(position, null, property);
Rect fieldPosition = EditorGUI.PrefixLabel(position, label);
Rect toggleRect = fieldPosition;
toggleRect.width = 16;
Rect floatFieldRect = fieldPosition;
floatFieldRect.xMin += 16;
var use = EditorGUI.Toggle(toggleRect, useProperty.boolValue);
useProperty.boolValue = use;
if (use) {
EditorGUIUtility.labelWidth = 4;
property.floatValue = EditorGUI.FloatField(floatFieldRect, new GUIContent(" "), property.floatValue);
EditorGUIUtility.labelWidth = 0;
}
EditorGUI.EndProperty();
}
}
#endif

Unity struct is serialized, but not editable from component menu

I have a struct in Unity which is declared like this:
[System.Serializable]
public struct IntVector2 {
public int x, z;
public IntVector2 (int x, int z) {
this.x = x;
this.z = z;
}
public static IntVector2 operator + (IntVector2 a, IntVector2 b) {
a.x += b.x;
a.z += b.z;
return a;
}
}
Then, I added an IntVector2 as a field on a script. When I looked at the script component on the sidebar, the struct and its variables were nowhere to be found. What am I doing wrong?
EDIT: Here is the code of my script:
using UnityEngine;
using System.Collections;
public class Maze : MonoBehaviour {
public IntVector2 size;
public MazeCell cellPrefab;
private MazeCell[,] cells;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public MazeCell GetCell (IntVector2 coordinates) {
return cells[coordinates.x, coordinates.z];
}
public float generationStepDelay;
public IEnumerator Generate () {
WaitForSeconds delay = new WaitForSeconds(generationStepDelay);
cells = new MazeCell[size.x, size.z];
IntVector2 coordinates = RandomCoordinates;
while (ContainsCoordinates(coordinates) && GetCell(coordinates) = null) {
yield return delay;
CreateCell(coordinates);
coordinates += MazeDirections.RandomValue.ToIntVector2();
}
}
private void CreateCell (IntVector2 coordinates) {
MazeCell newCell = Instantiate(cellPrefab) as MazeCell;
cells[coordinates.x, coordinates.z] = newCell;
newCell.name = "Maze Cell " + coordinates.x + ", " + coordinates.z;
newCell.coordinates = coordinates;
newCell.transform.parent = transform;
newCell.transform.localPosition = new Vector3(coordinates.x - size.x * 0.5f + 0.5f, 0f, coordinates.z - size.z * 0.5f + 0.5f);
}
public IntVector2 RandomCoordinates {
get {
return new IntVector2(Random.Range(0, size.x), Random.Range(0, size.z));
}
}
public bool ContainsCoordinates (IntVector2 coordinate) {
return coordinate.x >= 0 && coordinate.x < size.x && coordinate.z >= 0 && coordinate.z < size.z;
}
}
The one that is not shown is size

Loading an X position between classes gives a "field is never assigned to" warning

So I created a small game in XNA and I am at the stage of coding AI. The problem I have currently is that I can't load the X position of the redNinja (player's character) and have the blueNinja (AI) read it and walk towards it.
Every time I try to reference it via redNinja.Position.X, it gives me the field is never assigned to, and will always have it's default value null. warning.
namespace Ninja_DM
{
class AI
{
Texture2D blueNinja;
Ninjas redNinja;
float timer = 0f;
float interval = 130f;
int currentFrame = 0;
int spriteSpeed = 2;
int spriteWidth = 32;
int spriteHeight = 28;
public Rectangle sourceRect;
Vector2 position_b;
Vector2 origin;
public Vector2 Position
{
get { return position_b; }
set { position_b = value; }
}
public Vector2 Origin
{
get { return origin; }
set { origin = value; }
}
public Texture2D Texture
{
get { return blueNinja; }
set { blueNinja = value; }
}
public Rectangle SourceRect
{
get { return sourceRect; }
set { sourceRect = value; }
}
public AI(Texture2D texture, int currentFrame, int spriteWidth, int spriteHeight)
{
this.blueNinja = texture;
this.currentFrame = currentFrame;
this.spriteWidth = spriteWidth;
this.spriteHeight = spriteHeight;
}
public void AIMovement(GameTime gameTime)
{
sourceRect = new Rectangle(30 * currentFrame, 0, 30, 37);
if (position_b.X > redNinja.Position.X)
{
AnimateLeftAI(gameTime);
if (position_b.X < 20)
{
position_b.X += spriteSpeed;
}
}
if (position_b.X < redNinja.Position.X)
{
AnimateRightAI(gameTime);
if (position_b.X < 1100)
{
position_b.X += spriteSpeed;
}
}
}
public void AnimateLeftAI(GameTime gameTime)
{
timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
if (timer > interval)
{
currentFrame++;
if (currentFrame > 4)
{
currentFrame = 3;
}
timer = 0f;
}
}
public void AnimateRightAI(GameTime gameTime)
{
timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
if (timer > interval)
{
currentFrame++;
if (currentFrame > 4)
{
currentFrame = 3;
}
timer = 0f;
}
}
}
}
you would need to bring the player's ninja as an argument when calling AIMovement(), something like this:
public void AIMovement(GameTime gameTime, Ninjas playerNinja)
{
sourceRect = new Rectangle(30 * currentFrame, 0, 30, 37);
if (position_b.X > playerNinja.Position.X)
{
AnimateLeftAI(gameTime);
if (position_b.X < 20)
{
position_b.X += spriteSpeed;
}
}
if (position_b.X < playerNinja.Position.X)
{
AnimateRightAI(gameTime);
if (position_b.X < 1100)
{
position_b.X += spriteSpeed;
}
}
}
Notice you really don't need to declare a field variable called redNinja anymore because you bring the Ninjas in that you are testing against as arguments/parameters of the method.

Categories