How can I select object in hierarchy in Unity via script? - c#

private void CheckingSelection() {
Transform child = Selection.activeTransform;
Transform[] patchesTransform = builder.GetLevelEditorPatchesTransform();
foreach (var parent in patchesTransform) {
if (child.IsChildOf(parent) && child != parent) {
Debug.Log("Set active " + parent.gameObject);
Selection.activeGameObject = parent.gameObject;
}
}
}
That's what I do, but it does not select the parent. What am I do wrong ?

The deal is how I called method CheckingSelection();
I added this method to delegate Selection.selectionChanged. And I thought its kind of logical things to do my checking after selecting something. But it was not working. It might be of internal Unity things, that block recursy or some.
So, I addedCheckingSelection() method to EditorApplication.update delegate, and it works.

Related

How to store functions inside of functions in a LIST?

How do I store function inside a function in a List<>?
I know its a bit confusing but idk how to explain it in more details. That's how I understand my problem.
So I wanna store functions inside a List<> and one of the functions consists another functions inside it. Since the List is executed as first in first out, when it comes to the functions with another functions, I want it to execute the child until it finishes before it continues to another element in the parent List.
For scenario, the method with another method inside is A Loop. I want it to iterate until certain condition is met then it stops. Then, continues to another method store in parents List.
As for now, I can store method inside List. It just idk how to execute the method inside method.
Here is the sneak peak of the code :/
private List<Function_> TranslateCodeFromBlocks(Transform parent, List<Function_> sequence_, List<Function_> insideLoop)
{
foreach (Transform child in parent)
{
var functionName = child.name.Split('_');
if (functionName[0] == "Function")
{
string function = functionName[1];
switch (function)
{
case "MoveRight":
sequence_.Add(new MoveRight("MoveRight"));
break;
case "MoveLeft":
sequence_.Add(new MoveLeft("MoveLeft"));
break;
case "MoveUp":
sequence_.Add(new MoveUp("MoveUp"));
break;
case "MoveDown":
sequence_.Add(new MoveDown("MoveDown"));
break;
case "MoveLoop":
foreach (Transform compLoop in parent)
{
var loopName = child.name.Split('_');
if (loopName[0] == "Function")
{
string tempLoop = loopName[1];
switch (function)
{
case "MoveRight":
insideLoop.Add(new MoveRight("MoveRight"));
break;
case "MoveLeft":
insideLoop.Add(new MoveLeft("MoveLeft"));
break;
case "MoveUp":
insideLoop.Add(new MoveUp("MoveUp"));
break;
case "MoveDown":
insideLoop.Add(new MoveDown("MoveDown"));
break;
}
}
}
sequence_.Add(new MoveLoop(insideLoop)); //this return error. Idk what to code, im stucked here.
break;
}
}
}
return sequence_;
}
}
It's a bit complicated, I hope you guys understand it. so as you can see, when it comes to MoveLoop (which consists few game object), I want the code to find each of the child and add it into another List<> which called insideLoop. This List<> will execute just normal, it's just happen to be inside of another functions called MoveLoop. The rest beside MoveLoop, is added into the parent List<> called sequence.
public MainLoop(Rigidbody2D mainTarget, List<Function_> sequence_)
{
this.end = false;
this.stop = false;
this.mainTarget = mainTarget;
this.sequence_ = sequence_;
}
public IEnumerator Play()
{
int i;
foreach (Function_ fun in this.sequence_)
{
fun.Func(this.mainTarget);
this.stop = true;
Stop();
yield return new WaitForSeconds(1);
}
}
}
And then this code is to execute the List<> called Sequence which is the parent List<>. How do I call and execute the List<> insideLoop while List<> Sequence_ is being executed?
public class MoveUp : Function_ {
public MoveUp(string ID) : base(ID)
{
this.ID = ID;
}
override public void Func(Rigidbody2D mainTarget)
{
Vector2 position = mainTarget.position;
position.y += 50;
mainTarget.MovePosition(position);
moveUp = true;
}
public class MoveRight : Function_ {
public MoveRight(string ID) : base(ID)
{
this.ID = ID;
}
override public void Func(Rigidbody2D mainTarget)
{
Vector2 position = mainTarget.position;
moveRight = true;
position.x += 45;
mainTarget.MovePosition(position);
}
Here are few sneak peak of what the MoveUp, MoveRight do.
Im new to this so pardon me if my programming terms are wrong.
EDIT: Problem Solved.
You can store delegates within a list.
List<Func<int, int>> funcs = new List<Func<int, int>>();
funcs.Add(i => i * 2);
funcs[0].Invoke(1); //returns 2
Please, take a look at Func, Action and Predicate delegates, see Delegates: Predicate vs. Action vs. Func .

How to pass argument to method in EventTrigger from script C# Unity

Hi,
I have problem with event triggers. I don't know how can I pass an argument to my function. I need to do it through editor, because I have a lot of objects that use this script and this method is only difference between them.
It is fragment of my code, simplify for question:
public override void OnEndDrag(PointerEventData data)
{
lpbc = null;
if (data.pointerCurrentRaycast.gameObject == null || data.pointerCurrentRaycast.gameObject.tag!="Field")
{
return;
}
if (data.pointerCurrentRaycast.gameObject.tag == "Field")
{
//some methods to define my go
GameObject go;
//HERE I want to call function from picture BUT with my go
//when I do below line, I can call EndDrag with my function, but how to pass my argument??????????
base.OnEndDrag(data);
}
}

LayoutRebuilder.ForceRebuildLayoutImmediate not rebuilding HorizontalLayoutGroup Unity

I'm working on a component where I need the correct anchored positions of children of a HorizontalLayoutGroup in the Start function.
I can force the HorizontalLayoutGroup to rebuild by doing:
public HorizontalLayoutGroup horizLayoutGroup;
public RectTransform exampleChild;
private void Start()
{
horizLayoutGroup.CalculateLayoutInputHorizontal();
horizLayoutGroup.CalculateLayoutInputVertical();
horizLayoutGroup.SetLayoutHorizontal();
horizLayoutGroup.SetLayoutVertical();
Debug.Log(exampleChild.anchoredPosition);
}
But it seems odd that doing:
public RectTransform horizRectTransform;
public RectTransform exampleChild;
private void Start()
{
LayoutRebuilder.ForceRebuildLayoutImmediate(horizRectTransform);
Debug.Log(exampleChild.anchoredPosition);
}
Does not work, because as far as I can tell from the source code LayoutRebuilder.ForceRebuildLayoutImmediate is calling the same functions:
public static void ForceRebuildLayoutImmediate(RectTransform layoutRoot)
{
var rebuilder = s_Rebuilders.Get();
rebuilder.Initialize(layoutRoot);
rebuilder.Rebuild(CanvasUpdate.Layout);
s_Rebuilders.Release(rebuilder);
}
public void Rebuild(CanvasUpdate executing)
{
switch (executing)
{
case CanvasUpdate.Layout:
// It's unfortunate that we'll perform the same GetComponents querys for the tree 2 times,
// but each tree have to be fully iterated before going to the next action,
// so reusing the results would entail storing results in a Dictionary or similar,
// which is probably a bigger overhead than performing GetComponents multiple times.
PerformLayoutCalculation(m_ToRebuild, e => (e as ILayoutElement).CalculateLayoutInputHorizontal());
PerformLayoutControl(m_ToRebuild, e => (e as ILayoutController).SetLayoutHorizontal());
PerformLayoutCalculation(m_ToRebuild, e => (e as ILayoutElement).CalculateLayoutInputVertical());
PerformLayoutControl(m_ToRebuild, e => (e as ILayoutController).SetLayoutVertical());
break;
}
}
And the whole purpose of it seems to be to rebuild layouts: Wiki Entry
Forces an immediate rebuild of the layout element and child layout elements affected by the calculations.
So yeah I don't really have a problem with this necessarily I'm just wondering why it doesn't work as one would expect it to. If anyone has more info on this I would be thrilled to hear it!
Links to the source code for things:
LayoutRebulider
HorizontalLayoutGroup
HorizontalOrVerticalLayoutGroup
LayoutGroup

Why is my Button not correctly registering the output?

I have the following code:
void Setup(CityBuilding[] buildings) {
foreach (CityBuilding building in buildings)
{
GameObject buildingDisp = Instantiate(singleGoodsDisplay);
//... Other stuff not relevent happens here
buildingDisp.GetComponent<Button>().onClick.AddListener(() => { ProcessClick(building); });
Debug.Log(building);
}
}
private void ProcessClick(CityBuilding building)
{
Debug.Log(building);
}
The bottom line is, I have a few buttons that are saved as a prefab and instantiated. I'm adding an onClick Listener to it, in the form of a lambda function. I'm passing in a data object. Right now buildings is an array of two. I see that both items are debugged, however, when I actually click on the buttons, I always see the second item is used, never the first. I'm not quite sure what I'm doing wrong. Any thoughts? Thanks!
It seems that the object reference isn't saved, it only uses the latest. What does work is to save a copy and pass it, as follows:
void Setup(CityBuilding[] buildings) {
foreach (CityBuilding building in buildings)
{
CityBuilding temp=building;
GameObject buildingDisp = Instantiate(singleGoodsDisplay);
//... Other stuff not relevent happens here
buildingDisp.GetComponent<Button>().onClick.AddListener(() => { ProcessClick(temp); });
}
}

Coded UI discovering controls

I have a ui coded ui test in visual studio 2010.
I want to write a code which will:
Discover all the controls on a window and child windows which are button, grid, label
write a uimap with the id which is the name of the control in the code.
For starting it, I've write the following:
public void CodedUITestMethod1()
{
string uiTestFileName = #"D:\dev11\ConsoleApplication1\TestProject1\UIMap.uitest";
UITest uiTest = UITest.Create(uiTestFileName);
Microsoft.VisualStudio.TestTools.UITest.Common.UIMap.UIMap newMap = new Microsoft.VisualStudio.TestTools.UITest.Common.UIMap.UIMap();
newMap.Id = "UIMap";
uiTest.Maps.Add(newMap);
GetAllChildren(BrowserWindow.Launch(new Uri("http://bing.com")), uiTest.Maps[0];);
uiTest.Save(uiTestFileName);
}
private void GetAllChildren(UITestControl uiTestControl, Microsoft.VisualStudio.TestTools.UITest.Common.UIMap.UIMap map)
{
foreach (UITestControl child in uiTestControl.GetChildren())
{
map.AddUIObject((IUITechnologyElement)child.GetProperty(UITestControl.PropertyNames.UITechnologyElement));
GetAllChildren(child, map);
}
}
But it insert into the recursive loop and doesn't end it.
Can anyone help me?
I think that to avoid possible infinite recursion you have to add this code:
private void GetAllChildren(UITestControl uiTestControl, Microsoft.VisualStudio.TestTools.UITest.Common.UIMap.UIMap map)
{
foreach (UITestControl child in uiTestControl.GetChildren())
{
IUITechnologyElement tElem=(IUITechnologyElement)child.GetProperty(UITestControl.PropertyNames.UITechnologyElement);
if (!map.Contains(tElem))
{
map.AddUIObject(tElem);
GetAllChildren(child, map);
}
}
}
This way you avoid to consider the same object multiple times and keep away from possible visual tree cycle.
Before you call map.AddUIObject and GetAllChildren in the foreach loop, check to make sure the object doesn't already exist in the map collection.
Check that the child has children before calling GetAllChildren(child, map)
if(child.HasChildren) {
GetAllChildren(child, map);
}

Categories