I'm trying to access my scrollrect, to know whether or not the component's drag is used, but the on-drag method is a function as the documentation says, some idea of how to access ondrag like:
"if ondrag is active ....."
See ScrollRect.OnBeginDrag and ScrollRect.OnEndDrag
You can simply use the interfaces IBeginDragHandler and IEndDragHandler on your own component and e.g. set a bool there
public class YourComponent : MonoBehaviour, IBeginDragHandler, IEndDragHandler
{
public bool isDrag { get; private set; }
public void OnBeginDrag()
{
isDrag = true;
}
public void OnEndDrag()
{
isDrag = false;
}
}
and than check this bool instead
if(GetComponent<YourComponent>.isDrag) // ....
Related
I need to call a protected variable from a public class into an if statement in a private method of another public class
I am programing a video game in unity and I need to use a bool variable (that shows if the character is out of stamina) in an if statement to determine whether or not the character can run
This is what my code looks like excluding everything unrelated to the problem
Public class CharacterStats : MonoBehaviour
{
[SerialzeField] protected bool Tired;
}
Public class PlayerMovement : MonoBehaviour
{
Private void HandleRunning()
{
If (Input.GetKeyDown(KeyCode.LeftShift) && X != True)
{
Speed = RunSpeed;
}
}
}
X is where I want the Tired variable to be.
Use a public readonly property like e.g.
public class CharacterStats : MonoBehaviour
{
// Keep you serialized field protected
[SerialzeField] protected bool tired;
// Have a public read-only accessor property
public bool Tired => tired;
}
and then e.g.
public class PlayerMovement : MonoBehaviour
{
// Somehow you will need to get a reference to the CharacterStats instance
// e.g. via the Inspector
[SerializeField] private CharacterStats stats;
[SerializeField] private float RunSpeed;
private float Speed;
private void HandleRunning()
{
if (Input.GetKeyDown(KeyCode.LeftShift) && !stats.IsTired)
{
Speed = RunSpeed;
}
}
}
Alternatively (and my apologies to #aybe who had answered this) you can actually directly serialize a property using explicitely
[field: SerializeField] public bool Tired { get; protected set; }
this is a property which can be accessed by everyone but only this and inherited classes (and due to the serialization now the Inspector) have the permission to set the value.
In general: Fix your casing! In c# all keywords are lower key!
I am controlling a text GameObject. I am performing operations such as SetActive() and changing the text of the gameObject. Now I am duplicating the same object and I want the duplicated object to follow the behaviors of its main gameObject. That is ObjA is parent and ObjB is a clone. If I change the text UI through code of objA, I want objB to automatically change its component. How do I achieve this behavior?
There are multiple ways to do that, but it will always be by code, there is no "authomatism" to do that.
So by code you can make a relation child to parent or parent to child.
One way could be that one:
public class Parent : MonoBehaviour
{
public Child child = null;
public void DoSomething()
{
this.gameObject.SetActive(true);
child.DoSomething();
}
}
public class Child : MonoBehaviour
{
public void DoSomething()
{
this.gameObject.SetActive(true);
}
}
Another fancy way to do that is using delegates, or Actions:
public class Parent : MonoBehaviour
{
public Action OnDoSomething = null;
public Action OnDoSomethingElse = null;
public void DoSomething()
{
this.gameObject.SetActive(false);
OnDoSomething();
}
public void DoSomethingElse()
{
this.gameObject.SetActive(true);
OnDoSomethingElse();
}
}
public class Child : MonoBehaviour
{
public Parent parent = null;
public void Awake()
{
parent.OnDoSomething += ChildDoSometing;
parent.OnDoSomethingElse += ChildDoSometingElse;
}
public void OnDestroy()
{
parent.OnDoSomething -= ChildDoSometing;
parent.OnDoSomethingElse -= ChildDoSometingElse;
}
public void ChildDoSometing()
{
this.gameObject.SetActive(false);
}
public void ChildDoSometingElse()
{
this.gameObject.SetActive(false);
}
}
You can be tempted to pass your own method as Action parameter like Action<Action> but remember that child will call parent method, won't operate on his own. So in this case if you do something like:
public class Parent : MonoBehaviour
{
public Action<Action> OnDoSomething = null;
[ContextMenu("A")]
public void DoSomething()
{
this.gameObject.SetActive(true);
OnDoSomething(this.DoSomething);
}
public void DoSomethingElse()
{
print("Hello");
}
}
public class Child : MonoBehaviour
{
public Parent parent = null;
public void Awake()
{
parent.OnDoSomething += RepeatedAction;
}
public void OnDestroy()
{
parent.OnDoSomething -= RepeatedAction;
}
public void RepeatedAction(Action actionToRepeat)
{
actionToRepeat?.Invoke();
}
}
Will result on StackOverflow exception, cause child will call parent, who calls child, who calls again parent...you can see the problem.
Anyway would be nice to declare an abstract base class that have all the methods, and let both classes inherit from that class, and implement those methods.
I have a class in Unity 2017 that only shows some of the public methods in the inspector.
using System.Collections.Generic;
using UnityEngine;
public class Inventory : MonoBehaviour
{
List<ShipPart> _inventory;
int currentInvPosition = 0;
bool invExists = false;
// Use this for initialization
void Start () {
CreateInventory(0, 0);
}
// Show all inventory parts as gameobjects
public void CreateInventory(int quality, int part)
{
...
}
void DestroyInventory()
{
...
}
public void ScrollInvLeft()
{
...
}
public void ScrollInvRight()
{
...
}
void UpdateInv(float offset)
{
...
}
public void AddInventoryItem(ShipPart newShipPart)
{
...
}
public void RemoveInventoryItem(ShipPart oldShipPart)
{
...
}
public void Test1(){}
public void Test2(int i){}
}
I thought it might be because the invisible methods have parameters, so I added the last two methods. However they are visible in the inspector!
I am trying to call the methods from a dropdown UI element, but have also tested from a button and that cant see them either.
What am I doing wrong?
As indicated in the official Unity tutorials, if you want to provide a function to an event in the inspector, the function must meet the following requirements:
The function must be public
The function must have a return type of void
The function must take no or one parameter
If the function takes one parameter, the latter must be one of the following types:
int
float
string
bool
UnityEngine.Object, or any type inheriting from UnityEngine.Object (such as GameObject, MonoBehaviour, ScriptableObject, ...)
I have a problem.
I have in my new table two new fields
1) Name -> AccountNum, EDT--> DimensionDynamicAccount
2) Name -> AccountType, EDT--> LedgerJournalACType
class declaration
:
public class FormRun extends ObjectRun
{
DimensionDynamicAccountController dimAccountController;
}
init (for the form):
public void init()
{
super();
dimAccountController = DimensionDynamicAccountController::construct(
MyTable_ds,
fieldstr(MyTable, LedgerDimension),
fieldstr(MyTable, AccountType));
}
4. Override the following methods on the Segmented Entry control instance in the form design.
public void jumpRef()
{
dimAccountController.jumpRef();
}
public void loadAutoCompleteData(LoadAutoCompleteDataEventArgs _e)
{
super(_e);
dimAccountController.loadAutoCompleteData(_e);
}
public void segmentValueChanged(SegmentValueChangedEventArgs _e)
{
super(_e);
dimAccountController.segmentValueChanged(_e);
}
public void loadSegments()
{
super();
dimAccountController.parmControl(this);
dimAccountController.loadSegments();
}
public boolean validate()
{
boolean isValid;
isValid = super();
isValid = dimAccountController.validate() && isValid;
return isValid;
}
5. Override the following methods on the data source field that backs the Segmented Entry control.
public Common resolveReference(FormReferenceControl _formReferenceControl)
{
return dimAccountController.resolveReference();
}
Now my problem is Lookup only works for AccountType=="Ledger" not for customer, Vendor etc...
If I have a AccountType == Vendor or similant but different to Ledger I see this
I would want to have same the same thing that's in the LedgerJournalTrans Form
There is a solution,
thanks all,
enjoy
This might be too obvious, but I think you're missing the lookup() method.
See:
\Forms\LedgerJournalTransDaily\Designs\Design\[Tab:Tab]\[TabPage:OverViewTab]\[Grid:overviewGrid]\SegmentedEntry:LedgerJournalTrans_AccountNum\Methods\lookup
public void lookup()
{
if (!ledgerJournalEngine.accountNumLookup(ledgerJournalTrans_AccountNum,
ledgerJournalTrans,
ledgerJournalTrans.OffsetAccountType,
ledgerJournalTrans.parmOffsetAccount(),
ledgerJournalTrans_Asset))
{
super();
}
}
I am using getters and setters for variables to avoid checking if they are null. Also I don't need Start() and Awake() functions in most cases.
public Button[] TitlebarButtons
{
get { return titlebar_buttons ?? (titlebar_buttons = GetComponentsInChildren<Button>()); }
}
private Button[] titlebar_buttons;
public Color CloseButtonNormalColor
{
get { return TitlebarButtons[2].colors.normalColor; }
set
{
ColorBlock temp = ColorBlock.defaultColorBlock;
temp.normalColor = value;
temp.highlightedColor = TitlebarButtons[2].colors.highlightedColor;
temp.pressedColor = TitlebarButtons[2].colors.pressedColor;
TitlebarButtons[2].colors = temp;
}
}
And in Editor script I am trying to make CloseButtonNormalColor a Serialized Property:
private Title Title;
private SerializedProperty close_button_normal_color;
void OnEnable()
{
Title = (Title)target;
close_button_normal_color = serializedObject.FindProperty("CloseButtonNormalColor");
}
But when I'm using it, NullReferenceExeption appears.
close_button_normal_color.colorValue = EditorGUILayout.ColorField("Normal", close_button_normal_color.colorValue);
Is there any solution for that?
Usually to just exposes properties on inspector you can use
[ShowProperty]
public MyProperty {get; set;}
and fields
[SerializeField]
private myField;
i found two "workarounds" for this.
One come from this thread in unity forum:
https://forum.unity.com/threads/using-property-fields-in-custom-editor-when-using-auto-properties.828597/
So, you can:
public class ClassToCustomEditor
{
[field:SerializeField] public int CustomEditorProperty { get; set; }
}
and then in your custom editor script:
void OnEnable()
{
IsCraftable = serializedObject.FindProperty(
string.Format("<{0}>k__BackingField", "IsCraftable")
);
}
for me, in Unity 2020.1.14f1 works like a charm. If you need more details, i suggest you to visit the thread above.
The other work around is create private fields (whose FindProperty find) and then create propeties who access and modify these fields.
Something like:
public class MyClassToCustomEditor
{
[SerializeField] private string itemName;
public string ItemName
{
get { return itemName; }
set { itemName = value; }
}
}
and then the FindProperty would be able to find it right the way you write it.